public void modifyChildLeftTuplesforQuery(
     final RightTuple rightTuple,
     final PropagationContext context,
     final InternalWorkingMemory workingMemory) {
   LeftTuple childLeftTuple = rightTuple.firstChild;
   while (childLeftTuple != null) {
     childLeftTuple.getLeftTupleSink().modifyLeftTuple(childLeftTuple, context, workingMemory);
     childLeftTuple = childLeftTuple.getRightParentNext();
   }
 }
 public void propagateRetractRightTuple(
     final RightTuple rightTuple,
     final PropagationContext context,
     final InternalWorkingMemory workingMemory) {
   LeftTuple child = rightTuple.firstChild;
   while (child != null) {
     LeftTuple temp = child.getRightParentNext();
     doPropagateRetractLeftTuple(context, workingMemory, child, child.getLeftTupleSink());
     child.unlinkFromLeftParent();
     child.unlinkFromRightParent();
     child = temp;
   }
 }
 public LeftTuple propagateRetractChildLeftTuple(
     LeftTuple childLeftTuple,
     LeftTuple parentLeftTuple,
     PropagationContext context,
     InternalWorkingMemory workingMemory) {
   // iterate to find all child tuples for the shared node
   while (childLeftTuple != null && childLeftTuple.getLeftParent() == parentLeftTuple) {
     // this will iterate for each child node when the
     // the current node is shared
     LeftTuple temp = childLeftTuple.getRightParentNext();
     doPropagateRetractLeftTuple(
         context, workingMemory, childLeftTuple, childLeftTuple.getLeftTupleSink());
     childLeftTuple.unlinkFromRightParent();
     childLeftTuple.unlinkFromLeftParent();
     childLeftTuple = temp;
   }
   return childLeftTuple;
 }
  public LeftTuple propagateModifyChildLeftTuple(
      LeftTuple childLeftTuple,
      LeftTuple parentLeftTuple,
      PropagationContext context,
      InternalWorkingMemory workingMemory,
      boolean tupleMemoryEnabled) {
    // iterate to find all child tuples for the shared node
    while (childLeftTuple != null && childLeftTuple.getLeftParent() == parentLeftTuple) {
      // this will iterate for each child node when the
      // the current node is shared

      // preserve the current LeftTuple, as we need to iterate to the next before re-adding
      LeftTuple temp = childLeftTuple;
      childLeftTuple.getLeftTupleSink().modifyLeftTuple(childLeftTuple, context, workingMemory);
      childLeftTuple = childLeftTuple.getRightParentNext();
      temp.reAddLeft();
    }
    return childLeftTuple;
  }
Exemplo n.º 5
0
 private void removePreviousMatchesForRightTuple(
     final RightTuple rightTuple,
     final PropagationContext context,
     final InternalWorkingMemory workingMemory,
     final AccumulateMemory memory,
     final LeftTuple firstChild) {
   for (LeftTuple match = firstChild; match != null; ) {
     final LeftTuple tmp = match.getRightParentNext();
     final LeftTuple parent = match.getLeftParent();
     final AccumulateContext accctx = (AccumulateContext) parent.getObject();
     removeMatch(rightTuple, match, workingMemory, memory, accctx, true);
     if (accctx.getAction() == null) {
       // schedule a test to evaluate the constraints, this is an optimisation for sub networks
       // We set Source to LEFT, even though this is a right propagation, because it might end up
       // doing multiple right propagations anyway
       EvaluateResultConstraints action =
           new EvaluateResultConstraints(
               ActivitySource.LEFT, parent, context, workingMemory, memory, accctx, true, this);
       accctx.setAction(action);
       context.addInsertAction(action);
     }
     match = tmp;
   }
 }
