Example #1
0
  public static void writeLeftTuples(
      MarshallerWriteContext context, InternalFactHandle[] factHandles) throws IOException {
    ObjectOutputStream stream = context.stream;
    InternalWorkingMemory wm = context.wm;

    // Write out LeftTuples
    // context.out.println( "LeftTuples Start" );
    for (InternalFactHandle handle : factHandles) {
      // InternalFactHandle handle = (InternalFactHandle) it.next();

      for (LeftTuple leftTuple = handle.getFirstLeftTuple();
          leftTuple != null;
          leftTuple = (LeftTuple) leftTuple.getLeftParentNext()) {
        stream.writeShort(PersisterEnums.LEFT_TUPLE);
        int sinkId = leftTuple.getLeftTupleSink().getId();
        stream.writeInt(sinkId);
        stream.writeInt(handle.getId());

        // context.out.println( "LeftTuple sinkId:" + leftTuple.getLeftTupleSink().getId() + "
        // handleId:" + handle.getId() );
        writeLeftTuple(leftTuple, context, true);
      }
    }

    stream.writeShort(PersisterEnums.END);
    // context.out.println( "LeftTuples End" );
  }
  /**
   * Retract the <code>FactHandleimpl</code> from the <code>Rete</code> network. Also remove the
   * <code>FactHandleImpl</code> from the node memory.
   *
   * @param rightTuple The fact handle.
   * @param object The object to assert.
   * @param workingMemory The working memory session.
   */
  public void retractObject(
      final InternalFactHandle factHandle,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {

    if (context.getType() == PropagationContext.MODIFICATION
        && this.skipOnModify
        && context.getDormantActivations() == 0) {
      return;
    }

    if (this.objectMemoryEnabled) {
      final ObjectHashSet memory = (ObjectHashSet) workingMemory.getNodeMemory(this);
      memory.remove(factHandle);
    }

    for (RightTuple rightTuple = factHandle.getRightTuple();
        rightTuple != null;
        rightTuple = (RightTuple) rightTuple.getHandleNext()) {
      rightTuple.getRightTupleSink().retractRightTuple(rightTuple, context, workingMemory);
    }
    factHandle.setRightTuple(null);

    for (LeftTuple leftTuple = factHandle.getLeftTuple();
        leftTuple != null;
        leftTuple = (LeftTuple) leftTuple.getLeftParentNext()) {
      leftTuple.getLeftTupleSink().retractLeftTuple(leftTuple, context, workingMemory);
    }
    factHandle.setLeftTuple(null);
  }
 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 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);
   }
 }
 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;
   }
 }
Example #6
0
    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);
    }
 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);
 }
Example #8
0
    public void rowAdded(
        final Rule rule,
        LeftTuple resultLeftTuple,
        PropagationContext context,
        InternalWorkingMemory workingMemory) {

      QueryTerminalNode node = (QueryTerminalNode) resultLeftTuple.getLeftTupleSink();
      Declaration[] decls = node.getDeclarations();
      DroolsQuery query = (DroolsQuery) this.factHandle.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 resultHandle =
          createQueryResultHandle(context, workingMemory, objects);

      RightTuple rightTuple = new RightTuple(resultHandle);
      if (query.isOpen()) {
        rightTuple.setLeftTuple(resultLeftTuple);
        resultLeftTuple.setObject(rightTuple);
      }

      this.node
          .getSinkPropagator()
          .createChildLeftTuplesforQuery(
              this.leftTuple,
              rightTuple,
              true, // this must always be true, otherwise we can't
              // find the child tuples to iterate for evaluating the query results
              query.isOpen());

      RightTupleList rightTuples = query.getResultInsertRightTupleList();
      if (rightTuples == null) {
        rightTuples = new RightTupleList();
        query.setResultInsertRightTupleList(rightTuples);
        QueryResultInsertAction evalAction =
            new QueryResultInsertAction(context, this.factHandle, leftTuple, this.node);
        context.getQueue2().addFirst(evalAction);
      }

      rightTuples.add(rightTuple);
    }
