private void updateSalience(int currentSalience) { // the queue may be emtpy if no more matches are left, so reset it to default salience 0 int newSalience = queue.isEmpty() ? SalienceInteger.DEFAULT_SALIENCE.getValue() : queue.peek().getSalience(); if (currentSalience != newSalience) { // salience changed, so the RuleAgendaItem needs to be removed and re-added, for sorting ruleAgendaItem.remove(); } if (!ruleAgendaItem.isQueued()) { ruleAgendaItem.setSalience(newSalience); ruleAgendaItem.getAgendaGroup().add(ruleAgendaItem); } }
public void cancel(InternalWorkingMemory wm, EventSupport es) { while (!tupleList.isEmpty()) { RuleTerminalNodeLeftTuple rtnLt = (RuleTerminalNodeLeftTuple) tupleList.removeFirst(); if (queue != null) { queue.dequeue(rtnLt); } es.getAgendaEventSupport().fireActivationCancelled(rtnLt, wm, MatchCancelledCause.CLEAR); } }
public void addQueuedLeftTuple(LeftTuple leftTuple) { int currentSalience = queue.isEmpty() ? 0 : queue.peek().getSalience(); queue.enqueue((Activation) leftTuple); updateSalience(currentSalience); }
private void removeQueuedLeftTuple(LeftTuple leftTuple) { int currentSalience = queue.isEmpty() ? 0 : queue.peek().getSalience(); queue.dequeue(((Activation) leftTuple)); updateSalience(currentSalience); }
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; }