private BetaNode createBetaNode(int id, int type, LeftTupleSource leftTupleSource) { MockObjectSource mockObjectSource = new MockObjectSource(8); BetaNode betaNode = null; switch (type) { case JOIN_NODE: { betaNode = new JoinNode( id, leftTupleSource, mockObjectSource, new EmptyBetaConstraints(), buildContext); break; } case EXISTS_NODE: { betaNode = new ExistsNode( id, leftTupleSource, mockObjectSource, new EmptyBetaConstraints(), buildContext); break; } case NOT_NODE: { betaNode = new NotNode( id, leftTupleSource, mockObjectSource, new EmptyBetaConstraints(), buildContext); break; } } mockObjectSource.attach(); betaNode.attach(); return betaNode; }
@Test public void testEqualsObject() { final LeftTupleSource ts = new MockTupleSource(1); final ObjectSource os = new MockObjectSource(2); InternalKnowledgeBase kBase = (InternalKnowledgeBase) KnowledgeBaseFactory.newKnowledgeBase(); BuildContext buildContext = new BuildContext(kBase, kBase.getReteooBuilder().getIdGenerator()); final BetaNode j1 = new JoinNode(1, ts, os, EmptyBetaConstraints.getInstance(), buildContext); final BetaNode j2 = new JoinNode(2, ts, os, EmptyBetaConstraints.getInstance(), buildContext); final BetaNode n1 = new NotNode(3, ts, os, EmptyBetaConstraints.getInstance(), buildContext); final BetaNode n2 = new NotNode(4, ts, os, EmptyBetaConstraints.getInstance(), buildContext); assertEquals(j1, j1); assertEquals(j2, j2); assertEquals(j1, j2); assertEquals(n1, n1); assertEquals(n2, n2); assertEquals(n1, n2); assertFalse(j1.equals(n1)); assertFalse(j1.equals(n2)); assertFalse(n1.equals(j1)); assertFalse(n1.equals(j2)); }
public static void findLeftTupleBlocker( BetaNode betaNode, RightTupleMemory rtm, ContextEntry[] contextEntry, BetaConstraints constraints, LeftTuple leftTuple, FastIterator it, PropagationContext context, boolean useLeftMemory) { // This method will also remove rightTuples that are from subnetwork where no leftmemory use // used for (RightTuple rightTuple = betaNode.getFirstRightTuple(leftTuple, rtm, null, it); rightTuple != null; ) { RightTuple nextRight = (RightTuple) it.next(rightTuple); if (constraints.isAllowedCachedLeft(contextEntry, rightTuple.getFactHandle())) { leftTuple.setBlocker(rightTuple); if (useLeftMemory) { rightTuple.addBlocked(leftTuple); break; } else if (betaNode.isRightInputIsRiaNode()) { // If we aren't using leftMemory and the right input is a RIAN, then we must iterate and // find all subetwork right tuples and remove them // so we don't break rtm.remove(rightTuple); } else { break; } } rightTuple = nextRight; } }
@Test public void testAllLinkedInWithNotNodesOnly() { setUp(NOT_NODE); assertEquals(NotNode.class, n3.getClass()); // make sure it created NotNodes KieBaseConfiguration kconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); kconf.setOption(RuleEngineOption.PHREAK); AbstractWorkingMemory wm = new AbstractWorkingMemory( 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase((RuleBaseConfiguration) kconf)); BetaMemory bm = (BetaMemory) wm.getNodeMemory(n3); createSegmentMemory(n3, wm); assertTrue(bm.getSegmentMemory().isSegmentLinked()); // not nodes start off linked DefaultFactHandle f1 = (DefaultFactHandle) wm.insert("test1"); // unlinked after first assertion n3.assertObject(f1, context, wm); // this doesn't unlink on the assertObject, as the node's memory must be processed. So use the // helper method the main network evaluator uses. PhreakNotNode.unlinkNotNodeOnRightInsert((NotNode) n3, bm, wm); assertFalse(bm.getSegmentMemory().isSegmentLinked()); n3.retractRightTuple(f1.getFirstRightTuple(), context, wm); assertTrue(bm.getSegmentMemory().isSegmentLinked()); // assertFalse( bm.getSegmentMemory().isSigmentLinked() ); // check retraction unlinks again }
@Test public void testLiaNodeInitialisation() { setUp(JOIN_NODE); // Initialise from lian KieBaseConfiguration kconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); kconf.setOption(RuleEngineOption.PHREAK); AbstractWorkingMemory wm = new AbstractWorkingMemory( 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase((RuleBaseConfiguration) kconf)); SegmentUtilities.createSegmentMemory(liaNode, wm); liaNode.assertObject((InternalFactHandle) wm.insert("str"), context, wm); LiaNodeMemory liaMem = (LiaNodeMemory) wm.getNodeMemory(liaNode); assertEquals(1, liaMem.getNodePosMaskBit()); assertEquals(3, liaMem.getSegmentMemory().getAllLinkedMaskTest()); BetaMemory bm1 = (BetaMemory) wm.getNodeMemory(n1); assertEquals(2, bm1.getNodePosMaskBit()); assertEquals(3, bm1.getSegmentMemory().getAllLinkedMaskTest()); // Initialise from n1 wm = new AbstractWorkingMemory( 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase((RuleBaseConfiguration) kconf)); n1.assertObject((InternalFactHandle) wm.insert("str"), context, wm); liaMem = (LiaNodeMemory) wm.getNodeMemory(liaNode); assertEquals(1, liaMem.getNodePosMaskBit()); assertEquals(3, liaMem.getSegmentMemory().getAllLinkedMaskTest()); bm1 = (BetaMemory) wm.getNodeMemory(n1); assertEquals(2, bm1.getNodePosMaskBit()); assertEquals(3, bm1.getSegmentMemory().getAllLinkedMaskTest()); }
@Test public void testAllLinkedInWithExistsNodesOnly() { setUp(EXISTS_NODE); assertEquals(ExistsNode.class, n3.getClass()); // make sure it created ExistsNodes KieBaseConfiguration kconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); kconf.setOption(RuleEngineOption.PHREAK); AbstractWorkingMemory wm = new AbstractWorkingMemory( 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase((RuleBaseConfiguration) kconf)); DefaultFactHandle f1 = (DefaultFactHandle) wm.insert("test1"); n3.assertObject(f1, context, wm); BetaMemory bm = (BetaMemory) wm.getNodeMemory(n3); assertFalse(bm.getSegmentMemory().isSegmentLinked()); n4.assertObject(f1, context, wm); assertFalse(bm.getSegmentMemory().isSegmentLinked()); n5.assertObject(f1, context, wm); assertFalse(bm.getSegmentMemory().isSegmentLinked()); n6.assertObject(f1, context, wm); assertTrue( bm.getSegmentMemory() .isSegmentLinked()); // only after all 4 nodes are populated, is the segment linked in n6.retractRightTuple(f1.getLastRightTuple(), context, wm); assertFalse(bm.getSegmentMemory().isSegmentLinked()); // check retraction unlinks again }
@Test public void testLiaNodeLinking() { setUp(JOIN_NODE); // Initialise from lian KieBaseConfiguration kconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); kconf.setOption(RuleEngineOption.PHREAK); AbstractWorkingMemory wm = new AbstractWorkingMemory( 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase((RuleBaseConfiguration) kconf)); SegmentUtilities.createSegmentMemory(liaNode, wm); InternalFactHandle fh1 = (InternalFactHandle) wm.insert("str1"); n1.assertObject(fh1, context, wm); LiaNodeMemory liaMem = (LiaNodeMemory) wm.getNodeMemory(liaNode); assertEquals(1, liaMem.getNodePosMaskBit()); assertEquals(3, liaMem.getSegmentMemory().getAllLinkedMaskTest()); BetaMemory bm1 = (BetaMemory) wm.getNodeMemory(n1); assertEquals(2, bm1.getNodePosMaskBit()); assertEquals(3, bm1.getSegmentMemory().getAllLinkedMaskTest()); // still unlinked assertFalse(liaMem.getSegmentMemory().isSegmentLinked()); // now linked InternalFactHandle fh2 = (InternalFactHandle) wm.insert("str2"); liaNode.assertObject(fh2, context, wm); assertTrue(liaMem.getSegmentMemory().isSegmentLinked()); // test unlink after one retract liaNode.retractLeftTuple(fh2.getFirstLeftTuple(), context, wm); assertFalse(liaMem.getSegmentMemory().isSegmentLinked()); // check counter, after multiple asserts InternalFactHandle fh3 = (InternalFactHandle) wm.insert("str3"); InternalFactHandle fh4 = (InternalFactHandle) wm.insert("str4"); liaNode.assertObject(fh3, context, wm); liaNode.assertObject(fh4, context, wm); assertTrue(liaMem.getSegmentMemory().isSegmentLinked()); liaNode.retractLeftTuple(fh3.getFirstLeftTuple(), context, wm); assertTrue(liaMem.getSegmentMemory().isSegmentLinked()); liaNode.retractLeftTuple(fh4.getFirstLeftTuple(), context, wm); assertFalse(liaMem.getSegmentMemory().isSegmentLinked()); }
public void modifyObject( final InternalFactHandle handle, final PropagationContext context, final ObjectTypeConf objectTypeConf, final InternalWorkingMemory wm) { if (log.isTraceEnabled()) { log.trace("Update {}", handle.toString()); } // checks if shadow is enabled if (objectTypeConf.isShadowEnabled()) { // the user has implemented the ShadowProxy interface, let their implementation // know it is safe to update the information the engine can see. ((ShadowProxy) handle.getObject()).updateProxy(); } ObjectTypeNode[] cachedNodes = objectTypeConf.getObjectTypeNodes(); // make a reference to the previous tuples, then null then on the handle ModifyPreviousTuples modifyPreviousTuples = new ModifyPreviousTuples( handle.getFirstLeftTuple(), handle.getFirstRightTuple(), unlinkingEnabled); handle.clearLeftTuples(); handle.clearRightTuples(); for (int i = 0, length = cachedNodes.length; i < length; i++) { cachedNodes[i].modifyObject(handle, modifyPreviousTuples, context, wm); // remove any right tuples that matches the current OTN before continue the modify on the next // OTN cache entry if (i < cachedNodes.length - 1) { RightTuple rightTuple = modifyPreviousTuples.peekRightTuple(); while (rightTuple != null && ((BetaNode) rightTuple.getRightTupleSink()).getObjectTypeNode() == cachedNodes[i]) { modifyPreviousTuples.removeRightTuple(); if (unlinkingEnabled) { BetaMemory bm = BetaNode.getBetaMemory((BetaNode) rightTuple.getRightTupleSink(), wm); BetaNode.doDeleteRightTuple(rightTuple, wm, bm); } else { ((BetaNode) rightTuple.getRightTupleSink()).retractRightTuple(rightTuple, context, wm); } rightTuple = modifyPreviousTuples.peekRightTuple(); } LeftTuple leftTuple; ObjectTypeNode otn; while (true) { leftTuple = modifyPreviousTuples.peekLeftTuple(); otn = null; if (leftTuple != null) { LeftTupleSink leftTupleSink = leftTuple.getLeftTupleSink(); if (leftTupleSink instanceof LeftTupleSource) { otn = ((LeftTupleSource) leftTupleSink).getLeftTupleSource().getObjectTypeNode(); } else if (leftTupleSink instanceof RuleTerminalNode) { otn = ((RuleTerminalNode) leftTupleSink).getObjectTypeNode(); } } if (otn == null || otn == cachedNodes[i + 1]) break; modifyPreviousTuples.removeLeftTuple(); if (unlinkingEnabled) { LeftInputAdapterNode liaNode = (LeftInputAdapterNode) leftTuple.getLeftTupleSink().getLeftTupleSource(); LiaNodeMemory lm = (LiaNodeMemory) wm.getNodeMemory(liaNode); LeftInputAdapterNode.doDeleteObject( leftTuple, context, lm.getSegmentMemory(), wm, liaNode, true, lm); } else { leftTuple.getLeftTupleSink().retractLeftTuple(leftTuple, context, wm); } } } } modifyPreviousTuples.retractTuples(context, wm); }
public static void dpUpdatesExistentialReorderRightMemory( BetaMemory bm, BetaNode betaNode, RightTupleSets srcRightTuples) { RightTupleMemory rtm = bm.getRightTupleMemory(); boolean resumeFromCurrent = !(betaNode.isIndexedUnificationJoin() || rtm.getIndexType().isComparison()); // remove all the staged rightTuples from the memory before to readd them all // this is to avoid split bucket when an updated rightTuple hasn't been moved yet // and so it is the first entry in the wrong bucket for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) { RightTuple next = rightTuple.getStagedNext(); if (rightTuple.getMemory() != null) { rightTuple.setTempRightTupleMemory(rightTuple.getMemory()); if (resumeFromCurrent) { if (rightTuple.getBlocked() != null) { // look for a non-staged right tuple first forward ... RightTuple tempRightTuple = (RightTuple) rightTuple.getNext(); while (tempRightTuple != null && tempRightTuple.getStagedType() != LeftTuple.NONE) { // next cannot be an updated or deleted rightTuple tempRightTuple = (RightTuple) tempRightTuple.getNext(); } // ... and if cannot find one try backward if (tempRightTuple == null) { tempRightTuple = (RightTuple) rightTuple.getPrevious(); while (tempRightTuple != null && tempRightTuple.getStagedType() != LeftTuple.NONE) { // next cannot be an updated or deleted rightTuple tempRightTuple = (RightTuple) tempRightTuple.getPrevious(); } } rightTuple.setTempNextRightTuple(tempRightTuple); } } rightTuple.setTempBlocked(rightTuple.getBlocked()); rightTuple.nullBlocked(); rtm.remove(rightTuple); } rightTuple = next; } for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) { RightTuple next = rightTuple.getStagedNext(); if (rightTuple.getTempRightTupleMemory() != null) { rtm.add(rightTuple); if (resumeFromCurrent) { RightTuple tempRightTuple = rightTuple.getTempNextRightTuple(); if (rightTuple.getBlocked() != null && tempRightTuple == null && rightTuple.getMemory() == rightTuple.getTempRightTupleMemory()) { // the next RightTuple was null, but current RightTuple was added back into the same // bucket, so reset as root blocker to re-match can be attempted rightTuple.setTempNextRightTuple(rightTuple); } } for (LeftTuple childLeftTuple = rightTuple.getFirstChild(); childLeftTuple != null; ) { LeftTuple childNext = childLeftTuple.getRightParentNext(); childLeftTuple.reAddLeft(); childLeftTuple = childNext; } } rightTuple = next; } }
private void doRiaNode2( InternalWorkingMemory wm, LeftTupleSets srcTuples, RightInputAdapterNode riaNode, LinkedList<StackEntry> stack) { ObjectSink[] sinks = riaNode.getSinkPropagator().getSinks(); BetaNode betaNode = (BetaNode) sinks[0]; BetaMemory bm; Memory nodeMem = wm.getNodeMemory(betaNode); if (NodeTypeEnums.AccumulateNode == betaNode.getType()) { bm = ((AccumulateMemory) nodeMem).getBetaMemory(); } else { bm = (BetaMemory) nodeMem; } // Build up iteration array for other sinks BetaNode[] bns = null; BetaMemory[] bms = null; int length = sinks.length; if (length > 1) { bns = new BetaNode[sinks.length - 1]; bms = new BetaMemory[sinks.length - 1]; for (int i = 1; i < length; i++) { bns[i - 1] = (BetaNode) sinks[i]; Memory nodeMem2 = wm.getNodeMemory(bns[i - 1]); if (NodeTypeEnums.AccumulateNode == betaNode.getType()) { bms[i - 1] = ((AccumulateMemory) nodeMem2).getBetaMemory(); } else { bms[i - 1] = (BetaMemory) nodeMem2; } } } length--; // subtract one, as first is not in the array; for (LeftTuple leftTuple = srcTuples.getInsertFirst(); leftTuple != null; ) { LeftTuple next = leftTuple.getStagedNext(); PropagationContext pctx = leftTuple.getPropagationContext(); InternalFactHandle handle = riaNode.createFactHandle(leftTuple, pctx, wm); RightTuple rightTuple = new RightTuple(handle, betaNode); leftTuple.setObject(rightTuple); rightTuple.setPropagationContext(pctx); bm.getStagedRightTuples().addInsert(rightTuple); if (bns != null) { // Add peered RightTuples, they are attached to FH - unlink LeftTuples that has a peer ref for (int i = 0; i < length; i++) { rightTuple = new RightTuple(handle, bns[i]); rightTuple.setPropagationContext(pctx); bms[i].getStagedRightTuples().addInsert(rightTuple); } } leftTuple.clearStaged(); leftTuple = next; } for (LeftTuple leftTuple = srcTuples.getDeleteFirst(); leftTuple != null; ) { LeftTuple next = leftTuple.getStagedNext(); RightTuple rightTuple = (RightTuple) leftTuple.getObject(); RightTupleSets rightTuples = bm.getStagedRightTuples(); switch (rightTuple.getStagedType()) { case LeftTuple.INSERT: { rightTuples.removeInsert(rightTuple); break; } case LeftTuple.UPDATE: { rightTuples.removeUpdate(rightTuple); break; } } rightTuples.addDelete(rightTuple); if (bns != null) { // Add peered RightTuples, they are attached to FH - unlink LeftTuples that has a peer ref for (int i = 0; i < length; i++) { rightTuple = rightTuple.getHandleNext(); rightTuples = bms[i].getStagedRightTuples(); switch (rightTuple.getStagedType()) { case LeftTuple.INSERT: { rightTuples.removeInsert(rightTuple); break; } case LeftTuple.UPDATE: { rightTuples.removeUpdate(rightTuple); break; } } rightTuples.addDelete(rightTuple); } } leftTuple.clearStaged(); leftTuple = next; } for (LeftTuple leftTuple = srcTuples.getUpdateFirst(); leftTuple != null; ) { LeftTuple next = leftTuple.getStagedNext(); RightTuple rightTuple = (RightTuple) leftTuple.getObject(); RightTupleSets rightTuples = bm.getStagedRightTuples(); switch (rightTuple.getStagedType()) { case LeftTuple.INSERT: { rightTuples.removeInsert(rightTuple); break; } case LeftTuple.UPDATE: { rightTuples.removeUpdate(rightTuple); break; } } rightTuples.addUpdate(rightTuple); if (bns != null) { // Add peered RightTuples, they are attached to FH - unlink LeftTuples that has a peer ref for (int i = 0; i < length; i++) { rightTuple = rightTuple.getHandleNext(); rightTuples = bms[i].getStagedRightTuples(); switch (rightTuple.getStagedType()) { case LeftTuple.INSERT: { rightTuples.removeInsert(rightTuple); break; } case LeftTuple.UPDATE: { rightTuples.removeUpdate(rightTuple); break; } } rightTuples.addUpdate(rightTuple); } } leftTuple.clearStaged(); leftTuple = next; } srcTuples.resetAll(); }
private void doRiaNode( InternalWorkingMemory wm, LeftInputAdapterNode liaNode, PathMemory rmem, LeftTupleSets srcTuples, BetaNode betaNode, LeftTupleSinkNode sink, SegmentMemory[] smems, int smemIndex, Memory nodeMem, BetaMemory bm, LinkedList<StackEntry> stack, Set<String> visitedRules, RuleExecutor executor) { RiaPathMemory pathMem = bm.getRiaRuleMemory(); SegmentMemory[] subnetworkSmems = pathMem.getSegmentMemories(); SegmentMemory subSmem = null; for (int i = 0; subSmem == null; i++) { // segment positions outside of the subnetwork, in the parent chain, are null // so we must iterate to find the first non null segment memory subSmem = subnetworkSmems[i]; } // if (betaNode.getLeftTupleSource().getSinkPropagator().size() == 2) { // // sub network is not part of share split, so need to handle propagation // // this ensures the first LeftTuple is actually the subnetwork node // // and the main outer network now receives the peer, notice the swap at the end // "srcTuples == peerTuples" // LeftTupleSets peerTuples = new LeftTupleSets(); // SegmentPropagator.processPeers(srcTuples, peerTuples, betaNode); // // Make sure subnetwork Segment has tuples to process // LeftTupleSets subnetworkStaged = subSmem.getStagedLeftTuples(); // subnetworkStaged.addAll(srcTuples); // // srcTuples.resetAll(); // // srcTuples = peerTuples; // } // Resume the node after the riaNode segment has been processed and the right input memory // populated StackEntry stackEntry = new StackEntry( liaNode, betaNode, sink, rmem, nodeMem, smems, smemIndex, srcTuples, visitedRules, false); stack.add(stackEntry); if (log.isTraceEnabled()) { int offset = getOffset(betaNode); log.trace( "{} RiaQueue {} {}", indent(offset), betaNode.toString(), srcTuples.toStringSizes()); } // RightInputAdapterNode riaNode = ( RightInputAdapterNode ) betaNode.getRightInput(); // RiaNodeMemory riaNodeMemory = (RiaNodeMemory) wm.getNodeMemory((MemoryFactory) // betaNode.getRightInput()); // LeftTupleSets riaStagedTuples = eval2( liaNode, pathMem, (LeftTupleSink) subSmem.getRootNode(), subSmem.getNodeMemories().getFirst(), subnetworkSmems, subSmem.getPos(), subSmem.getStagedLeftTuples(), wm, stack, visitedRules, true, executor); }
public void eval2( LeftInputAdapterNode liaNode, PathMemory rmem, NetworkNode node, Memory nodeMem, SegmentMemory[] smems, int smemIndex, LeftTupleSets trgTuples, InternalWorkingMemory wm, LinkedList<StackEntry> stack, Set<String> visitedRules, boolean processRian, RuleExecutor executor) { LeftTupleSets srcTuples; SegmentMemory smem = smems[smemIndex]; while (true) { srcTuples = trgTuples; // previous target, is now the source if (log.isTraceEnabled()) { int offset = getOffset(node); log.trace( "{} {} {} {}", indent(offset), ++cycle, node.toString(), srcTuples.toStringSizes()); } if (NodeTypeEnums.isTerminalNode(node)) { TerminalNode rtn = (TerminalNode) node; if (node.getType() == NodeTypeEnums.QueryTerminalNode) { pQtNode.doNode((QueryTerminalNode) rtn, wm, srcTuples, stack); } else { pRtNode.doNode(rtn, wm, srcTuples, executor); } return; } else if (NodeTypeEnums.RightInputAdaterNode == node.getType()) { doRiaNode2(wm, srcTuples, (RightInputAdapterNode) node, stack); return; } LeftTupleSets stagedLeftTuples; if (node == smem.getTipNode() && smem.getFirst() != null) { // we are about to process the segment tip, allow it to merge insert/update/delete clashes // Can happen if the next segments have not yet been initialized stagedLeftTuples = smem.getFirst().getStagedLeftTuples(); } else { stagedLeftTuples = null; } LeftTupleSinkNode sink = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink(); trgTuples = new LeftTupleSets(); if (NodeTypeEnums.isBetaNode(node)) { BetaNode betaNode = (BetaNode) node; BetaMemory bm = null; AccumulateMemory am = null; if (NodeTypeEnums.AccumulateNode == node.getType()) { am = (AccumulateMemory) nodeMem; bm = am.getBetaMemory(); } else { bm = (BetaMemory) nodeMem; } if (processRian && betaNode.isRightInputIsRiaNode()) { // if the subnetwork is nested in this segment, it will create srcTuples containing // peer LeftTuples, suitable for the node in the main path. doRiaNode( wm, liaNode, rmem, srcTuples, betaNode, sink, smems, smemIndex, nodeMem, bm, stack, visitedRules, executor); return; // return here is doRiaNode queues the evaluation on the stack, which is necessary // to handled nested query nodes } if (!bm.getDequeu().isEmpty()) { // If there are no staged RightTuples, then process the Dequeue, popping entries, until // another insert/expiration clash RightTupleSets rightTuples = bm.getStagedRightTuples(); if (rightTuples.isEmpty()) { // nothing staged, so now process the Dequeu Deque<RightTuple> que = bm.getDequeu(); while (!que.isEmpty()) { RightTuple rightTuple = que.peekFirst(); if (rightTuple.getPropagationContext().getType() == PropagationContext.EXPIRATION && // Cannot pop an expired fact, if the insert/update has not yet been evaluated. rightTuple.getStagedType() != LeftTuple.NONE) { break; } switch (rightTuple.getPropagationContext().getType()) { case PropagationContext.INSERTION: case PropagationContext.RULE_ADDITION: rightTuples.addInsert(rightTuple); break; case PropagationContext.MODIFICATION: rightTuples.addUpdate(rightTuple); break; case PropagationContext.DELETION: case PropagationContext.EXPIRATION: case PropagationContext.RULE_REMOVAL: rightTuples.addDelete(rightTuple); break; } que.removeFirst(); } } if (!bm.getDequeu().isEmpty()) { // The DeQue is not empty, add StackEntry for reprocessing. StackEntry stackEntry = new StackEntry( liaNode, node, sink, rmem, nodeMem, smems, smemIndex, trgTuples, visitedRules, false); stack.add(stackEntry); } } switch (node.getType()) { case NodeTypeEnums.JoinNode: { pJoinNode.doNode( (JoinNode) node, sink, bm, wm, srcTuples, trgTuples, stagedLeftTuples); break; } case NodeTypeEnums.NotNode: { pNotNode.doNode((NotNode) node, sink, bm, wm, srcTuples, trgTuples, stagedLeftTuples); break; } case NodeTypeEnums.ExistsNode: { pExistsNode.doNode( (ExistsNode) node, sink, bm, wm, srcTuples, trgTuples, stagedLeftTuples); break; } case NodeTypeEnums.AccumulateNode: { pAccNode.doNode( (AccumulateNode) node, sink, am, wm, srcTuples, trgTuples, stagedLeftTuples); break; } } } else { switch (node.getType()) { case NodeTypeEnums.EvalConditionNode: { pEvalNode.doNode( (EvalConditionNode) node, (EvalMemory) nodeMem, sink, wm, srcTuples, trgTuples, stagedLeftTuples); break; } case NodeTypeEnums.FromNode: { pFromNode.doNode( (FromNode) node, (FromMemory) nodeMem, sink, wm, srcTuples, trgTuples, stagedLeftTuples); break; } case NodeTypeEnums.QueryElementNode: { QueryElementNodeMemory qmem = (QueryElementNodeMemory) nodeMem; if (srcTuples.isEmpty() && qmem.getResultLeftTuples().isEmpty()) { // no point in evaluating query element, and setting up stack, if there is nothing // to process break; } QueryElementNode qnode = (QueryElementNode) node; if (visitedRules == Collections.<String>emptySet()) { visitedRules = new HashSet<String>(); } visitedRules.add(qnode.getQueryElement().getQueryName()); // result tuples can happen when reactivity occurs inside of the query, prior to // evaluation // we will need special behaviour to add the results again, when this query result // resumes trgTuples.addAll(qmem.getResultLeftTuples()); if (!srcTuples.isEmpty()) { // only process the Query Node if there are src tuples StackEntry stackEntry = new StackEntry( liaNode, node, sink, rmem, nodeMem, smems, smemIndex, trgTuples, visitedRules, true); stack.add(stackEntry); pQueryNode.doNode( qnode, (QueryElementNodeMemory) nodeMem, stackEntry, sink, wm, srcTuples); SegmentMemory qsmem = ((QueryElementNodeMemory) nodeMem).getQuerySegmentMemory(); List<PathMemory> qrmems = qsmem.getPathMemories(); // Build the evaluation information for each 'or' branch // Exception fo the last, place each entry on the stack, the last one evaluate now. for (int i = qrmems.size() - 1; i >= 0; i--) { PathMemory qrmem = qrmems.get(i); rmem = qrmem; smems = qrmem.getSegmentMemories(); smemIndex = 0; smem = smems[smemIndex]; // 0 liaNode = (LeftInputAdapterNode) smem.getRootNode(); if (liaNode == smem.getTipNode()) { // segment only has liaNode in it // nothing is staged in the liaNode, so skip to next segment smem = smems[++smemIndex]; // 1 node = smem.getRootNode(); nodeMem = smem.getNodeMemories().getFirst(); } else { // lia is in shared segment, so point to next node node = liaNode.getSinkPropagator().getFirstLeftTupleSink(); nodeMem = smem.getNodeMemories().getFirst().getNext(); // skip the liaNode memory } trgTuples = smem.getStagedLeftTuples(); if (i != 0 && !trgTuples.isEmpty()) { // All entries except the last should be placed on the stack for evaluation // later. stackEntry = new StackEntry( liaNode, node, null, rmem, nodeMem, smems, smemIndex, trgTuples, visitedRules, false); if (log.isTraceEnabled()) { int offset = getOffset(stackEntry.getNode()); log.trace( "{} ORQueue branch={} {} {}", indent(offset), i, stackEntry.getNode().toString(), trgTuples.toStringSizes()); } stack.add(stackEntry); } } processRian = true; // make sure it's reset, so ria nodes are processed continue; } break; } case NodeTypeEnums.ConditionalBranchNode: { pBranchNode.doNode( (ConditionalBranchNode) node, (ConditionalBranchMemory) nodeMem, sink, wm, srcTuples, trgTuples, stagedLeftTuples, executor); break; } } } if (node != smem.getTipNode()) { // get next node and node memory in the segment node = sink; nodeMem = nodeMem.getNext(); } else { // Reached end of segment, start on new segment. SegmentPropagator.propagate(smem, trgTuples, wm); smem = smems[++smemIndex]; trgTuples = smem.getStagedLeftTuples(); if (log.isTraceEnabled()) { log.trace("Segment {}", smemIndex); } node = (LeftTupleSink) smem.getRootNode(); nodeMem = smem.getNodeMemories().getFirst(); } processRian = true; // make sure it's reset, so ria nodes are processed } }
public void setUp(int... type) { KieBaseConfiguration kconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); kconf.setOption(RuleEngineOption.PHREAK); ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase((RuleBaseConfiguration) kconf); buildContext = new BuildContext(ruleBase, ruleBase.getReteooBuilder().getIdGenerator()); PropagationContextFactory pctxFactory = ruleBase.getConfiguration().getComponentFactory().getPropagationContextFactory(); context = pctxFactory.createPropagationContext(0, PropagationContext.INSERTION, null, null, null); MockTupleSource mockTupleSource = new MockTupleSource(9); rule1 = new Rule("rule1"); rule2 = new Rule("rule2"); rule3 = new Rule("rule3"); ObjectTypeNode otn = new ObjectTypeNode(2, null, new ClassObjectType(String.class), buildContext); liaNode = new LeftInputAdapterNode(3, otn, buildContext); // 3, 4, 5, 6 are in same shared segment n1 = createBetaNode(10, type[0], liaNode); n2 = createBetaNode(11, type[1], n1); RuleTerminalNode rtn1 = new RuleTerminalNode(18, n2, rule1, rule1.getLhs(), 0, buildContext); rtn1.attach(); n3 = createBetaNode(12, type[2], n1); n4 = createBetaNode(13, type[3], n3); n5 = createBetaNode(14, type[4], n4); n6 = createBetaNode(15, type[5], n5); RuleTerminalNode rtn2 = new RuleTerminalNode(19, n6, rule2, rule2.getLhs(), 0, buildContext); rtn2.attach(); n7 = createBetaNode(16, type[6], n6); n8 = createBetaNode(17, type[7], n7); RuleTerminalNode rtn3 = new RuleTerminalNode(20, n8, rule3, rule3.getLhs(), 0, buildContext); rtn3.attach(); // n1 -> n2 -> r1 // \ // n3 -> n4 -> n5 -> n6 -> r2 // \ // n7 -> n8 -> r3 n1.getAssociations().put(rule1, null); n1.getAssociations().put(rule2, null); n1.getAssociations().put(rule3, null); n2.getAssociations().put(rule1, null); n2.getAssociations().put(rule2, null); n2.getAssociations().put(rule3, null); n3.getAssociations().put(rule2, null); n3.getAssociations().put(rule3, null); n4.getAssociations().put(rule2, null); n4.getAssociations().put(rule3, null); n5.getAssociations().put(rule2, null); n5.getAssociations().put(rule3, null); n6.getAssociations().put(rule2, null); n6.getAssociations().put(rule3, null); n7.getAssociations().put(rule3, null); n8.getAssociations().put(rule3, null); }
@Test public void testSingleNodeinSegment() { rule1 = new Rule("rule1"); rule2 = new Rule("rule2"); rule3 = new Rule("rule3"); KieBaseConfiguration kconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); kconf.setOption(RuleEngineOption.PHREAK); ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase((RuleBaseConfiguration) kconf); BuildContext buildContext = new BuildContext(ruleBase, ruleBase.getReteooBuilder().getIdGenerator()); MockObjectSource mockObjectSource = new MockObjectSource(8); MockTupleSource mockTupleSource = new MockTupleSource(9); // n2 is only node in it's segment ObjectTypeNode otn = new ObjectTypeNode(2, null, new ClassObjectType(String.class), buildContext); BetaNode n1 = new JoinNode( 10, new LeftInputAdapterNode(3, otn, buildContext), mockObjectSource, new EmptyBetaConstraints(), buildContext); BetaNode n2 = new JoinNode(11, n1, mockObjectSource, new EmptyBetaConstraints(), buildContext); BetaNode n3 = new JoinNode(12, n1, mockObjectSource, new EmptyBetaConstraints(), buildContext); BetaNode n4 = new JoinNode(13, n2, mockObjectSource, new EmptyBetaConstraints(), buildContext); BetaNode n5 = new JoinNode(14, n2, mockObjectSource, new EmptyBetaConstraints(), buildContext); n1.addAssociation(rule1, null); n1.addAssociation(rule2, null); n1.addAssociation(rule3, null); n2.addAssociation(rule2, null); n2.addAssociation(rule3, null); n3.addAssociation(rule1, null); n4.addAssociation(rule2, null); n5.addAssociation(rule3, null); mockObjectSource.attach(); mockTupleSource.attach(); n1.attach(); n2.attach(); n3.attach(); n4.attach(); n5.attach(); AbstractWorkingMemory wm = new AbstractWorkingMemory( 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase((RuleBaseConfiguration) kconf)); createSegmentMemory(n2, wm); BetaMemory bm = (BetaMemory) wm.getNodeMemory(n1); assertNull(bm.getSegmentMemory()); bm = (BetaMemory) wm.getNodeMemory(n3); assertNull(bm.getSegmentMemory()); bm = (BetaMemory) wm.getNodeMemory(n4); assertNull(bm.getSegmentMemory()); bm = (BetaMemory) wm.getNodeMemory(n2); assertEquals(1, bm.getNodePosMaskBit()); assertEquals(1, bm.getSegmentMemory().getAllLinkedMaskTest()); }
public void writeExternal(ObjectOutput out) throws IOException { super.writeExternal(out); out.writeBoolean(emptyBetaConstraints); }
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { super.readExternal(in); emptyBetaConstraints = in.readBoolean(); }