public void propagateModifyChildLeftTuple(
     LeftTuple leftTuple,
     PropagationContext context,
     InternalWorkingMemory workingMemory,
     boolean tupleMemoryEnabled) {
   for (LeftTuple childLeftTuple = leftTuple.getFirstChild();
       childLeftTuple != null;
       childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) {
     childLeftTuple.getLeftTupleSink().modifyLeftTuple(childLeftTuple, context, workingMemory);
   }
 }
Exemple #2
0
 private void restoreList(final LeftTuple parent, final LeftTuple[] matchings) {
   // concatenate matchings list at the end of the children list
   if (parent.getFirstChild() == null) {
     parent.setFirstChild(matchings[0]);
     parent.setLastChild(matchings[1]);
   } else if (matchings[0] != null) {
     parent.getLastChild().setLeftParentNext(matchings[0]);
     matchings[0].setLeftParentPrevious(parent.getLastChild());
     parent.setLastChild(matchings[1]);
   }
 }
 public void propagateRetractLeftTuple(
     final LeftTuple leftTuple,
     final PropagationContext context,
     final InternalWorkingMemory workingMemory) {
   LeftTuple child = leftTuple.getFirstChild();
   while (child != null) {
     LeftTuple temp = child.getLeftParentNext();
     doPropagateRetractLeftTuple(context, workingMemory, child, child.getLeftTupleSink());
     child.unlinkFromRightParent();
     child.unlinkFromLeftParent();
     child = temp;
   }
 }
 public void propagateRetractLeftTupleDestroyRightTuple(
     final LeftTuple leftTuple,
     final PropagationContext context,
     final InternalWorkingMemory workingMemory) {
   LeftTuple child = leftTuple.getFirstChild();
   InternalFactHandle rightParent = child.getRightParent().getFactHandle();
   while (child != null) {
     LeftTuple temp = child.getLeftParentNext();
     doPropagateRetractLeftTuple(context, workingMemory, child, child.getLeftTupleSink());
     child.unlinkFromRightParent();
     child.unlinkFromLeftParent();
     child = temp;
   }
   workingMemory.getFactHandleFactory().destroyFactHandle(rightParent);
 }
Exemple #5
0
  /**
   * Skips the propagated tuple handles and return the first handle in the list that correspond to a
   * match
   *
   * @param leftTuple
   * @param accctx
   * @return
   */
  private LeftTuple getFirstMatch(
      final LeftTuple leftTuple, final AccumulateContext accctx, final boolean isUpdatingSink) {
    // unlink all right matches
    LeftTuple child = leftTuple.getFirstChild();

    if (accctx.propagated) {
      // To do that, we need to skip the first N children that are in fact
      // the propagated tuples
      int target = isUpdatingSink ? this.sink.size() - 1 : this.sink.size();
      for (int i = 0; i < target; i++) {
        child = child.getLeftParentNext();
      }
    }
    return child;
  }
  private static ProtobufMessages.NodeMemory writeQueryElementNodeMemory(
      final int nodeId, final Memory memory, final InternalWorkingMemory wm) {
    LeftTupleIterator it = LeftTupleIterator.iterator(wm, ((QueryElementNodeMemory) memory).node);

    ProtobufMessages.NodeMemory.QueryElementNodeMemory.Builder _query =
        ProtobufMessages.NodeMemory.QueryElementNodeMemory.newBuilder();
    for (LeftTuple leftTuple = (LeftTuple) it.next();
        leftTuple != null;
        leftTuple = (LeftTuple) it.next()) {
      InternalFactHandle handle = (InternalFactHandle) leftTuple.getObject();
      FactHandle _handle =
          ProtobufMessages.FactHandle.newBuilder()
              .setId(handle.getId())
              .setRecency(handle.getRecency())
              .build();

      ProtobufMessages.NodeMemory.QueryElementNodeMemory.QueryContext.Builder _context =
          ProtobufMessages.NodeMemory.QueryElementNodeMemory.QueryContext.newBuilder()
              .setTuple(PersisterHelper.createTuple(leftTuple))
              .setHandle(_handle);

      LeftTuple childLeftTuple = leftTuple.getFirstChild();
      while (childLeftTuple != null) {
        RightTuple rightParent = childLeftTuple.getRightParent();
        _context.addResult(
            ProtobufMessages.FactHandle.newBuilder()
                .setId(rightParent.getFactHandle().getId())
                .setRecency(rightParent.getFactHandle().getRecency())
                .build());
        while (childLeftTuple != null && childLeftTuple.getRightParent() == rightParent) {
          // skip to the next child that has a different right parent
          childLeftTuple = childLeftTuple.getLeftParentNext();
        }
      }
      _query.addContext(_context.build());
    }

    return _query.getContextCount() > 0
        ? ProtobufMessages.NodeMemory.newBuilder()
            .setNodeId(nodeId)
            .setNodeType(ProtobufMessages.NodeMemory.NodeType.QUERY_ELEMENT)
            .setQueryElement(_query.build())
            .build()
        : null;
  }
