public static void dpUpdatesReorderRightMemory(BetaMemory bm, RightTupleSets srcRightTuples) {
    RightTupleMemory rtm = bm.getRightTupleMemory();

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      if (rightTuple.getMemory() != null) {
        rightTuple.setTempRightTupleMemory(rightTuple.getMemory());
        rtm.remove(rightTuple);
      }
      rightTuple = next;
    }

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      if (rightTuple.getTempRightTupleMemory() != null) {
        rtm.add(rightTuple);
        for (LeftTuple childLeftTuple = rightTuple.getFirstChild(); childLeftTuple != null; ) {
          LeftTuple childNext = childLeftTuple.getRightParentNext();
          childLeftTuple.reAddLeft();
          childLeftTuple = childNext;
        }
      }
      rightTuple = next;
    }
  }
  /**
   * Tests the assertion of objects into LeftInputAdapterNode
   *
   * @throws Exception
   */
  @Test
  public void testAssertObjectWithoutMemory() throws Exception {
    PropagationContextFactory pctxFactory =
        kBase.getConfiguration().getComponentFactory().getPropagationContextFactory();
    final PropagationContext pcontext =
        pctxFactory.createPropagationContext(0, PropagationContext.INSERTION, null, null, null);

    BuildContext context = new BuildContext(kBase, kBase.getReteooBuilder().getIdGenerator());
    final EntryPointNode entryPoint = new EntryPointNode(-1, kBase.getRete(), context);
    entryPoint.attach(context);

    final ObjectTypeNode objectTypeNode =
        new ObjectTypeNode(0, entryPoint, new ClassObjectType(Object.class), context);

    objectTypeNode.attach(context);

    final LeftInputAdapterNode liaNode = new LeftInputAdapterNode(23, objectTypeNode, buildContext);
    liaNode.attach(context);

    final StatefulKnowledgeSessionImpl workingMemory = new StatefulKnowledgeSessionImpl(1L, kBase);

    final MockLeftTupleSink sink = new MockLeftTupleSink();
    liaNode.addTupleSink(sink);

    final Object string1 = "cheese";

    // assert object
    final DefaultFactHandle f0 = (DefaultFactHandle) workingMemory.insert(string1);
    liaNode.assertObject(f0, pcontext, workingMemory);

    final List asserted = sink.getAsserted();
    assertLength(1, asserted);
    final LeftTuple tuple0 = (LeftTuple) ((Object[]) asserted.get(0))[0];
    assertSame(string1, workingMemory.getObject(tuple0.get(0)));
  }
  public static void dpUpdatesExistentialReorderLeftMemory(
      BetaMemory bm, LeftTupleSets srcLeftTuples) {
    LeftTupleMemory ltm = bm.getLeftTupleMemory();

    // sides must first be re-ordered, to ensure iteration integrity
    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();
      if (leftTuple.getMemory() != null) {
        ltm.remove(leftTuple);
      }
      leftTuple = next;
    }

    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();
      if (leftTuple.getBlocker() == null) {
        ltm.add(leftTuple);
        for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; ) {
          LeftTuple childNext = childLeftTuple.getLeftParentNext();
          childLeftTuple.reAddRight();
          childLeftTuple = childNext;
        }
      }
      leftTuple = next;
    }
  }
    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 void closeLiveQuery(final InternalFactHandle factHandle) {

    try {
      startOperation();
      this.ruleBase.readLock();
      this.lock.lock();

      final PropagationContext pCtx =
          new PropagationContextImpl(
              getNextPropagationIdCounter(),
              PropagationContext.INSERTION,
              null,
              null,
              factHandle,
              getEntryPoint());

      if (this.ruleBase.getConfiguration().isPhreakEnabled()) {
        LeftInputAdapterNode lian =
            (LeftInputAdapterNode)
                factHandle.getFirstLeftTuple().getLeftTupleSink().getLeftTupleSource();
        LiaNodeMemory lmem = (LiaNodeMemory) getNodeMemory((MemoryFactory) lian);
        SegmentMemory lsmem = lmem.getSegmentMemory();

        LeftTuple childLeftTuple =
            factHandle.getFirstLeftTuple(); // there is only one, all other LTs are peers
        LeftInputAdapterNode.doDeleteObject(
            childLeftTuple, childLeftTuple.getPropagationContext(), lsmem, this, lian, false, lmem);

        List<PathMemory> rmems = lmem.getSegmentMemory().getPathMemories();
        for (int i = 0, length = rmems.size(); i < length; i++) {
          PathMemory rm = rmems.get(i);

          RuleNetworkEvaluatorActivation evaluator =
              agenda.createRuleNetworkEvaluatorActivation(
                  Integer.MAX_VALUE, rm, (TerminalNode) rm.getNetworkNode());
          evaluator.evaluateNetwork(this, 0, -1);
        }
      } else {
        getEntryPointNode().retractQuery(factHandle, pCtx, this);

        pCtx.evaluateActionQueue(this);
      }

      getFactHandleFactory().destroyFactHandle(factHandle);

    } finally {
      this.lock.unlock();
      this.ruleBase.readUnlock();
      endOperation();
    }
  }
