コード例 #1
0
  public static ProtobufMessages.Activation writeActivation(
      MarshallerWriteContext context, AgendaItem agendaItem) {
    ProtobufMessages.Activation.Builder _activation = ProtobufMessages.Activation.newBuilder();

    RuleImpl rule = agendaItem.getRule();
    _activation.setPackageName(rule.getPackage());
    _activation.setRuleName(rule.getName());
    _activation.setTuple(writeTuple(agendaItem.getTuple()));
    _activation.setSalience(agendaItem.getSalience());
    _activation.setIsActivated(agendaItem.isQueued());
    _activation.setEvaluated(agendaItem.isRuleAgendaItem());

    if (agendaItem.getActivationGroupNode() != null) {
      _activation.setActivationGroup(
          agendaItem.getActivationGroupNode().getActivationGroup().getName());
    }

    if (agendaItem.getFactHandle() != null) {
      _activation.setHandleId(agendaItem.getFactHandle().getId());
    }

    org.drools.core.util.LinkedList<LogicalDependency> list = agendaItem.getLogicalDependencies();
    if (list != null && !list.isEmpty()) {
      for (LogicalDependency node = list.getFirst(); node != null; node = node.getNext()) {
        _activation.addLogicalDependency(((BeliefSet) node.getJustified()).getFactHandle().getId());
      }
    }
    return _activation.build();
  }
コード例 #2
0
ファイル: OutputMarshaller.java プロジェクト: Orlandos/drools
  public static void writeActivation(
      MarshallerWriteContext context,
      LeftTuple leftTuple,
      AgendaItem agendaItem,
      RuleTerminalNode ruleTerminalNode)
      throws IOException {
    ObjectOutputStream stream = context.stream;

    stream.writeLong(agendaItem.getActivationNumber());

    stream.writeInt(context.terminalTupleMap.get(leftTuple));

    stream.writeInt(agendaItem.getSalience());

    Rule rule = agendaItem.getRule();
    stream.writeUTF(rule.getPackage());
    stream.writeUTF(rule.getName());

    // context.out.println( "Rule " + rule.getPackage() + "." + rule.getName() );

    // context.out.println( "AgendaItem long:" +
    // agendaItem.getPropagationContext().getPropagationNumber() );
    stream.writeLong(agendaItem.getPropagationContext().getPropagationNumber());

    if (agendaItem.getActivationGroupNode() != null) {
      stream.writeBoolean(true);
      // context.out.println( "ActivationGroup bool:" + true );
      stream.writeUTF(agendaItem.getActivationGroupNode().getActivationGroup().getName());
      // context.out.println( "ActivationGroup string:" +
      // agendaItem.getActivationGroupNode().getActivationGroup().getName() );
    } else {
      stream.writeBoolean(false);
      // context.out.println( "ActivationGroup bool:" + false );
    }

    stream.writeBoolean(agendaItem.isActivated());
    // context.out.println( "AgendaItem bool:" + agendaItem.isActivated() );

    if (agendaItem.getFactHandle() != null) {
      stream.writeBoolean(true);
      stream.writeInt(agendaItem.getFactHandle().getId());
    } else {
      stream.writeBoolean(false);
    }

    org.drools.core.util.LinkedList list = agendaItem.getLogicalDependencies();
    if (list != null && !list.isEmpty()) {
      for (LogicalDependency node = (LogicalDependency) list.getFirst();
          node != null;
          node = (LogicalDependency) node.getNext()) {
        stream.writeShort(PersisterEnums.LOGICAL_DEPENDENCY);
        stream.writeInt(((InternalFactHandle) node.getJustified()).getId());
        // context.out.println( "Logical Depenency : int " + ((InternalFactHandle)
        // node.getFactHandle()).getId() );
      }
    }
    stream.writeShort(PersisterEnums.END);
  }