Example #9
0
  public static void writeInitialFactHandleLeftTuples(MarshallerWriteContext context)
      throws IOException {
    ObjectOutputStream stream = context.stream;

    // context.out.println( "InitialFact LeftTuples Start" );
    InternalFactHandle handle = context.wm.getInitialFactHandle();
    for (LeftTuple leftTuple = handle.getFirstLeftTuple();
        leftTuple != null;
        leftTuple = (LeftTuple) leftTuple.getLeftParentNext()) {
      stream.writeShort(PersisterEnums.LEFT_TUPLE);

      stream.writeInt(leftTuple.getLeftTupleSink().getId());
      // context.out.println( "LeftTuple sinkId:" + leftTuple.getLeftTupleSink().getId() );
      writeLeftTuple(leftTuple, context, true);
    }
    stream.writeShort(PersisterEnums.END);
    // context.out.println( "InitialFact LeftTuples End" );
  }
 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;
  }
  /** Retracts the corresponding tuple by retrieving and retracting the fact created for it */
  public void retractLeftTuple(
      final LeftTuple tuple,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final ObjectHashMap memory = (ObjectHashMap) workingMemory.getNodeMemory(this);
    // retrieve handle from memory
    final InternalFactHandle factHandle = (InternalFactHandle) memory.remove(tuple);

    for (RightTuple rightTuple = factHandle.getFirstRightTuple();
        rightTuple != null;
        rightTuple = (RightTuple) rightTuple.getHandleNext()) {
      rightTuple.getRightTupleSink().retractRightTuple(rightTuple, context, workingMemory);
    }
    factHandle.clearRightTuples();

    for (LeftTuple leftTuple = factHandle.getLastLeftTuple();
        leftTuple != null;
        leftTuple = (LeftTuple) leftTuple.getLeftParentNext()) {
      leftTuple.getLeftTupleSink().retractLeftTuple(leftTuple, context, workingMemory);
    }
    factHandle.clearLeftTuples();
  }
Example #13
0
  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);
  }
Example #14
0
  /**
   * Retract the <code>FactHandleimpl</code> from the <code>Rete</code> network. Also remove the
   * <code>FactHandleImpl</code> from the node memory.
   *
   * @param rightTuple The fact handle.
   * @param object The object to assert.
   * @param workingMemory The working memory session.
   */
  public void retractObject(
      final InternalFactHandle factHandle,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    if (objectMemoryEnabled && !(queryNode && !((DroolsQuery) factHandle.getObject()).isOpen())) {
      final ObjectHashSet memory = (ObjectHashSet) workingMemory.getNodeMemory(this);
      memory.remove(factHandle);
    }

    for (RightTuple rightTuple = factHandle.getFirstRightTuple();
        rightTuple != null;
        rightTuple = (RightTuple) rightTuple.getHandleNext()) {
      rightTuple.getRightTupleSink().retractRightTuple(rightTuple, context, workingMemory);
    }
    factHandle.clearRightTuples();

    for (LeftTuple leftTuple = factHandle.getFirstLeftTuple();
        leftTuple != null;
        leftTuple = (LeftTuple) leftTuple.getLeftParentNext()) {
      leftTuple.getLeftTupleSink().retractLeftTuple(leftTuple, context, workingMemory);
    }
    factHandle.clearLeftTuples();
  }