Beispiel #6
0
  /**
   * Assert a new <code>ReteTuple</code> from the left input. It iterates over the right <code>
   * FactHandleImpl</code>'s and if any match is found, a copy of the <code>ReteTuple</code> is made
   * and propagated.
   *
   * @param tuple The <code>Tuple</code> being asserted.
   * @param context The <code>PropagationContext</code>
   * @param workingMemory The working memory session.
   */
  public void assertLeftTuple(
      final LeftTuple leftTuple,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory(this);

    RightTupleMemory rightMemory = memory.getRightTupleMemory();

    ContextEntry[] contextEntry = memory.getContext();

    boolean useLeftMemory = true;
    if (!this.tupleMemoryEnabled) {
      // This is a hack, to not add closed DroolsQuery objects
      Object object = ((InternalFactHandle) context.getFactHandle()).getObject();
      if (!(object instanceof DroolsQuery) || !((DroolsQuery) object).isOpen()) {
        useLeftMemory = false;
      }
    }

    this.constraints.updateFromTuple(contextEntry, workingMemory, leftTuple);

    FastIterator it = getRightIterator(rightMemory);

    for (RightTuple rightTuple =
            getFirstRightTuple(
                leftTuple, rightMemory, (InternalFactHandle) context.getFactHandle(), it);
        rightTuple != null;
        rightTuple = (RightTuple) it.next(rightTuple)) {
      if (this.constraints.isAllowedCachedLeft(contextEntry, rightTuple.getFactHandle())) {

        leftTuple.setBlocker(rightTuple);
        if (useLeftMemory) {
          rightTuple.addBlocked(leftTuple);
        }

        break;
      }
    }

    this.constraints.resetTuple(contextEntry);

    if (leftTuple.getBlocker() != null) {
      // tuple is not blocked to propagate
      this.sink.propagateAssertLeftTuple(leftTuple, context, workingMemory, useLeftMemory);
    } else if (useLeftMemory) {
      // LeftTuple is not blocked, so add to memory so other RightTuples can match
      memory.getLeftTupleMemory().add(leftTuple);
    }
  }
    public void execute(InternalWorkingMemory workingMemory) {
      leftTuple.setLeftTupleSink(this.node);
      if (leftTuple.getFirstChild() == null) {
        this.node.assertLeftTuple(leftTuple, context, workingMemory);
      } else {
        if (retract) {
          this.node
              .getSinkPropagator()
              .propagateRetractLeftTuple(leftTuple, context, workingMemory);
        } else {
          this.node
              .getSinkPropagator()
              .propagateModifyChildLeftTuple(leftTuple, context, workingMemory, true);
        }
      }

      if (leftTuple.getLeftParent() == null) {
        // It's not an open query, as we aren't recording parent chains, so we need to clear out
        // right memory

        Object node = workingMemory.getNodeMemory(this.node);

        RightTupleMemory rightMemory = null;
        if (node instanceof BetaMemory) {
          rightMemory = ((BetaMemory) node).getRightTupleMemory();
        } else if (node instanceof AccumulateMemory) {
          rightMemory = ((AccumulateMemory) node).betaMemory.getRightTupleMemory();
        }

        final TupleStartEqualsConstraint constraint = TupleStartEqualsConstraint.getInstance();
        TupleStartEqualsConstraintContextEntry contextEntry =
            new TupleStartEqualsConstraintContextEntry();
        contextEntry.updateFromTuple(workingMemory, leftTuple);

        FastIterator rightIt = rightMemory.fastIterator();
        RightTuple temp = null;
        for (RightTuple rightTuple =
                rightMemory.getFirst(
                    leftTuple, (InternalFactHandle) context.getFactHandle(), rightIt);
            rightTuple != null; ) {
          temp = (RightTuple) rightIt.next(rightTuple);

          if (constraint.isAllowedCachedLeft(contextEntry, rightTuple.getFactHandle())) {
            rightMemory.remove(rightTuple);
          }
          rightTuple = temp;
        }
      }
    }
  public static void findLeftTupleBlocker(
      BetaNode betaNode,
      RightTupleMemory rtm,
      ContextEntry[] contextEntry,
      BetaConstraints constraints,
      LeftTuple leftTuple,
      FastIterator it,
      PropagationContext context,
      boolean useLeftMemory) {
    // This method will also remove rightTuples that are from subnetwork where no leftmemory use
    // used

    for (RightTuple rightTuple = betaNode.getFirstRightTuple(leftTuple, rtm, null, it);
        rightTuple != null; ) {
      RightTuple nextRight = (RightTuple) it.next(rightTuple);
      if (constraints.isAllowedCachedLeft(contextEntry, rightTuple.getFactHandle())) {
        leftTuple.setBlocker(rightTuple);

        if (useLeftMemory) {
          rightTuple.addBlocked(leftTuple);
          break;
        } else if (betaNode.isRightInputIsRiaNode()) {
          // If we aren't using leftMemory and the right input is a RIAN, then we must iterate and
          // find all subetwork right tuples and remove them
          // so we don't break
          rtm.remove(rightTuple);
        } else {
          break;
        }
      }
      rightTuple = nextRight;
    }
  }