コード例 #3
0
  private void doRiaNode(
      InternalWorkingMemory wm,
      LeftInputAdapterNode liaNode,
      PathMemory pmem,
      TupleSets<LeftTuple> srcTuples,
      BetaNode betaNode,
      LeftTupleSinkNode sink,
      SegmentMemory[] smems,
      int smemIndex,
      Memory nodeMem,
      BetaMemory bm,
      LinkedList<StackEntry> stack,
      RuleExecutor executor) {
    RiaPathMemory pathMem = bm.getRiaRuleMemory();
    SegmentMemory[] subnetworkSmems = pathMem.getSegmentMemories();
    SegmentMemory subSmem = null;
    for (int i = 0; subSmem == null; i++) {
      // segment positions outside of the subnetwork, in the parent chain, are null
      // so we must iterate to find the first non null segment memory
      subSmem = subnetworkSmems[i];
    }

    // Resume the node after the riaNode segment has been processed and the right input memory
    // populated
    StackEntry stackEntry =
        new StackEntry(
            liaNode,
            betaNode,
            bm.getNodePosMaskBit(),
            sink,
            pmem,
            nodeMem,
            smems,
            smemIndex,
            srcTuples,
            false,
            false);
    stack.add(stackEntry);
    if (log.isTraceEnabled()) {
      int offset = getOffset(betaNode);
      log.trace(
          "{} RiaQueue {} {}", indent(offset), betaNode.toString(), srcTuples.toStringSizes());
    }

    TupleSets<LeftTuple> subLts = subSmem.getStagedLeftTuples().takeAll();
    // node is first in the segment, so bit is 1
    innerEval(
        liaNode,
        pathMem,
        subSmem.getRootNode(),
        1,
        subSmem.getNodeMemories().getFirst(),
        subnetworkSmems,
        subSmem.getPos(),
        subLts,
        wm,
        stack,
        true,
        executor);
  }
コード例 #4
0
ファイル: ReteAgenda.java プロジェクト: chearius/drools
  public void clearAndCancelStagedActivations() {
    if (getStageActivationsGroup().isEmpty()) {
      return;
    }
    org.drools.core.util.LinkedList<ActivationGroupNode> list =
        getStageActivationsGroup().getList();

    final EventSupport eventsupport = (EventSupport) this.workingMemory;
    for (ActivationGroupNode node = list.removeFirst(); node != null; node = list.removeFirst()) {
      AgendaItem item = (AgendaItem) node.getActivation();
      // This must be set to false otherwise modify won't work properly
      item.setQueued(false);
      eventsupport
          .getAgendaEventSupport()
          .fireActivationCancelled(item, this.workingMemory, MatchCancelledCause.CLEAR);
    }
  }
コード例 #5
0
ファイル: ReteAgenda.java プロジェクト: chearius/drools
  public int unstageActivations() {
    if (!declarativeAgenda || getStageActivationsGroup().isEmpty()) {
      return 0;
    }
    org.drools.core.util.LinkedList<ActivationGroupNode> list =
        getStageActivationsGroup().getList();

    int i = 0;
    for (ActivationGroupNode node = list.removeFirst(); node != null; node = list.removeFirst()) {
      AgendaItem item = (AgendaItem) node.getActivation();
      item.setActivationGroupNode(null);

      addActivation(item, false);
      i++;
    }

    notifyHalt();

    return i;
  }
