use of org.drools.core.common.Memory in project drools by kiegroup.
the class AddRemoveRule method processLeftTuples.
/**
* Populates the SegmentMemory with staged LeftTuples. If the parent is not a Beta or From node, it iterates up to find the first node with memory. If necessary
* It traverses to the LiaNode's ObjectTypeNode. It then iterates the LeftTuple chains, where an existing LeftTuple is staged
* as delete. Or a new LeftTuple is created and staged as an insert.
*/
private static void processLeftTuples(LeftTupleNode node, InternalWorkingMemory wm, boolean insert, Rule rule) {
// *** if you make a fix here, it most likely needs to be in PhreakActivationIteratorToo ***
// Must iterate up until a node with memory is found, this can be followed to find the LeftTuples
// which provide the potential peer of the tuple being added or removed
Memory memory = wm.getNodeMemories().peekNodeMemory(node);
if (memory == null || memory.getSegmentMemory() == null) {
// segment has never been initialized, which means the rule(s) have never been linked and thus no Tuples to fix
return;
}
SegmentMemory sm = memory.getSegmentMemory();
while (NodeTypeEnums.LeftInputAdapterNode != node.getType()) {
if (NodeTypeEnums.isBetaNode(node)) {
BetaMemory bm;
if (NodeTypeEnums.AccumulateNode == node.getType()) {
AccumulateMemory am = (AccumulateMemory) memory;
bm = am.getBetaMemory();
FastIterator it = bm.getLeftTupleMemory().fullFastIterator();
Tuple lt = BetaNode.getFirstTuple(bm.getLeftTupleMemory(), it);
for (; lt != null; lt = (LeftTuple) it.next(lt)) {
AccumulateContext accctx = (AccumulateContext) lt.getContextObject();
visitChild(accctx.getResultLeftTuple(), insert, wm, rule);
}
} else if (NodeTypeEnums.ExistsNode == node.getType()) {
bm = (BetaMemory) wm.getNodeMemory((MemoryFactory) node);
// done off the RightTupleMemory, as exists only have unblocked tuples on the left side
FastIterator it = bm.getRightTupleMemory().fullFastIterator();
RightTuple rt = (RightTuple) BetaNode.getFirstTuple(bm.getRightTupleMemory(), it);
for (; rt != null; rt = (RightTuple) it.next(rt)) {
for (LeftTuple lt = rt.getBlocked(); lt != null; lt = lt.getBlockedNext()) {
visitChild(wm, insert, rule, it, lt);
}
}
} else {
bm = (BetaMemory) wm.getNodeMemory((MemoryFactory) node);
FastIterator it = bm.getLeftTupleMemory().fullFastIterator();
Tuple lt = BetaNode.getFirstTuple(bm.getLeftTupleMemory(), it);
visitChild(wm, insert, rule, it, lt);
}
return;
} else if (NodeTypeEnums.FromNode == node.getType()) {
FromMemory fm = (FromMemory) wm.getNodeMemory((MemoryFactory) node);
TupleMemory ltm = fm.getBetaMemory().getLeftTupleMemory();
FastIterator it = ltm.fullFastIterator();
for (LeftTuple lt = (LeftTuple) ltm.getFirst(null); lt != null; lt = (LeftTuple) it.next(lt)) {
visitChild(lt, insert, wm, rule);
}
return;
}
if (sm.getRootNode() == node) {
sm = wm.getNodeMemory((MemoryFactory<Memory>) node.getLeftTupleSource()).getSegmentMemory();
}
node = node.getLeftTupleSource();
}
// No beta or from nodes, so must retrieve LeftTuples from the LiaNode.
// This is done by scanning all the LeftTuples referenced from the FactHandles in the ObjectTypeNode
LeftInputAdapterNode lian = (LeftInputAdapterNode) node;
ObjectSource os = lian.getObjectSource();
while (os.getType() != NodeTypeEnums.ObjectTypeNode) {
os = os.getParentObjectSource();
}
ObjectTypeNode otn = (ObjectTypeNode) os;
final ObjectTypeNodeMemory omem = wm.getNodeMemory(otn);
if (omem == null) {
// no OTN memory yet, i.e. no inserted matching objects, so no Tuples to process
return;
}
Iterator<InternalFactHandle> it = omem.iterator();
while (it.hasNext()) {
InternalFactHandle fh = it.next();
fh.forEachLeftTuple(lt -> {
LeftTuple nextLt = lt.getHandleNext();
// Each lt is for a different lian, skip any lian not associated with the rule. Need to use lt parent (souce) not child to check the lian.
if (lt.getTupleSource().isAssociatedWith(rule)) {
visitChild(lt, insert, wm, rule);
if (lt.getHandlePrevious() != null) {
lt.getHandlePrevious().setHandleNext(nextLt);
}
if (nextLt != null) {
nextLt.setHandlePrevious(lt.getHandlePrevious());
}
}
});
}
}
use of org.drools.core.common.Memory in project drools by kiegroup.
the class AddRemoveRule method getPathEndMemories.
private static PathEndNodeMemories getPathEndMemories(InternalWorkingMemory wm, PathEndNodes pathEndNodes) {
PathEndNodeMemories tnMems = new PathEndNodeMemories();
for (LeftTupleNode node : pathEndNodes.otherEndNodes) {
if (node.getType() == NodeTypeEnums.RightInputAdaterNode) {
RiaNodeMemory riaMem = (RiaNodeMemory) wm.getNodeMemories().peekNodeMemory(node);
if (riaMem != null) {
tnMems.otherPmems.add(riaMem.getRiaPathMemory());
}
} else {
PathMemory pmem = (PathMemory) wm.getNodeMemories().peekNodeMemory(node);
if (pmem != null) {
tnMems.otherPmems.add(pmem);
}
}
}
tnMems.subjectPmem = (PathMemory) wm.getNodeMemories().peekNodeMemory(pathEndNodes.subjectEndNode);
if (tnMems.subjectPmem == null && !tnMems.otherPmems.isEmpty()) {
// If "other pmem's are initialized, then the subject needs to be initialized too.
tnMems.subjectPmem = (PathMemory) wm.getNodeMemory((MemoryFactory<Memory>) pathEndNodes.subjectEndNode);
}
for (LeftTupleNode node : pathEndNodes.subjectEndNodes) {
if (node.getType() == NodeTypeEnums.RightInputAdaterNode) {
RiaNodeMemory riaMem = (RiaNodeMemory) wm.getNodeMemories().peekNodeMemory(node);
if (riaMem == null && !tnMems.otherPmems.isEmpty()) {
riaMem = (RiaNodeMemory) wm.getNodeMemory((MemoryFactory<Memory>) node);
}
if (riaMem != null) {
tnMems.subjectPmems.add(riaMem.getRiaPathMemory());
}
} else {
PathMemory pmem = (PathMemory) wm.getNodeMemories().peekNodeMemory(node);
if (pmem != null) {
tnMems.subjectPmems.add(pmem);
}
}
}
return tnMems;
}
use of org.drools.core.common.Memory in project drools by kiegroup.
the class AddRemoveRule method addNewPaths.
private static void addNewPaths(InternalWorkingMemory wm, Set<SegmentMemory> smemsToNotify, List<PathMemory> pmems) {
// Multiple paths may be renetrant, in the case of a second subnetwork on the same rule.
// Must make sure we don't duplicate the child smem, and when found, just update it with new pmem.
Set<LeftTupleNode> visited = new HashSet<LeftTupleNode>();
for (PathMemory pmem : pmems) {
LeftTupleSink tipNode = (LeftTupleSink) pmem.getPathEndNode();
LeftTupleNode child = tipNode;
LeftTupleNode parent = tipNode.getLeftTupleSource();
while (true) {
if (visited.add(child)) {
if (parent != null && parent.getAssociationsSize() != 1 && child.getAssociationsSize() == 1) {
// This is the split point that the new path enters an existing path.
// If the parent has other child SegmentMemorys then it must create a new child SegmentMemory
// If the parent is a query node, then it's internal data structure needs changing
// all right input data must be propagated
Memory mem = wm.getNodeMemories().peekNodeMemory(parent);
if (mem != null && mem.getSegmentMemory() != null) {
SegmentMemory sm = mem.getSegmentMemory();
if (sm.getFirst() != null && sm.size() < parent.getSinkPropagator().size()) {
LeftTupleSink[] sinks = parent.getSinkPropagator().getSinks();
for (int i = sm.size(); i < sinks.length; i++) {
SegmentMemory childSmem = SegmentUtilities.createChildSegment(wm, sinks[i]);
sm.add(childSmem);
pmem.setSegmentMemory(childSmem.getPos(), childSmem);
smemsToNotify.add(childSmem);
}
}
correctMemoryOnSplitsChanged(parent, null, wm);
}
} else {
Memory mem = wm.getNodeMemories().peekNodeMemory(child);
// The root of each segment
if (mem != null) {
SegmentMemory sm = mem.getSegmentMemory();
if (sm != null && !sm.getPathMemories().contains(pmem)) {
sm.addPathMemory(pmem);
pmem.setSegmentMemory(sm.getPos(), sm);
sm.notifyRuleLinkSegment(wm, pmem);
}
}
}
} else {
Memory mem = wm.getNodeMemories().peekNodeMemory(child);
if (mem != null) {
mem.getSegmentMemory().notifyRuleLinkSegment(wm, pmem);
}
}
if (parent == null) {
break;
}
child = parent;
parent = parent.getLeftTupleSource();
}
}
}
use of org.drools.core.common.Memory in project drools by kiegroup.
the class AddRemoveRule method forceFlushLeftTuple.
public static void forceFlushLeftTuple(PathMemory pmem, SegmentMemory sm, InternalWorkingMemory wm, TupleSets<LeftTuple> leftTupleSets) {
SegmentMemory[] smems = pmem.getSegmentMemories();
LeftTupleNode node;
Memory mem;
long bit = 1;
if (sm.getRootNode().getType() == NodeTypeEnums.LeftInputAdapterNode && sm.getTipNode().getType() != NodeTypeEnums.LeftInputAdapterNode) {
// The segment is the first and it has the lian shared with other nodes, the lian must be skipped, so adjust the bit and sink
node = sm.getRootNode().getSinkPropagator().getFirstLeftTupleSink();
mem = sm.getNodeMemories().get(1);
// adjust bit to point to next node
bit = 2;
} else {
node = sm.getRootNode();
mem = sm.getNodeMemories().get(0);
}
PathMemory rtnPmem = NodeTypeEnums.isTerminalNode(pmem.getPathEndNode()) ? pmem : wm.getNodeMemory((AbstractTerminalNode) pmem.getPathEndNode().getPathEndNodes()[0]);
InternalAgenda agenda = pmem.getActualAgenda(wm);
new RuleNetworkEvaluator().outerEval(pmem, node, bit, mem, smems, sm.getPos(), leftTupleSets, agenda, new LinkedList<StackEntry>(), true, rtnPmem.getOrCreateRuleAgendaItem(agenda).getRuleExecutor());
}
use of org.drools.core.common.Memory in project drools by kiegroup.
the class AddRemoveRule method mergeNodeMemories.
private static void mergeNodeMemories(SegmentMemory sm1, SegmentMemory sm2) {
LinkedList<Memory> smNodeMemories1 = sm1.getNodeMemories();
LinkedList<Memory> smNodeMemories2 = sm2.getNodeMemories();
int nodePosMask = 1;
for (int i = 0, length = smNodeMemories1.size(); i < length; i++) {
nodePosMask = nodePosMask >> 1;
}
for (Memory mem = smNodeMemories2.getFirst(); mem != null; ) {
Memory next = mem.getNext();
smNodeMemories2.remove(mem);
smNodeMemories1.add(mem);
mem.setSegmentMemory(sm1);
// correct the NodePosMaskBit
if (mem instanceof SegmentNodeMemory) {
((SegmentNodeMemory) mem).setNodePosMaskBit(nodePosMask);
}
nodePosMask = nodePosMask >> 1;
mem = next;
}
}
Aggregations