Beispiel #9
0
 @Override
 public LeftTuple createPeer(LeftTuple original) {
   FromNodeLeftTuple peer = new FromNodeLeftTuple();
   peer.initPeer((BaseLeftTuple) original, this);
   original.setPeer(peer);
   return peer;
 }
Beispiel #10
0
  public static LeftTuple deleteRightChild(
      LeftTuple childLeftTuple, LeftTupleSets trgLeftTuples, LeftTupleSets stagedLeftTuples) {
    switch (childLeftTuple.getStagedType()) {
        // handle clash with already staged entries
      case LeftTuple.INSERT:
        stagedLeftTuples.removeInsert(childLeftTuple);
        break;
      case LeftTuple.UPDATE:
        stagedLeftTuples.removeUpdate(childLeftTuple);
        break;
    }

    LeftTuple next = childLeftTuple.getRightParentNext();

    trgLeftTuples.addDelete(childLeftTuple);
    childLeftTuple.unlinkFromRightParent();
    childLeftTuple.unlinkFromLeftParent();

    return next;
  }
Beispiel #11
0
 public static boolean useLeftMemory(LeftTupleSource tupleSource, LeftTuple leftTuple) {
   boolean useLeftMemory = true;
   if (!tupleSource.isLeftTupleMemoryEnabled()) {
     // This is a hack, to not add closed DroolsQuery objects
     Object object = leftTuple.getRootLeftTuple().getLastHandle().getObject();
     if (!(object instanceof DroolsQuery) || !((DroolsQuery) object).isOpen()) {
       useLeftMemory = false;
     }
   }
   return useLeftMemory;
 }
 public void execute(InternalWorkingMemory workingMemory) {
   InternalFactHandle factHandle = (InternalFactHandle) leftTuple.getObject();
   if (node.isOpenQuery()) {
     // iterate to the query terminal node, as the child leftTuples will get picked up there
     workingMemory
         .getEntryPointNode()
         .retractObject(
             factHandle,
             context,
             workingMemory
                 .getObjectTypeConfigurationRegistry()
                 .getObjectTypeConf(workingMemory.getEntryPoint(), factHandle.getObject()),
             workingMemory);
     // workingMemory.getFactHandleFactory().destroyFactHandle( factHandle );
   } else {
     // get child left tuples, as there is no open query
     if (leftTuple.getFirstChild() != null) {
       node.getSinkPropagator().propagateRetractLeftTuple(leftTuple, context, workingMemory);
     }
   }
 }