コード例 #6
0
  public static ProtobufMessages.Activation writeActivation(
      MarshallerWriteContext context, AgendaItem agendaItem) {
    ProtobufMessages.Activation.Builder _activation = ProtobufMessages.Activation.newBuilder();

    Rule rule = agendaItem.getRule();
    _activation.setPackageName(rule.getPackage());
    _activation.setRuleName(rule.getName());

    ProtobufMessages.Tuple.Builder _tb = ProtobufMessages.Tuple.newBuilder();
    for (LeftTuple entry = agendaItem.getTuple(); entry != null; entry = entry.getParent()) {
      InternalFactHandle handle = entry.getLastHandle();
      _tb.addHandleId(handle.getId());
    }
    _activation.setTuple(_tb.build());

    _activation.setSalience(agendaItem.getSalience());
    _activation.setIsActivated(agendaItem.isActivated());

    if (agendaItem.getActivationGroupNode() != null) {
      _activation.setActivationGroup(
          agendaItem.getActivationGroupNode().getActivationGroup().getName());
    }

    if (agendaItem.getFactHandle() != null) {
      _activation.setHandleId(agendaItem.getFactHandle().getId());
    }

    org.drools.core.util.LinkedList list = agendaItem.getLogicalDependencies();
    if (list != null && !list.isEmpty()) {
      for (LogicalDependency node = (LogicalDependency) list.getFirst();
          node != null;
          node = (LogicalDependency) node.getNext()) {
        _activation.addLogicalDependency(((InternalFactHandle) node.getJustified()).getId());
      }
    }
    return _activation.build();
  }
コード例 #7
0
 public void outerEval(
     LeftInputAdapterNode liaNode,
     PathMemory pmem,
     NetworkNode node,
     long bit,
     Memory nodeMem,
     SegmentMemory[] smems,
     int smemIndex,
     TupleSets<LeftTuple> trgTuples,
     InternalWorkingMemory wm,
     LinkedList<StackEntry> stack,
     boolean processRian,
     RuleExecutor executor) {
   innerEval(
       liaNode,
       pmem,
       node,
       bit,
       nodeMem,
       smems,
       smemIndex,
       trgTuples,
       wm,
       stack,
       processRian,
       executor);
   while (true) {
     // eval
     if (!stack.isEmpty()) {
       StackEntry entry = stack.removeLast();
       evalStackEntry(entry, stack, executor, wm);
     } else {
       return; // stack is empty return;
     }
   }
 }
コード例 #8
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;
  }
コード例 #9
0
  public static void writeTruthMaintenanceSystem(
      MarshallerWriteContext context, ProtobufMessages.RuleData.Builder _session)
      throws IOException {
    ObjectHashMap assertMap = context.wm.getTruthMaintenanceSystem().getAssertMap();
    ObjectHashMap justifiedMap = context.wm.getTruthMaintenanceSystem().getJustifiedMap();

    if (!assertMap.isEmpty() || !justifiedMap.isEmpty()) {
      EqualityKey[] keys = new EqualityKey[assertMap.size()];
      org.drools.core.util.Iterator it = assertMap.iterator();
      int i = 0;
      for (org.drools.core.util.ObjectHashMap.ObjectEntry entry =
              (org.drools.core.util.ObjectHashMap.ObjectEntry) it.next();
          entry != null;
          entry = (org.drools.core.util.ObjectHashMap.ObjectEntry) it.next()) {
        EqualityKey key = (EqualityKey) entry.getKey();
        keys[i++] = key;
      }

      Arrays.sort(keys, EqualityKeySorter.instance);

      ProtobufMessages.TruthMaintenanceSystem.Builder _tms =
          ProtobufMessages.TruthMaintenanceSystem.newBuilder();

      // write the assert map of Equality keys
      for (EqualityKey key : keys) {
        ProtobufMessages.EqualityKey.Builder _key = ProtobufMessages.EqualityKey.newBuilder();
        _key.setStatus(key.getStatus());
        _key.setHandleId(key.getFactHandle().getId());
        if (key.getOtherFactHandle() != null && !key.getOtherFactHandle().isEmpty()) {
          for (InternalFactHandle handle : key.getOtherFactHandle()) {
            _key.addOtherHandle(handle.getId());
          }
        }
        _tms.addKey(_key.build());
      }

      it = justifiedMap.iterator();
      i = 0;
      for (org.drools.core.util.ObjectHashMap.ObjectEntry entry =
              (org.drools.core.util.ObjectHashMap.ObjectEntry) it.next();
          entry != null;
          entry = (org.drools.core.util.ObjectHashMap.ObjectEntry) it.next()) {
        ProtobufMessages.Justification.Builder _justification =
            ProtobufMessages.Justification.newBuilder();
        _justification.setHandleId(((Integer) entry.getKey()).intValue());

        org.drools.core.util.LinkedList list = (org.drools.core.util.LinkedList) entry.getValue();
        for (LinkedListEntry node = (LinkedListEntry) list.getFirst();
            node != null;
            node = (LinkedListEntry) node.getNext()) {
          LogicalDependency dependency = (LogicalDependency) node.getObject();
          org.drools.spi.Activation activation = dependency.getJustifier();
          ProtobufMessages.Activation _activation =
              ProtobufMessages.Activation.newBuilder()
                  .setPackageName(activation.getRule().getPackage())
                  .setRuleName(activation.getRule().getName())
                  .setTuple(PersisterHelper.createTuple(activation.getTuple()))
                  .build();
          _justification.addActivation(_activation);
        }
        _tms.addJustification(_justification.build());
      }
      _session.setTms(_tms.build());
    }
  }