Exemplo n.º 6
0
  public static void writeLeftTuple(
      LeftTuple leftTuple, MarshallerWriteContext context, boolean recurse) throws IOException {
    ObjectOutputStream stream = context.stream;
    InternalRuleBase ruleBase = context.ruleBase;
    InternalWorkingMemory wm = context.wm;

    LeftTupleSink sink = leftTuple.getLeftTupleSink();

    switch (sink.getType()) {
      case NodeTypeEnums.JoinNode:
        {
          // context.out.println( "JoinNode" );
          for (LeftTuple childLeftTuple = leftTuple.getFirstChild();
              childLeftTuple != null;
              childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) {
            stream.writeShort(PersisterEnums.RIGHT_TUPLE);
            int childSinkId = childLeftTuple.getLeftTupleSink().getId();
            stream.writeInt(childSinkId);
            stream.writeInt(childLeftTuple.getRightParent().getFactHandle().getId());
            // context.out.println( "RightTuple int:" + childLeftTuple.getLeftTupleSink().getId() +
            // " int:" + childLeftTuple.getRightParent().getFactHandle().getId() );
            writeLeftTuple(childLeftTuple, context, recurse);
          }
          stream.writeShort(PersisterEnums.END);
          // context.out.println( "JoinNode   ---   END" );
          break;
        }
      case NodeTypeEnums.QueryRiaFixerNode:
      case NodeTypeEnums.EvalConditionNode:
        {
          // context.out.println( ".... EvalConditionNode" );
          for (LeftTuple childLeftTuple = leftTuple.getFirstChild();
              childLeftTuple != null;
              childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) {
            stream.writeShort(PersisterEnums.LEFT_TUPLE);
            stream.writeInt(childLeftTuple.getLeftTupleSink().getId());
            writeLeftTuple(childLeftTuple, context, recurse);
          }
          stream.writeShort(PersisterEnums.END);
          // context.out.println( "---- EvalConditionNode   ---   END" );
          break;
        }
      case NodeTypeEnums.NotNode:
      case NodeTypeEnums.ForallNotNode:
        {
          if (leftTuple.getBlocker() == null) {
            // is not blocked so has children
            stream.writeShort(PersisterEnums.LEFT_TUPLE_NOT_BLOCKED);

            for (LeftTuple childLeftTuple = leftTuple.getFirstChild();
                childLeftTuple != null;
                childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) {
              stream.writeShort(PersisterEnums.LEFT_TUPLE);
              stream.writeInt(childLeftTuple.getLeftTupleSink().getId());
              writeLeftTuple(childLeftTuple, context, recurse);
            }
            stream.writeShort(PersisterEnums.END);

          } else {
            stream.writeShort(PersisterEnums.LEFT_TUPLE_BLOCKED);
            stream.writeInt(leftTuple.getBlocker().getFactHandle().getId());
          }
          break;
        }
      case NodeTypeEnums.ExistsNode:
        {
          if (leftTuple.getBlocker() == null) {
            // is blocked so has children
            stream.writeShort(PersisterEnums.LEFT_TUPLE_NOT_BLOCKED);
          } else {
            stream.writeShort(PersisterEnums.LEFT_TUPLE_BLOCKED);
            stream.writeInt(leftTuple.getBlocker().getFactHandle().getId());

            for (LeftTuple childLeftTuple = leftTuple.getFirstChild();
                childLeftTuple != null;
                childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) {
              stream.writeShort(PersisterEnums.LEFT_TUPLE);
              stream.writeInt(childLeftTuple.getLeftTupleSink().getId());
              writeLeftTuple(childLeftTuple, context, recurse);
            }
            stream.writeShort(PersisterEnums.END);
          }
          break;
        }
      case NodeTypeEnums.AccumulateNode:
        {
          // context.out.println( ".... AccumulateNode" );
          // accumulate nodes generate new facts on-demand and need special procedures when
          // serializing to persistent storage
          AccumulateMemory memory = (AccumulateMemory) context.wm.getNodeMemory((BetaNode) sink);
          AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();
          // first we serialize the generated fact handle
          writeFactHandle(
              context,
              stream,
              context.objectMarshallingStrategyStore,
              accctx.result.getFactHandle());
          // then we serialize the associated accumulation context
          stream.writeObject(accctx.context);
          // then we serialize the boolean propagated flag
          stream.writeBoolean(accctx.propagated);

          // then we serialize all the propagated tuples
          for (LeftTuple childLeftTuple = leftTuple.getFirstChild();
              childLeftTuple != null;
              childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) {
            if (leftTuple.getLeftTupleSink().getId() == childLeftTuple.getLeftTupleSink().getId()) {
              // this is a matching record, so, associate the right tuples
              // context.out.println( "RightTuple(match) int:" +
              // childLeftTuple.getLeftTupleSink().getId() + " int:" +
              // childLeftTuple.getRightParent().getFactHandle().getId() );
              stream.writeShort(PersisterEnums.RIGHT_TUPLE);
              stream.writeInt(childLeftTuple.getRightParent().getFactHandle().getId());
            } else {
              // this is a propagation record
              // context.out.println( "RightTuple(propagation) int:" +
              // childLeftTuple.getLeftTupleSink().getId() + " int:" +
              // childLeftTuple.getRightParent().getFactHandle().getId() );
              stream.writeShort(PersisterEnums.LEFT_TUPLE);
              int sinkId = childLeftTuple.getLeftTupleSink().getId();
              stream.writeInt(sinkId);
              writeLeftTuple(childLeftTuple, context, recurse);
            }
          }
          stream.writeShort(PersisterEnums.END);
          // context.out.println( "---- AccumulateNode   ---   END" );
          break;
        }
      case NodeTypeEnums.RightInputAdaterNode:
        {
          // context.out.println( ".... RightInputAdapterNode" );
          // RIANs generate new fact handles on-demand to wrap tuples and need special procedures
          // when serializing to persistent storage
          ObjectHashMap memory = (ObjectHashMap) context.wm.getNodeMemory((NodeMemory) sink);
          InternalFactHandle ifh = (InternalFactHandle) memory.get(leftTuple);
          // first we serialize the generated fact handle ID
          // context.out.println( "FactHandle id:"+ifh.getId() );
          stream.writeInt(ifh.getId());
          stream.writeLong(ifh.getRecency());

          writeRightTuples(ifh, context);

          stream.writeShort(PersisterEnums.END);
          // context.out.println( "---- RightInputAdapterNode   ---   END" );
          break;
        }
      case NodeTypeEnums.FromNode:
        {
          // context.out.println( ".... FromNode" );
          // FNs generate new fact handles on-demand to wrap objects and need special procedures
          // when serializing to persistent storage
          FromMemory memory = (FromMemory) context.wm.getNodeMemory((NodeMemory) sink);

          Map<Object, RightTuple> matches = (Map<Object, RightTuple>) leftTuple.getObject();
          for (RightTuple rightTuples : matches.values()) {
            // first we serialize the generated fact handle ID
            stream.writeShort(PersisterEnums.FACT_HANDLE);
            writeFactHandle(
                context,
                stream,
                context.objectMarshallingStrategyStore,
                rightTuples.getFactHandle());
            writeRightTuples(rightTuples.getFactHandle(), context);
          }
          stream.writeShort(PersisterEnums.END);
          for (LeftTuple childLeftTuple = leftTuple.getFirstChild();
              childLeftTuple != null;
              childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) {
            stream.writeShort(PersisterEnums.RIGHT_TUPLE);
            stream.writeInt(childLeftTuple.getLeftTupleSink().getId());
            stream.writeInt(childLeftTuple.getRightParent().getFactHandle().getId());
            // context.out.println( "RightTuple int:" + childLeftTuple.getLeftTupleSink().getId() +
            // " int:" + childLeftTuple.getRightParent().getFactHandle().getId() );
            writeLeftTuple(childLeftTuple, context, recurse);
          }
          stream.writeShort(PersisterEnums.END);
          // context.out.println( "---- FromNode   ---   END" );
          break;
        }
      case NodeTypeEnums.UnificationNode:
        {
          // context.out.println( ".... UnificationNode" );

          QueryElementNode node = (QueryElementNode) sink;
          boolean isOpen = node.isOpenQuery();

          context.writeBoolean(isOpen);
          if (isOpen) {
            InternalFactHandle factHandle = (InternalFactHandle) leftTuple.getObject();
            DroolsQuery query = (DroolsQuery) factHandle.getObject();

            // context.out.println( "factHandle:" +  factHandle );

            factHandle.setObject(null);
            writeFactHandle(context, stream, context.objectMarshallingStrategyStore, 0, factHandle);
            factHandle.setObject(query);
            writeLeftTuples(context, new InternalFactHandle[] {factHandle});
          } else {
            for (LeftTuple childLeftTuple = leftTuple.getFirstChild();
                childLeftTuple != null;
                childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) {
              stream.writeShort(PersisterEnums.LEFT_TUPLE);
              stream.writeInt(childLeftTuple.getLeftTupleSink().getId());
              InternalFactHandle factHandle = childLeftTuple.getLastHandle();
              writeFactHandle(
                  context, stream, context.objectMarshallingStrategyStore, 1, factHandle);
              writeLeftTuple(childLeftTuple, context, recurse);
            }
            stream.writeShort(PersisterEnums.END);
          }
          // context.out.println( "---- EvalConditionNode   ---   END" );
          break;
        }
      case NodeTypeEnums.RuleTerminalNode:
        {
          // context.out.println( "RuleTerminalNode" );
          int pos = context.terminalTupleMap.size();
          context.terminalTupleMap.put(leftTuple, pos);
          break;
        }
      case NodeTypeEnums.QueryTerminalNode:
        {
          // context.out.println( ".... QueryTerminalNode" );
          //                LeftTuple entry = leftTuple;
          //
          //                // find the DroolsQuery object
          //                while ( entry.getParent() != null ) {
          //                    entry = entry.getParent();
          //                }
          //
          //                // Now output all the child tuples in the caller network
          //                DroolsQuery query = (DroolsQuery) entry.getLastHandle().getObject();
          //                if ( query.getQueryResultCollector() instanceof
          // UnificationNodeViewChangedEventListener ) {
          //                    context.writeBoolean( true );
          //                    UnificationNodeViewChangedEventListener collector =
          // (UnificationNodeViewChangedEventListener) query.getQueryResultCollector();
          //                    leftTuple = collector.getLeftTuple();
          //
          context.writeBoolean(true);
          RightTuple rightTuple = (RightTuple) leftTuple.getObject();
          // context.out.println( "rightTuple:" +  rightTuple.getFactHandle() );
          writeFactHandle(
              context,
              stream,
              context.objectMarshallingStrategyStore,
              1,
              rightTuple.getFactHandle());

          for (LeftTuple childLeftTuple = rightTuple.firstChild;
              childLeftTuple != null;
              childLeftTuple = (LeftTuple) childLeftTuple.getRightParentNext()) {
            stream.writeShort(PersisterEnums.LEFT_TUPLE);
            stream.writeInt(childLeftTuple.getLeftTupleSink().getId());
            writeLeftTuple(childLeftTuple, context, recurse);
          }

          //                    for ( LeftTuple childLeftTuple = leftTuple.getFirstChild();
          // childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()
          // ) {
          //                        stream.writeShort( PersisterEnums.LEFT_TUPLE );
          //                        stream.writeInt( childLeftTuple.getLeftTupleSink().getId() );
          //                        writeFactHandle( context,
          //                                         stream,
          //                                         context.objectMarshallingStrategyStore,
          //                                         1,
          //                                         childLeftTuple.getLastHandle() );
          //                        writeLeftTuple( childLeftTuple,
          //                                        context,
          //                                        recurse );
          //                    }
          //                } else {
          //                    context.writeBoolean( false );
          //                }
          stream.writeShort(PersisterEnums.END);
          // context.out.println( "---- QueryTerminalNode   ---   END" );
          break;
        }
    }
  }