Beispiel #13
0
  /** Updates the given sink propagating all previously propagated tuples to it */
  public void updateSink(
      final LeftTupleSink sink,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory(this);
    Iterator it = memory.getRightTupleMemory().iterator();

    // Relies on the fact that any propagated LeftTuples are blocked, but due to lazy blocking
    // they will only be blocked once. So we can iterate the right memory to find the left tuples to
    // propagate
    for (RightTuple rightTuple = (RightTuple) it.next();
        rightTuple != null;
        rightTuple = (RightTuple) it.next()) {
      LeftTuple leftTuple = rightTuple.getBlocked();
      while (leftTuple != null) {
        sink.assertLeftTuple(
            sink.createLeftTuple(leftTuple, sink, context, true), context, workingMemory);
        leftTuple = leftTuple.getBlockedNext();
      }
    }
  }
  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);
      }
    }
  }
Beispiel #15
0
  /**
   * Assert a new <code>FactHandleImpl</code> from the right input. If it matches any left
   * ReteTuple's that had no matches before, propagate tuple as an assertion.
   *
   * @param factHandle The <code>FactHandleImpl</code> being asserted.
   * @param context The <code>PropagationContext</code>
   * @param workingMemory The working memory session.
   */
  public void assertRightTuple(
      final RightTuple rightTuple,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory(this);

    memory.getRightTupleMemory().add(rightTuple);

    if (memory.getLeftTupleMemory() == null || memory.getLeftTupleMemory().size() == 0) {
      // do nothing here, as no left memory
      return;
    }

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

    LeftTupleMemory leftMemory = memory.getLeftTupleMemory();
    FastIterator it = getLeftIterator(leftMemory);
    for (LeftTuple leftTuple = getFirstLeftTuple(rightTuple, leftMemory, context, it);
        leftTuple != null; ) {
      // preserve next now, in case we remove this leftTuple
      LeftTuple temp = (LeftTuple) it.next(leftTuple);

      // we know that only unblocked LeftTuples are  still in the memory
      if (this.constraints.isAllowedCachedRight(memory.getContext(), leftTuple)) {
        leftTuple.setBlocker(rightTuple);
        rightTuple.addBlocked(leftTuple);

        memory.getLeftTupleMemory().remove(leftTuple);

        this.sink.propagateAssertLeftTuple(leftTuple, context, workingMemory, true);
      }

      leftTuple = temp;
    }

    this.constraints.resetFactHandle(memory.getContext());
  }
Beispiel #16
0
  /**
   * Retract the
   * <code>ReteTuple<code>, any resulting propagated joins are also retracted.
   *
   * @param leftTuple
   *            The tuple being retracted
   * @param context
   *            The <code>PropagationContext</code>
   * @param workingMemory
   *            The working memory session.
   */
  public void retractLeftTuple(
      final LeftTuple leftTuple,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    RightTuple blocker = leftTuple.getBlocker();
    if (blocker == null) {
      final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory(this);
      memory.getLeftTupleMemory().remove(leftTuple);
    } else {
      this.sink.propagateRetractLeftTuple(leftTuple, context, workingMemory);

      blocker.removeBlocked(leftTuple);
    }
  }
    public ProtobufMessages.ActionQueue.Action serialize(MarshallerWriteContext context) {
      ProtobufMessages.ActionQueue.Assert.Builder _assert =
          ProtobufMessages.ActionQueue.Assert.newBuilder();
      _assert
          .setHandleId(this.factHandle.getId())
          .setRemoveLogical(this.removeLogical)
          .setUpdateEqualsMap(this.updateEqualsMap);

      if (this.leftTuple != null) {
        ProtobufMessages.Tuple.Builder _tuple = ProtobufMessages.Tuple.newBuilder();
        for (LeftTuple entry = this.leftTuple; entry != null; entry = entry.getParent()) {
          _tuple.addHandleId(entry.getLastHandle().getId());
        }
        _assert
            .setOriginPkgName(ruleOrigin.getPackageName())
            .setOriginRuleName(ruleOrigin.getName())
            .setTuple(_tuple.build());
      }
      return ProtobufMessages.ActionQueue.Action.newBuilder()
          .setType(ProtobufMessages.ActionQueue.ActionType.ASSERT)
          .setAssert(_assert.build())
          .build();
    }
