public static void writePropagationContexts(MarshallerWriteContext context) throws IOException {
    ObjectOutputStream stream = context.stream;

    if (context.terminalTupleMap != null && context.terminalTupleMap.size() > 0) {
      Entry<LeftTuple, Integer>[] entries =
          context.terminalTupleMap.entrySet().toArray(new Entry[context.terminalTupleMap.size()]);
      Arrays.sort(entries, TupleSorter.instance);

      // Map<LeftTuple, Integer> tuples = context.terminalTupleMap;
      if (entries.length != 0) {
        Map<Long, PropagationContext> pcMap = new HashMap<Long, PropagationContext>();
        for (Entry<LeftTuple, Integer> entry : entries) {
          LeftTuple leftTuple = entry.getKey();
          if (leftTuple.getObject() != null) {
            PropagationContext pc = ((Activation) leftTuple.getObject()).getPropagationContext();
            if (!pcMap.containsKey(pc.getPropagationNumber())) {
              stream.writeShort(PersisterEnums.PROPAGATION_CONTEXT);
              writePropagationContext(context, pc);
              pcMap.put(pc.getPropagationNumber(), pc);
            }
          }
        }
      }
    }

    stream.writeShort(PersisterEnums.END);
  }
Exemple #2
0
  /**
   * @inheritDoc As the accumulate node will always generate a resulting tuple, we must always
   *     destroy it
   */
  public void retractLeftTuple(
      final LeftTuple leftTuple,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory(this);

    if (leftTuple.getMemory().isStagingMemory()) {
      leftTuple.getMemory().remove(leftTuple);
    } else {
      ((BetaMemory) memory.getBetaMemory()).getLeftTupleMemory().remove(leftTuple);
    }
    leftTuple.setMemory(null);

    final AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();
    if (accctx.getAction() != null) {
      // there is a scheduled activation, we must cancel it
      context.removeInsertAction(accctx.getAction());
    }
    leftTuple.setObject(null);

    removePreviousMatchesForLeftTuple(leftTuple, workingMemory, memory, accctx);

    if (accctx.propagated) {
      // if tuple was previously propagated, retract it and destroy result fact handle
      this.sink.propagateRetractLeftTupleDestroyRightTuple(leftTuple, context, workingMemory);
    } else {
      // if not propagated, just destroy the result fact handle
      // workingMemory.getFactHandleFactory().destroyFactHandle( accctx.result.getFactHandle() );
    }
  }
    public void rowUpdated(
        final Rule rule,
        final LeftTuple resultLeftTuple,
        final PropagationContext context,
        final InternalWorkingMemory workingMemory) {
      RightTuple rightTuple = (RightTuple) resultLeftTuple.getObject();
      if (rightTuple.getMemory() != null) {
        // Already sheduled as an insert
        return;
      }

      rightTuple.setLeftTuple(null);
      resultLeftTuple.setObject(null);

      // We need to recopy everything back again, as we don't know what has or hasn't changed
      QueryTerminalNode node = (QueryTerminalNode) resultLeftTuple.getLeftTupleSink();
      Declaration[] decls = node.getDeclarations();
      InternalFactHandle rootHandle = resultLeftTuple.get(0);
      DroolsQuery query = (DroolsQuery) rootHandle.getObject();

      Object[] objects = new Object[query.getElements().length];

      Declaration decl;
      for (int i = 0, length = this.variables.length; i < length; i++) {
        decl = decls[this.variables[i]];
        objects[this.variables[i]] =
            decl.getValue(workingMemory, resultLeftTuple.get(decl).getObject());
      }

      QueryElementFactHandle handle = (QueryElementFactHandle) rightTuple.getFactHandle();

      handle.setRecency(workingMemory.getFactHandleFactory().getAtomicRecency().incrementAndGet());
      handle.setObject(objects);

      if (query.isOpen()) {
        rightTuple.setLeftTuple(resultLeftTuple);
        resultLeftTuple.setObject(rightTuple);
      }

      // Don't need to recreate child links, as they will already be there form the first "add"

      RightTupleList rightTuples = query.getResultUpdateRightTupleList();
      if (rightTuples == null) {
        rightTuples = new RightTupleList();
        query.setResultUpdateRightTupleList(rightTuples);
        QueryResultUpdateAction updateAction =
            new QueryResultUpdateAction(context, this.factHandle, leftTuple, this.node);
        context.getQueue2().addFirst(updateAction);
      }
      rightTuples.add(rightTuple);
    }
