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