예제 #1
0
  public static void propagate(
      LeftTupleSink sink,
      Tuple leftTuple,
      RightTuple rightTuple,
      BetaConstraints betaConstraints,
      PropagationContext propagationContext,
      ContextEntry[] context,
      boolean useLeftMemory,
      TupleSets<LeftTuple> trgLeftTuples,
      TupleSets<LeftTuple> stagedLeftTuples) {
    if (betaConstraints.isAllowedCachedLeft(context, rightTuple.getFactHandle())) {

      if (rightTuple.getFirstChild() == null) {
        // this is a new match, so propagate as assert
        LeftTuple childLeftTuple =
            sink.createLeftTuple(
                (LeftTuple) leftTuple, rightTuple, null, null, sink, useLeftMemory);
        childLeftTuple.setPropagationContext(propagationContext);
        trgLeftTuples.addInsert(childLeftTuple);
      } else {
        LeftTuple childLeftTuple = rightTuple.getFirstChild();
        childLeftTuple.setPropagationContext(propagationContext);
        updateChildLeftTuple(childLeftTuple, stagedLeftTuples, trgLeftTuples);
      }
    } else {
      deleteChildLeftTuple(
          propagationContext, trgLeftTuples, stagedLeftTuples, rightTuple.getFirstChild());
    }
  }
예제 #2
0
  public static void doUpdatesReorderRightMemory(
      BetaMemory bm, TupleSets<RightTuple> srcRightTuples) {
    TupleMemory 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;
    }
  }
예제 #3
0
  public void doLeftUpdates(
      FromNode fromNode,
      FromMemory fm,
      LeftTupleSink sink,
      InternalWorkingMemory wm,
      TupleSets<LeftTuple> srcLeftTuples,
      TupleSets<LeftTuple> trgLeftTuples,
      TupleSets<LeftTuple> stagedLeftTuples) {
    BetaMemory bm = fm.getBetaMemory();
    ContextEntry[] context = bm.getContext();
    BetaConstraints betaConstraints = fromNode.getBetaConstraints();
    AlphaNodeFieldConstraint[] alphaConstraints = fromNode.getAlphaConstraints();
    DataProvider dataProvider = fromNode.getDataProvider();
    Class<?> resultClass = fromNode.getResultClass();

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

      PropagationContext propagationContext = leftTuple.getPropagationContext();

      final Map<Object, RightTuple> previousMatches =
          (Map<Object, RightTuple>) leftTuple.getContextObject();
      final Map<Object, RightTuple> newMatches = new HashMap<Object, RightTuple>();
      leftTuple.setContextObject(newMatches);

      betaConstraints.updateFromTuple(context, wm, leftTuple);

      FastIterator rightIt = LinkedList.fastIterator;
      for (final java.util.Iterator<?> it =
              dataProvider.getResults(leftTuple, wm, propagationContext, fm.providerContext);
          it.hasNext(); ) {
        final Object object = it.next();
        if ((object == null) || !resultClass.isAssignableFrom(object.getClass())) {
          continue; // skip anything if it not assignable
        }

        RightTuple rightTuple = previousMatches.remove(object);

        if (rightTuple == null) {
          // new match, propagate assert
          rightTuple = fromNode.createRightTuple(leftTuple, propagationContext, wm, object);
        } else {
          // previous match, so reevaluate and propagate modify
          if (rightIt.next(rightTuple) != null) {
            // handle the odd case where more than one object has the same hashcode/equals value
            previousMatches.put(object, (RightTuple) rightIt.next(rightTuple));
            rightTuple.setNext(null);
          }
        }

        checkConstraintsAndPropagate(
            sink,
            leftTuple,
            rightTuple,
            alphaConstraints,
            betaConstraints,
            propagationContext,
            wm,
            fm,
            context,
            true,
            trgLeftTuples,
            null);

        fromNode.addToCreatedHandlesMap(newMatches, rightTuple);
      }

      for (RightTuple rightTuple : previousMatches.values()) {
        for (RightTuple current = rightTuple;
            current != null;
            current = (RightTuple) rightIt.next(current)) {
          deleteChildLeftTuple(
              propagationContext, trgLeftTuples, stagedLeftTuples, current.getFirstChild());
        }
      }

      leftTuple.clearStaged();
      leftTuple = next;
    }
    betaConstraints.resetTuple(context);
  }
예제 #4
0
  public static void doUpdatesExistentialReorderRightMemory(
      BetaMemory bm, BetaNode betaNode, TupleSets<RightTuple> srcRightTuples) {
    TupleMemory 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.setBlocked(null);
        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;
    }
  }