Exemple #7
0
  protected LeftTuple[] splitList(
      final LeftTuple parent, final AccumulateContext accctx, final boolean isUpdatingSink) {
    LeftTuple[] matchings = new LeftTuple[2];

    // save the matchings list
    matchings[0] = getFirstMatch(parent, accctx, isUpdatingSink);
    matchings[1] = matchings[0] != null ? parent.getLastChild() : null;

    // update the tuple for the actual propagations
    if (matchings[0] != null) {
      if (parent.getFirstChild() == matchings[0]) {
        parent.setFirstChild(null);
      }
      parent.setLastChild(matchings[0].getLeftParentPrevious());
      if (parent.getLastChild() != null) {
        parent.getLastChild().setLeftParentNext(null);
        matchings[0].setLeftParentPrevious(null);
      }
    }

    return matchings;
  }
  public void updateSink(
      final LeftTupleSink sink,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    LeftTupleIterator it = LeftTupleIterator.iterator(workingMemory, this);

    for (LeftTuple leftTuple = (LeftTuple) it.next();
        leftTuple != null;
        leftTuple = (LeftTuple) it.next()) {
      LeftTuple childLeftTuple = leftTuple.getFirstChild();
      while (childLeftTuple != null) {
        RightTuple rightParent = childLeftTuple.getRightParent();
        sink.assertLeftTuple(
            sink.createLeftTuple(leftTuple, rightParent, childLeftTuple, null, sink, true),
            context,
            workingMemory);

        while (childLeftTuple != null && childLeftTuple.getRightParent() == rightParent) {
          // skip to the next child that has a different right parent
          childLeftTuple = childLeftTuple.getLeftParentNext();
        }
      }
    }
  }
  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;
        }
    }
  }