Beispiel #18
0
  public void modifyRightTuple(
      RightTuple rightTuple, PropagationContext context, InternalWorkingMemory workingMemory) {
    final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory(this);

    if (memory.getLeftTupleMemory() == null
        || (memory.getLeftTupleMemory().size() == 0 && rightTuple.getBlocked() == null)) {
      // do nothing here, as we know there are no left tuples

      // normally do this at the end, but as we are exiting early, make sure the buckets are still
      // correct.
      memory.getRightTupleMemory().removeAdd(rightTuple);
      return;
    }

    // TODO: wtd with behaviours?
    //        if ( !behavior.assertRightTuple( memory.getBehaviorContext(),
    //                                         rightTuple,
    //                                         workingMemory ) ) {
    //            // destroy right tuple
    //            rightTuple.unlinkFromRightParent();
    //            return;
    //        }
    this.constraints.updateFromFactHandle(
        memory.getContext(), workingMemory, rightTuple.getFactHandle());

    LeftTupleMemory leftMemory = memory.getLeftTupleMemory();
    FastIterator leftIt = getLeftIterator(leftMemory);
    LeftTuple firstLeftTuple = getFirstLeftTuple(rightTuple, leftMemory, context, leftIt);

    LeftTuple firstBlocked = rightTuple.getBlocked();
    // we now have  reference to the first Blocked, so null it in the rightTuple itself, so we can
    // rebuild
    rightTuple.nullBlocked();

    // first process non-blocked tuples, as we know only those ones are in the left memory.
    for (LeftTuple leftTuple = firstLeftTuple; leftTuple != null; ) {
      // preserve next now, in case we remove this leftTuple
      LeftTuple temp = (LeftTuple) leftIt.next(leftTuple);

      // we know that only unblocked LeftTuples are  still in the memory
      if (this.constraints.isAllowedCachedRight(memory.getContext(), leftTuple)) {
        leftTuple.setBlocker(rightTuple);
        rightTuple.addBlocked(leftTuple);

        // this is now blocked so remove from memory
        leftMemory.remove(leftTuple);

        // subclasses like ForallNotNode might override this propagation
        this.sink.propagateAssertLeftTuple(leftTuple, context, workingMemory, true);
      }

      leftTuple = temp;
    }

    RightTupleMemory rightTupleMemory = memory.getRightTupleMemory();
    if (firstBlocked != null) {
      boolean useComparisonIndex = rightTupleMemory.getIndexType().isComparison();

      // now process existing blocks, we only process existing and not new from above loop
      FastIterator rightIt = getRightIterator(rightTupleMemory);
      RightTuple rootBlocker = useComparisonIndex ? null : (RightTuple) rightIt.next(rightTuple);

      RightTupleList list = rightTuple.getMemory();

      // we must do this after we have the next in memory
      // We add to the end to give an opportunity to re-match if in same bucket
      rightTupleMemory.removeAdd(rightTuple);

      if (!useComparisonIndex && rootBlocker == null && list == rightTuple.getMemory()) {
        // we are at the end of the list, but still in same bucket, so set to self, to give self a
        // chance to rematch
        rootBlocker = rightTuple;
      }

      // iterate all the existing previous blocked LeftTuples
      for (LeftTuple leftTuple = (LeftTuple) firstBlocked; leftTuple != null; ) {
        LeftTuple temp = leftTuple.getBlockedNext();

        leftTuple.setBlockedPrevious(null); // must null these as we are re-adding them to the list
        leftTuple.setBlockedNext(null);

        leftTuple.setBlocker(null);

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

        if (useComparisonIndex) {
          rootBlocker =
              getFirstRightTuple(
                  leftTuple,
                  rightTupleMemory,
                  (InternalFactHandle) context.getFactHandle(),
                  rightIt);
        }

        // we know that older tuples have been checked so continue next
        for (RightTuple newBlocker = rootBlocker;
            newBlocker != null;
            newBlocker = (RightTuple) rightIt.next(newBlocker)) {
          if (this.constraints.isAllowedCachedLeft(
              memory.getContext(), newBlocker.getFactHandle())) {
            leftTuple.setBlocker(newBlocker);
            newBlocker.addBlocked(leftTuple);

            break;
          }
        }

        if (leftTuple.getBlocker() == null) {
          // was previous blocked and not in memory, so add
          memory.getLeftTupleMemory().add(leftTuple);

          // subclasses like ForallNotNode might override this propagation
          this.sink.propagateRetractLeftTuple(leftTuple, context, workingMemory);
        }

        leftTuple = temp;
      }
    } else {
      // we had to do this at the end, rather than beginning as this 'if' block needs the next
      // memory tuple
      rightTupleMemory.removeAdd(rightTuple);
    }

    this.constraints.resetFactHandle(memory.getContext());
    this.constraints.resetTuple(memory.getContext());
  }
