Example #1
0
    public void execute(InternalWorkingMemory workingMemory) {
      DroolsQuery query = (DroolsQuery) factHandle.getObject();
      RightTupleList rightTuples = query.getResultInsertRightTupleList();
      query.setResultInsertRightTupleList(
          null); // null so further operations happen on a new stack element

      for (RightTuple rightTuple = rightTuples.getFirst(); rightTuple != null; ) {
        RightTuple tmp = (RightTuple) rightTuple.getNext();
        rightTuples.remove(rightTuple);
        for (LeftTuple childLeftTuple = rightTuple.firstChild;
            childLeftTuple != null;
            childLeftTuple = (LeftTuple) childLeftTuple.getRightParentNext()) {
          node.getSinkPropagator()
              .doPropagateAssertLeftTuple(
                  context, workingMemory, childLeftTuple, childLeftTuple.getLeftTupleSink());
        }
        rightTuple = tmp;
      }

      // @FIXME, this should work, but it's closing needed fact handles
      // actually an evaluation 34 appears on the stack twice....
      //            if ( !node.isOpenQuery() ) {
      //                workingMemory.getFactHandleFactory().destroyFactHandle( this.factHandle );
      //            }
    }
  public static void doModifyLeftTuple(
      InternalFactHandle factHandle,
      ModifyPreviousTuples modifyPreviousTuples,
      PropagationContext context,
      InternalWorkingMemory workingMemory,
      LeftTupleSink sink,
      ObjectTypeNode.Id leftInputOtnId,
      BitMask leftInferredMask) {
    LeftTuple leftTuple = modifyPreviousTuples.peekLeftTuple();
    while (leftTuple != null
        && leftTuple.getLeftTupleSink().getLeftInputOtnId() != null
        && leftTuple.getLeftTupleSink().getLeftInputOtnId().before(leftInputOtnId)) {
      modifyPreviousTuples.removeLeftTuple();

      // we skipped this node, due to alpha hashing, so retract now
      ((LeftInputAdapterNode) leftTuple.getLeftTupleSink().getLeftTupleSource())
          .retractLeftTuple(leftTuple, context, workingMemory);

      leftTuple = modifyPreviousTuples.peekLeftTuple();
    }

    if (leftTuple != null
        && leftTuple.getLeftTupleSink().getLeftInputOtnId() != null
        && leftTuple.getLeftTupleSink().getLeftInputOtnId().equals(leftInputOtnId)) {
      modifyPreviousTuples.removeLeftTuple();
      leftTuple.reAdd();
      if (context.getModificationMask().intersects(leftInferredMask)) {
        // LeftTuple previously existed, so continue as modify, unless it's currently staged
        sink.modifyLeftTuple(leftTuple, context, workingMemory);
      }
    } else {
      if (context.getModificationMask().intersects(leftInferredMask)) {
        // LeftTuple does not exist, so create and continue as assert
        LeftTuple newLeftTuple = sink.createLeftTuple(factHandle, sink, true);

        sink.assertLeftTuple(newLeftTuple, context, workingMemory);
      }
    }
  }
Example #3
0
  public void modifyObject(
      final InternalFactHandle handle,
      final PropagationContext context,
      final ObjectTypeConf objectTypeConf,
      final InternalWorkingMemory wm) {
    if (log.isTraceEnabled()) {
      log.trace("Update {}", handle.toString());
    }

    // checks if shadow is enabled
    if (objectTypeConf.isShadowEnabled()) {
      // the user has implemented the ShadowProxy interface, let their implementation
      // know it is safe to update the information the engine can see.
      ((ShadowProxy) handle.getObject()).updateProxy();
    }

    ObjectTypeNode[] cachedNodes = objectTypeConf.getObjectTypeNodes();

    // make a reference to the previous tuples, then null then on the handle
    ModifyPreviousTuples modifyPreviousTuples =
        new ModifyPreviousTuples(
            handle.getFirstLeftTuple(), handle.getFirstRightTuple(), unlinkingEnabled);
    handle.clearLeftTuples();
    handle.clearRightTuples();

    for (int i = 0, length = cachedNodes.length; i < length; i++) {
      cachedNodes[i].modifyObject(handle, modifyPreviousTuples, context, wm);

      // remove any right tuples that matches the current OTN before continue the modify on the next
      // OTN cache entry
      if (i < cachedNodes.length - 1) {
        RightTuple rightTuple = modifyPreviousTuples.peekRightTuple();
        while (rightTuple != null
            && ((BetaNode) rightTuple.getRightTupleSink()).getObjectTypeNode() == cachedNodes[i]) {
          modifyPreviousTuples.removeRightTuple();

          if (unlinkingEnabled) {
            BetaMemory bm = BetaNode.getBetaMemory((BetaNode) rightTuple.getRightTupleSink(), wm);
            BetaNode.doDeleteRightTuple(rightTuple, wm, bm);
          } else {
            ((BetaNode) rightTuple.getRightTupleSink()).retractRightTuple(rightTuple, context, wm);
          }

          rightTuple = modifyPreviousTuples.peekRightTuple();
        }

        LeftTuple leftTuple;
        ObjectTypeNode otn;
        while (true) {
          leftTuple = modifyPreviousTuples.peekLeftTuple();
          otn = null;
          if (leftTuple != null) {
            LeftTupleSink leftTupleSink = leftTuple.getLeftTupleSink();
            if (leftTupleSink instanceof LeftTupleSource) {
              otn = ((LeftTupleSource) leftTupleSink).getLeftTupleSource().getObjectTypeNode();
            } else if (leftTupleSink instanceof RuleTerminalNode) {
              otn = ((RuleTerminalNode) leftTupleSink).getObjectTypeNode();
            }
          }

          if (otn == null || otn == cachedNodes[i + 1]) break;

          modifyPreviousTuples.removeLeftTuple();

          if (unlinkingEnabled) {
            LeftInputAdapterNode liaNode =
                (LeftInputAdapterNode) leftTuple.getLeftTupleSink().getLeftTupleSource();
            LiaNodeMemory lm = (LiaNodeMemory) wm.getNodeMemory(liaNode);
            LeftInputAdapterNode.doDeleteObject(
                leftTuple, context, lm.getSegmentMemory(), wm, liaNode, true, lm);
          } else {
            leftTuple.getLeftTupleSink().retractLeftTuple(leftTuple, context, wm);
          }
        }
      }
    }
    modifyPreviousTuples.retractTuples(context, wm);
  }