Exemple #4
0
  /**
   * @inheritDoc When a new object is asserted into an AccumulateNode, do this:
   *     <p>1. Select all matching tuples from left memory 2. For each matching tuple, call a modify
   *     tuple
   */
  public void assertRightTuple(
      final RightTuple rightTuple,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory(this);

    memory.betaMemory.getRightTupleMemory().add(rightTuple);

    if (memory.betaMemory.getLeftTupleMemory() == null
        || memory.betaMemory.getLeftTupleMemory().size() == 0) {
      // do nothing here, as we know there are no left tuples at this stage in sequential mode or
      // for a query.
      // unless it's an "Open Query" and thus that will have left memory, so continue as normal
      return;
    }

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

    LeftTupleMemory leftMemory = memory.betaMemory.getLeftTupleMemory();

    FastIterator leftIt = getLeftIterator(leftMemory);

    for (LeftTuple leftTuple = getFirstLeftTuple(rightTuple, leftMemory, context, leftIt);
        leftTuple != null;
        leftTuple = (LeftTuple) leftIt.next(leftTuple)) {
      if (this.constraints.isAllowedCachedRight(memory.betaMemory.getContext(), leftTuple)) {
        final AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();
        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);
        }
      }
    }

    this.constraints.resetFactHandle(memory.betaMemory.getContext());
  }
  public Object next() {
    Activation acc = null;
    if (this.currentLeftTuple != null) {
      acc = (Activation) currentLeftTuple.getObject();
      this.currentLeftTuple = (LeftTuple) leftTupleIter.next();

      while (currentLeftTuple == null && (node = (TerminalNode) nodeIter.next()) != null) {
        if (!(node instanceof RuleTerminalNode)) {
          continue;
        }
        leftTupleIter = LeftTupleIterator.iterator(wm, node);
        this.currentLeftTuple = (LeftTuple) leftTupleIter.next();
      }
    }

    return acc;
  }
  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
  public void updateSink(
      final LeftTupleSink sink,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory(this);

    final Iterator tupleIter = memory.betaMemory.getLeftTupleMemory().iterator();
    for (LeftTuple leftTuple = (LeftTuple) tupleIter.next();
        leftTuple != null;
        leftTuple = (LeftTuple) tupleIter.next()) {
      AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();
      if (accctx.propagated) {
        // temporarily break the linked list to avoid wrong interactions
        LeftTuple[] matchings = splitList(leftTuple, accctx, true);
        sink.assertLeftTuple(
            sink.createLeftTuple(leftTuple, accctx.result, null, null, sink, true),
            context,
            workingMemory);
        restoreList(leftTuple, matchings);
      }
    }
  }
  public static void writeActivations(MarshallerWriteContext context) throws IOException {
    ObjectOutputStream stream = context.stream;

    Entry<LeftTuple, Integer>[] entries =
        context.terminalTupleMap.entrySet().toArray(new Entry[context.terminalTupleMap.size()]);
    Arrays.sort(entries, TupleSorter.instance);

    // Map<LeftTuple, Integer> tuples = context.terminalTupleMap;
    if (entries.length != 0) {
      for (Entry<LeftTuple, Integer> entry : entries) {
        if (entry.getKey().getObject() != null) {
          LeftTuple leftTuple = entry.getKey();
          stream.writeShort(PersisterEnums.ACTIVATION);
          writeActivation(
              context,
              leftTuple,
              (AgendaItem) leftTuple.getObject(),
              (RuleTerminalNode) leftTuple.getLeftTupleSink());
        }
      }
    }
    stream.writeShort(PersisterEnums.END);
  }
  @SuppressWarnings("unchecked")
  private static ProtobufMessages.NodeMemory writeFromNodeMemory(
      final int nodeId, final Memory memory) {
    FromMemory fromMemory = (FromMemory) memory;

    if (fromMemory.betaMemory.getLeftTupleMemory().size() > 0) {
      ProtobufMessages.NodeMemory.FromNodeMemory.Builder _from =
          ProtobufMessages.NodeMemory.FromNodeMemory.newBuilder();

      final org.drools.core.util.Iterator tupleIter =
          fromMemory.betaMemory.getLeftTupleMemory().iterator();
      for (LeftTuple leftTuple = (LeftTuple) tupleIter.next();
          leftTuple != null;
          leftTuple = (LeftTuple) tupleIter.next()) {
        Map<Object, RightTuple> matches = (Map<Object, RightTuple>) leftTuple.getObject();
        ProtobufMessages.NodeMemory.FromNodeMemory.FromContext.Builder _context =
            ProtobufMessages.NodeMemory.FromNodeMemory.FromContext.newBuilder()
                .setTuple(PersisterHelper.createTuple(leftTuple));
        for (RightTuple rightTuple : matches.values()) {
          FactHandle _handle =
              ProtobufMessages.FactHandle.newBuilder()
                  .setId(rightTuple.getFactHandle().getId())
                  .setRecency(rightTuple.getFactHandle().getRecency())
                  .build();
          _context.addHandle(_handle);
        }
        _from.addContext(_context.build());
      }

      return ProtobufMessages.NodeMemory.newBuilder()
          .setNodeId(nodeId)
          .setNodeType(ProtobufMessages.NodeMemory.NodeType.FROM)
          .setFrom(_from.build())
          .build();
    }
    return null;
  }
  private static ProtobufMessages.NodeMemory writeAccumulateNodeMemory(
      final int nodeId, final Memory memory) {
    // for accumulate nodes, we need to store the ID of created (result) handles
    AccumulateMemory accmem = (AccumulateMemory) memory;
    if (accmem.betaMemory.getLeftTupleMemory().size() > 0) {
      ProtobufMessages.NodeMemory.AccumulateNodeMemory.Builder _accumulate =
          ProtobufMessages.NodeMemory.AccumulateNodeMemory.newBuilder();

      final org.drools.core.util.Iterator tupleIter =
          accmem.betaMemory.getLeftTupleMemory().iterator();
      for (LeftTuple leftTuple = (LeftTuple) tupleIter.next();
          leftTuple != null;
          leftTuple = (LeftTuple) tupleIter.next()) {
        AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();
        if (accctx.result != null) {
          FactHandle _handle =
              ProtobufMessages.FactHandle.newBuilder()
                  .setId(accctx.result.getFactHandle().getId())
                  .setRecency(accctx.result.getFactHandle().getRecency())
                  .build();
          _accumulate.addContext(
              ProtobufMessages.NodeMemory.AccumulateNodeMemory.AccumulateContext.newBuilder()
                  .setTuple(PersisterHelper.createTuple(leftTuple))
                  .setResultHandle(_handle)
                  .build());
        }
      }

      return ProtobufMessages.NodeMemory.newBuilder()
          .setNodeId(nodeId)
          .setNodeType(ProtobufMessages.NodeMemory.NodeType.ACCUMULATE)
          .setAccumulate(_accumulate.build())
          .build();
    }
    return null;
  }
    public void rowRemoved(
        final Rule rule,
        final LeftTuple resultLeftTuple,
        final PropagationContext context,
        final InternalWorkingMemory workingMemory) {
      RightTuple rightTuple = (RightTuple) resultLeftTuple.getObject();
      rightTuple.setLeftTuple(null);
      resultLeftTuple.setObject(null);

      DroolsQuery query = (DroolsQuery) this.factHandle.getObject();

      RightTupleList rightTuples = query.getResultRetractRightTupleList();
      if (rightTuples == null) {
        rightTuples = new RightTupleList();
        query.setResultRetractRightTupleList(rightTuples);
        QueryResultRetractAction retractAction =
            new QueryResultRetractAction(context, this.factHandle, leftTuple, this.node);
        context.getQueue2().addFirst(retractAction);
      }
      if (rightTuple.getMemory() != null) {
        throw new RuntimeException();
      }
      rightTuples.add(rightTuple);
    }
