LeftTupleSets trgLeftTuples,
LeftTupleSets stagedLeftTuples) {
BetaMemory bm = fm.getBetaMemory();
LeftTupleMemory ltm = bm.getLeftTupleMemory();
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.getObject();
final Map<Object, RightTuple> newMatches = new HashMap<Object, RightTuple>();
leftTuple.setObject(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,
bm,
context,
true,
trgLeftTuples,
null);
fromNode.addToCreatedHandlesMap(newMatches,
rightTuple);
}
for (RightTuple rightTuple : previousMatches.values()) {
for (RightTuple current = rightTuple; current != null; current = (RightTuple) rightIt.next(current)) {
LeftTuple childLeftTuple = current.getFirstChild();
if (childLeftTuple != null) {
// childLeftTuple is null, if the constraints in the 'from' pattern fail
childLeftTuple.unlinkFromLeftParent();
childLeftTuple.unlinkFromRightParent();
switch (childLeftTuple.getStagedType()) {
// handle clash with already staged entries
case LeftTuple.INSERT:
stagedLeftTuples.removeInsert(childLeftTuple);
break;
case LeftTuple.UPDATE:
stagedLeftTuples.removeUpdate(childLeftTuple);
break;
}
childLeftTuple.setPropagationContext(propagationContext);
trgLeftTuples.addDelete(childLeftTuple);
}
}
}
leftTuple.clearStaged();
leftTuple = next;
}
betaConstraints.resetTuple(context);
}