use of org.drools.core.common.MemoryFactory in project drools by kiegroup.
the class SegmentUtilities method updateRiaAndTerminalMemory.
/**
* This adds the segment memory to the terminal node or ria node's list of memories.
* In the case of the terminal node this allows it to know that all segments from
* the tip to root are linked.
* In the case of the ria node its all the segments up to the start of the subnetwork.
* This is because the rianode only cares if all of it's segments are linked, then
* it sets the bit of node it is the right input for.
*/
private static int updateRiaAndTerminalMemory(LeftTupleSource lt, LeftTupleSource originalLt, SegmentMemory smem, InternalWorkingMemory wm, boolean fromPrototype, int nodeTypesInSegment) {
nodeTypesInSegment = checkSegmentBoundary(lt, wm, nodeTypesInSegment);
for (LeftTupleSink sink : lt.getSinkPropagator().getSinks()) {
if (NodeTypeEnums.isLeftTupleSource(sink)) {
nodeTypesInSegment = updateRiaAndTerminalMemory((LeftTupleSource) sink, originalLt, smem, wm, fromPrototype, nodeTypesInSegment);
} else if (sink.getType() == NodeTypeEnums.RightInputAdaterNode) {
// Even though we don't add the pmem and smem together, all pmem's for all pathend nodes must be initialized
RiaNodeMemory riaMem = (RiaNodeMemory) wm.getNodeMemory((MemoryFactory) sink);
// Only add the RIANode, if the LeftTupleSource is part of the RIANode subnetwork
if (inSubNetwork((RightInputAdapterNode) sink, originalLt)) {
PathMemory pmem = riaMem.getRiaPathMemory();
smem.addPathMemory(pmem);
if (smem.getPos() < pmem.getSegmentMemories().length) {
pmem.setSegmentMemory(smem.getPos(), smem);
}
if (fromPrototype) {
ObjectSink[] nodes = ((RightInputAdapterNode) sink).getObjectSinkPropagator().getSinks();
for (ObjectSink node : nodes) {
// check if the SegmentMemory has been already created by the BetaNode and if so avoid to build it twice
if (NodeTypeEnums.isLeftTupleSource(node) && wm.getNodeMemory((MemoryFactory) node).getSegmentMemory() == null) {
restoreSegmentFromPrototype(wm, (LeftTupleSource) node, nodeTypesInSegment);
}
}
} else if ((pmem.getAllLinkedMaskTest() & (1L << pmem.getSegmentMemories().length)) == 0) {
// must eagerly initialize child segment memories
ObjectSink[] nodes = ((RightInputAdapterNode) sink).getObjectSinkPropagator().getSinks();
for (ObjectSink node : nodes) {
if (NodeTypeEnums.isLeftTupleSource(node)) {
createSegmentMemory((LeftTupleSource) node, wm);
}
}
}
}
} else if (NodeTypeEnums.isTerminalNode(sink)) {
PathMemory pmem = (PathMemory) wm.getNodeMemory((MemoryFactory) sink);
smem.addPathMemory(pmem);
// with the former one and in this case doesn't have to be added to the the path memory
if (smem.getPos() < pmem.getSegmentMemories().length) {
pmem.setSegmentMemory(smem.getPos(), smem);
if (smem.isSegmentLinked()) {
// not's can cause segments to be linked, and the rules need to be notified for evaluation
smem.notifyRuleLinkSegment(wm);
}
checkEagerSegmentCreation(sink.getLeftTupleSource(), wm, nodeTypesInSegment);
}
}
}
return nodeTypesInSegment;
}
use of org.drools.core.common.MemoryFactory in project drools by kiegroup.
the class NotNodeLeftTuple method getAccumulatedObjects.
@Override
public Collection<Object> getAccumulatedObjects() {
if (NodeTypeEnums.ExistsNode != getTupleSink().getType()) {
return Collections.emptyList();
}
BetaNode betaNode = ((BetaNode) getTupleSink());
BetaConstraints constraints = betaNode.getRawConstraints();
InternalWorkingMemory wm = getFactHandle().getEntryPoint().getInternalWorkingMemory();
BetaMemory bm = (BetaMemory) wm.getNodeMemory((MemoryFactory) getTupleSink());
TupleMemory rtm = bm.getRightTupleMemory();
FastIterator it = betaNode.getRightIterator(rtm);
ContextEntry[] contextEntry = bm.getContext();
constraints.updateFromTuple(contextEntry, wm, this);
Collection<Object> result = new ArrayList<>();
for (RightTuple rightTuple = betaNode.getFirstRightTuple(this, rtm, null, it); rightTuple != null; ) {
RightTuple nextRight = (RightTuple) it.next(rightTuple);
InternalFactHandle fh = rightTuple.getFactHandleForEvaluation();
if (constraints.isAllowedCachedLeft(contextEntry, fh)) {
result.add(fh.getObject());
}
rightTuple = nextRight;
}
return result;
}
use of org.drools.core.common.MemoryFactory in project drools by kiegroup.
the class LinkingTest method testNonReactiveSubNetworkOwnSegmentMasks.
@Test
public void testNonReactiveSubNetworkOwnSegmentMasks() throws Exception {
String str = "";
str += "package org.kie \n";
str += "import " + A.class.getCanonicalName() + "\n";
str += "import " + B.class.getCanonicalName() + "\n";
str += "import " + C.class.getCanonicalName() + "\n";
str += "import " + D.class.getCanonicalName() + "\n";
str += "import " + E.class.getCanonicalName() + "\n";
str += "import " + F.class.getCanonicalName() + "\n";
str += "import " + G.class.getCanonicalName() + "\n";
str += "global java.util.List list \n";
str += "rule rule1 when \n";
str += " A() \n";
str += " exists( B() and C() ) \n";
str += " exists( eval(1==1) ) \n";
str += " D() \n";
str += "then \n";
str += "end \n";
str += "rule rule2 when \n";
str += " A() \n";
str += " exists( B() and C() ) \n";
str += " exists( eval(1==1) ) \n";
str += " E() \n";
str += "then \n";
str += "end \n";
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL);
assertFalse(kbuilder.getErrors().toString(), kbuilder.hasErrors());
InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addPackages(kbuilder.getKnowledgePackages());
ObjectTypeNode node = getObjectTypeNode(kbase, A.class);
InternalWorkingMemory wm = ((StatefulKnowledgeSessionImpl) kbase.newKieSession());
LeftInputAdapterNode liaNode = (LeftInputAdapterNode) node.getObjectSinkPropagator().getSinks()[0];
assertEquals(2, liaNode.getSinkPropagator().size());
JoinNode bNode = (JoinNode) liaNode.getSinkPropagator().getSinks()[0];
JoinNode cNode = (JoinNode) bNode.getSinkPropagator().getSinks()[0];
ExistsNode exists1n = (ExistsNode) liaNode.getSinkPropagator().getSinks()[1];
EvalConditionNode evalNode = (EvalConditionNode) exists1n.getSinkPropagator().getSinks()[0];
ExistsNode exists2n = (ExistsNode) exists1n.getSinkPropagator().getSinks()[1];
JoinNode dNode = (JoinNode) exists2n.getSinkPropagator().getSinks()[0];
RuleTerminalNode rtn = (RuleTerminalNode) dNode.getSinkPropagator().getSinks()[0];
wm.insert(new A());
PathMemory pmem = (PathMemory) wm.getNodeMemory(rtn);
assertEquals(4, pmem.getSegmentMemories().length);
// the exists eval segment does not need to be linked in
assertEquals(11, pmem.getAllLinkedMaskTest());
RightInputAdapterNode.RiaNodeMemory riaMem = (RightInputAdapterNode.RiaNodeMemory) wm.getNodeMemory((MemoryFactory) exists1n.getRightInput());
// second segment must be linked in
assertEquals(2, riaMem.getRiaPathMemory().getAllLinkedMaskTest());
wm.insert(new B());
wm.insert(new C());
assertEquals(2, riaMem.getRiaPathMemory().getSegmentMemories().length);
riaMem = (RightInputAdapterNode.RiaNodeMemory) wm.getNodeMemory((MemoryFactory) exists2n.getRightInput());
// no segments to be linked in
assertEquals(0, riaMem.getRiaPathMemory().getAllLinkedMaskTest());
}
use of org.drools.core.common.MemoryFactory 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());
}
}
});
}
}
Aggregations