コード例 #10
0
ファイル: EqualityKey.java プロジェクト: hustmilan/drools
 public void writeExternal(ObjectOutput out) throws IOException {
   super.writeExternal(out);
   out.writeInt(hashCode);
   out.writeInt(status);
 }
コード例 #11
0
ファイル: EqualityKey.java プロジェクト: hustmilan/drools
 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
   super.readExternal(in);
   hashCode = in.readInt();
   status = in.readInt();
 }
コード例 #12
0
  private boolean evalQueryNode(
      LeftInputAdapterNode liaNode,
      PathMemory pmem,
      NetworkNode node,
      long bit,
      Memory nodeMem,
      SegmentMemory[] smems,
      int smemIndex,
      TupleSets<LeftTuple> trgTuples,
      InternalWorkingMemory wm,
      LinkedList<StackEntry> stack,
      TupleSets<LeftTuple> srcTuples,
      LeftTupleSinkNode sink,
      TupleSets<LeftTuple> stagedLeftTuples) {
    QueryElementNodeMemory qmem = (QueryElementNodeMemory) nodeMem;

    if (srcTuples.isEmpty() && qmem.getResultLeftTuples().isEmpty()) {
      // no point in evaluating query element, and setting up stack, if there is nothing to process
      return false;
    }

    QueryElementNode qnode = (QueryElementNode) node;

    if (log.isTraceEnabled()) {
      int offset = getOffset(node);
      log.trace(
          "{} query result tuples {}", indent(offset), qmem.getResultLeftTuples().toStringSizes());
    }

    // result tuples can happen when reactivity occurs inside of the query, prior to evaluation
    // we will need special behaviour to add the results again, when this query result resumes
    trgTuples.addAll(qmem.getResultLeftTuples());
    qmem.setNodeCleanWithoutNotify();

    if (!srcTuples.isEmpty()) {
      // only process the Query Node if there are src tuples
      StackEntry stackEntry =
          new StackEntry(
              liaNode, node, bit, sink, pmem, nodeMem, smems, smemIndex, trgTuples, true, true);

      stack.add(stackEntry);

      pQueryNode.doNode(
          qnode,
          (QueryElementNodeMemory) nodeMem,
          stackEntry,
          wm,
          srcTuples,
          trgTuples,
          stagedLeftTuples);

      SegmentMemory qsmem = ((QueryElementNodeMemory) nodeMem).getQuerySegmentMemory();
      List<PathMemory> qpmems = qsmem.getPathMemories();

      // Build the evaluation information for each 'or' branch
      for (int i = 0; i < qpmems.size(); i++) {
        PathMemory qpmem = qpmems.get(i);

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

        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();
          bit = 1;
        } else {
          // lia is in shared segment, so point to next node
          node = liaNode.getSinkPropagator().getFirstLeftTupleSink();
          nodeMem = smem.getNodeMemories().getFirst().getNext(); // skip the liaNode memory
          bit = 2;
        }

        trgTuples = smem.getStagedLeftTuples().takeAll();
        stackEntry =
            new StackEntry(
                liaNode, node, bit, null, pmem, nodeMem, smems, smemIndex, trgTuples, false, true);
        if (log.isTraceEnabled()) {
          int offset = getOffset(stackEntry.getNode());
          log.trace(
              "{} ORQueue branch={} {} {}",
              indent(offset),
              i,
              stackEntry.getNode().toString(),
              trgTuples.toStringSizes());
        }
        stack.add(stackEntry);
      }
      return true;
    } else {
      return false;
    }
  }