Beispiel #19
0
  public void modifyLeftTuple(
      LeftTuple leftTuple, PropagationContext context, InternalWorkingMemory workingMemory) {
    final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory(this);
    RightTupleMemory rightMemory = memory.getRightTupleMemory();

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

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

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

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

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

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

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

          break;
        }
      }
    }

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

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

    this.constraints.resetTuple(memory.getContext());
  }
Beispiel #20
0
  /**
   * Retract the <code>FactHandleImpl</code>. If the handle has any <code>ReteTuple</code> matches
   * and those tuples now have no other match, retract tuple
   *
   * @param handle the <codeFactHandleImpl</code> being retracted
   * @param context The <code>PropagationContext</code>
   * @param workingMemory The working memory session.
   */
  public void retractRightTuple(
      final RightTuple rightTuple,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory(this);
    if (isUnlinkingEnabled()) {
      doDeleteRightTuple(rightTuple, workingMemory, memory);
      return;
    }

    RightTupleMemory rightTupleMemory = memory.getRightTupleMemory();
    boolean useComparisonIndex = rightTupleMemory.getIndexType().isComparison();
    FastIterator rightIt = rightTupleMemory.fastIterator();
    RightTuple rootBlocker = useComparisonIndex ? null : (RightTuple) rightIt.next(rightTuple);

    rightTupleMemory.remove(rightTuple);
    rightTuple.setMemory(null);

    if (rightTuple.getBlocked() == null) {
      return;
    }

    for (LeftTuple leftTuple = (LeftTuple) rightTuple.getBlocked(); leftTuple != null; ) {
      LeftTuple temp = leftTuple.getBlockedNext();

      leftTuple.setBlocker(null);
      leftTuple.setBlockedPrevious(null);
      leftTuple.setBlockedNext(null);

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

      if (useComparisonIndex) {
        rootBlocker =
            getFirstRightTuple(
                leftTuple, rightTupleMemory, (InternalFactHandle) context.getFactHandle(), rightIt);
      }

      // we know that older tuples have been checked so continue previously
      for (RightTuple newBlocker = rootBlocker;
          newBlocker != null;
          newBlocker = (RightTuple) rightIt.next(newBlocker)) {
        if (this.constraints.isAllowedCachedLeft(memory.getContext(), newBlocker.getFactHandle())) {
          leftTuple.setBlocker(newBlocker);
          newBlocker.addBlocked(leftTuple);

          break;
        }
      }

      if (leftTuple.getBlocker() == null) {
        // was previous blocked and not in memory, so add
        memory.getLeftTupleMemory().add(leftTuple);

        this.sink.propagateRetractLeftTuple(leftTuple, context, workingMemory);
      }

      leftTuple = temp;
    }
    rightTuple.nullBlocked();
    this.constraints.resetTuple(memory.getContext());
  }
