Example #1
0
  public synchronized int evaluateNetworkAndFire(
      InternalWorkingMemory wm, final AgendaFilter filter, int fireCount, int fireLimit) {
    LinkedList<StackEntry> outerStack = new LinkedList<StackEntry>();

    InternalAgenda agenda = (InternalAgenda) wm.getAgenda();
    boolean fireUntilHalt = agenda.isFireUntilHalt();

    reEvaluateNetwork(wm, outerStack, fireUntilHalt);
    wm.executeQueuedActions();

    return fire(wm, filter, fireCount, fireLimit, outerStack, agenda, fireUntilHalt);
  }
Example #2
0
  private boolean haltRuleFiring(
      RuleAgendaItem nextRule,
      int fireCount,
      int fireLimit,
      int localFireCount,
      InternalAgenda agenda,
      int salience) {

    return !agenda.continueFiring(0)
        || ((nextRule != null)
            && (!ruleAgendaItem.getRule().getAgendaGroup().equals(nextRule.getAgendaGroup())
                || !isHighestSalience(nextRule, salience)))
        || (fireLimit >= 0 && (localFireCount + fireCount >= fireLimit));
  }
Example #3
0
 public synchronized void fire(InternalWorkingMemory wm, LinkedList<StackEntry> outerStack) {
   InternalAgenda agenda = (InternalAgenda) wm.getAgenda();
   boolean fireUntilHalt = agenda.isFireUntilHalt();
   fire(wm, null, 0, Integer.MAX_VALUE, outerStack, agenda, fireUntilHalt);
 }
