use of org.drools.core.util.FastIterator in project drools by kiegroup.
the class PhreakFromNode method doLeftUpdates.
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())) {
// skip anything if it not assignable
continue;
}
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, stagedLeftTuples);
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);
}
use of org.drools.core.util.FastIterator in project drools by kiegroup.
the class PhreakFromNode method unlinkCreatedHandles.
public static void unlinkCreatedHandles(final LeftTuple leftTuple) {
Map<Object, RightTuple> matches = (Map<Object, RightTuple>) leftTuple.getContextObject();
FastIterator rightIt = LinkedList.fastIterator;
for (RightTuple rightTuple : matches.values()) {
for (RightTuple current = rightTuple; current != null; ) {
RightTuple next = (RightTuple) rightIt.next(current);
current.unlinkFromRightParent();
current = next;
}
}
}
use of org.drools.core.util.FastIterator in project drools by kiegroup.
the class PhreakJoinNode method doLeftUpdates.
public void doLeftUpdates(JoinNode joinNode, LeftTupleSink sink, BetaMemory bm, InternalWorkingMemory wm, TupleSets<LeftTuple> srcLeftTuples, TupleSets<LeftTuple> trgLeftTuples, TupleSets<LeftTuple> stagedLeftTuples) {
TupleMemory rtm = bm.getRightTupleMemory();
ContextEntry[] contextEntry = bm.getContext();
BetaConstraints constraints = joinNode.getRawConstraints();
for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
LeftTuple next = leftTuple.getStagedNext();
constraints.updateFromTuple(contextEntry, wm, leftTuple);
FastIterator it = joinNode.getRightIterator(rtm);
RightTuple rightTuple = joinNode.getFirstRightTuple(leftTuple, rtm, null, it);
// if rightTuple is null, we assume there was a bucket change and that bucket is empty
if (rtm.isIndexed() && !it.isFullIterator()) {
// our index has changed, so delete all the previous propagations
for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; ) {
LeftTuple nextChild = childLeftTuple.getHandleNext();
if (rightTuple == null || rightTuple.getMemory() != childLeftTuple.getRightParent().getMemory()) {
RuleNetworkEvaluator.unlinkAndDeleteChildLeftTuple(childLeftTuple, trgLeftTuples, stagedLeftTuples);
}
childLeftTuple = nextChild;
}
}
// we can't do anything if RightTupleMemory is empty
if (rightTuple != null) {
doLeftUpdatesProcessChildren(leftTuple.getFirstChild(), leftTuple, rightTuple, stagedLeftTuples, contextEntry, constraints, sink, it, trgLeftTuples);
}
leftTuple.clearStaged();
leftTuple = next;
}
constraints.resetTuple(contextEntry);
}
use of org.drools.core.util.FastIterator in project drools by kiegroup.
the class PhreakNotNode method doLeftUpdates.
public void doLeftUpdates(NotNode notNode, LeftTupleSink sink, BetaMemory bm, InternalWorkingMemory wm, TupleSets<LeftTuple> srcLeftTuples, TupleSets<LeftTuple> trgLeftTuples, TupleSets<LeftTuple> stagedLeftTuples) {
TupleMemory ltm = bm.getLeftTupleMemory();
TupleMemory rtm = bm.getRightTupleMemory();
ContextEntry[] contextEntry = bm.getContext();
BetaConstraints constraints = notNode.getRawConstraints();
boolean leftUpdateOptimizationAllowed = notNode.isLeftUpdateOptimizationAllowed();
for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
LeftTuple next = leftTuple.getStagedNext();
FastIterator rightIt = notNode.getRightIterator(rtm);
RightTuple firstRightTuple = notNode.getFirstRightTuple(leftTuple, rtm, null, 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) {
if (leftTuple.getMemory() != null) {
// memory can be null, if blocker was deleted in same do loop
ltm.remove(leftTuple);
}
} else {
// check if we changed bucket
if (rtm.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()) {
blocker.removeBlocked(leftTuple);
blocker = null;
}
}
}
constraints.updateFromTuple(contextEntry, wm, leftTuple);
if (!leftUpdateOptimizationAllowed && blocker != null) {
blocker.removeBlocked(leftTuple);
blocker = null;
}
// if we where not blocked before (or changed buckets), or the previous blocker no longer blocks, then find the next blocker
if (blocker == null || !constraints.isAllowedCachedLeft(contextEntry, blocker.getFactHandleForEvaluation())) {
if (blocker != null) {
// remove previous blocker if it exists, as we know it doesn't block any more
blocker.removeBlocked(leftTuple);
}
// 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 (constraints.isAllowedCachedLeft(contextEntry, newBlocker.getFactHandleForEvaluation())) {
leftTuple.setBlocker(newBlocker);
newBlocker.addBlocked(leftTuple);
break;
}
}
LeftTuple childLeftTuple = leftTuple.getFirstChild();
if (leftTuple.getBlocker() != null) {
// blocked
if (childLeftTuple != null) {
// blocked, with previous children, so must have not been previously blocked, so retract
// no need to remove, as we removed at the start
// to be matched against, as it's now blocked
// we have the righttuple, so use it for the pctx
childLeftTuple.setPropagationContext(leftTuple.getBlocker().getPropagationContext());
RuleNetworkEvaluator.unlinkAndDeleteChildLeftTuple(childLeftTuple, trgLeftTuples, stagedLeftTuples);
}
// else: it's blocked now and no children so blocked before, thus do nothing
} else if (childLeftTuple == null) {
// not blocked, with no children, must have been previously blocked so assert
insertChildLeftTuple(sink, trgLeftTuples, ltm, leftTuple, leftTuple.getPropagationContext(), true);
} else {
updateChildLeftTuple(childLeftTuple, stagedLeftTuples, trgLeftTuples);
// not blocked, with children, so wasn't previous blocked and still isn't so modify
// add to memory so other fact handles can attempt to match
ltm.add(leftTuple);
childLeftTuple.reAddLeft();
}
}
leftTuple.clearStaged();
leftTuple = next;
}
constraints.resetTuple(contextEntry);
}
use of org.drools.core.util.FastIterator in project drools by kiegroup.
the class LeftTupleIterator method getNextLeftTuple.
public LeftTuple getNextLeftTuple(LeftTupleSource source, LeftTupleSink sink, LeftTuple leftTuple, InternalWorkingMemory wm) {
if (otnIterator != null) {
LeftTuple leftParent = leftTuple.getLeftParent();
while (leftTuple != null) {
leftTuple = leftTuple.getHandleNext();
for (; leftTuple != null; leftTuple = leftTuple.getHandleNext()) {
// Iterate to find the next left tuple for this sink, skip tuples for other sinks due to sharing split
if (leftTuple.getTupleSink() == sink) {
return leftTuple;
}
}
}
// We have a parent LeftTuple so try there next
if (leftParent != null) {
// we know it has to be evalNode query element node
while (leftParent != null) {
leftParent = getNextLeftTuple(source.getLeftTupleSource(), (LeftTupleSink) source, leftParent, wm);
if (leftParent != null) {
for (leftTuple = leftParent.getFirstChild(); leftTuple != null; leftTuple = leftTuple.getHandleNext()) {
if (leftTuple.getTupleSink() == sink) {
return leftTuple;
}
}
}
}
return null;
}
// We have exhausted the current FactHandle, now try the next
while (otnIterator.hasNext()) {
InternalFactHandle handle = otnIterator.next();
leftTuple = handle.findFirstLeftTuple(lt -> lt.getTupleSink() == sink);
if (leftTuple != null) {
return leftTuple;
}
}
// We've exhausted this OTN so set the iterator to null
otnIterator = null;
} else if (source instanceof AccumulateNode) {
// when using phreak, accumulate result tuples will not link to leftParent, but to parent instead
BetaMemory memory = ((AccumulateMemory) wm.getNodeMemory((MemoryFactory) source)).getBetaMemory();
FastIterator localIt = memory.getLeftTupleMemory().fullFastIterator(leftTuple.getParent());
LeftTuple childLeftTuple = leftTuple;
leftTuple = childLeftTuple.getParent();
while (leftTuple != null) {
if (childLeftTuple == null) {
childLeftTuple = leftTuple.getFirstChild();
} else {
childLeftTuple = childLeftTuple.getHandleNext();
}
for (; childLeftTuple != null; childLeftTuple = childLeftTuple.getHandleNext()) {
if (childLeftTuple.getTupleSink() == sink) {
return childLeftTuple;
}
}
leftTuple = (LeftTuple) localIt.next(leftTuple);
}
} else if (source instanceof JoinNode || source instanceof NotNode || source instanceof FromNode || source instanceof AccumulateNode) {
BetaMemory memory;
FastIterator localIt;
if (source instanceof FromNode) {
memory = ((FromMemory) wm.getNodeMemory((MemoryFactory) source)).getBetaMemory();
} else if (source instanceof AccumulateNode) {
memory = ((AccumulateMemory) wm.getNodeMemory((MemoryFactory) source)).getBetaMemory();
} else {
memory = (BetaMemory) wm.getNodeMemory((MemoryFactory) source);
}
localIt = memory.getLeftTupleMemory().fullFastIterator(leftTuple.getLeftParent());
LeftTuple childLeftTuple = leftTuple;
leftTuple = childLeftTuple.getLeftParent();
while (leftTuple != null) {
if (childLeftTuple == null) {
childLeftTuple = leftTuple.getFirstChild();
} else {
childLeftTuple = childLeftTuple.getHandleNext();
}
for (; childLeftTuple != null; childLeftTuple = childLeftTuple.getHandleNext()) {
if (childLeftTuple.getTupleSink() == sink) {
return childLeftTuple;
}
}
leftTuple = (LeftTuple) localIt.next(leftTuple);
}
}
if (source instanceof ExistsNode) {
BetaMemory memory = (BetaMemory) wm.getNodeMemory((MemoryFactory) source);
RightTuple rightTuple = leftTuple.getLeftParent().getBlocker();
FastIterator localIt = memory.getRightTupleMemory().fullFastIterator(rightTuple);
for (LeftTuple childleftTuple = leftTuple.getHandleNext(); childleftTuple != null; childleftTuple = childleftTuple.getHandleNext()) {
if (childleftTuple.getTupleSink() == sink) {
return childleftTuple;
}
}
leftTuple = leftTuple.getLeftParent();
// now move onto next RightTuple
while (rightTuple != null) {
if (rightTuple.getBlocked() != null) {
if (leftTuple != null) {
leftTuple = leftTuple.getBlockedNext();
} else {
leftTuple = rightTuple.getBlocked();
}
for (; leftTuple != null; leftTuple = leftTuple.getBlockedNext()) {
for (LeftTuple childleftTuple = leftTuple.getFirstChild(); childleftTuple != null; childleftTuple = childleftTuple.getHandleNext()) {
if (childleftTuple.getTupleSink() == sink) {
return childleftTuple;
}
}
}
}
rightTuple = (RightTuple) localIt.next(rightTuple);
}
} else if (source instanceof EvalConditionNode || source instanceof QueryElementNode) {
LeftTuple childLeftTuple = leftTuple;
if (leftTuple != null) {
leftTuple = leftTuple.getLeftParent();
while (leftTuple != null) {
if (childLeftTuple != null) {
childLeftTuple = childLeftTuple.getHandleNext();
} else {
childLeftTuple = leftTuple.getFirstChild();
}
for (; childLeftTuple != null; childLeftTuple = childLeftTuple.getHandleNext()) {
if (childLeftTuple.getTupleSink() == sink) {
return childLeftTuple;
}
}
if (source instanceof EvalConditionNode) {
leftTuple = getNextLeftTuple(source.getLeftTupleSource(), (LeftTupleSink) source, leftTuple, wm);
} else {
leftTuple = getNextLeftTuple(source.getLeftTupleSource(), (LeftTupleSink) source, leftTuple, wm);
}
}
}
}
return null;
}
Aggregations