Exemple #12
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;
   }
 }
Exemple #13
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;
        }
    }
  }
  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 #15
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());
  }
Exemple #16
0
  public void modifyLeftTuple(
      LeftTuple leftTuple, PropagationContext context, InternalWorkingMemory workingMemory) {
    final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory(this);
    final AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();

    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.getLeftTupleMemory().removeAdd(leftTuple);

    this.constraints.updateFromTuple(bm.getContext(), workingMemory, leftTuple);
    LeftTuple childLeftTuple = getFirstMatch(leftTuple, accctx, false);

    RightTupleMemory rightMemory = bm.getRightTupleMemory();

    FastIterator rightIt = getRightIterator(rightMemory);

    RightTuple rightTuple = getFirstRightTuple(leftTuple, rightMemory, context, rightIt);

    // first check our index (for indexed nodes only) hasn't changed and we are returning the same
    // bucket
    // if rightTuple is null, we assume there was a bucket change and that bucket is empty
    if (childLeftTuple != null
        && rightMemory.isIndexed()
        && !rightIt.isFullIterator()
        && (rightTuple == null
            || (rightTuple.getMemory() != childLeftTuple.getRightParent().getMemory()))) {
      // our index has changed, so delete all the previous matchings
      removePreviousMatchesForLeftTuple(leftTuple, workingMemory, memory, accctx);

      childLeftTuple = null; // null so the next check will attempt matches for new bucket
    }

    // we can't do anything if RightTupleMemory is empty
    if (rightTuple != 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 (; rightTuple != null; rightTuple = (RightTuple) rightIt.next(rightTuple)) {
          final InternalFactHandle handle = rightTuple.getFactHandle();
          if (this.constraints.isAllowedCachedLeft(bm.getContext(), handle)) {
            // add a new match
            addMatch(leftTuple, rightTuple, null, null, workingMemory, memory, accctx, true);
          }
        }
      } else {
        boolean isDirty = false;
        // in the same bucket, so iterate and compare
        for (; rightTuple != null; rightTuple = (RightTuple) rightIt.next(rightTuple)) {
          final InternalFactHandle handle = rightTuple.getFactHandle();

          if (this.constraints.isAllowedCachedLeft(bm.getContext(), handle)) {
            if (childLeftTuple == null || childLeftTuple.getRightParent() != rightTuple) {
              // add a new match
              addMatch(
                  leftTuple, rightTuple, childLeftTuple, null, workingMemory, memory, accctx, true);
            } else {
              // we must re-add this to ensure deterministic iteration
              LeftTuple temp = childLeftTuple.getLeftParentNext();
              childLeftTuple.reAddRight();
              childLeftTuple = temp;
            }
          } else if (childLeftTuple != null && childLeftTuple.getRightParent() == rightTuple) {
            LeftTuple temp = childLeftTuple.getLeftParentNext();
            // remove the match
            removeMatch(rightTuple, childLeftTuple, workingMemory, memory, accctx, false);
            childLeftTuple = temp;
            // the next line means that when a match is removed from the current leftTuple
            // and the accumulate does not support the reverse operation, then the whole
            // result is dirty (since removeMatch above is not recalculating the total)
            // and we need to do this later
            isDirty = !accumulate.supportsReverse();
          }
          // else do nothing, was false before and false now.
        }
        if (isDirty) {
          reaccumulateForLeftTuple(leftTuple, workingMemory, memory, accctx);
        }
      }
    }

    this.constraints.resetTuple(memory.betaMemory.getContext());
    if (accctx.getAction() == null) {
      evaluateResultConstraints(
          ActivitySource.LEFT, leftTuple, context, workingMemory, memory, accctx, true);
    } // else evaluation is already scheduled, so do nothing
  }