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;
  }
Example #2
0
  public void modifyRightTuple(
      RightTuple rightTuple, PropagationContext context, InternalWorkingMemory workingMemory) {
    final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory(this);

    BetaMemory bm = memory.betaMemory;

    // Add and remove to make sure we are in the right bucket and at the end
    // this is needed to fix for indexing and deterministic iteration
    bm.getRightTupleMemory().removeAdd(rightTuple);

    if (bm.getLeftTupleMemory() == null || bm.getLeftTupleMemory().size() == 0) {
      // do nothing here, as we know there are no left tuples at this stage in sequential mode.
      return;
    }

    LeftTuple childLeftTuple = rightTuple.firstChild;

    LeftTupleMemory leftMemory = bm.getLeftTupleMemory();

    FastIterator leftIt = getLeftIterator(leftMemory);

    LeftTuple leftTuple = getFirstLeftTuple(rightTuple, leftMemory, context, leftIt);

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

    // first check our index (for indexed nodes only) hasn't changed and we are returning the same
    // bucket
    // We assume a bucket change if leftTuple == null
    if (childLeftTuple != null
        && leftMemory.isIndexed()
        && !leftIt.isFullIterator()
        && (leftTuple == null
            || (leftTuple.getMemory() != childLeftTuple.getLeftParent().getMemory()))) {
      // our index has changed, so delete all the previous matches
      removePreviousMatchesForRightTuple(
          rightTuple, context, workingMemory, memory, childLeftTuple);
      childLeftTuple = null; // null so the next check will attempt matches for new bucket
    }

    // if LeftTupleMemory is empty, there are no matches to modify
    if (leftTuple != null) {
      if (childLeftTuple == null) {
        // either we are indexed and changed buckets or
        // we had no children before, but there is a bucket to potentially match, so try as normal
        // assert
        for (; leftTuple != null; leftTuple = (LeftTuple) leftIt.next(leftTuple)) {
          if (this.constraints.isAllowedCachedRight(bm.getContext(), leftTuple)) {
            final AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();
            // add a new match
            addMatch(leftTuple, rightTuple, null, null, workingMemory, memory, accctx, true);
            if (accctx.getAction() == null) {
              // schedule a test to evaluate the constraints, this is an optimisation for sub
              // networks
              // We set Source to LEFT, even though this is a right propagation, because it might
              // end up
              // doing multiple right propagations anyway
              EvaluateResultConstraints action =
                  new EvaluateResultConstraints(
                      ActivitySource.LEFT,
                      leftTuple,
                      context,
                      workingMemory,
                      memory,
                      accctx,
                      true,
                      this);
              accctx.setAction(action);
              context.addInsertAction(action);
            }
          }
        }
      } else {
        // in the same bucket, so iterate and compare
        for (; leftTuple != null; leftTuple = (LeftTuple) leftIt.next(leftTuple)) {
          if (this.constraints.isAllowedCachedRight(bm.getContext(), leftTuple)) {
            final AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();
            LeftTuple temp = null;
            if (childLeftTuple != null && childLeftTuple.getLeftParent() == leftTuple) {
              temp = childLeftTuple.getRightParentNext();
              // we must re-add this to ensure deterministic iteration
              childLeftTuple.reAddLeft();
              removeMatch(rightTuple, childLeftTuple, workingMemory, memory, accctx, true);
              childLeftTuple = temp;
            }
            // add a new match
            addMatch(
                leftTuple, rightTuple, null, childLeftTuple, workingMemory, memory, accctx, true);
            if (temp != null) {
              childLeftTuple = temp;
            }
            if (accctx.getAction() == null) {
              // schedule a test to evaluate the constraints, this is an optimisation for sub
              // networks
              // We set Source to LEFT, even though this is a right propagation, because it might
              // end up
              // doing multiple right propagations anyway
              EvaluateResultConstraints action =
                  new EvaluateResultConstraints(
                      ActivitySource.LEFT,
                      leftTuple,
                      context,
                      workingMemory,
                      memory,
                      accctx,
                      true,
                      this);
              accctx.setAction(action);
              context.addInsertAction(action);
            }
          } else if (childLeftTuple != null && childLeftTuple.getLeftParent() == leftTuple) {

            LeftTuple temp = childLeftTuple.getRightParentNext();
            final AccumulateContext accctx = (AccumulateContext) leftTuple.getObject();
            // remove the match
            removeMatch(rightTuple, childLeftTuple, workingMemory, memory, accctx, true);
            if (accctx.getAction() == null) {
              // schedule a test to evaluate the constraints, this is an optimisation for sub
              // networks
              // We set Source to LEFT, even though this is a right propagation, because it might
              // end up
              // doing multiple right propagations anyway
              EvaluateResultConstraints action =
                  new EvaluateResultConstraints(
                      ActivitySource.LEFT,
                      leftTuple,
                      context,
                      workingMemory,
                      memory,
                      accctx,
                      true,
                      this);
              accctx.setAction(action);
              context.addInsertAction(action);
            }

            childLeftTuple = temp;
          }
          // else do nothing, was false before and false now.
        }
      }
    }

    this.constraints.resetFactHandle(bm.getContext());
  }