コード例 #13
0
  private void doRiaNode(
      InternalWorkingMemory wm,
      LeftInputAdapterNode liaNode,
      PathMemory rmem,
      LeftTupleSets srcTuples,
      BetaNode betaNode,
      LeftTupleSinkNode sink,
      SegmentMemory[] smems,
      int smemIndex,
      Memory nodeMem,
      BetaMemory bm,
      LinkedList<StackEntry> stack,
      Set<String> visitedRules,
      RuleExecutor executor) {
    RiaPathMemory pathMem = bm.getRiaRuleMemory();
    SegmentMemory[] subnetworkSmems = pathMem.getSegmentMemories();
    SegmentMemory subSmem = null;
    for (int i = 0; subSmem == null; i++) {
      // segment positions outside of the subnetwork, in the parent chain, are null
      // so we must iterate to find the first non null segment memory
      subSmem = subnetworkSmems[i];
    }

    //        if (betaNode.getLeftTupleSource().getSinkPropagator().size() == 2) {
    //            // sub network is not part of  share split, so need to handle propagation
    //            // this ensures the first LeftTuple is actually the subnetwork node
    //            // and the main outer network now receives the peer, notice the swap at the end
    // "srcTuples == peerTuples"
    //            LeftTupleSets peerTuples = new LeftTupleSets();
    //            SegmentPropagator.processPeers(srcTuples, peerTuples, betaNode);
    //            // Make sure subnetwork Segment has tuples to process
    //            LeftTupleSets subnetworkStaged = subSmem.getStagedLeftTuples();
    //            subnetworkStaged.addAll(srcTuples);
    //
    //            srcTuples.resetAll();
    //
    //            srcTuples = peerTuples;
    //        }

    // Resume the node after the riaNode segment has been processed and the right input memory
    // populated
    StackEntry stackEntry =
        new StackEntry(
            liaNode,
            betaNode,
            sink,
            rmem,
            nodeMem,
            smems,
            smemIndex,
            srcTuples,
            visitedRules,
            false);
    stack.add(stackEntry);
    if (log.isTraceEnabled()) {
      int offset = getOffset(betaNode);
      log.trace(
          "{} RiaQueue {} {}", indent(offset), betaNode.toString(), srcTuples.toStringSizes());
    }

    //        RightInputAdapterNode riaNode = ( RightInputAdapterNode ) betaNode.getRightInput();
    // RiaNodeMemory riaNodeMemory = (RiaNodeMemory) wm.getNodeMemory((MemoryFactory)
    // betaNode.getRightInput());
    // LeftTupleSets riaStagedTuples =
    eval2(
        liaNode,
        pathMem,
        (LeftTupleSink) subSmem.getRootNode(),
        subSmem.getNodeMemories().getFirst(),
        subnetworkSmems,
        subSmem.getPos(),
        subSmem.getStagedLeftTuples(),
        wm,
        stack,
        visitedRules,
        true,
        executor);
  }
