Search in sources :

Example 41 with LeftTuple

use of org.drools.core.reteoo.LeftTuple in project drools by kiegroup.

the class PhreakExistsNode method doRightUpdates.

public void doRightUpdates(ExistsNode existsNode, LeftTupleSink sink, BetaMemory bm, InternalWorkingMemory wm, TupleSets<RightTuple> srcRightTuples, TupleSets<LeftTuple> trgLeftTuples, TupleSets<LeftTuple> stagedLeftTuples) {
    TupleMemory ltm = bm.getLeftTupleMemory();
    TupleMemory rtm = bm.getRightTupleMemory();
    ContextEntry[] contextEntry = bm.getContext();
    BetaConstraints constraints = existsNode.getRawConstraints();
    boolean iterateFromStart = existsNode.isIndexedUnificationJoin() || rtm.getIndexType().isComparison();
    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
        RightTuple next = rightTuple.getStagedNext();
        if (ltm != null && ltm.size() > 0) {
            FastIterator leftIt = existsNode.getLeftIterator(ltm);
            LeftTuple firstLeftTuple = existsNode.getFirstLeftTuple(rightTuple, ltm, leftIt);
            constraints.updateFromFactHandle(contextEntry, wm, rightTuple.getFactHandleForEvaluation());
            // 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);
                    // subclasses like ForallNotNode might override this propagation
                    insertChildLeftTuple(sink, trgLeftTuples, leftTuple, rightTuple.getPropagationContext(), true);
                }
                leftTuple = temp;
            }
        }
        LeftTuple firstBlocked = rightTuple.getTempBlocked();
        if (firstBlocked != null) {
            RightTuple rootBlocker = rightTuple.getTempNextRightTuple();
            if (rootBlocker == null) {
                iterateFromStart = true;
            }
            FastIterator rightIt = existsNode.getRightIterator(rtm);
            // iterate all the existing previous blocked LeftTuples
            for (LeftTuple leftTuple = firstBlocked; leftTuple != null; ) {
                LeftTuple temp = leftTuple.getBlockedNext();
                // must null these as we are re-adding them to the list
                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 = existsNode.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)) {
                    // 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.getFactHandleForEvaluation())) {
                        leftTuple.setBlocker(newBlocker);
                        newBlocker.addBlocked(leftTuple);
                        break;
                    }
                }
                if (leftTuple.getBlocker() == null) {
                    // was previous blocked and not in memory, so add
                    if (ltm != null) {
                        ltm.add(leftTuple);
                    }
                    LeftTuple childLeftTuple = leftTuple.getFirstChild();
                    if (childLeftTuple != null) {
                        childLeftTuple.setPropagationContext(rightTuple.getPropagationContext());
                        RuleNetworkEvaluator.unlinkAndDeleteChildLeftTuple(childLeftTuple, trgLeftTuples, stagedLeftTuples);
                    }
                }
                leftTuple = temp;
            }
        }
        rightTuple.clearStaged();
        rightTuple = next;
    }
    constraints.resetFactHandle(contextEntry);
}
Also used : BetaConstraints(org.drools.core.common.BetaConstraints) FastIterator(org.drools.core.util.FastIterator) RightTuple(org.drools.core.reteoo.RightTuple) LeftTuple(org.drools.core.reteoo.LeftTuple) PhreakJoinNode.updateChildLeftTuple(org.drools.core.phreak.PhreakJoinNode.updateChildLeftTuple) TupleMemory(org.drools.core.reteoo.TupleMemory) ContextEntry(org.drools.core.rule.ContextEntry)

Example 42 with LeftTuple

use of org.drools.core.reteoo.LeftTuple 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);
}
Also used : BetaConstraints(org.drools.core.common.BetaConstraints) PropagationContext(org.drools.core.spi.PropagationContext) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) BetaMemory(org.drools.core.reteoo.BetaMemory) LeftTuple(org.drools.core.reteoo.LeftTuple) PhreakJoinNode.updateChildLeftTuple(org.drools.core.phreak.PhreakJoinNode.updateChildLeftTuple) RightTuple(org.drools.core.reteoo.RightTuple) ContextEntry(org.drools.core.rule.ContextEntry) DataProvider(org.drools.core.spi.DataProvider) AlphaNodeFieldConstraint(org.drools.core.spi.AlphaNodeFieldConstraint) FastIterator(org.drools.core.util.FastIterator) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 43 with LeftTuple