Exemple #10
0
  protected void doRemove(
      final RuleRemovalContext context,
      final ReteooBuilder builder,
      final BaseNode node,
      final InternalWorkingMemory[] workingMemories) {
    if (!node.isInUse()) {
      removeTupleSink((LeftTupleSink) node);
    }
    if (!this.isInUse() || context.getCleanupAdapter() != null) {
      for (InternalWorkingMemory workingMemory : workingMemories) {
        BetaMemory memory;
        Object object = workingMemory.getNodeMemory(this);

        // handle special cases for Accumulate to make sure they tidy up their specific data
        // like destroying the local FactHandles
        if (object instanceof AccumulateMemory) {
          memory = ((AccumulateMemory) object).betaMemory;
        } else {
          memory = (BetaMemory) object;
        }

        FastIterator it = memory.getLeftTupleMemory().fullFastIterator();
        for (LeftTuple leftTuple = getFirstLeftTuple(memory.getLeftTupleMemory(), it);
            leftTuple != null; ) {
          LeftTuple tmp = (LeftTuple) it.next(leftTuple);
          if (context.getCleanupAdapter() != null) {
            LeftTuple child;
            while ((child = leftTuple.getFirstChild()) != null) {
              if (child.getLeftTupleSink() == this) {
                // this is a match tuple on collect and accumulate nodes, so just unlink it
                child.unlinkFromLeftParent();
                child.unlinkFromRightParent();
              } else {
                // the cleanupAdapter will take care of the unlinking
                context.getCleanupAdapter().cleanUp(child, workingMemory);
              }
            }
          }
          memory.getLeftTupleMemory().remove(leftTuple);
          leftTuple.unlinkFromLeftParent();
          leftTuple.unlinkFromRightParent();
          leftTuple = tmp;
        }

        // handle special cases for Accumulate to make sure they tidy up their specific data
        // like destroying the local FactHandles
        if (object instanceof AccumulateMemory) {
          ((AccumulateNode) this).doRemove(workingMemory, (AccumulateMemory) object);
        }

        if (!this.isInUse()) {
          it = memory.getRightTupleMemory().fullFastIterator();
          for (RightTuple rightTuple = getFirstRightTuple(memory.getRightTupleMemory(), it);
              rightTuple != null; ) {
            RightTuple tmp = (RightTuple) it.next(rightTuple);
            if (rightTuple.getBlocked() != null) {
              // special case for a not, so unlink left tuple from here, as they aren't in the left
              // memory
              for (LeftTuple leftTuple = rightTuple.getBlocked(); leftTuple != null; ) {
                LeftTuple temp = leftTuple.getBlockedNext();

                leftTuple.setBlocker(null);
                leftTuple.setBlockedPrevious(null);
                leftTuple.setBlockedNext(null);
                leftTuple.unlinkFromLeftParent();
                leftTuple = temp;
              }
            }
            memory.getRightTupleMemory().remove(rightTuple);
            rightTuple.unlinkFromRightParent();
            rightTuple = tmp;
          }
          workingMemory.clearNodeMemory(this);
        }
      }
      context.setCleanupAdapter(null);
    }
    this.rightInput.remove(context, builder, this, workingMemories);
    this.leftInput.remove(context, builder, this, workingMemories);
  }
  public void modifyLeftTuple(
      LeftTuple leftTuple, PropagationContext context, InternalWorkingMemory workingMemory) {
    final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory(this);
    RightTupleMemory rightMemory = memory.getRightTupleMemory();

    FastIterator rightIt = getRightIterator(rightMemory);
    RightTuple firstRightTuple = getFirstRightTuple(leftTuple, rightMemory, context, rightIt);

    // If in memory, remove it, because we'll need to add it anyway if it's not blocked, to ensure
    // iteration order
    RightTuple blocker = leftTuple.getBlocker();
    if (blocker == null) {
      memory.getLeftTupleMemory().remove(leftTuple);
    } else {
      // check if we changed bucket
      if (rightMemory.isIndexed() && !rightIt.isFullIterator()) {
        // if newRightTuple is null, we assume there was a bucket change and that bucket is empty
        if (firstRightTuple == null || firstRightTuple.getMemory() != blocker.getMemory()) {
          // we changed bucket, so blocker no longer blocks
          blocker.removeBlocked(leftTuple);
          leftTuple.setBlocker(null);
          leftTuple.setBlockedPrevious(null);
          leftTuple.setBlockedNext(null);
          blocker = null;
        }
      }
    }

    this.constraints.updateFromTuple(memory.getContext(), workingMemory, leftTuple);

    // if we where not blocked before (or changed buckets), or the previous blocker no longer
    // blocks, then find the next blocker
    if (blocker == null
        || !this.constraints.isAllowedCachedLeft(memory.getContext(), blocker.getFactHandle())) {

      if (blocker != null) {
        // remove previous blocker if it exists, as we know it doesn't block any more
        blocker.removeBlocked(leftTuple);
        leftTuple.setBlocker(null);
        leftTuple.setBlockedPrevious(null);
        leftTuple.setBlockedNext(null);
      }

      FastIterator it = memory.getRightTupleMemory().fastIterator();

      // find first blocker, because it's a modify, we need to start from the beginning again
      for (RightTuple newBlocker = firstRightTuple;
          newBlocker != null;
          newBlocker = (RightTuple) rightIt.next(newBlocker)) {
        if (this.constraints.isAllowedCachedLeft(memory.getContext(), newBlocker.getFactHandle())) {
          leftTuple.setBlocker(newBlocker);
          newBlocker.addBlocked(leftTuple);

          break;
        }
      }
    }

    if (leftTuple.getBlocker() == null) {
      // not blocked
      memory
          .getLeftTupleMemory()
          .add(leftTuple); // add to memory so other fact handles can attempt to match

      if (leftTuple.getFirstChild() != null) {
        // with previous children, retract
        this.sink.propagateRetractLeftTuple(leftTuple, context, workingMemory);
      }
      // with no previous children. do nothing.
    } else if (leftTuple.getFirstChild() == null) {
      // blocked, with no previous children, assert
      this.sink.propagateAssertLeftTuple(leftTuple, context, workingMemory, true);
    } else {
      // blocked, with previous children, modify
      this.sink.propagateModifyChildLeftTuple(leftTuple, context, workingMemory, true);
    }

    this.constraints.resetTuple(memory.getContext());
  }
  public void modifyLeftTuple(
      LeftTuple leftTuple, PropagationContext context, InternalWorkingMemory workingMemory) {
    boolean executeAsOpenQuery = openQuery;
    if (executeAsOpenQuery) {
      // There is no point in doing an open query if the caller is a non-open query.
      Object object = ((InternalFactHandle) leftTuple.get(0)).getObject();
      if (object instanceof DroolsQuery && !((DroolsQuery) object).isOpen()) {
        executeAsOpenQuery = false;
      }
    }

    if (!executeAsOpenQuery) {
      // Was never open so execute as a retract + assert
      if (leftTuple.getFirstChild() != null) {
        this.sink.propagateRetractLeftTuple(leftTuple, context, workingMemory);
      }
      assertLeftTuple(leftTuple, context, workingMemory);
      return;
    }

    InternalFactHandle handle = (InternalFactHandle) leftTuple.getObject();
    DroolsQuery queryObject = (DroolsQuery) handle.getObject();
    if (queryObject.getAction() != null) {
      // we already have an insert scheduled for this query, but have re-entered it
      // do nothing
      return;
    }

    Object[] argTemplate =
        this.queryElement.getArgTemplate(); // an array of declr, variable and literals
    Object[] args =
        new Object[argTemplate.length]; // the actual args, to be created from the  template

    // first copy everything, so that we get the literals. We will rewrite the declarations and
    // variables next
    System.arraycopy(argTemplate, 0, args, 0, args.length);

    int[] declIndexes = this.queryElement.getDeclIndexes();

    for (int i = 0, length = declIndexes.length; i < length; i++) {
      Declaration declr = (Declaration) argTemplate[declIndexes[i]];

      Object tupleObject = leftTuple.get(declr).getObject();

      Object o;

      if (tupleObject instanceof DroolsQuery) {
        // If the query passed in a Variable, we need to use it
        ArrayElementReader arrayReader = (ArrayElementReader) declr.getExtractor();
        if (((DroolsQuery) tupleObject).getVariables()[arrayReader.getIndex()] != null) {
          o = Variable.v;
        } else {
          o = declr.getValue(workingMemory, tupleObject);
        }
      } else {
        o = declr.getValue(workingMemory, tupleObject);
      }

      args[declIndexes[i]] = o;
    }

    int[] varIndexes = this.queryElement.getVariableIndexes();
    for (int i = 0, length = varIndexes.length; i < length; i++) {
      if (argTemplate[varIndexes[i]] == Variable.v) {
        // Need to check against the arg template, as the varIndexes also includes re-declared
        // declarations
        args[varIndexes[i]] = Variable.v;
      }
    }

    queryObject.setParameters(args);
    ((UnificationNodeViewChangedEventListener) queryObject.getQueryResultCollector())
        .setVariables(varIndexes);

    QueryUpdateAction action = new QueryUpdateAction(context, handle, leftTuple, this);
    context.getQueue1().addFirst(action);
  }