Example #15
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 static void readLeftTuple(LeftTuple parentLeftTuple, MarshallerReaderContext context)
      throws IOException, ClassNotFoundException {
    ObjectInputStream stream = context.stream;
    Map<Integer, BaseNode> sinks = context.sinks;

    LeftTupleSink sink = parentLeftTuple.getLeftTupleSink();

    switch (sink.getType()) {
      case NodeTypeEnums.JoinNode:
        {
          BetaMemory memory = (BetaMemory) context.wm.getNodeMemory((BetaNode) sink);
          addToLeftMemory(parentLeftTuple, memory);

          while (stream.readShort() == PersisterEnums.RIGHT_TUPLE) {
            int childSinkId = stream.readInt();
            LeftTupleSink childSink = (LeftTupleSink) sinks.get(childSinkId);
            int factHandleId = stream.readInt();
            RightTupleKey key = new RightTupleKey(factHandleId, sink);
            RightTuple rightTuple = context.rightTuples.get(key);
            LeftTuple childLeftTuple =
                childSink.createLeftTuple(parentLeftTuple, rightTuple, null, null, childSink, true);
            readLeftTuple(childLeftTuple, context);
          }
          break;
        }
      case NodeTypeEnums.EvalConditionNode:
        {
          while (stream.readShort() == PersisterEnums.LEFT_TUPLE) {
            LeftTupleSink childSink = (LeftTupleSink) sinks.get(stream.readInt());
            LeftTuple childLeftTuple = childSink.createLeftTuple(parentLeftTuple, childSink, true);
            readLeftTuple(childLeftTuple, context);
          }
          break;
        }
      case NodeTypeEnums.NotNode:
      case NodeTypeEnums.ForallNotNode:
        {
          BetaMemory memory = (BetaMemory) context.wm.getNodeMemory((BetaNode) sink);
          int type = stream.readShort();
          if (type == PersisterEnums.LEFT_TUPLE_NOT_BLOCKED) {
            addToLeftMemory(parentLeftTuple, memory);

            while (stream.readShort() == PersisterEnums.LEFT_TUPLE) {
              LeftTupleSink childSink = (LeftTupleSink) sinks.get(stream.readInt());
              LeftTuple childLeftTuple =
                  childSink.createLeftTuple(parentLeftTuple, childSink, true);
              readLeftTuple(childLeftTuple, context);
            }

          } else {
            int factHandleId = stream.readInt();
            RightTupleKey key = new RightTupleKey(factHandleId, sink);
            RightTuple rightTuple = context.rightTuples.get(key);

            parentLeftTuple.setBlocker(rightTuple);
            rightTuple.addBlocked(parentLeftTuple);
          }
          break;
        }
      case NodeTypeEnums.ExistsNode:
        {
          BetaMemory memory = (BetaMemory) context.wm.getNodeMemory((BetaNode) sink);
          int type = stream.readShort();
          if (type == PersisterEnums.LEFT_TUPLE_NOT_BLOCKED) {
            addToLeftMemory(parentLeftTuple, memory);
          } else {
            int factHandleId = stream.readInt();
            RightTupleKey key = new RightTupleKey(factHandleId, sink);
            RightTuple rightTuple = context.rightTuples.get(key);

            parentLeftTuple.setBlocker(rightTuple);
            rightTuple.addBlocked(parentLeftTuple);

            while (stream.readShort() == PersisterEnums.LEFT_TUPLE) {
              LeftTupleSink childSink = (LeftTupleSink) sinks.get(stream.readInt());
              LeftTuple childLeftTuple =
                  childSink.createLeftTuple(parentLeftTuple, childSink, true);
              readLeftTuple(childLeftTuple, context);
            }
          }
          break;
        }
      case NodeTypeEnums.AccumulateNode:
        {
          // accumulate nodes generate new facts on-demand and need special procedures when
          // de-serializing from persistent storage
          AccumulateMemory memory = (AccumulateMemory) context.wm.getNodeMemory((BetaNode) sink);
          memory.betaMemory.getLeftTupleMemory().add(parentLeftTuple);

          AccumulateContext accctx = new AccumulateContext();
          parentLeftTuple.setObject(accctx);

          // first we de-serialize the generated fact handle
          InternalFactHandle handle = readFactHandle(context);
          accctx.result = new RightTuple(handle, (RightTupleSink) sink);

          // then we de-serialize the associated accumulation context
          accctx.context = (Serializable[]) stream.readObject();
          // then we de-serialize the boolean propagated flag
          accctx.propagated = stream.readBoolean();

          // then we de-serialize all the propagated tuples
          short head = -1;
          while ((head = stream.readShort()) != PersisterEnums.END) {
            switch (head) {
              case PersisterEnums.RIGHT_TUPLE:
                {
                  int factHandleId = stream.readInt();
                  RightTupleKey key = new RightTupleKey(factHandleId, sink);
                  RightTuple rightTuple = context.rightTuples.get(key);
                  // just wiring up the match record
                  sink.createLeftTuple(parentLeftTuple, rightTuple, null, null, sink, true);
                  break;
                }
              case PersisterEnums.LEFT_TUPLE:
                {
                  int sinkId = stream.readInt();
                  LeftTupleSink childSink = (LeftTupleSink) sinks.get(sinkId);
                  LeftTuple childLeftTuple =
                      new LeftTupleImpl(parentLeftTuple, accctx.result, childSink, true);
                  readLeftTuple(childLeftTuple, context);
                  break;
                }
              default:
                {
                  throw new RuntimeDroolsException(
                      "Marshalling error. This is a bug. Please contact the development team.");
                }
            }
          }
          break;
        }
      case NodeTypeEnums.RightInputAdaterNode:
        {
          // RIANs generate new fact handles on-demand to wrap tuples and need special procedures
          // when de-serializing from persistent storage
          ObjectHashMap memory = (ObjectHashMap) context.wm.getNodeMemory((NodeMemory) sink);
          // create fact handle
          int id = stream.readInt();
          long recency = stream.readLong();
          InternalFactHandle handle =
              new DefaultFactHandle(
                  id,
                  parentLeftTuple,
                  recency,
                  context.wm.getEntryPoints().get(EntryPoint.DEFAULT.getEntryPointId()));
          memory.put(parentLeftTuple, handle);

          readRightTuples(handle, context);

          stream.readShort(); // Persistence.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);

          memory.betaMemory.getLeftTupleMemory().add(parentLeftTuple);
          Map<Object, RightTuple> matches = new LinkedHashMap<Object, RightTuple>();
          parentLeftTuple.setObject(matches);

          while (stream.readShort() == PersisterEnums.FACT_HANDLE) {
            // we de-serialize the generated fact handle ID
            InternalFactHandle handle = readFactHandle(context);
            context.handles.put(handle.getId(), handle);
            readRightTuples(handle, context);
            matches.put(handle.getObject(), handle.getFirstRightTuple());
          }
          while (stream.readShort() == PersisterEnums.RIGHT_TUPLE) {
            LeftTupleSink childSink = (LeftTupleSink) sinks.get(stream.readInt());
            int factHandleId = stream.readInt();
            RightTupleKey key =
                new RightTupleKey(
                    factHandleId, null); // created tuples in from node always use null sink
            RightTuple rightTuple = context.rightTuples.get(key);
            LeftTuple childLeftTuple =
                new LeftTupleImpl(parentLeftTuple, rightTuple, childSink, true);
            readLeftTuple(childLeftTuple, context);
          }
          //                context.out.println( "FromNode   ---   END" );
          break;
        }
      case NodeTypeEnums.UnificationNode:
        {
          boolean isOpen = context.readBoolean();

          if (isOpen) {
            QueryElementNode node = (QueryElementNode) sink;
            InternalFactHandle handle = readFactHandle(context);
            context.handles.put(handle.getId(), handle);
            node.createDroolsQuery(parentLeftTuple, handle, context.wm);
            readLeftTuples(context);
          } else {
            while (stream.readShort() == PersisterEnums.LEFT_TUPLE) {
              LeftTupleSink childSink = (LeftTupleSink) sinks.get(stream.readInt());
              // we de-serialize the generated fact handle ID
              InternalFactHandle handle = readFactHandle(context);
              context.handles.put(handle.getId(), handle);
              RightTuple rightTuple = new RightTuple(handle);
              // @TODO check if open query
              LeftTuple childLeftTuple =
                  new LeftTupleImpl(parentLeftTuple, rightTuple, childSink, true);
              readLeftTuple(childLeftTuple, context);
            }
          }
          break;
        }
      case NodeTypeEnums.RuleTerminalNode:
        {
          int pos = context.terminalTupleMap.size();
          context.terminalTupleMap.put(pos, parentLeftTuple);
          break;
        }
      case NodeTypeEnums.QueryTerminalNode:
        {
          boolean unificationNode = context.readBoolean();
          if (unificationNode) {
            // we de-serialize the generated fact handle ID
            InternalFactHandle handle = readFactHandle(context);
            context.handles.put(handle.getId(), handle);
            RightTuple rightTuple = new RightTuple(handle);
            parentLeftTuple.setObject(rightTuple);

            LeftTuple entry = parentLeftTuple;

            // find the DroolsQuery object
            while (entry.getParent() != null) {
              entry = entry.getParent();
            }
            DroolsQuery query = (DroolsQuery) entry.getLastHandle().getObject();
            LeftTuple leftTuple =
                ((UnificationNodeViewChangedEventListener) query.getQueryResultCollector())
                    .getLeftTuple();

            while (stream.readShort() == PersisterEnums.LEFT_TUPLE) {
              LeftTupleSink childSink = (LeftTupleSink) sinks.get(stream.readInt());
              // @TODO check if open query!!!
              LeftTuple childLeftTuple =
                  childSink.createLeftTuple(leftTuple, rightTuple, childSink);
              readLeftTuple(childLeftTuple, context);
            }
          }
          break;
        }
    }
  }
  public static Activation readActivation(MarshallerReaderContext context) throws IOException {
    ObjectInputStream stream = context.stream;
    InternalRuleBase ruleBase = context.ruleBase;
    InternalWorkingMemory wm = context.wm;

    long activationNumber = stream.readLong();

    int pos = stream.readInt();
    LeftTuple leftTuple = context.terminalTupleMap.get(pos);

    int salience = stream.readInt();

    String pkgName = stream.readUTF();
    String ruleName = stream.readUTF();
    Package pkg = ruleBase.getPackage(pkgName);
    Rule rule = pkg.getRule(ruleName);

    RuleTerminalNode ruleTerminalNode = (RuleTerminalNode) leftTuple.getLeftTupleSink();

    PropagationContext pc = context.propagationContexts.get(stream.readLong());

    AgendaItem activation;

    boolean scheduled = false;
    if (rule.getTimer() != null) {
      activation =
          new ScheduledAgendaItem(
              activationNumber, leftTuple, (InternalAgenda) wm.getAgenda(), pc, ruleTerminalNode);
      scheduled = true;
    } else {
      activation = new AgendaItem(activationNumber, leftTuple, salience, pc, ruleTerminalNode);
    }
    leftTuple.setObject(activation);

    if (stream.readBoolean()) {
      String activationGroupName = stream.readUTF();
      ((DefaultAgenda) wm.getAgenda())
          .getActivationGroup(activationGroupName)
          .addActivation(activation);
    }

    boolean activated = stream.readBoolean();
    activation.setActivated(activated);

    if (stream.readBoolean()) {
      InternalFactHandle handle = context.handles.get(stream.readInt());
      activation.setFactHandle(handle);
      handle.setObject(activation);
    }

    InternalAgendaGroup agendaGroup;
    if (rule.getAgendaGroup() == null
        || rule.getAgendaGroup().equals("")
        || rule.getAgendaGroup().equals(AgendaGroup.MAIN)) {
      // Is the Rule AgendaGroup undefined? If it is use MAIN,
      // which is added to the Agenda by default
      agendaGroup =
          (InternalAgendaGroup) ((DefaultAgenda) wm.getAgenda()).getAgendaGroup(AgendaGroup.MAIN);
    } else {
      // AgendaGroup is defined, so try and get the AgendaGroup
      // from the Agenda
      agendaGroup =
          (InternalAgendaGroup)
              ((DefaultAgenda) wm.getAgenda()).getAgendaGroup(rule.getAgendaGroup());
    }

    activation.setAgendaGroup(agendaGroup);

    if (!scheduled && activated) {
      if (rule.getRuleFlowGroup() == null) {
        agendaGroup.add(activation);
      } else {
        InternalRuleFlowGroup rfg =
            (InternalRuleFlowGroup)
                ((DefaultAgenda) wm.getAgenda()).getRuleFlowGroup(rule.getRuleFlowGroup());
        rfg.addActivation(activation);
      }
    }

    TruthMaintenanceSystem tms = context.wm.getTruthMaintenanceSystem();
    while (stream.readShort() == PersisterEnums.LOGICAL_DEPENDENCY) {
      int factHandleId = stream.readInt();
      InternalFactHandle handle = (InternalFactHandle) context.handles.get(factHandleId);
      ObjectTypeConf typeConf =
          context
              .wm
              .getObjectTypeConfigurationRegistry()
              .getObjectTypeConf(
                  ((NamedEntryPoint) handle.getEntryPoint()).getEntryPoint(), handle.getObject());
      tms.addLogicalDependency(handle, activation, pc, rule, typeConf);
    }

    return activation;
  }
