Пример #1
0
  public int evaluateNetwork(PathMemory pmem, InternalWorkingMemory wm, RuleExecutor executor) {
    SegmentMemory[] smems = pmem.getSegmentMemories();

    int smemIndex = 0;
    SegmentMemory smem = smems[smemIndex]; // 0
    LeftInputAdapterNode liaNode = (LeftInputAdapterNode) smem.getRootNode();

    NetworkNode node;
    Memory nodeMem;
    if (liaNode == smem.getTipNode()) {
      // segment only has liaNode in it
      // nothing is staged in the liaNode, so skip to next segment
      smem = smems[++smemIndex]; // 1
      node = smem.getRootNode();
      nodeMem = smem.getNodeMemories().getFirst();
    } else {
      // lia is in shared segment, so point to next node
      node = liaNode.getSinkPropagator().getFirstLeftTupleSink();
      nodeMem = smem.getNodeMemories().getFirst().getNext(); // skip the liaNode memory
    }

    LeftTupleSets srcTuples = smem.getStagedLeftTuples();

    if (log.isTraceEnabled()) {
      log.trace(
          "Rule[name={}] segments={} {}",
          ((TerminalNode) pmem.getNetworkNode()).getRule().getName(),
          smems.length,
          srcTuples.toStringSizes());
    }

    Set<String> visitedRules;
    if (((TerminalNode) pmem.getNetworkNode()).getType() == NodeTypeEnums.QueryTerminalNode) {
      visitedRules = new HashSet<String>();
    } else {
      visitedRules = Collections.<String>emptySet();
    }

    LinkedList<StackEntry> stack = new LinkedList<StackEntry>();
    eval1(
        liaNode,
        pmem,
        (LeftTupleSink) node,
        nodeMem,
        smems,
        smemIndex,
        srcTuples,
        wm,
        stack,
        visitedRules,
        true,
        executor);

    return 0;
  }
Пример #2
0
  public void evaluateNetwork(PathMemory pmem, RuleExecutor executor, InternalWorkingMemory wm) {
    SegmentMemory[] smems = pmem.getSegmentMemories();

    int smemIndex = 0;
    SegmentMemory smem = smems[smemIndex]; // 0
    LeftInputAdapterNode liaNode = (LeftInputAdapterNode) smem.getRootNode();

    LinkedList<StackEntry> stack = new LinkedList<StackEntry>();

    NetworkNode node;
    Memory nodeMem;
    long bit = 1;
    if (liaNode == smem.getTipNode()) {
      // segment only has liaNode in it
      // nothing is staged in the liaNode, so skip to next segment
      smem = smems[++smemIndex]; // 1
      node = smem.getRootNode();
      nodeMem = smem.getNodeMemories().getFirst();
    } else {
      // lia is in shared segment, so point to next node
      bit = 2;
      node = liaNode.getSinkPropagator().getFirstLeftTupleSink();
      nodeMem = smem.getNodeMemories().getFirst().getNext(); // skip the liaNode memory
    }

    TupleSets<LeftTuple> srcTuples = smem.getStagedLeftTuples();
    if (log.isTraceEnabled()) {
      log.trace(
          "Rule[name={}] segments={} {}",
          ((TerminalNode) pmem.getNetworkNode()).getRule().getName(),
          smems.length,
          srcTuples.toStringSizes());
    }
    outerEval(
        liaNode, pmem, node, bit, nodeMem, smems, smemIndex, srcTuples, wm, stack, true, executor);
  }
Пример #3
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;
  }