コード例 #14
0
  public void eval2(
      LeftInputAdapterNode liaNode,
      PathMemory rmem,
      NetworkNode node,
      Memory nodeMem,
      SegmentMemory[] smems,
      int smemIndex,
      LeftTupleSets trgTuples,
      InternalWorkingMemory wm,
      LinkedList<StackEntry> stack,
      Set<String> visitedRules,
      boolean processRian,
      RuleExecutor executor) {
    LeftTupleSets srcTuples;
    SegmentMemory smem = smems[smemIndex];
    while (true) {
      srcTuples = trgTuples; // previous target, is now the source
      if (log.isTraceEnabled()) {
        int offset = getOffset(node);
        log.trace(
            "{} {} {} {}", indent(offset), ++cycle, node.toString(), srcTuples.toStringSizes());
      }

      if (NodeTypeEnums.isTerminalNode(node)) {
        TerminalNode rtn = (TerminalNode) node;
        if (node.getType() == NodeTypeEnums.QueryTerminalNode) {
          pQtNode.doNode((QueryTerminalNode) rtn, wm, srcTuples, stack);
        } else {
          pRtNode.doNode(rtn, wm, srcTuples, executor);
        }
        return;
      } else if (NodeTypeEnums.RightInputAdaterNode == node.getType()) {
        doRiaNode2(wm, srcTuples, (RightInputAdapterNode) node, stack);
        return;
      }

      LeftTupleSets stagedLeftTuples;
      if (node == smem.getTipNode() && smem.getFirst() != null) {
        // we are about to process the segment tip, allow it to merge insert/update/delete clashes
        // Can happen if the next segments have not yet been initialized
        stagedLeftTuples = smem.getFirst().getStagedLeftTuples();
      } else {
        stagedLeftTuples = null;
      }

      LeftTupleSinkNode sink = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink();

      trgTuples = new LeftTupleSets();

      if (NodeTypeEnums.isBetaNode(node)) {
        BetaNode betaNode = (BetaNode) node;

        BetaMemory bm = null;
        AccumulateMemory am = null;
        if (NodeTypeEnums.AccumulateNode == node.getType()) {
          am = (AccumulateMemory) nodeMem;
          bm = am.getBetaMemory();
        } else {
          bm = (BetaMemory) nodeMem;
        }

        if (processRian && betaNode.isRightInputIsRiaNode()) {
          // if the subnetwork is nested in this segment, it will create srcTuples containing
          // peer LeftTuples, suitable for the node in the main path.
          doRiaNode(
              wm,
              liaNode,
              rmem,
              srcTuples,
              betaNode,
              sink,
              smems,
              smemIndex,
              nodeMem,
              bm,
              stack,
              visitedRules,
              executor);
          return; // return here is doRiaNode queues the evaluation on the stack, which is necessary
          // to handled nested query nodes
        }

        if (!bm.getDequeu().isEmpty()) {
          // If there are no staged RightTuples, then process the Dequeue, popping entries, until
          // another insert/expiration clash
          RightTupleSets rightTuples = bm.getStagedRightTuples();
          if (rightTuples.isEmpty()) {
            // nothing staged, so now process the Dequeu
            Deque<RightTuple> que = bm.getDequeu();
            while (!que.isEmpty()) {
              RightTuple rightTuple = que.peekFirst();
              if (rightTuple.getPropagationContext().getType() == PropagationContext.EXPIRATION
                  &&
                  // Cannot pop an expired fact, if the insert/update has not yet been evaluated.
                  rightTuple.getStagedType() != LeftTuple.NONE) {
                break;
              }

              switch (rightTuple.getPropagationContext().getType()) {
                case PropagationContext.INSERTION:
                case PropagationContext.RULE_ADDITION:
                  rightTuples.addInsert(rightTuple);
                  break;
                case PropagationContext.MODIFICATION:
                  rightTuples.addUpdate(rightTuple);
                  break;
                case PropagationContext.DELETION:
                case PropagationContext.EXPIRATION:
                case PropagationContext.RULE_REMOVAL:
                  rightTuples.addDelete(rightTuple);
                  break;
              }
              que.removeFirst();
            }
          }

          if (!bm.getDequeu().isEmpty()) {
            // The DeQue is not empty, add StackEntry for reprocessing.
            StackEntry stackEntry =
                new StackEntry(
                    liaNode,
                    node,
                    sink,
                    rmem,
                    nodeMem,
                    smems,
                    smemIndex,
                    trgTuples,
                    visitedRules,
                    false);
            stack.add(stackEntry);
          }
        }

        switch (node.getType()) {
          case NodeTypeEnums.JoinNode:
            {
              pJoinNode.doNode(
                  (JoinNode) node, sink, bm, wm, srcTuples, trgTuples, stagedLeftTuples);
              break;
            }
          case NodeTypeEnums.NotNode:
            {
              pNotNode.doNode((NotNode) node, sink, bm, wm, srcTuples, trgTuples, stagedLeftTuples);
              break;
            }
          case NodeTypeEnums.ExistsNode:
            {
              pExistsNode.doNode(
                  (ExistsNode) node, sink, bm, wm, srcTuples, trgTuples, stagedLeftTuples);
              break;
            }
          case NodeTypeEnums.AccumulateNode:
            {
              pAccNode.doNode(
                  (AccumulateNode) node, sink, am, wm, srcTuples, trgTuples, stagedLeftTuples);
              break;
            }
        }
      } else {
        switch (node.getType()) {
          case NodeTypeEnums.EvalConditionNode:
            {
              pEvalNode.doNode(
                  (EvalConditionNode) node,
                  (EvalMemory) nodeMem,
                  sink,
                  wm,
                  srcTuples,
                  trgTuples,
                  stagedLeftTuples);
              break;
            }
          case NodeTypeEnums.FromNode:
            {
              pFromNode.doNode(
                  (FromNode) node,
                  (FromMemory) nodeMem,
                  sink,
                  wm,
                  srcTuples,
                  trgTuples,
                  stagedLeftTuples);
              break;
            }
          case NodeTypeEnums.QueryElementNode:
            {
              QueryElementNodeMemory qmem = (QueryElementNodeMemory) nodeMem;

              if (srcTuples.isEmpty() && qmem.getResultLeftTuples().isEmpty()) {
                // no point in evaluating query element, and setting up stack, if there is nothing
                // to process
                break;
              }

              QueryElementNode qnode = (QueryElementNode) node;
              if (visitedRules == Collections.<String>emptySet()) {
                visitedRules = new HashSet<String>();
              }
              visitedRules.add(qnode.getQueryElement().getQueryName());

              // result tuples can happen when reactivity occurs inside of the query, prior to
              // evaluation
              // we will need special behaviour to add the results again, when this query result
              // resumes
              trgTuples.addAll(qmem.getResultLeftTuples());

              if (!srcTuples.isEmpty()) {
                // only process the Query Node if there are src tuples
                StackEntry stackEntry =
                    new StackEntry(
                        liaNode,
                        node,
                        sink,
                        rmem,
                        nodeMem,
                        smems,
                        smemIndex,
                        trgTuples,
                        visitedRules,
                        true);

                stack.add(stackEntry);

                pQueryNode.doNode(
                    qnode, (QueryElementNodeMemory) nodeMem, stackEntry, sink, wm, srcTuples);

                SegmentMemory qsmem = ((QueryElementNodeMemory) nodeMem).getQuerySegmentMemory();
                List<PathMemory> qrmems = qsmem.getPathMemories();

                // Build the evaluation information for each 'or' branch
                // Exception fo the last, place each entry on the stack, the last one evaluate now.
                for (int i = qrmems.size() - 1; i >= 0; i--) {
                  PathMemory qrmem = qrmems.get(i);

                  rmem = qrmem;
                  smems = qrmem.getSegmentMemories();
                  smemIndex = 0;
                  smem = smems[smemIndex]; // 0
                  liaNode = (LeftInputAdapterNode) smem.getRootNode();

                  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
                  }

                  trgTuples = smem.getStagedLeftTuples();

                  if (i != 0 && !trgTuples.isEmpty()) {
                    // All entries except the last should be placed on the stack for evaluation
                    // later.
                    stackEntry =
                        new StackEntry(
                            liaNode,
                            node,
                            null,
                            rmem,
                            nodeMem,
                            smems,
                            smemIndex,
                            trgTuples,
                            visitedRules,
                            false);
                    if (log.isTraceEnabled()) {
                      int offset = getOffset(stackEntry.getNode());
                      log.trace(
                          "{} ORQueue branch={} {} {}",
                          indent(offset),
                          i,
                          stackEntry.getNode().toString(),
                          trgTuples.toStringSizes());
                    }
                    stack.add(stackEntry);
                  }
                }
                processRian = true; //  make sure it's reset, so ria nodes are processed
                continue;
              }
              break;
            }
          case NodeTypeEnums.ConditionalBranchNode:
            {
              pBranchNode.doNode(
                  (ConditionalBranchNode) node,
                  (ConditionalBranchMemory) nodeMem,
                  sink,
                  wm,
                  srcTuples,
                  trgTuples,
                  stagedLeftTuples,
                  executor);
              break;
            }
        }
      }

      if (node != smem.getTipNode()) {
        // get next node and node memory in the segment
        node = sink;
        nodeMem = nodeMem.getNext();
      } else {
        // Reached end of segment, start on new segment.
        SegmentPropagator.propagate(smem, trgTuples, wm);
        smem = smems[++smemIndex];
        trgTuples = smem.getStagedLeftTuples();
        if (log.isTraceEnabled()) {
          log.trace("Segment {}", smemIndex);
        }
        node = (LeftTupleSink) smem.getRootNode();
        nodeMem = smem.getNodeMemories().getFirst();
      }
      processRian = true; //  make sure it's reset, so ria nodes are processed
    }
  }