Example #4
0
  private int fire(
      InternalWorkingMemory wm,
      AgendaFilter filter,
      int fireCount,
      int fireLimit,
      LinkedList<StackEntry> outerStack,
      InternalAgenda agenda,
      boolean fireUntilHalt) {
    int localFireCount = 0;
    if (!tupleList.isEmpty()) {
      RuleTerminalNode rtn = (RuleTerminalNode) pmem.getNetworkNode();

      if (!fireExitedEarly && isDeclarativeAgendaEnabled()) {
        // Network Evaluation can notify meta rules, which should be given a chance to fire first
        RuleAgendaItem nextRule = agenda.peekNextRule();
        if (!isHighestSalience(nextRule, ruleAgendaItem.getSalience())) {
          fireExitedEarly = true;
          return localFireCount;
        }
      }

      while (!tupleList.isEmpty()) {
        LeftTuple leftTuple;
        if (queue != null) {
          leftTuple = (LeftTuple) queue.dequeue();
          tupleList.remove(leftTuple);
        } else {
          leftTuple = tupleList.removeFirst();
          ((Activation) leftTuple).setQueued(false);
        }

        rtn =
            (RuleTerminalNode)
                leftTuple
                    .getSink(); // branches result in multiple RTN's for a given rule, so unwrap per
        // LeftTuple
        RuleImpl rule = rtn.getRule();

        PropagationContext pctx = leftTuple.getPropagationContext();
        pctx = RuleTerminalNode.findMostRecentPropagationContext(leftTuple, pctx);

        // check if the rule is not effective or
        // if the current Rule is no-loop and the origin rule is the same then return
        if (cancelAndContinue(wm, rtn, rule, leftTuple, pctx, filter)) {
          continue;
        }

        AgendaItem item = (AgendaItem) leftTuple;
        if (agenda.getActivationsFilter() != null
            && !agenda.getActivationsFilter().accept(item, wm, rtn)) {
          // only relevant for seralization, to not refire Matches already fired
          continue;
        }

        agenda.fireActivation(item);
        localFireCount++;

        if (rtn.getLeftTupleSource() == null) {
          break; // The activation firing removed this rule from the rule base
        }

        int salience =
            ruleAgendaItem.getSalience(); // dyanmic salience may have updated it, so get again.
        if (queue != null && !queue.isEmpty() && salience != queue.peek().getSalience()) {
          ruleAgendaItem.dequeue();
          ruleAgendaItem.setSalience(queue.peek().getSalience());
          ruleAgendaItem.getAgendaGroup().add(ruleAgendaItem);
          salience = ruleAgendaItem.getSalience();
        }

        RuleAgendaItem nextRule = agenda.peekNextRule();
        if (haltRuleFiring(nextRule, fireCount, fireLimit, localFireCount, agenda, salience)) {
          break; // another rule has high priority and is on the agenda, so evaluate it first
        }
        reEvaluateNetwork(wm, outerStack, fireUntilHalt);
        wm.executeQueuedActions();

        if (tupleList.isEmpty() && !outerStack.isEmpty()) {
          // the outer stack is nodes needing evaluation, once all rule firing is done
          // such as window expiration, which must be done serially
          StackEntry entry = outerStack.removeFirst();
          NETWORK_EVALUATOR.evalStackEntry(entry, outerStack, outerStack, this, wm);
        }
      }
    }

    removeRuleAgendaItemWhenEmpty(wm);

    fireExitedEarly = false;
    return localFireCount;
  }
  private static void writeAgenda(
      MarshallerWriteContext context, ProtobufMessages.RuleData.Builder _ksb) throws IOException {
    InternalWorkingMemory wm = context.wm;
    InternalAgenda agenda = (InternalAgenda) wm.getAgenda();

    org.drools.core.marshalling.impl.ProtobufMessages.Agenda.Builder _ab =
        ProtobufMessages.Agenda.newBuilder();

    AgendaGroup[] agendaGroups =
        (AgendaGroup[])
            agenda
                .getAgendaGroupsMap()
                .values()
                .toArray(new AgendaGroup[agenda.getAgendaGroupsMap().size()]);
    Arrays.sort(agendaGroups, AgendaGroupSorter.instance);
    for (AgendaGroup ag : agendaGroups) {
      AgendaGroupQueueImpl group = (AgendaGroupQueueImpl) ag;
      org.drools.core.marshalling.impl.ProtobufMessages.Agenda.AgendaGroup.Builder _agb =
          ProtobufMessages.Agenda.AgendaGroup.newBuilder();
      _agb.setName(group.getName())
          .setIsActive(group.isActive())
          .setIsAutoDeactivate(group.isAutoDeactivate())
          .setClearedForRecency(group.getClearedForRecency())
          .setHasRuleFlowLister(group.isRuleFlowListener())
          .setActivatedForRecency(group.getActivatedForRecency());

      Map<Long, String> nodeInstances = group.getNodeInstances();
      for (Map.Entry<Long, String> entry : nodeInstances.entrySet()) {
        org.drools.core.marshalling.impl.ProtobufMessages.Agenda.AgendaGroup.NodeInstance.Builder
            _nib = ProtobufMessages.Agenda.AgendaGroup.NodeInstance.newBuilder();
        _nib.setProcessInstanceId(entry.getKey());
        _nib.setNodeInstanceId(entry.getValue());
        _agb.addNodeInstance(_nib.build());
      }

      _ab.addAgendaGroup(_agb.build());
    }

    org.drools.core.marshalling.impl.ProtobufMessages.Agenda.FocusStack.Builder _fsb =
        ProtobufMessages.Agenda.FocusStack.newBuilder();
    LinkedList<AgendaGroup> focusStack = agenda.getStackList();
    for (Iterator<AgendaGroup> it = focusStack.iterator(); it.hasNext(); ) {
      AgendaGroup group = it.next();
      _fsb.addGroupName(group.getName());
    }
    _ab.setFocusStack(_fsb.build());

    // serialize all dormant activations
    org.drools.core.util.Iterator it = ActivationIterator.iterator(wm);
    List<org.drools.core.spi.Activation> dormant = new ArrayList<org.drools.core.spi.Activation>();
    for (org.drools.core.spi.Activation item = (org.drools.core.spi.Activation) it.next();
        item != null;
        item = (org.drools.core.spi.Activation) it.next()) {
      if (!item.isQueued()) {
        dormant.add(item);
      }
    }
    Collections.sort(dormant, ActivationsSorter.INSTANCE);
    for (org.drools.core.spi.Activation activation : dormant) {
      _ab.addMatch(writeActivation(context, (AgendaItem) activation));
    }

    // serialize all network evaluator activations
    for (Activation activation : agenda.getActivations()) {
      if (activation.isRuleAgendaItem()) {
        // serialize it
        _ab.addRuleActivation(writeActivation(context, (AgendaItem) activation));
      }
    }

    _ksb.setAgenda(_ab.build());
  }