Exemplo n.º 7
0
  public void modifyRightTuple(
      RightTuple rightTuple, PropagationContext context, InternalWorkingMemory workingMemory) {
    final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory(this);

    BetaMemory bm = memory.betaMemory;

    // Add and remove to make sure we are in the right bucket and at the end
    // this is needed to fix for indexing and deterministic iteration
    bm.getRightTupleMemory().removeAdd(rightTuple);

    if (bm.getLeftTupleMemory() == null || bm.getLeftTupleMemory().size() == 0) {
      // do nothing here, as we know there are no left tuples at this stage in sequential mode.
      return;
    }

    LeftTuple childLeftTuple = rightTuple.firstChild;

    LeftTupleMemory leftMemory = bm.getLeftTupleMemory();

    FastIterator leftIt = getLeftIterator(leftMemory);

    LeftTuple leftTuple = getFirstLeftTuple(rightTuple, leftMemory, context, leftIt);

    this.constraints.updateFromFactHandle(
        bm.getContext(), workingMemory, rightTuple.getFactHandle());

    // first check our index (for indexed nodes only) hasn't changed and we are returning the same
    // bucket
    // We assume a bucket change if leftTuple == null
    if (childLeftTuple != null
        && leftMemory.isIndexed()
        && !leftIt.isFullIterator()
        && (leftTuple == null
            || (leftTuple.getMemory() != childLeftTuple.getLeftParent().getMemory()))) {
      // our index has changed, so delete all the previous matches
      removePreviousMatchesForRightTuple(
          rightTuple, context, workingMemory, memory, childLeftTuple);
      childLeftTuple = null; // null so the next check will attempt matches for new bucket
    }

    // if LeftTupleMemory is empty, there are no matches to modify
    if (leftTuple != null) {
      if (childLeftTuple == null) {
        // either we are indexed and changed buckets or
        // we had no children before, but there is a bucket to potentially match, so try as normal
        // assert
        for (; leftTuple != null; leftTuple = (LeftTuple) leftIt.next(leftTuple)) {
          if (this.constraints.isAllowedCachedRight(bm.getContext(), leftTuple)) {
            final AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();
            // add a new match
            addMatch(leftTuple, rightTuple, null, null, workingMemory, memory, accctx, true);
            if (accctx.getAction() == null) {
              // schedule a test to evaluate the constraints, this is an optimisation for sub
              // networks
              // We set Source to LEFT, even though this is a right propagation, because it might
              // end up
              // doing multiple right propagations anyway
              EvaluateResultConstraints action =
                  new EvaluateResultConstraints(
                      ActivitySource.LEFT,
                      leftTuple,
                      context,
                      workingMemory,
                      memory,
                      accctx,
                      true,
                      this);
              accctx.setAction(action);
              context.addInsertAction(action);
            }
          }
        }
      } else {
        // in the same bucket, so iterate and compare
        for (; leftTuple != null; leftTuple = (LeftTuple) leftIt.next(leftTuple)) {
          if (this.constraints.isAllowedCachedRight(bm.getContext(), leftTuple)) {
            final AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();
            LeftTuple temp = null;
            if (childLeftTuple != null && childLeftTuple.getLeftParent() == leftTuple) {
              temp = childLeftTuple.getRightParentNext();
              // we must re-add this to ensure deterministic iteration
              childLeftTuple.reAddLeft();
              removeMatch(rightTuple, childLeftTuple, workingMemory, memory, accctx, true);
              childLeftTuple = temp;
            }
            // add a new match
            addMatch(
                leftTuple, rightTuple, null, childLeftTuple, workingMemory, memory, accctx, true);
            if (temp != null) {
              childLeftTuple = temp;
            }
            if (accctx.getAction() == null) {
              // schedule a test to evaluate the constraints, this is an optimisation for sub
              // networks
              // We set Source to LEFT, even though this is a right propagation, because it might
              // end up
              // doing multiple right propagations anyway
              EvaluateResultConstraints action =
                  new EvaluateResultConstraints(
                      ActivitySource.LEFT,
                      leftTuple,
                      context,
                      workingMemory,
                      memory,
                      accctx,
                      true,
                      this);
              accctx.setAction(action);
              context.addInsertAction(action);
            }
          } else if (childLeftTuple != null && childLeftTuple.getLeftParent() == leftTuple) {

            LeftTuple temp = childLeftTuple.getRightParentNext();
            final AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();
            // remove the match
            removeMatch(rightTuple, childLeftTuple, workingMemory, memory, accctx, true);
            if (accctx.getAction() == null) {
              // schedule a test to evaluate the constraints, this is an optimisation for sub
              // networks
              // We set Source to LEFT, even though this is a right propagation, because it might
              // end up
              // doing multiple right propagations anyway
              EvaluateResultConstraints action =
                  new EvaluateResultConstraints(
                      ActivitySource.LEFT,
                      leftTuple,
                      context,
                      workingMemory,
                      memory,
                      accctx,
                      true,
                      this);
              accctx.setAction(action);
              context.addInsertAction(action);
            }

            childLeftTuple = temp;
          }
          // else do nothing, was false before and false now.
        }
      }
    }

    this.constraints.resetFactHandle(bm.getContext());
  }