public void doNode( NotNode notNode, LeftTupleSink sink, BetaMemory bm, InternalWorkingMemory wm, LeftTupleSets srcLeftTuples, LeftTupleSets trgLeftTuples, LeftTupleSets stagedLeftTuples) { RightTupleSets srcRightTuples = bm.getStagedRightTuples().takeAll(); if (srcLeftTuples.getDeleteFirst() != null) { // left deletes must come before right deletes. Otherwise right deletes could // stage an insertion, that is later deleted in the rightDelete, causing potential problems doLeftDeletes(bm, srcLeftTuples, trgLeftTuples, stagedLeftTuples); } if (srcLeftTuples.getUpdateFirst() != null) { // must happen before right inserts, so it can find left tuples to block. RuleNetworkEvaluator.doUpdatesExistentialReorderLeftMemory(bm, srcLeftTuples); } if (srcRightTuples.getUpdateFirst() != null) { RuleNetworkEvaluator.doUpdatesExistentialReorderRightMemory( bm, notNode, srcRightTuples); // this also preserves the next rightTuple } if (srcRightTuples.getInsertFirst() != null) { // must come before right updates and inserts, as they might cause insert propagation, while // this causes delete propagations, resulting in staging clash. doRightInserts(notNode, bm, wm, srcRightTuples, trgLeftTuples, stagedLeftTuples); } if (srcRightTuples.getUpdateFirst() != null) { // must come after rightInserts and before rightDeletes, to avoid staging clash doRightUpdates(notNode, sink, bm, wm, srcRightTuples, trgLeftTuples, stagedLeftTuples); } if (srcRightTuples.getDeleteFirst() != null) { // must come after rightUpdates, to avoid staging clash doRightDeletes(notNode, sink, bm, wm, srcRightTuples, trgLeftTuples); } if (srcLeftTuples.getUpdateFirst() != null) { doLeftUpdates(notNode, sink, bm, wm, srcLeftTuples, trgLeftTuples, stagedLeftTuples); } if (srcLeftTuples.getInsertFirst() != null) { doLeftInserts(notNode, sink, bm, wm, srcLeftTuples, trgLeftTuples); } srcRightTuples.resetAll(); srcLeftTuples.resetAll(); }
public void doRightInserts( NotNode notNode, BetaMemory bm, InternalWorkingMemory wm, RightTupleSets srcRightTuples, LeftTupleSets trgLeftTuples, LeftTupleSets stagedLeftTuples) { LeftTupleMemory ltm = bm.getLeftTupleMemory(); RightTupleMemory rtm = bm.getRightTupleMemory(); ContextEntry[] contextEntry = bm.getContext(); BetaConstraints constraints = notNode.getRawConstraints(); // this must be processed here, rather than initial insert, as we need to link the blocker unlinkNotNodeOnRightInsert(notNode, bm, wm); for (RightTuple rightTuple = srcRightTuples.getInsertFirst(); rightTuple != null; ) { RightTuple next = rightTuple.getStagedNext(); rtm.add(rightTuple); if (ltm == null || ltm.size() == 0) { // do nothing here, as no left memory rightTuple.clearStaged(); rightTuple = next; continue; } FastIterator it = notNode.getLeftIterator(ltm); PropagationContext context = rightTuple.getPropagationContext(); constraints.updateFromFactHandle(contextEntry, wm, rightTuple.getFactHandle()); for (LeftTuple leftTuple = notNode.getFirstLeftTuple(rightTuple, ltm, context, it); leftTuple != null; ) { // preserve next now, in case we remove this leftTuple LeftTuple temp = (LeftTuple) it.next(leftTuple); if (leftTuple.getStagedType() == LeftTuple.UPDATE) { // ignore, as it will get processed via left iteration. Children cannot be processed twice leftTuple = temp; continue; } // we know that only unblocked LeftTuples are still in the memory if (constraints.isAllowedCachedRight(contextEntry, leftTuple)) { leftTuple.setBlocker(rightTuple); rightTuple.addBlocked(leftTuple); // this is now blocked so remove from memory ltm.remove(leftTuple); // subclasses like ForallNotNode might override this propagation // ** @TODO (mdp) need to not break forall LeftTuple childLeftTuple = leftTuple.getFirstChild(); if (childLeftTuple != null) { // NotNode only has one child childLeftTuple.setPropagationContext(rightTuple.getPropagationContext()); RuleNetworkEvaluator.deleteLeftChild(childLeftTuple, trgLeftTuples, stagedLeftTuples); } } leftTuple = temp; } rightTuple.clearStaged(); rightTuple = next; } constraints.resetFactHandle(contextEntry); }