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); }
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)); }
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); }
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()); }