Example #18
0
  @Test
  public void testDynamicAddRule() {
    // DROOLS-17
    String str =
        "import org.drools.integrationtests.MiscTest2.A\n"
            + "rule r1 when\n"
            + "    $a : A( f1 == 1 )\n"
            + "then\n"
            + "end\n"
            + "\n"
            + "rule r2 when\n"
            + "    $a : A( f2 == 1 )\n"
            + "then\n"
            + "end\n"
            + "\n"
            + "rule r3 when\n"
            + "    $a : A( f3 == 1 )"
            + "then\n"
            + "end";

    String str2 =
        "import org.drools.integrationtests.MiscTest2.A\n"
            + "rule r4 when\n"
            + "    $a : A( f2 == 1, f4 == 1 )"
            + "then\n"
            + "end";

    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add(ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL);

    if (kbuilder.hasErrors()) {
      fail(kbuilder.getErrors().toString());
    }

    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

    StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
    FactHandle fh = ksession.insert(new A(1, 1, 1, 1));

    ksession.fireAllRules();

    kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add(ResourceFactory.newByteArrayResource(str2.getBytes()), ResourceType.DRL);

    if (kbuilder.hasErrors()) {
      fail(kbuilder.getErrors().toString());
    }
    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

    ksession.fireAllRules();

    // this second insert forces the regeneration of the otnIds
    ksession.insert(new A(2, 2, 2, 2));

    LeftTuple leftTuple = ((DefaultFactHandle) fh).getFirstLeftTuple();
    ObjectTypeNode.Id letTupleOtnId = leftTuple.getLeftTupleSink().getLeftInputOtnId();
    leftTuple = leftTuple.getLeftParentNext();
    while (leftTuple != null) {
      assertTrue(letTupleOtnId.before(leftTuple.getLeftTupleSink().getLeftInputOtnId()));
      letTupleOtnId = leftTuple.getLeftTupleSink().getLeftInputOtnId();
      leftTuple = leftTuple.getLeftParentNext();
    }
  }
Example #19
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);
  }