public static void dpUpdatesReorderRightMemory(BetaMemory bm, RightTupleSets srcRightTuples) { RightTupleMemory 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 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 doRightUpdates( NotNode notNode, LeftTupleSink sink, 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(); boolean iterateFromStart = notNode.isIndexedUnificationJoin() || rtm.getIndexType().isComparison(); for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) { RightTuple next = rightTuple.getStagedNext(); PropagationContext context = rightTuple.getPropagationContext(); constraints.updateFromFactHandle(contextEntry, wm, rightTuple.getFactHandle()); FastIterator leftIt = notNode.getLeftIterator(ltm); LeftTuple firstLeftTuple = notNode.getFirstLeftTuple(rightTuple, ltm, context, leftIt); LeftTuple firstBlocked = rightTuple.getTempBlocked(); // first process non-blocked tuples, as we know only those ones are in the left memory. for (LeftTuple leftTuple = firstLeftTuple; leftTuple != null; ) { // preserve next now, in case we remove this leftTuple LeftTuple temp = (LeftTuple) leftIt.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); LeftTuple childLeftTuple = leftTuple.getFirstChild(); if (childLeftTuple != null) { childLeftTuple.setPropagationContext(rightTuple.getPropagationContext()); RuleNetworkEvaluator.deleteRightChild(childLeftTuple, trgLeftTuples, stagedLeftTuples); } } leftTuple = temp; } if (firstBlocked != null) { RightTuple rootBlocker = rightTuple.getTempNextRightTuple(); if (rootBlocker == null) { iterateFromStart = true; } FastIterator rightIt = notNode.getRightIterator(rtm); // iterate all the existing previous blocked LeftTuples for (LeftTuple leftTuple = firstBlocked; leftTuple != null; ) { LeftTuple temp = leftTuple.getBlockedNext(); leftTuple.clearBlocker(); if (leftTuple.getStagedType() == LeftTuple.UPDATE) { // ignore, as it will get processed via left iteration. Children cannot be processed // twice // but need to add it back into list first leftTuple.setBlocker(rightTuple); rightTuple.addBlocked(leftTuple); leftTuple = temp; continue; } constraints.updateFromTuple(contextEntry, wm, leftTuple); if (iterateFromStart) { rootBlocker = notNode.getFirstRightTuple(leftTuple, rtm, null, rightIt); } // we know that older tuples have been checked so continue next for (RightTuple newBlocker = rootBlocker; newBlocker != null; newBlocker = (RightTuple) rightIt.next(newBlocker)) { // cannot select a RightTuple queued in the delete list // There may be UPDATE RightTuples too, but that's ok. They've already been re-added to // the correct bucket, safe to be reprocessed. if (leftTuple.getStagedType() != LeftTuple.DELETE && newBlocker.getStagedType() != LeftTuple.DELETE && constraints.isAllowedCachedLeft(contextEntry, newBlocker.getFactHandle())) { leftTuple.setBlocker(newBlocker); newBlocker.addBlocked(leftTuple); break; } } if (leftTuple.getBlocker() == null) { // was previous blocked and not in memory, so add ltm.add(leftTuple); // subclasses like ForallNotNode might override this propagation trgLeftTuples.addInsert( sink.createLeftTuple(leftTuple, sink, rightTuple.getPropagationContext(), true)); } leftTuple = temp; } } rightTuple.clearStaged(); rightTuple = next; } constraints.resetFactHandle(contextEntry); constraints.resetTuple(contextEntry); }
public static void dpUpdatesExistentialReorderRightMemory( BetaMemory bm, BetaNode betaNode, RightTupleSets srcRightTuples) { RightTupleMemory 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.nullBlocked(); 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; } }