use of org.drools.core.reteoo.LeftTuple in project drools by kiegroup.

the class PhreakFromNode method doLeftDeletes.

public void doLeftDeletes(FromMemory fm, TupleSets<LeftTuple> srcLeftTuples, TupleSets<LeftTuple> trgLeftTuples, TupleSets<LeftTuple> stagedLeftTuples) {
    BetaMemory bm = fm.getBetaMemory();
    TupleMemory ltm = bm.getLeftTupleMemory();
    for (LeftTuple leftTuple = srcLeftTuples.getDeleteFirst(); leftTuple != null; ) {
        LeftTuple next = leftTuple.getStagedNext();
        ltm.remove(leftTuple);
        Map<Object, RightTuple> matches = (Map<Object, RightTuple>) leftTuple.getContextObject();
        if (leftTuple.getFirstChild() != null) {
            LeftTuple childLeftTuple = leftTuple.getFirstChild();
            while (childLeftTuple != null) {
                childLeftTuple.setPropagationContext(leftTuple.getPropagationContext());
                LeftTuple nextChild = childLeftTuple.getHandleNext();
                RuleNetworkEvaluator.unlinkAndDeleteChildLeftTuple(childLeftTuple, trgLeftTuples, stagedLeftTuples);
                childLeftTuple = nextChild;
            }
        }
        // if matches == null, the deletion might be happening before the fact was even propagated. See BZ-1019473 for details.
        if (matches != null) {
            // @TODO (mdp) is this really necessary? won't the entire FH and RightTuple chaines just et GC'd?
            unlinkCreatedHandles(leftTuple);
        }
        leftTuple.clearStaged();
        leftTuple = next;
    }
}
Also used : BetaMemory(org.drools.core.reteoo.BetaMemory) LeftTuple(org.drools.core.reteoo.LeftTuple) PhreakJoinNode.updateChildLeftTuple(org.drools.core.phreak.PhreakJoinNode.updateChildLeftTuple) RightTuple(org.drools.core.reteoo.RightTuple) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) TupleMemory(org.drools.core.reteoo.TupleMemory)

Example 44 with LeftTuple

use of org.drools.core.reteoo.LeftTuple in project drools by kiegroup.

the class PhreakFromNode method propagate.

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.getFactHandleForEvaluation())) {
        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());
    }
}
Also used : LeftTuple(org.drools.core.reteoo.LeftTuple) PhreakJoinNode.updateChildLeftTuple(org.drools.core.phreak.PhreakJoinNode.updateChildLeftTuple)

Example 45 with LeftTuple

use of org.drools.core.reteoo.LeftTuple 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);
}
Also used : BetaConstraints(org.drools.core.common.BetaConstraints) FastIterator(org.drools.core.util.FastIterator) LeftTuple(org.drools.core.reteoo.LeftTuple) RightTuple(org.drools.core.reteoo.RightTuple) TupleMemory(org.drools.core.reteoo.TupleMemory) ContextEntry(org.drools.core.rule.ContextEntry)

Aggregations

LeftTuple (org.drools.core.reteoo.LeftTuple)125 RightTuple (org.drools.core.reteoo.RightTuple)41 TupleMemory (org.drools.core.reteoo.TupleMemory)37 InternalFactHandle (org.drools.core.common.InternalFactHandle)34 FastIterator (org.drools.core.util.FastIterator)22 BetaConstraints (org.drools.core.common.BetaConstraints)21 BetaMemory (org.drools.core.reteoo.BetaMemory)21 ContextEntry (org.drools.core.rule.ContextEntry)20 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)18 PhreakJoinNode.updateChildLeftTuple (org.drools.core.phreak.PhreakJoinNode.updateChildLeftTuple)16 AccumulateContext (org.drools.core.reteoo.AccumulateNode.AccumulateContext)13 SegmentMemory (org.drools.core.reteoo.SegmentMemory)13 Test (org.junit.Test)13 KieSession (org.kie.api.runtime.KieSession)13 Tuple (org.drools.core.spi.Tuple)12 WorkingMemory (org.drools.core.WorkingMemory)11 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)11 FromMemory (org.drools.core.reteoo.FromNode.FromMemory)10 AccumulateMemory (org.drools.core.reteoo.AccumulateNode.AccumulateMemory)9 ArrayList (java.util.ArrayList)8