Beispiel #21
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);
  }
 public void execute(InternalWorkingMemory workingMemory) {
   final AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();
   accctx.setAction(null);
   node.evaluateResultConstraints(
       source, leftTuple, context, workingMemory, memory, accctx, useLeftMemory);
 }
Beispiel #23
0
  private void doRiaNode2(
      InternalWorkingMemory wm,
      LeftTupleSets srcTuples,
      RightInputAdapterNode riaNode,
      LinkedList<StackEntry> stack) {

    ObjectSink[] sinks = riaNode.getSinkPropagator().getSinks();

    BetaNode betaNode = (BetaNode) sinks[0];
    BetaMemory bm;
    Memory nodeMem = wm.getNodeMemory(betaNode);
    if (NodeTypeEnums.AccumulateNode == betaNode.getType()) {
      bm = ((AccumulateMemory) nodeMem).getBetaMemory();
    } else {
      bm = (BetaMemory) nodeMem;
    }

    // Build up iteration array for other sinks
    BetaNode[] bns = null;
    BetaMemory[] bms = null;
    int length = sinks.length;
    if (length > 1) {
      bns = new BetaNode[sinks.length - 1];
      bms = new BetaMemory[sinks.length - 1];
      for (int i = 1; i < length; i++) {
        bns[i - 1] = (BetaNode) sinks[i];
        Memory nodeMem2 = wm.getNodeMemory(bns[i - 1]);
        if (NodeTypeEnums.AccumulateNode == betaNode.getType()) {
          bms[i - 1] = ((AccumulateMemory) nodeMem2).getBetaMemory();
        } else {
          bms[i - 1] = (BetaMemory) nodeMem2;
        }
      }
    }

    length--; // subtract one, as first is not in the array;
    for (LeftTuple leftTuple = srcTuples.getInsertFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();

      PropagationContext pctx = leftTuple.getPropagationContext();
      InternalFactHandle handle = riaNode.createFactHandle(leftTuple, pctx, wm);

      RightTuple rightTuple = new RightTuple(handle, betaNode);
      leftTuple.setObject(rightTuple);
      rightTuple.setPropagationContext(pctx);
      bm.getStagedRightTuples().addInsert(rightTuple);

      if (bns != null) {
        // Add peered RightTuples, they are attached to FH - unlink LeftTuples that has a peer ref
        for (int i = 0; i < length; i++) {
          rightTuple = new RightTuple(handle, bns[i]);
          rightTuple.setPropagationContext(pctx);
          bms[i].getStagedRightTuples().addInsert(rightTuple);
        }
      }

      leftTuple.clearStaged();
      leftTuple = next;
    }

    for (LeftTuple leftTuple = srcTuples.getDeleteFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();

      RightTuple rightTuple = (RightTuple) leftTuple.getObject();
      RightTupleSets rightTuples = bm.getStagedRightTuples();
      switch (rightTuple.getStagedType()) {
        case LeftTuple.INSERT:
          {
            rightTuples.removeInsert(rightTuple);
            break;
          }
        case LeftTuple.UPDATE:
          {
            rightTuples.removeUpdate(rightTuple);
            break;
          }
      }
      rightTuples.addDelete(rightTuple);

      if (bns != null) {
        // Add peered RightTuples, they are attached to FH - unlink LeftTuples that has a peer ref
        for (int i = 0; i < length; i++) {
          rightTuple = rightTuple.getHandleNext();
          rightTuples = bms[i].getStagedRightTuples();
          switch (rightTuple.getStagedType()) {
            case LeftTuple.INSERT:
              {
                rightTuples.removeInsert(rightTuple);
                break;
              }
            case LeftTuple.UPDATE:
              {
                rightTuples.removeUpdate(rightTuple);
                break;
              }
          }
          rightTuples.addDelete(rightTuple);
        }
      }

      leftTuple.clearStaged();
      leftTuple = next;
    }

    for (LeftTuple leftTuple = srcTuples.getUpdateFirst(); leftTuple != null; ) {
      LeftTuple next = leftTuple.getStagedNext();

      RightTuple rightTuple = (RightTuple) leftTuple.getObject();
      RightTupleSets rightTuples = bm.getStagedRightTuples();
      switch (rightTuple.getStagedType()) {
        case LeftTuple.INSERT:
          {
            rightTuples.removeInsert(rightTuple);
            break;
          }
        case LeftTuple.UPDATE:
          {
            rightTuples.removeUpdate(rightTuple);
            break;
          }
      }
      rightTuples.addUpdate(rightTuple);

      if (bns != null) {
        // Add peered RightTuples, they are attached to FH - unlink LeftTuples that has a peer ref
        for (int i = 0; i < length; i++) {
          rightTuple = rightTuple.getHandleNext();
          rightTuples = bms[i].getStagedRightTuples();
          switch (rightTuple.getStagedType()) {
            case LeftTuple.INSERT:
              {
                rightTuples.removeInsert(rightTuple);
                break;
              }
            case LeftTuple.UPDATE:
              {
                rightTuples.removeUpdate(rightTuple);
                break;
              }
          }
          rightTuples.addUpdate(rightTuple);
        }
      }

      leftTuple.clearStaged();
      leftTuple = next;
    }

    srcTuples.resetAll();
  }
