This is an automated email from the ASF dual-hosted git repository.

mariofusco pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git


The following commit(s) were added to refs/heads/main by this push:
     new f63bb2dae5 [incubator-kie-issues #203] Cleanup Phreak code - extract 
segment prototype registry (#6491)
f63bb2dae5 is described below

commit f63bb2dae589087584e64b1bc2c5e3eddfe6a61c
Author: Paolo Bizzarri <[email protected]>
AuthorDate: Mon Oct 20 08:08:39 2025 +0200

    [incubator-kie-issues #203] Cleanup Phreak code - extract segment prototype 
registry (#6491)
    
    * Extracted the interface SegmentPrototypeRegistry
    
    * Consistent naming fixes
    
    * Added missing Apache headers
---
 .../drools/core/common/ConcurrentNodeMemories.java |  2 +-
 .../org/drools/core/impl/InternalRuleBase.java     |  3 +
 .../org/drools/core/impl/KnowledgeBaseImpl.java    | 27 +++++----
 .../core/phreak/BuildtimeSegmentUtilities.java     | 22 +++----
 .../org/drools/core/phreak/EagerPhreakBuilder.java | 43 +++++++-------
 .../org/drools/core/phreak/LazyPhreakBuilder.java  | 54 ++++++++---------
 .../core/phreak/RuntimeSegmentUtilities.java       |  8 ++-
 .../java/org/drools/core/reteoo/SegmentMemory.java |  5 --
 .../core/reteoo/SegmentPrototypeRegistry.java      | 40 +++++++++++++
 .../core/reteoo/SegmentPrototypeRegistryImpl.java  | 68 ++++++++++++++++++++++
 .../core/reteoo/builder/ReteooRuleBuilder.java     |  2 +-
 .../rulebase/SessionsAwareKnowledgeBase.java       |  5 ++
 .../kiesession/NodeSegmentUnlinkingTest.java       |  8 +--
 .../org/drools/kiesession/RuleUnlinkingTest.java   |  4 +-
 .../RuleUnlinkingWithSegmentMemoryTest.java        |  2 +-
 .../mvel/integrationtests/phreak/AddRuleTest.java  | 12 ++--
 16 files changed, 213 insertions(+), 92 deletions(-)

diff --git 
a/drools-core/src/main/java/org/drools/core/common/ConcurrentNodeMemories.java 
b/drools-core/src/main/java/org/drools/core/common/ConcurrentNodeMemories.java
index 54441183d6..712c760ed0 100644
--- 
a/drools-core/src/main/java/org/drools/core/common/ConcurrentNodeMemories.java
+++ 
b/drools-core/src/main/java/org/drools/core/common/ConcurrentNodeMemories.java
@@ -70,7 +70,7 @@ public class ConcurrentNodeMemories implements NodeMemories {
 
     private void resetSegmentMemory(SegmentMemory smem) {
         if (smem != null) {
-            smem.reset(ruleBase.getSegmentPrototype(smem));
+            
smem.reset(ruleBase.getSegmentPrototypeRegistry().getSegmentPrototype(smem));
             if (smem.isSegmentLinked()) {
                 smem.notifyRuleLinkSegment(reteEvaluator);
             }
diff --git 
a/drools-core/src/main/java/org/drools/core/impl/InternalRuleBase.java 
b/drools-core/src/main/java/org/drools/core/impl/InternalRuleBase.java
index 8d0b340db8..2accff1b4e 100644
--- a/drools-core/src/main/java/org/drools/core/impl/InternalRuleBase.java
+++ b/drools-core/src/main/java/org/drools/core/impl/InternalRuleBase.java
@@ -42,6 +42,7 @@ import org.drools.core.reteoo.Rete;
 import org.drools.core.reteoo.ReteooBuilder;
 import org.drools.core.reteoo.SegmentMemory;
 import org.drools.core.reteoo.SegmentMemory.SegmentPrototype;
+import org.drools.core.reteoo.SegmentPrototypeRegistry;
 import org.drools.core.rule.accessor.FactHandleFactory;
 import org.kie.api.KieBaseConfiguration;
 import org.kie.api.builder.ReleaseId;
@@ -116,6 +117,8 @@ public interface InternalRuleBase extends RuleBase {
 
 
     ClassFieldAccessorCache getClassFieldAccessorCache();
+    
+    SegmentPrototypeRegistry getSegmentPrototypeRegistry();
 
     void invalidateSegmentPrototype(LeftTupleNode rootNode);
     SegmentMemory createSegmentFromPrototype(ReteEvaluator reteEvaluator, 
LeftTupleSource tupleSource);
diff --git 
a/drools-core/src/main/java/org/drools/core/impl/KnowledgeBaseImpl.java 
b/drools-core/src/main/java/org/drools/core/impl/KnowledgeBaseImpl.java
index 4a7977c11c..98f6f1b146 100644
--- a/drools-core/src/main/java/org/drools/core/impl/KnowledgeBaseImpl.java
+++ b/drools-core/src/main/java/org/drools/core/impl/KnowledgeBaseImpl.java
@@ -73,6 +73,8 @@ import org.drools.core.reteoo.ReteooBuilder;
 import org.drools.core.reteoo.RuntimeComponentFactory;
 import org.drools.core.reteoo.SegmentMemory;
 import org.drools.core.reteoo.SegmentMemory.SegmentPrototype;
+import org.drools.core.reteoo.SegmentPrototypeRegistry;
+import org.drools.core.reteoo.SegmentPrototypeRegistryImpl;
 import org.drools.core.reteoo.TerminalNode;
 import org.drools.core.reteoo.builder.BuildContext;
 import org.drools.core.reteoo.builder.NodeFactory;
@@ -136,8 +138,9 @@ public class KnowledgeBaseImpl implements InternalRuleBase {
     /** The root Rete-OO for this <code>RuleBase</code>. */
     private transient Rete rete;
     private ReteooBuilder reteooBuilder;
-    private final transient Map<Integer, SegmentPrototype> segmentProtos = 
isEagerSegmentCreation() ? new HashMap<>() : new ConcurrentHashMap<>();
 
+    private SegmentPrototypeRegistry segmentPrototypeRegistry;
+    
     // This is just a hack, so spring can find the list of generated classes
     public List<List<String>> jaxbClasses;
 
@@ -179,6 +182,7 @@ public class KnowledgeBaseImpl implements InternalRuleBase {
         this.globals = new HashMap<>();
 
         this.classFieldAccessorCache = new 
ClassFieldAccessorCache(this.rootClassLoader);
+        this.segmentPrototypeRegistry = new 
SegmentPrototypeRegistryImpl(isEagerSegmentCreation());
 
         setupRete();
 
@@ -917,35 +921,38 @@ public class KnowledgeBaseImpl implements 
InternalRuleBase {
         return this.reteooBuilder.getMemoryIdsGenerator().getLastId() + 1;
     }
 
+    public SegmentPrototypeRegistry getSegmentPrototypeRegistry() {
+        return segmentPrototypeRegistry;
+    }
+
     public boolean hasSegmentPrototypes() {
-        return !segmentProtos.isEmpty();
+        return segmentPrototypeRegistry.hasSegmentPrototypes();
     }
 
     public void registerSegmentPrototype(LeftTupleNode tupleSource, 
SegmentPrototype smem) {
-        segmentProtos.put(tupleSource.getId(), smem);
+        segmentPrototypeRegistry.registerSegmentPrototype(tupleSource, smem);
     }
 
     public void invalidateSegmentPrototype(LeftTupleNode rootNode) {
-        segmentProtos.remove(rootNode.getId());
+        segmentPrototypeRegistry.invalidateSegmentPrototype(rootNode);
     }
 
     @Override
     public SegmentPrototype getSegmentPrototype(LeftTupleNode node) {
-        return segmentProtos.get(node.getId());
+        return segmentPrototypeRegistry.getSegmentPrototype(node);
     }
 
     @Override
     public SegmentMemory createSegmentFromPrototype(ReteEvaluator 
reteEvaluator, LeftTupleSource tupleSource) {
-        SegmentPrototype proto = segmentProtos.get(tupleSource.getId());
-        return createSegmentFromPrototype(reteEvaluator, proto);
+        return 
segmentPrototypeRegistry.createSegmentFromPrototype(reteEvaluator, tupleSource);
     }
 
     public SegmentMemory createSegmentFromPrototype(ReteEvaluator 
reteEvaluator, SegmentPrototype proto) {
-        return proto.newSegmentMemory(reteEvaluator);
+        return 
segmentPrototypeRegistry.createSegmentFromPrototype(reteEvaluator, proto);
     }
 
     public SegmentPrototype getSegmentPrototype(SegmentMemory segment) {
-        return segmentProtos.get(segment.getRootNode().getId());
+        return segmentPrototypeRegistry.getSegmentPrototype(segment);
     }
 
     private static class TypeDeclarationCandidate {
@@ -1053,7 +1060,7 @@ public class KnowledgeBaseImpl implements 
InternalRuleBase {
             // All Protos must be created, before inserting objects.
             for (TerminalNode tn : terminalNodes) {
                 tn.getPathMemSpec();
-                BuildtimeSegmentUtilities.createPathProtoMemories(this, tn, 
null);
+                
BuildtimeSegmentUtilities.createPathProtoMemories(this.getSegmentPrototypeRegistry(),
 tn, null);
             }
             Set<Integer> visited = new HashSet<>();
             for (TerminalNode tn : terminalNodes) {
diff --git 
a/drools-core/src/main/java/org/drools/core/phreak/BuildtimeSegmentUtilities.java
 
b/drools-core/src/main/java/org/drools/core/phreak/BuildtimeSegmentUtilities.java
index f9389a89f1..7d06a64486 100644
--- 
a/drools-core/src/main/java/org/drools/core/phreak/BuildtimeSegmentUtilities.java
+++ 
b/drools-core/src/main/java/org/drools/core/phreak/BuildtimeSegmentUtilities.java
@@ -23,7 +23,6 @@ import java.util.List;
 
 import org.drools.base.common.NetworkNode;
 import org.drools.base.reteoo.NodeTypeEnums;
-import org.drools.core.impl.InternalRuleBase;
 import org.drools.core.reteoo.AsyncReceiveNode;
 import org.drools.core.reteoo.AsyncSendNode;
 import org.drools.core.reteoo.BetaNode;
@@ -57,6 +56,7 @@ import 
org.drools.core.reteoo.SegmentMemory.RightInputAdapterPrototype;
 import org.drools.core.reteoo.SegmentMemory.SegmentPrototype;
 import org.drools.core.reteoo.SegmentMemory.TerminalPrototype;
 import org.drools.core.reteoo.SegmentMemory.TimerMemoryPrototype;
+import org.drools.core.reteoo.SegmentPrototypeRegistry;
 import org.drools.core.reteoo.TerminalNode;
 import org.drools.core.reteoo.TimerNode;
 
@@ -119,11 +119,11 @@ public class BuildtimeSegmentUtilities {
         return allLinkedMaskTest;
     }
 
-    public static SegmentPrototype[] createPathProtoMemories(InternalRuleBase 
rbase,
+    public static SegmentPrototype[] 
createPathProtoMemories(SegmentPrototypeRegistry segmentPrototypeRegistry,
                                                              TerminalNode tn,
                                                              TerminalNode 
removingTn) {
         // Will initialise all segments in a path
-        SegmentPrototype[] smems = createLeftTupleNodeProtoMemories(rbase, tn, 
removingTn);
+        SegmentPrototype[] smems = 
createLeftTupleNodeProtoMemories(segmentPrototypeRegistry, tn, removingTn);
 
         // smems are empty, if there is no beta network. Which means it has an 
AlphaTerminalNode
         if (smems.length > 0) {
@@ -133,7 +133,7 @@ public class BuildtimeSegmentUtilities {
         return smems;
     }
 
-    public static SegmentPrototype[] 
createLeftTupleNodeProtoMemories(InternalRuleBase rbase,
+    public static SegmentPrototype[] 
createLeftTupleNodeProtoMemories(SegmentPrototypeRegistry 
segmentPrototypeRegistry,
                                                                       
LeftTupleNode lts,
                                                                       
TerminalNode removingTn) {
         LeftTupleNode segmentRoot = lts;
@@ -151,10 +151,10 @@ public class BuildtimeSegmentUtilities {
             }
 
             // Store all nodes for the main path in reverse order (we're 
starting from the terminal node).
-            SegmentPrototype smem = rbase.getSegmentPrototype(segmentRoot);
+            SegmentPrototype smem = 
segmentPrototypeRegistry.getSegmentPrototype(segmentRoot);
             if (smem == null) {
                 start = segmentRoot.getPathIndex(); // we want counter to 
start from the new segment proto only
-                smem = createSegmentMemory(rbase, segmentRoot, segmentTip, 
removingTn, recordBefore);
+                smem = createSegmentMemory(segmentPrototypeRegistry,  
segmentRoot, segmentTip, removingTn, recordBefore);
             }
             smems.add(0, smem);
 
@@ -194,7 +194,7 @@ public class BuildtimeSegmentUtilities {
     /**
      * Initialises the NodeSegment memory for all nodes in the segment.
      */
-    public static SegmentPrototype createSegmentMemory(InternalRuleBase rbase,
+    private static SegmentPrototype 
createSegmentMemory(SegmentPrototypeRegistry segmentPrototypeRegistry,
                                                        LeftTupleNode 
segmentRoot,
                                                        LeftTupleNode 
segmentTip,
                                                        TerminalNode removingTn,
@@ -216,7 +216,7 @@ public class BuildtimeSegmentUtilities {
             nodeTypesInSegment = updateNodeTypesMask(node, nodeTypesInSegment);
             if (NodeTypeEnums.isBetaNode(node)) {
                 boolean updateAllLinked = node.getPathIndex() < recordBefore 
&& updateNodeBit;
-                allLinkedTestMask = processBetaNode(rbase, (BetaNode) node, 
removingTn, smem, memories,
+                allLinkedTestMask = processBetaNode(segmentPrototypeRegistry, 
(BetaNode) node, removingTn, smem, memories,
                         nodes, nodePosMask, allLinkedTestMask, 
updateAllLinked);
             } else {
                 switch (node.getType()) {
@@ -273,7 +273,7 @@ public class BuildtimeSegmentUtilities {
         smem.setMemories(memories.toArray(new 
MemoryPrototype[memories.size()]));
         smem.setNodeTypesInSegment(nodeTypesInSegment);
 
-        rbase.registerSegmentPrototype(segmentRoot, smem);
+        segmentPrototypeRegistry.registerSegmentPrototype(segmentRoot, smem);
 
         return smem;
     }
@@ -391,7 +391,7 @@ public class BuildtimeSegmentUtilities {
         return allLinkedTestMask;
     }
 
-    private static long processBetaNode(InternalRuleBase rbase,
+    private static long processBetaNode(SegmentPrototypeRegistry 
prototypeRegistry, 
                                         BetaNode betaNode,
                                         TerminalNode removingTn,
                                         SegmentPrototype smem,
@@ -405,7 +405,7 @@ public class BuildtimeSegmentUtilities {
             // there is a subnetwork, so create all it's segment memory 
prototypes
             tton = (TupleToObjectNode) betaNode.getRightInput().getParent();
 
-            SegmentPrototype[] smems = createLeftTupleNodeProtoMemories(rbase, 
tton, removingTn);
+            SegmentPrototype[] smems = 
createLeftTupleNodeProtoMemories(prototypeRegistry, tton, removingTn);
             setSegments(tton, smems);
 
             if (updateNodeBit && canBeDisabled(betaNode) && 
tton.getPathMemSpec().allLinkedTestMask() > 0) {
diff --git 
a/drools-core/src/main/java/org/drools/core/phreak/EagerPhreakBuilder.java 
b/drools-core/src/main/java/org/drools/core/phreak/EagerPhreakBuilder.java
index c7b7ea0eaa..41766b60e2 100644
--- a/drools-core/src/main/java/org/drools/core/phreak/EagerPhreakBuilder.java
+++ b/drools-core/src/main/java/org/drools/core/phreak/EagerPhreakBuilder.java
@@ -68,6 +68,7 @@ import org.drools.core.reteoo.RuntimeComponentFactory;
 import org.drools.core.reteoo.SegmentMemory;
 import org.drools.core.reteoo.SegmentMemory.SegmentPrototype;
 import org.drools.core.reteoo.SegmentNodeMemory;
+import org.drools.core.reteoo.SegmentPrototypeRegistry;
 import org.drools.core.reteoo.TerminalNode;
 import org.drools.core.reteoo.Tuple;
 import org.drools.core.reteoo.TupleFactory;
@@ -102,7 +103,7 @@ public class EagerPhreakBuilder implements PhreakBuilder {
 
         Set<Integer> visited = new HashSet<>();
         if (tn.getPathNodes()[0].getAssociatedTerminalsSize() == 1) {
-            BuildtimeSegmentUtilities.createPathProtoMemories(kBase, tn, null);
+            
BuildtimeSegmentUtilities.createPathProtoMemories(kBase.getSegmentPrototypeRegistry(),
 tn, null);
 
             // rule added with no sharing, so populate it's lian
             wms.forEach(wm -> Add.insertLiaFacts(wm, tn.getPathNodes()[0], 
visited, false));
@@ -110,9 +111,9 @@ public class EagerPhreakBuilder implements PhreakBuilder {
             List<Pair> exclBranchRoots = getExclusiveBranchRoots(tn);
 
             // Process existing branches from the split  points
-            exclBranchRoots.forEach(pair -> Add.processSplit(kBase, wms, 
pair.parent, smemsToNotify));
+            exclBranchRoots.forEach(pair -> 
Add.processSplit(kBase.getSegmentPrototypeRegistry(), wms, pair.parent, 
smemsToNotify));
 
-            Add.addNewPaths(kBase, wms, exclBranchRoots, tn, smemsToNotify);
+            Add.addNewPaths(kBase.getSegmentPrototypeRegistry(), wms, 
exclBranchRoots, tn, smemsToNotify);
 
             exclBranchRoots.forEach(pair -> processLeftTuples(wms, 
pair.parent, tn, true));
         }
@@ -155,14 +156,14 @@ public class EagerPhreakBuilder implements PhreakBuilder {
         if (exclBranchRoots.isEmpty()) {
             LeftTupleNode lian = tn.getPathNodes()[0];
             processLeftTuples(wms, lian, tn, false);
-            Remove.removeExistingPaths(kBase, wms, exclBranchRoots, tn);
+            Remove.removeExistingPaths(kBase.getSegmentPrototypeRegistry(), 
wms, exclBranchRoots, tn);
         } else {
             exclBranchRoots.forEach(pair -> processLeftTuples(wms, 
pair.parent, tn, false));
-            Remove.removeExistingPaths(kBase, wms, exclBranchRoots, tn);
+            Remove.removeExistingPaths(kBase.getSegmentPrototypeRegistry(), 
wms, exclBranchRoots, tn);
 
             // Process existing branches from the split  points
             Set<Integer> visited = new HashSet<>();
-            exclBranchRoots.forEach(pair -> Remove.processMerges(kBase, wms, 
pair.parent, tn, visited));
+            exclBranchRoots.forEach(pair -> 
Remove.processMerges(kBase.getSegmentPrototypeRegistry(), wms, pair.parent, tn, 
visited));
         }
 
         for (InternalWorkingMemory wm : wms) {
@@ -298,15 +299,15 @@ public class EagerPhreakBuilder implements PhreakBuilder {
             detachedTuples.forEach(d -> d.reattachToRight());
         }
 
-        public static SegmentPrototype processSplit(InternalRuleBase kbase,
+        public static SegmentPrototype processSplit(SegmentPrototypeRegistry 
segmentPrototypeRegistry,
                                                     
Collection<InternalWorkingMemory> wms,
                                                     LeftTupleNode splitNode,
                                                     Set<SegmentMemoryPair> 
smemsToNotify) {
             LeftTupleNode segmentRoot = 
BuildtimeSegmentUtilities.findSegmentRoot(splitNode);
-            SegmentPrototype proto1 = kbase.getSegmentPrototype(segmentRoot);
+            SegmentPrototype proto1 = 
segmentPrototypeRegistry.getSegmentPrototype(segmentRoot);
             if (proto1.getTipNode() != splitNode) {
                 // split does not already exist, add it.
-                return splitSegment(kbase, wms, proto1, splitNode, 
smemsToNotify);
+                return splitSegment(segmentPrototypeRegistry, wms, proto1, 
splitNode, smemsToNotify);
             }
 
             // split already exists, add it.
@@ -427,7 +428,7 @@ public class EagerPhreakBuilder implements PhreakBuilder {
             notifyImpactedSegments(wm, sm2, smemsToNotify);
         }
 
-        public static SegmentPrototype splitSegment(InternalRuleBase kbase,
+        public static SegmentPrototype splitSegment(SegmentPrototypeRegistry 
prototypeRegistry,
                                                     
Collection<InternalWorkingMemory> wms,
                                                     SegmentPrototype proto1,
                                                     LeftTupleNode splitNode,
@@ -437,7 +438,7 @@ public class EagerPhreakBuilder implements PhreakBuilder {
             // Create the new segment proto
             LeftTupleNode proto2RootNode = 
splitNode.getSinkPropagator().getFirstLeftTupleSink();
             SegmentPrototype proto2 = new SegmentPrototype(proto2RootNode, 
proto1.getTipNode());
-            kbase.registerSegmentPrototype(proto2RootNode, proto2);
+            prototypeRegistry.registerSegmentPrototype(proto2RootNode, proto2);
             proto2.setPos(proto1.getPos() + 1);
 
             // Split the nodes across proto1 and proto2
@@ -481,13 +482,13 @@ public class EagerPhreakBuilder implements PhreakBuilder {
             return proto2;
         }
 
-        private static void addNewPaths(InternalRuleBase kBase,
+        private static void addNewPaths(SegmentPrototypeRegistry 
prototypeRegistry,
                                         Collection<InternalWorkingMemory> wms,
                                         List<Pair> exclBranchRoots,
                                         TerminalNode tn,
                                         Set<SegmentMemoryPair> smemsToNotify) {
             // create protos
-            BuildtimeSegmentUtilities.createPathProtoMemories(kBase, tn, null);
+            
BuildtimeSegmentUtilities.createPathProtoMemories(prototypeRegistry, tn, null);
 
             // update SegmentProtos with new EndNodes
             for (PathEndNode endNode : tn.getPathEndNodes()) {
@@ -574,7 +575,7 @@ public class EagerPhreakBuilder implements PhreakBuilder {
 
     public static class Remove {
 
-        private static void removeExistingPaths(InternalRuleBase kbase,
+        private static void removeExistingPaths(SegmentPrototypeRegistry 
segmentPrototypeRegistry,
                                                 
Collection<InternalWorkingMemory> wms,
                                                 List<Pair> exclBranchRoots,
                                                 TerminalNode tn) {
@@ -602,7 +603,7 @@ public class EagerPhreakBuilder implements PhreakBuilder {
                         smproto.setPathEndNodes(newNodes);
                     } else {
                         // unregister the segments exclusive to the branch 
being used
-                        
kbase.invalidateSegmentPrototype(smproto.getRootNode());
+                        
segmentPrototypeRegistry.invalidateSegmentPrototype(smproto.getRootNode());
                     }
                 }
             }
@@ -674,7 +675,7 @@ public class EagerPhreakBuilder implements PhreakBuilder {
             }
         }
 
-        private static void processMerges(InternalRuleBase kBase,
+        private static void processMerges(SegmentPrototypeRegistry 
segmentPrototypeRegistry,
                                           Collection<InternalWorkingMemory> 
wms,
                                           LeftTupleNode splitNode,
                                           TerminalNode tn,
@@ -688,7 +689,7 @@ public class EagerPhreakBuilder implements PhreakBuilder {
                 // with the tn ignored, it's no longer a semgnet tip so it's 
segment is ready to merge
                 LeftTupleNode segmentRoot = 
BuildtimeSegmentUtilities.findSegmentRoot(splitNode, tn);
 
-                SegmentPrototype proto1 = 
kBase.getSegmentPrototype(segmentRoot);
+                SegmentPrototype proto1 = 
segmentPrototypeRegistry.getSegmentPrototype(segmentRoot);
 
                 // find the remaining child and get it's proto
                 LeftTupleNode ltn = null;
@@ -706,12 +707,12 @@ public class EagerPhreakBuilder implements PhreakBuilder {
                     throw new RuntimeException();
                 }
 
-                SegmentPrototype proto2 = kBase.getSegmentPrototype(ltn);
-                mergeSegments(kBase, wms, proto1, proto2);
+                SegmentPrototype proto2 = 
segmentPrototypeRegistry.getSegmentPrototype(ltn);
+                mergeSegments(segmentPrototypeRegistry, wms, proto1, proto2);
             }
         }
 
-        public static void mergeSegments(InternalRuleBase kbase,
+        public static void mergeSegments(SegmentPrototypeRegistry 
segmentPrototypeRegistry,
                                          Collection<InternalWorkingMemory> wms,
                                          SegmentPrototype proto1,
                                          SegmentPrototype proto2) {
@@ -751,7 +752,7 @@ public class EagerPhreakBuilder implements PhreakBuilder {
                 updatePaths(wms, newList, proto1, endNode);
             }
 
-            kbase.invalidateSegmentPrototype(proto2.getRootNode());
+            
segmentPrototypeRegistry.invalidateSegmentPrototype(proto2.getRootNode());
         }
 
         private static void mergeSegment(ReteEvaluator wm,
diff --git 
a/drools-core/src/main/java/org/drools/core/phreak/LazyPhreakBuilder.java 
b/drools-core/src/main/java/org/drools/core/phreak/LazyPhreakBuilder.java
index 8a19410830..b2fa7674c4 100644
--- a/drools-core/src/main/java/org/drools/core/phreak/LazyPhreakBuilder.java
+++ b/drools-core/src/main/java/org/drools/core/phreak/LazyPhreakBuilder.java
@@ -71,6 +71,7 @@ import org.drools.core.reteoo.RightTuple;
 import org.drools.core.reteoo.RuleTerminalNodeLeftTuple;
 import org.drools.core.reteoo.RuntimeComponentFactory;
 import org.drools.core.reteoo.SegmentMemory;
+import org.drools.core.reteoo.SegmentPrototypeRegistry;
 import org.drools.core.reteoo.TerminalNode;
 import org.drools.core.reteoo.TimerNode;
 import org.drools.core.reteoo.Tuple;
@@ -115,7 +116,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
             log.trace("Adding Rule {}", tn.getRule().getName());
         }
 
-        boolean hasProtos = kBase.hasSegmentPrototypes();
+        boolean hasProtos = 
kBase.getSegmentPrototypeRegistry().hasSegmentPrototypes();
         boolean hasWms = !wms.isEmpty();
 
         if (!hasProtos && !hasWms) {
@@ -124,7 +125,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
 
         RuleImpl rule = tn.getRule();
         LeftTupleNode firstSplit = getNetworkSplitPoint(tn);
-        PathEndNodes pathEndNodes = getPathEndNodes(kBase, rule, firstSplit, 
tn, hasProtos, hasWms);
+        PathEndNodes pathEndNodes = 
getPathEndNodes(kBase.getSegmentPrototypeRegistry(), rule, firstSplit, tn, 
hasProtos, hasWms);
 
         // Insert the facts for the new paths. This will iterate each new path 
from EndNode to the splitStart - but will not process the splitStart itself (as 
tha already exist).
         // It does not matter that the prior segments have not yet been 
processed for splitting, as this will only apply for branches of paths that did 
not exist before
@@ -176,7 +177,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
             log.trace("Removing Rule {}", tn.getRule().getName());
         }
 
-        boolean hasProtos = kBase.hasSegmentPrototypes();
+        boolean hasProtos = 
kBase.getSegmentPrototypeRegistry().hasSegmentPrototypes();
         boolean hasWms = !wms.isEmpty();
 
         if (!hasProtos && !hasWms) {
@@ -185,7 +186,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
 
         RuleImpl rule = tn.getRule();
         LeftTupleNode firstSplit = getNetworkSplitPoint(tn);
-        PathEndNodes pathEndNodes = getPathEndNodes(kBase, rule, firstSplit, 
tn, hasProtos, hasWms);
+        PathEndNodes pathEndNodes = 
getPathEndNodes(kBase.getSegmentPrototypeRegistry(), rule, firstSplit, tn, 
hasProtos, hasWms);
 
         for (InternalWorkingMemory wm : wms) {
             wm.flushPropagations();
@@ -1151,7 +1152,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
         List<PathMemory> otherPmems = new ArrayList<>();
     }
 
-    private static PathEndNodes getPathEndNodes(InternalRuleBase kBase,
+    private static PathEndNodes getPathEndNodes(SegmentPrototypeRegistry 
segmentPrototypeRegistry,
                                                 Rule processedRule,
                                                 LeftTupleNode lt,
                                                 TerminalNode tn,
@@ -1166,15 +1167,15 @@ class LazyPhreakBuilder implements PhreakBuilder {
         }
 
         if (hasProtos) {
-            invalidateRootNode(kBase, lt);
+            invalidateRootNode(segmentPrototypeRegistry, lt);
         }
 
-        collectPathEndNodes(kBase, processedRule, lt, endNodes, tn, hasProtos, 
hasWms, hasProtos && isSplit(lt));
+        collectPathEndNodes(segmentPrototypeRegistry, processedRule, lt, 
endNodes, tn, hasProtos, hasWms, hasProtos && isSplit(lt));
 
         return endNodes;
     }
 
-    private static void collectPathEndNodes(InternalRuleBase kBase,
+    private static void collectPathEndNodes(SegmentPrototypeRegistry 
segmentPrototypeRegistry,
                                             Rule processedRule,
                                             LeftTupleNode lt,
                                             PathEndNodes endNodes,
@@ -1192,12 +1193,12 @@ class LazyPhreakBuilder implements PhreakBuilder {
             if (hasProtos) {
                 if (isBelowNewSplit) {
                     if (isRootNode(sink, null)) {
-                        kBase.invalidateSegmentPrototype(sink);
+                        
segmentPrototypeRegistry.invalidateSegmentPrototype(sink);
                     }
                 } else {
                     isBelowNewSplit = isSplit(sink);
                     if (isBelowNewSplit) {
-                        invalidateRootNode(kBase, sink);
+                        invalidateRootNode(segmentPrototypeRegistry, sink);
                     }
                 }
             }
@@ -1208,7 +1209,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
                     }
                 }
 
-                collectPathEndNodes(kBase, processedRule, sink, endNodes, tn, 
hasProtos, hasWms, isBelowNewSplit);
+                collectPathEndNodes(segmentPrototypeRegistry, processedRule, 
sink, endNodes, tn, hasProtos, hasWms, isBelowNewSplit);
             } else if (NodeTypeEnums.isTerminalNode(sink)) {
                 endNodes.otherEndNodes.add((PathEndNode) sink);
             } else if (NodeTypeEnums.TupleToObjectNode == sink.getType()) {
@@ -1224,11 +1225,11 @@ class LazyPhreakBuilder implements PhreakBuilder {
         }
     }
 
-    private static void invalidateRootNode(InternalRuleBase kBase, 
LeftTupleNode lt) {
+    private static void invalidateRootNode(SegmentPrototypeRegistry 
segmentPrototypeRegistry, LeftTupleNode lt) {
         while (!isRootNode(lt, null)) {
             lt = lt.getLeftTupleSource();
         }
-        kBase.invalidateSegmentPrototype(lt);
+        segmentPrototypeRegistry.invalidateSegmentPrototype(lt);
     }
 
     private static class PathEndNodes {
@@ -1395,7 +1396,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
 
         updateSubnetworkAndTerminalMemory(reteEvaluator, tupleSource, 
tupleSource, smem, false, nodeTypesInSegment);
 
-        reteEvaluator.getKnowledgeBase().registerSegmentPrototype(segmentRoot, 
smem.getSegmentPrototype()
+        
reteEvaluator.getKnowledgeBase().getSegmentPrototypeRegistry().registerSegmentPrototype(segmentRoot,
 smem.getSegmentPrototype()
                 .initFromSegmentMemory(smem));
 
         return smem;
@@ -1409,7 +1410,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
                                             long nodePosMask) {
         // Initialize the QueryElementNode and have it's memory reference the 
actual query SegmentMemory
         SegmentMemory querySmem = getQuerySegmentMemory(reteEvaluator, 
queryNode);
-        QueryElementNode.QueryElementNodeMemory queryNodeMem = 
smem.createNodeMemory(queryNode, reteEvaluator);
+        QueryElementNode.QueryElementNodeMemory queryNodeMem = 
reteEvaluator.getNodeMemory(queryNode);
         queryNodeMem.setNodePosMaskBit(nodePosMask);
         queryNodeMem.setQuerySegmentMemory(querySmem);
         queryNodeMem.setSegmentMemory(smem);
@@ -1421,7 +1422,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
                                         MemoryFactory tupleSource,
                                         SegmentMemory smem,
                                         List<Memory> memories) {
-        Memory mem = smem.createNodeMemory(tupleSource, reteEvaluator);
+        Memory mem = reteEvaluator.getNodeMemory(tupleSource);
         memories.add(mem);
         mem.setSegmentMemory(smem);
     }
@@ -1430,7 +1431,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
                                              MemoryFactory tupleSource,
                                              SegmentMemory smem,
                                              List<Memory> memories) {
-        Memory mem = smem.createNodeMemory(tupleSource, reteEvaluator);
+        Memory mem = reteEvaluator.getNodeMemory(tupleSource);
         mem.setSegmentMemory(smem);
         memories.add(mem);
     }
@@ -1440,7 +1441,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
                                                 SegmentMemory smem,
                                                 List<Memory> memories,
                                                 long nodePosMask) {
-        AsyncReceiveNode.AsyncReceiveMemory tnMem = 
smem.createNodeMemory(tupleSource, reteEvaluator);
+        AsyncReceiveNode.AsyncReceiveMemory tnMem = 
reteEvaluator.getNodeMemory(tupleSource);
         memories.add(tnMem);
         tnMem.setNodePosMaskBit(nodePosMask);
         tnMem.setSegmentMemory(smem);
@@ -1451,7 +1452,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
                                                 SegmentMemory smem,
                                                 List<Memory> memories,
                                                 long nodePosMask) {
-        FromNode.FromMemory mem = ((FromNode.FromMemory) 
smem.createNodeMemory(tupleSource, reteEvaluator));
+        FromNode.FromMemory mem = ((FromNode.FromMemory) 
reteEvaluator.getNodeMemory(tupleSource));
         memories.add(mem);
         mem.setSegmentMemory(smem);
         mem.setNodePosMaskBit(nodePosMask);
@@ -1461,7 +1462,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
                                              ConditionalBranchNode tupleSource,
                                              SegmentMemory smem,
                                              List<Memory> memories) {
-        ConditionalBranchNode.ConditionalBranchMemory branchMem = 
smem.createNodeMemory(tupleSource, reteEvaluator);
+        ConditionalBranchNode.ConditionalBranchMemory branchMem = 
reteEvaluator.getNodeMemory(tupleSource);
         memories.add(branchMem);
         branchMem.setSegmentMemory(smem);
         // nodes after a branch CE can notify, but they cannot impact linking
@@ -1472,7 +1473,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
                                         EvalConditionNode tupleSource,
                                         SegmentMemory smem,
                                         List<Memory> memories) {
-        EvalConditionNode.EvalMemory evalMem = 
smem.createNodeMemory(tupleSource, reteEvaluator);
+        EvalConditionNode.EvalMemory evalMem = 
reteEvaluator.getNodeMemory(tupleSource);
         memories.add(evalMem);
         evalMem.setSegmentMemory(smem);
     }
@@ -1482,7 +1483,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
                                          SegmentMemory smem,
                                          List<Memory> memories,
                                          long nodePosMask) {
-        TimerNode.TimerNodeMemory tnMem = smem.createNodeMemory(tupleSource, 
reteEvaluator);
+        TimerNode.TimerNodeMemory tnMem = 
reteEvaluator.getNodeMemory(tupleSource);
         memories.add(tnMem);
         tnMem.setNodePosMaskBit(nodePosMask);
         tnMem.setSegmentMemory(smem);
@@ -1494,7 +1495,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
                                        List<Memory> memories,
                                        long nodePosMask,
                                        long allLinkedTestMask) {
-        LeftInputAdapterNode.LiaNodeMemory liaMemory = 
smem.createNodeMemory(tupleSource, reteEvaluator);
+        LeftInputAdapterNode.LiaNodeMemory liaMemory = 
reteEvaluator.getNodeMemory(tupleSource);
         memories.add(liaMemory);
         liaMemory.setSegmentMemory(smem);
         liaMemory.setNodePosMaskBit(nodePosMask);
@@ -1511,14 +1512,13 @@ class LazyPhreakBuilder implements PhreakBuilder {
                                         boolean updateNodeBit) {
         BetaMemory bm;
         if (NodeTypeEnums.AccumulateNode == betaNode.getType()) {
-            AccumulateNode.AccumulateMemory accMemory = 
((AccumulateNode.AccumulateMemory) smem.createNodeMemory(
-                    betaNode, reteEvaluator));
+            AccumulateNode.AccumulateMemory accMemory = 
((AccumulateNode.AccumulateMemory) reteEvaluator.getNodeMemory(betaNode));
             memories.add(accMemory);
             accMemory.setSegmentMemory(smem);
 
             bm = accMemory.getBetaMemory();
         } else {
-            bm = (BetaMemory) smem.createNodeMemory(betaNode, reteEvaluator);
+            bm = (BetaMemory) reteEvaluator.getNodeMemory(betaNode);
             memories.add(bm);
         }
 
@@ -1618,7 +1618,7 @@ class LazyPhreakBuilder implements PhreakBuilder {
     private static void restoreSegmentFromPrototype(ReteEvaluator 
reteEvaluator,
                                                     LeftTupleSource 
segmentRoot,
                                                     int nodeTypesInSegment) {
-        SegmentMemory smem = 
reteEvaluator.getKnowledgeBase().createSegmentFromPrototype(reteEvaluator, 
segmentRoot);
+        SegmentMemory smem = 
reteEvaluator.getKnowledgeBase().getSegmentPrototypeRegistry().createSegmentFromPrototype(reteEvaluator,
 segmentRoot);
         if (smem != null) {
             updateSubnetworkAndTerminalMemory(reteEvaluator, segmentRoot, 
segmentRoot, smem, true, nodeTypesInSegment);
         }
diff --git 
a/drools-core/src/main/java/org/drools/core/phreak/RuntimeSegmentUtilities.java 
b/drools-core/src/main/java/org/drools/core/phreak/RuntimeSegmentUtilities.java
index c94a77fc4f..5ec3d1e90d 100644
--- 
a/drools-core/src/main/java/org/drools/core/phreak/RuntimeSegmentUtilities.java
+++ 
b/drools-core/src/main/java/org/drools/core/phreak/RuntimeSegmentUtilities.java
@@ -39,6 +39,7 @@ import org.drools.core.reteoo.QueryElementNode;
 import org.drools.core.reteoo.TupleToObjectNode;
 import org.drools.core.reteoo.SegmentMemory;
 import org.drools.core.reteoo.SegmentMemory.SegmentPrototype;
+import org.drools.core.reteoo.SegmentPrototypeRegistry;
 
 import static org.drools.core.phreak.EagerPhreakBuilder.isInsideSubnetwork;
 
@@ -79,7 +80,8 @@ public class RuntimeSegmentUtilities {
     }
 
     private static SegmentMemory restoreSegmentFromPrototype(ReteEvaluator 
reteEvaluator, LeftTupleNode segmentRoot) {
-        SegmentPrototype proto = 
reteEvaluator.getKnowledgeBase().getSegmentPrototype(segmentRoot);
+        SegmentPrototypeRegistry segmentPrototypeRegistry = 
reteEvaluator.getKnowledgeBase().getSegmentPrototypeRegistry();
+        SegmentPrototype proto = 
segmentPrototypeRegistry.getSegmentPrototype(segmentRoot);
         if (proto == null || proto.getNodesInSegment() == null) {
             return null;
         }
@@ -100,7 +102,7 @@ public class RuntimeSegmentUtilities {
             }
         }
 
-        SegmentMemory smem = 
reteEvaluator.getKnowledgeBase().createSegmentFromPrototype(reteEvaluator, 
proto);
+        SegmentMemory smem = 
segmentPrototypeRegistry.createSegmentFromPrototype(reteEvaluator, proto);
 
         updateSubnetworkAndTerminalMemory(reteEvaluator, smem, proto);
 
@@ -203,7 +205,7 @@ public class RuntimeSegmentUtilities {
         return pmem;
     }
 
-    public static void initializePathMemory(ReteEvaluator reteEvaluator, 
PathEndNode pathEndNode, PathMemory pmem) {
+    private static void initializePathMemory(ReteEvaluator reteEvaluator, 
PathEndNode pathEndNode, PathMemory pmem) {
         if (pathEndNode.getEagerSegmentPrototypes() != null) {
             for (SegmentPrototype eager : 
pathEndNode.getEagerSegmentPrototypes()) {
                 if (pmem.getSegmentMemories()[eager.getPos()] == null) {
diff --git 
a/drools-core/src/main/java/org/drools/core/reteoo/SegmentMemory.java 
b/drools-core/src/main/java/org/drools/core/reteoo/SegmentMemory.java
index c836dc7d15..bf27716e08 100644
--- a/drools-core/src/main/java/org/drools/core/reteoo/SegmentMemory.java
+++ b/drools-core/src/main/java/org/drools/core/reteoo/SegmentMemory.java
@@ -34,7 +34,6 @@ import org.drools.core.phreak.BuildtimeSegmentUtilities;
 import org.drools.core.phreak.RuntimeSegmentUtilities;
 import org.drools.core.reteoo.AsyncReceiveNode.AsyncReceiveMemory;
 import org.drools.core.reteoo.QueryElementNode.QueryElementNodeMemory;
-import org.drools.core.reteoo.SegmentMemory.SegmentPrototype;
 import org.drools.core.reteoo.TupleToObjectNode.SubnetworkPathMemory;
 import org.drools.core.reteoo.TimerNode.TimerNodeMemory;
 import org.drools.core.util.LinkedList;
@@ -77,10 +76,6 @@ public class SegmentMemory extends LinkedList<SegmentMemory>
         this.proto = new SegmentPrototype(rootNode, null);
     }
 
-    public <T extends Memory> T createNodeMemory(MemoryFactory<T> 
memoryFactory, ReteEvaluator reteEvaluator) {
-        return reteEvaluator.getNodeMemory(memoryFactory);
-    }
-
     public LeftTupleNode getRootNode() {
         return proto.getRootNode();
     }
diff --git 
a/drools-core/src/main/java/org/drools/core/reteoo/SegmentPrototypeRegistry.java
 
b/drools-core/src/main/java/org/drools/core/reteoo/SegmentPrototypeRegistry.java
new file mode 100644
index 0000000000..06f284ad64
--- /dev/null
+++ 
b/drools-core/src/main/java/org/drools/core/reteoo/SegmentPrototypeRegistry.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.core.reteoo;
+
+import org.drools.core.common.ReteEvaluator;
+import org.drools.core.reteoo.SegmentMemory.SegmentPrototype;
+
+public interface SegmentPrototypeRegistry {
+    
+    void invalidateSegmentPrototype(LeftTupleNode rootNode);
+    
+    void registerSegmentPrototype(LeftTupleNode tupleSource, SegmentPrototype 
smem);
+
+    SegmentMemory createSegmentFromPrototype(ReteEvaluator reteEvaluator, 
LeftTupleSource tupleSource);
+
+    SegmentMemory createSegmentFromPrototype(ReteEvaluator reteEvaluator, 
SegmentPrototype smem);
+
+    SegmentPrototype getSegmentPrototype(SegmentMemory segment);
+
+    SegmentPrototype getSegmentPrototype(LeftTupleNode node);
+
+    boolean hasSegmentPrototypes();
+
+}
diff --git 
a/drools-core/src/main/java/org/drools/core/reteoo/SegmentPrototypeRegistryImpl.java
 
b/drools-core/src/main/java/org/drools/core/reteoo/SegmentPrototypeRegistryImpl.java
new file mode 100644
index 0000000000..e81bded164
--- /dev/null
+++ 
b/drools-core/src/main/java/org/drools/core/reteoo/SegmentPrototypeRegistryImpl.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.core.reteoo;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.drools.core.common.ReteEvaluator;
+import org.drools.core.reteoo.SegmentMemory.SegmentPrototype;
+
+
+public class SegmentPrototypeRegistryImpl implements SegmentPrototypeRegistry {
+    
+    private final transient Map<Integer, SegmentPrototype> segmentProtos;
+
+    public SegmentPrototypeRegistryImpl(boolean isEagerCreation) {
+        segmentProtos =  isEagerCreation ? new HashMap<>() : new 
ConcurrentHashMap<>();
+    }
+    
+    public boolean hasSegmentPrototypes() {
+        return !segmentProtos.isEmpty();
+    }
+
+    public void registerSegmentPrototype(LeftTupleNode tupleSource, 
SegmentPrototype smem) {
+        segmentProtos.put(tupleSource.getId(), smem);
+    }
+
+    public void invalidateSegmentPrototype(LeftTupleNode rootNode) {
+        segmentProtos.remove(rootNode.getId());
+    }
+
+    @Override
+    public SegmentPrototype getSegmentPrototype(LeftTupleNode node) {
+        return segmentProtos.get(node.getId());
+    }
+
+    @Override
+    public SegmentMemory createSegmentFromPrototype(ReteEvaluator 
reteEvaluator, LeftTupleSource tupleSource) {
+        SegmentPrototype proto = segmentProtos.get(tupleSource.getId());
+        return createSegmentFromPrototype(reteEvaluator, proto);
+    }
+
+    public SegmentMemory createSegmentFromPrototype(ReteEvaluator 
reteEvaluator, SegmentPrototype proto) {
+        return proto.newSegmentMemory(reteEvaluator);
+    }
+
+    public SegmentPrototype getSegmentPrototype(SegmentMemory segment) {
+        return segmentProtos.get(segment.getRootNode().getId());
+    }
+
+}
diff --git 
a/drools-core/src/main/java/org/drools/core/reteoo/builder/ReteooRuleBuilder.java
 
b/drools-core/src/main/java/org/drools/core/reteoo/builder/ReteooRuleBuilder.java
index 2bb2923230..6403061d31 100755
--- 
a/drools-core/src/main/java/org/drools/core/reteoo/builder/ReteooRuleBuilder.java
+++ 
b/drools-core/src/main/java/org/drools/core/reteoo/builder/ReteooRuleBuilder.java
@@ -216,7 +216,7 @@ public class ReteooRuleBuilder implements RuleBuilder {
 
         setPathEndNodes(context, terminalNode);
 
-        if (!PhreakBuilder.isEagerSegmentCreation() || 
context.getRuleBase().hasSegmentPrototypes()) {
+        if (!PhreakBuilder.isEagerSegmentCreation() || 
context.getRuleBase().getSegmentPrototypeRegistry().hasSegmentPrototypes()) {
             // only need to process this, if segment protos exist
             PhreakBuilder.get().addRule(context.getRuleBase(), 
context.getWorkingMemories(), terminalNode);
         }
diff --git 
a/drools-kiesession/src/main/java/org/drools/kiesession/rulebase/SessionsAwareKnowledgeBase.java
 
b/drools-kiesession/src/main/java/org/drools/kiesession/rulebase/SessionsAwareKnowledgeBase.java
index 69ac4d5f44..729368a638 100644
--- 
a/drools-kiesession/src/main/java/org/drools/kiesession/rulebase/SessionsAwareKnowledgeBase.java
+++ 
b/drools-kiesession/src/main/java/org/drools/kiesession/rulebase/SessionsAwareKnowledgeBase.java
@@ -46,6 +46,7 @@ import org.drools.core.reteoo.ReteooBuilder;
 import org.drools.core.reteoo.RuntimeComponentFactory;
 import org.drools.core.reteoo.SegmentMemory;
 import org.drools.core.reteoo.SegmentMemory.SegmentPrototype;
+import org.drools.core.reteoo.SegmentPrototypeRegistry;
 import org.drools.core.rule.accessor.FactHandleFactory;
 import org.kie.api.KieBaseConfiguration;
 import org.kie.api.builder.ReleaseId;
@@ -484,6 +485,10 @@ public class SessionsAwareKnowledgeBase implements 
InternalKnowledgeBase {
         return delegate.getMemoryCount();
     }
 
+    public SegmentPrototypeRegistry getSegmentPrototypeRegistry() {
+        return delegate.getSegmentPrototypeRegistry();
+    }
+    
     @Override
     public void invalidateSegmentPrototype(LeftTupleNode rootNode) {
         delegate.invalidateSegmentPrototype(rootNode);
diff --git 
a/drools-kiesession/src/test/java/org/drools/kiesession/NodeSegmentUnlinkingTest.java
 
b/drools-kiesession/src/test/java/org/drools/kiesession/NodeSegmentUnlinkingTest.java
index 48485282db..82fb77049a 100644
--- 
a/drools-kiesession/src/test/java/org/drools/kiesession/NodeSegmentUnlinkingTest.java
+++ 
b/drools-kiesession/src/test/java/org/drools/kiesession/NodeSegmentUnlinkingTest.java
@@ -198,7 +198,7 @@ public class NodeSegmentUnlinkingTest {
         for (TerminalNode tn : new TerminalNode[] {rtn1, rtn2, rtn3}) {
             tn.setPathEndNodes( new PathEndNode[] {tn});
             tn.resetPathMemSpec(null);
-            BuildtimeSegmentUtilities.createPathProtoMemories(kBase, tn, null);
+            
BuildtimeSegmentUtilities.createPathProtoMemories(kBase.getSegmentPrototypeRegistry(),
 tn, null);
         }
     }
 
@@ -254,13 +254,13 @@ public class NodeSegmentUnlinkingTest {
         n5.attach(buildContext);
 
         StatefulKnowledgeSessionImpl ksession = 
(StatefulKnowledgeSessionImpl)kBase.newKieSession();
-        SegmentPrototype[] protos = 
BuildtimeSegmentUtilities.createLeftTupleNodeProtoMemories(kBase, n3, null);
+        SegmentPrototype[] protos = 
BuildtimeSegmentUtilities.createLeftTupleNodeProtoMemories(kBase.getSegmentPrototypeRegistry(),
 n3, null);
         Arrays.stream(protos).forEach( p -> p.setPathEndNodes( new 
PathEndNode[0]));
 
-        protos = 
BuildtimeSegmentUtilities.createLeftTupleNodeProtoMemories(kBase, n4, null);
+        protos = 
BuildtimeSegmentUtilities.createLeftTupleNodeProtoMemories(kBase.getSegmentPrototypeRegistry(),
 n4, null);
         Arrays.stream(protos).forEach( p -> p.setPathEndNodes( new 
PathEndNode[0]));
 
-        protos = 
BuildtimeSegmentUtilities.createLeftTupleNodeProtoMemories(kBase, n5, null);
+        protos = 
BuildtimeSegmentUtilities.createLeftTupleNodeProtoMemories(kBase.getSegmentPrototypeRegistry(),
 n5, null);
         Arrays.stream(protos).forEach( p -> p.setPathEndNodes( new 
PathEndNode[0]));
         createSegmentMemory( n2, ksession );
 
diff --git 
a/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingTest.java 
b/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingTest.java
index eee0061479..c514b37003 100644
--- 
a/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingTest.java
+++ 
b/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingTest.java
@@ -194,7 +194,7 @@ public class RuleUnlinkingTest {
         for (TerminalNode tn : new TerminalNode[] {rtn1, rtn2, rtn3}) {
             tn.setPathEndNodes( new PathEndNode[] {tn});
             tn.resetPathMemSpec(null);
-            BuildtimeSegmentUtilities.createPathProtoMemories(kBase, tn, null);
+            
BuildtimeSegmentUtilities.createPathProtoMemories(kBase.getSegmentPrototypeRegistry(),
 tn, null);
         }
         
     }
@@ -381,7 +381,7 @@ public class RuleUnlinkingTest {
         for (TerminalNode tn : new TerminalNode[] {rtn1, rtn2, rtn3}) {
             tn.setPathEndNodes( new PathEndNode[] {tn});
             tn.resetPathMemSpec(null);
-            BuildtimeSegmentUtilities.createPathProtoMemories(kBase, tn, null);
+            
BuildtimeSegmentUtilities.createPathProtoMemories(kBase.getSegmentPrototypeRegistry(),
 tn, null);
         }
     }
 
diff --git 
a/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingWithSegmentMemoryTest.java
 
b/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingWithSegmentMemoryTest.java
index 65669be021..ee95f4648c 100644
--- 
a/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingWithSegmentMemoryTest.java
+++ 
b/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingWithSegmentMemoryTest.java
@@ -191,7 +191,7 @@ public class RuleUnlinkingWithSegmentMemoryTest {
         for (TerminalNode tn : new TerminalNode[] {rtn1, rtn2, rtn3}) {
             tn.setPathEndNodes( new PathEndNode[] {tn});
             tn.resetPathMemSpec(null);
-            BuildtimeSegmentUtilities.createPathProtoMemories(kBase, tn, null);
+            
BuildtimeSegmentUtilities.createPathProtoMemories(kBase.getSegmentPrototypeRegistry(),
 tn, null);
         }
     }
     
diff --git 
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/AddRuleTest.java
 
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/AddRuleTest.java
index bdb1411fac..a436bab538 100644
--- 
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/AddRuleTest.java
+++ 
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/AddRuleTest.java
@@ -113,7 +113,7 @@ public class AddRuleTest {
         
assertThat(smemProto0.getNodeTypesInSegment()).isEqualTo(BuildtimeSegmentUtilities.JOIN_NODE_BIT);
 
         SegmentPrototype[] oldSmemProtos = endNode.getSegmentPrototypes();
-        SegmentPrototype smemProto1 = Add.processSplit(kbase1, 
Collections.singletonList(wm), cbeta, new HashSet<>());
+        SegmentPrototype smemProto1 = 
Add.processSplit(kbase1.getSegmentPrototypeRegistry(), 
Collections.singletonList(wm), cbeta, new HashSet<>());
 
         assertSegmentsLengthAndPos(endNode, 2, oldSmemProtos, smemProto1, wm);
         assertThat(endNode.getSegmentPrototypes()[0]).isSameAs(smemProto0);
@@ -161,7 +161,7 @@ public class AddRuleTest {
         assertThat(smemProto0.getAllLinkedMaskTest()).isEqualTo(31);
         assertThat(smemProto0.getLinkedNodeMask()).isEqualTo(10); // nots must 
be linked in
         
assertThat(smemProto0.getNodeTypesInSegment()).isEqualTo(BuildtimeSegmentUtilities.JOIN_NODE_BIT
 | BuildtimeSegmentUtilities.NOT_NODE_BIT);
-        SegmentPrototype smemProto1 = Add.processSplit(kbase1, 
Collections.singletonList(wm), cbeta, new HashSet<>());
+        SegmentPrototype smemProto1 = 
Add.processSplit(kbase1.getSegmentPrototypeRegistry(), 
Collections.singletonList(wm), cbeta, new HashSet<>());
 
         assertThat(smemProto0.getAllLinkedMaskTest()).isEqualTo(7);
         assertThat(smemProto0.getLinkedNodeMask()).isEqualTo(2);
@@ -207,7 +207,7 @@ public class AddRuleTest {
         assertThat(smemProtoX.getPos()).isEqualTo(1);
 
         SegmentPrototype[] oldSmemProtos = endNode1.getSegmentPrototypes();
-        SegmentPrototype smemProtoE2 = Add.processSplit(kbase1, 
Collections.singletonList(wm), ebeta3, new HashSet<>());
+        SegmentPrototype smemProtoE2 = 
Add.processSplit(kbase1.getSegmentPrototypeRegistry(), 
Collections.singletonList(wm), ebeta3, new HashSet<>());
         assertSegmentsLengthAndPos(endNode0, 3, wm);
         assertSegmentsLengthAndPos(endNode1, 2, oldSmemProtos, smemProtoE2, 
wm);
 
@@ -262,7 +262,7 @@ public class AddRuleTest {
         assertSegmentsLengthAndPos(endNode1, 2, wm);
 
         // processSplit should return null, as it's alreayd split and this 
does nothing.
-        assertThat(Add.processSplit(kbase1, Collections.singletonList(wm), 
cbeta, new HashSet<>())).isNull();
+        assertThat(Add.processSplit(kbase1.getSegmentPrototypeRegistry(), 
Collections.singletonList(wm), cbeta, new HashSet<>())).isNull();
 
         // now add a rule at the given split, so we can check paths were all 
updated correctly
         addRuleAtGivenSplit(kbase1, wm, cbeta, yotn);
@@ -330,7 +330,7 @@ public class AddRuleTest {
         assertThat(smemProtoEV.getAllLinkedMaskTest()).isEqualTo(12); // first 
two are evals, so each is 0
 
         SegmentPrototype[] oldSmemProtos = endNode1.getSegmentPrototypes();
-        SegmentPrototype smemProtoE4 = Add.processSplit(kbase1, 
Collections.singletonList(wm), ebeta3, new HashSet<>());
+        SegmentPrototype smemProtoE4 = 
Add.processSplit(kbase1.getSegmentPrototypeRegistry(), 
Collections.singletonList(wm), ebeta3, new HashSet<>());
 
         assertSegmentsLengthAndPos(endNode1, 2, oldSmemProtos, smemProtoE4, 
wm);
 
@@ -369,7 +369,7 @@ public class AddRuleTest {
         assertSegmentsLengthAndPos(endNode0, 3, wm);
 
         SegmentPrototype[] oldSmemProtos = endNode0.getSegmentPrototypes();
-        SegmentPrototype smemProto1 = Add.processSplit(kbase1, 
Collections.singletonList(wm), bbeta, new HashSet<>());
+        SegmentPrototype smemProto1 = 
Add.processSplit(kbase1.getSegmentPrototypeRegistry(), 
Collections.singletonList(wm), bbeta, new HashSet<>());
 
         assertSegmentsLengthAndPos(endNode0, 4, oldSmemProtos, smemProto1, wm);
         
assertThat(endNode0.getPathMemSpec().allLinkedTestMask()).isEqualTo(15);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to