コード例 #15
0
  public void eval1(
      LeftInputAdapterNode liaNode,
      PathMemory rmem,
      NetworkNode node,
      Memory nodeMem,
      SegmentMemory[] smems,
      int smemIndex,
      LeftTupleSets trgTuples,
      InternalWorkingMemory wm,
      LinkedList<StackEntry> stack,
      Set<String> visitedRules,
      boolean processRian,
      RuleExecutor executor) {
    while (true) {
      eval2(
          liaNode,
          rmem,
          node,
          nodeMem,
          smems,
          smemIndex,
          trgTuples,
          wm,
          stack,
          visitedRules,
          processRian,
          executor);

      // eval
      if (!stack.isEmpty()) {
        StackEntry entry = stack.removeLast();

        node = entry.getNode();
        nodeMem = entry.getNodeMem();
        trgTuples = entry.getTrgTuples();
        if (node.getType() == NodeTypeEnums.QueryElementNode) {
          // copy across the results, if any from the query node memory
          trgTuples.addAll(((QueryElementNodeMemory) nodeMem).getResultLeftTuples());
        }

        LeftTupleSinkNode sink = entry.getSink();
        rmem = entry.getRmem();

        smems = entry.getSmems();
        smemIndex = entry.getSmemIndex();
        visitedRules = entry.getVisitedRules();
        if (NodeTypeEnums.isBetaNode(node)) {
          // queued beta nodes do not want their ria node evaluated, otherwise there is recursion
          processRian = false;
        } else {
          processRian = true;
        }

        if (entry.isResumeFromNextNode()) {
          SegmentMemory smem = smems[smemIndex];
          if (node != smem.getTipNode()) {
            // get next node and node memory in the segment
            LeftTupleSink nextSink = sink.getNextLeftTupleSinkNode();
            if (nextSink == null) {
              node = sink;
            } else {
              // there is a nested subnetwork, take out path
              node = nextSink;
            }

            nodeMem = nodeMem.getNext();
          } else {
            // Reached end of segment, start on new segment.
            SegmentPropagator.propagate(smem, trgTuples, wm);
            smem = smems[++smemIndex];
            trgTuples = smem.getStagedLeftTuples();
            node = (LeftTupleSink) smem.getRootNode();
            nodeMem = smem.getNodeMemories().getFirst();
          }
        }

        if (log.isTraceEnabled()) {
          int offset = getOffset(node);
          log.trace("{} Resume {} {}", indent(offset), node.toString(), trgTuples.toStringSizes());
        }
      } else {
        return; // stack is empty return;
      }
    }
  }