Beispiel #24
0
 public LeftTuple createPeer(LeftTuple original) {
   JoinNodeLeftTuple peer = new JoinNodeLeftTuple();
   peer.initPeer((BaseLeftTuple) original, this);
   original.setPeer(peer);
   return peer;
 }
Beispiel #25
0
  public static void dpUpdatesExistentialReorderRightMemory(
      BetaMemory bm, BetaNode betaNode, RightTupleSets srcRightTuples) {
    RightTupleMemory rtm = bm.getRightTupleMemory();

    boolean resumeFromCurrent =
        !(betaNode.isIndexedUnificationJoin() || rtm.getIndexType().isComparison());

    // remove all the staged rightTuples from the memory before to readd them all
    // this is to avoid split bucket when an updated rightTuple hasn't been moved yet
    // and so it is the first entry in the wrong bucket

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      if (rightTuple.getMemory() != null) {
        rightTuple.setTempRightTupleMemory(rightTuple.getMemory());

        if (resumeFromCurrent) {
          if (rightTuple.getBlocked() != null) {
            // look for a non-staged right tuple first forward ...
            RightTuple tempRightTuple = (RightTuple) rightTuple.getNext();
            while (tempRightTuple != null && tempRightTuple.getStagedType() != LeftTuple.NONE) {
              // next cannot be an updated or deleted rightTuple
              tempRightTuple = (RightTuple) tempRightTuple.getNext();
            }

            // ... and if cannot find one try backward
            if (tempRightTuple == null) {
              tempRightTuple = (RightTuple) rightTuple.getPrevious();
              while (tempRightTuple != null && tempRightTuple.getStagedType() != LeftTuple.NONE) {
                // next cannot be an updated or deleted rightTuple
                tempRightTuple = (RightTuple) tempRightTuple.getPrevious();
              }
            }

            rightTuple.setTempNextRightTuple(tempRightTuple);
          }
        }

        rightTuple.setTempBlocked(rightTuple.getBlocked());
        rightTuple.nullBlocked();
        rtm.remove(rightTuple);
      }
      rightTuple = next;
    }

    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
      RightTuple next = rightTuple.getStagedNext();
      if (rightTuple.getTempRightTupleMemory() != null) {

        rtm.add(rightTuple);

        if (resumeFromCurrent) {
          RightTuple tempRightTuple = rightTuple.getTempNextRightTuple();
          if (rightTuple.getBlocked() != null
              && tempRightTuple == null
              && rightTuple.getMemory() == rightTuple.getTempRightTupleMemory()) {
            // the next RightTuple was null, but current RightTuple was added back into the same
            // bucket, so reset as root blocker to re-match can be attempted
            rightTuple.setTempNextRightTuple(rightTuple);
          }
        }

        for (LeftTuple childLeftTuple = rightTuple.getFirstChild(); childLeftTuple != null; ) {
          LeftTuple childNext = childLeftTuple.getRightParentNext();
          childLeftTuple.reAddLeft();
          childLeftTuple = childNext;
        }
      }
      rightTuple = next;
    }
  }