Exemple #13
0
  /**
   * Evaluate result constraints and propagate assert in case they are true
   *
   * @param leftTuple
   * @param context
   * @param workingMemory
   * @param memory
   * @param accresult
   * @param handle
   */
  public void evaluateResultConstraints(
      final ActivitySource source,
      final LeftTuple leftTuple,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory,
      final AccumulateMemory memory,
      final AccumulateContext accctx,
      final boolean useLeftMemory) {

    // get the actual result
    final Object[] resultArray =
        this.accumulate.getResult(
            memory.workingMemoryContext, accctx.context, leftTuple, workingMemory);
    Object result = this.accumulate.isMultiFunction() ? resultArray : resultArray[0];
    if (result == null) {
      return;
    }

    if (accctx.result == null) {
      final InternalFactHandle handle =
          createResultFactHandle(context, workingMemory, leftTuple, result);

      accctx.result = createRightTuple(handle, this, context);
    } else {
      accctx.result.getFactHandle().setObject(result);
    }

    // First alpha node filters
    boolean isAllowed = result != null;
    for (int i = 0, length = this.resultConstraints.length; isAllowed && i < length; i++) {
      if (!this.resultConstraints[i].isAllowed(
          accctx.result.getFactHandle(), workingMemory, memory.alphaContexts[i])) {
        isAllowed = false;
      }
    }
    if (isAllowed) {
      this.resultBinder.updateFromTuple(memory.resultsContext, workingMemory, leftTuple);
      if (!this.resultBinder.isAllowedCachedLeft(
          memory.resultsContext, accctx.result.getFactHandle())) {
        isAllowed = false;
      }
      this.resultBinder.resetTuple(memory.resultsContext);
    }

    if (accctx.propagated == true) {
      // temporarily break the linked list to avoid wrong interactions
      LeftTuple[] matchings = splitList(leftTuple, accctx, false);
      if (isAllowed) {
        // modify
        if (ActivitySource.LEFT.equals(source)) {
          this.sink.propagateModifyChildLeftTuple(
              leftTuple.getFirstChild(), leftTuple, context, workingMemory, useLeftMemory);
        } else {
          this.sink.propagateModifyChildLeftTuple(
              leftTuple.getFirstChild(), accctx.result, context, workingMemory, useLeftMemory);
        }
      } else {
        // retract
        this.sink.propagateRetractLeftTuple(leftTuple, context, workingMemory);
        accctx.propagated = false;
      }
      // restore the matchings list
      restoreList(leftTuple, matchings);
    } else if (isAllowed) {
      // temporarily break the linked list to avoid wrong interactions
      LeftTuple[] matchings = splitList(leftTuple, accctx, false);
      // assert
      this.sink.propagateAssertLeftTuple(
          leftTuple, accctx.result, null, null, context, workingMemory, useLeftMemory);
      accctx.propagated = true;
      // restore the matchings list
      restoreList(leftTuple, matchings);
    }
  }