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()); } }
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; } }
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); }
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; } }