public void doLeftInserts( FromNode fromNode, FromMemory fm, LeftTupleSink sink, InternalWorkingMemory wm, TupleSets<LeftTuple> srcLeftTuples, TupleSets<LeftTuple> trgLeftTuples) { BetaMemory bm = fm.getBetaMemory(); ContextEntry[] context = bm.getContext(); BetaConstraints betaConstraints = fromNode.getBetaConstraints(); AlphaNodeFieldConstraint[] alphaConstraints = fromNode.getAlphaConstraints(); DataProvider dataProvider = fromNode.getDataProvider(); Class<?> resultClass = fromNode.getResultClass(); for (LeftTuple leftTuple = srcLeftTuples.getInsertFirst(); leftTuple != null; ) { LeftTuple next = leftTuple.getStagedNext(); PropagationContext propagationContext = leftTuple.getPropagationContext(); Map<Object, RightTuple> matches = null; boolean useLeftMemory = RuleNetworkEvaluator.useLeftMemory(fromNode, leftTuple); if (useLeftMemory) { fm.getBetaMemory().getLeftTupleMemory().add(leftTuple); matches = new LinkedHashMap<Object, RightTuple>(); leftTuple.setContextObject(matches); } betaConstraints.updateFromTuple(context, wm, leftTuple); for (final java.util.Iterator<?> it = dataProvider.getResults(leftTuple, wm, propagationContext, fm.providerContext); it.hasNext(); ) { final Object object = it.next(); if ((object == null) || !resultClass.isAssignableFrom(object.getClass())) { continue; // skip anything if it not assignable } RightTuple rightTuple = fromNode.createRightTuple(leftTuple, propagationContext, wm, object); checkConstraintsAndPropagate( sink, leftTuple, rightTuple, alphaConstraints, betaConstraints, propagationContext, wm, fm, context, useLeftMemory, trgLeftTuples, null); if (useLeftMemory) { fromNode.addToCreatedHandlesMap(matches, rightTuple); } } leftTuple.clearStaged(); leftTuple = next; } betaConstraints.resetTuple(context); }
public void doLeftUpdates( FromNode fromNode, FromMemory fm, LeftTupleSink sink, InternalWorkingMemory wm, TupleSets<LeftTuple> srcLeftTuples, TupleSets<LeftTuple> trgLeftTuples, TupleSets<LeftTuple> stagedLeftTuples) { BetaMemory bm = fm.getBetaMemory(); ContextEntry[] context = bm.getContext(); BetaConstraints betaConstraints = fromNode.getBetaConstraints(); AlphaNodeFieldConstraint[] alphaConstraints = fromNode.getAlphaConstraints(); DataProvider dataProvider = fromNode.getDataProvider(); Class<?> resultClass = fromNode.getResultClass(); for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) { LeftTuple next = leftTuple.getStagedNext(); PropagationContext propagationContext = leftTuple.getPropagationContext(); final Map<Object, RightTuple> previousMatches = (Map<Object, RightTuple>) leftTuple.getContextObject(); final Map<Object, RightTuple> newMatches = new HashMap<Object, RightTuple>(); leftTuple.setContextObject(newMatches); betaConstraints.updateFromTuple(context, wm, leftTuple); FastIterator rightIt = LinkedList.fastIterator; for (final java.util.Iterator<?> it = dataProvider.getResults(leftTuple, wm, propagationContext, fm.providerContext); it.hasNext(); ) { final Object object = it.next(); if ((object == null) || !resultClass.isAssignableFrom(object.getClass())) { continue; // skip anything if it not assignable } RightTuple rightTuple = previousMatches.remove(object); if (rightTuple == null) { // new match, propagate assert rightTuple = fromNode.createRightTuple(leftTuple, propagationContext, wm, object); } else { // previous match, so reevaluate and propagate modify if (rightIt.next(rightTuple) != null) { // handle the odd case where more than one object has the same hashcode/equals value previousMatches.put(object, (RightTuple) rightIt.next(rightTuple)); rightTuple.setNext(null); } } checkConstraintsAndPropagate( sink, leftTuple, rightTuple, alphaConstraints, betaConstraints, propagationContext, wm, fm, context, true, trgLeftTuples, null); fromNode.addToCreatedHandlesMap(newMatches, rightTuple); } for (RightTuple rightTuple : previousMatches.values()) { for (RightTuple current = rightTuple; current != null; current = (RightTuple) rightIt.next(current)) { deleteChildLeftTuple( propagationContext, trgLeftTuples, stagedLeftTuples, current.getFirstChild()); } } leftTuple.clearStaged(); leftTuple = next; } betaConstraints.resetTuple(context); }
@Test public void testAlphaNode() { final PropagationContext context = pctxFactory.createPropagationContext(0, PropagationContext.INSERTION, null, null, null); final StatefulKnowledgeSessionImpl workingMemory = new StatefulKnowledgeSessionImpl(1L, kBase); final ClassFieldReader extractor = store.getReader(Cheese.class, "type"); final MvelConstraint constraint = new MvelConstraintTestUtil( "type == \"stilton\"", FieldFactory.getInstance().getFieldValue("stilton"), extractor); final List list = new ArrayList(); final Cheese cheese1 = new Cheese("cheddar", 20); final Cheese cheese2 = new Cheese("brie", 20); list.add(cheese1); list.add(cheese2); final MockDataProvider dataProvider = new MockDataProvider(list); final Pattern pattern = new Pattern(0, new ClassObjectType(Cheese.class)); From fromCe = new From(dataProvider); fromCe.setResultPattern(pattern); final FromNode from = new FromNode( 3, dataProvider, new MockTupleSource(80), new AlphaNodeFieldConstraint[] {constraint}, null, true, buildContext, fromCe); final MockLeftTupleSink sink = new MockLeftTupleSink(5); from.addTupleSink(sink); final Person person1 = new Person("xxx1", 30); final FactHandle person1Handle = workingMemory.insert(person1); final LeftTuple tuple1 = new LeftTupleImpl((DefaultFactHandle) person1Handle, from, true); from.assertLeftTuple(tuple1, context, workingMemory); // nothing should be asserted, as cheese1 is cheddar and we are filtering on stilton assertEquals(0, sink.getAsserted().size()); // Set cheese1 to stilton and it should now propagate cheese1.setType("stilton"); final Person person2 = new Person("xxx2", 30); final FactHandle person2Handle = workingMemory.insert(person2); final LeftTuple tuple2 = new LeftTupleImpl((DefaultFactHandle) person2Handle, from, true); from.assertLeftTuple(tuple2, context, workingMemory); final List asserted = sink.getAsserted(); assertEquals(1, asserted.size()); Tuple tuple = (Tuple) ((Object[]) asserted.get(0))[0]; assertSame(person2, tuple.toFactHandles()[0].getObject()); assertSame(cheese1, tuple.toFactHandles()[1].getObject()); cheese2.setType("stilton"); final Person person3 = new Person("xxx2", 30); final FactHandle person3Handle = workingMemory.insert(person3); final LeftTuple tuple3 = new LeftTupleImpl((DefaultFactHandle) person3Handle, from, true); from.assertLeftTuple(tuple3, context, workingMemory); assertEquals(3, asserted.size()); tuple = (Tuple) ((Object[]) asserted.get(1))[0]; assertSame(person3, tuple.toFactHandles()[0].getObject()); assertSame(cheese1, tuple.toFactHandles()[1].getObject()); tuple = (Tuple) ((Object[]) asserted.get(2))[0]; assertSame(person3, tuple.toFactHandles()[0].getObject()); assertSame(cheese2, tuple.toFactHandles()[1].getObject()); assertNotSame(cheese1, cheese2); }
@Test public void testAssignable() { final PropagationContext context = pctxFactory.createPropagationContext(0, PropagationContext.INSERTION, null, null, null); final StatefulKnowledgeSessionImpl workingMemory = new StatefulKnowledgeSessionImpl(1L, kBase); final List list = new ArrayList(); // final Cheese cheese1 = new Cheese( "cheddar", // 20 ); // final Cheese cheese2 = new Cheese( "brie", // 20 ); // list.add( cheese1 ); // list.add( cheese2 ); Human h1 = new Human(); Human h2 = new Human(); Person p1 = new Person("darth", 105); Person p2 = new Person("yoda", 200); Person m1 = new Man("bobba", 95); Person m2 = new Man("luke", 40); list.add(h1); list.add(h2); list.add(p1); list.add(p1); list.add(m1); list.add(m2); final MockDataProvider dataProvider = new MockDataProvider(list); final Pattern pattern = new Pattern(0, new ClassObjectType(Person.class)); From fromCe = new From(dataProvider); fromCe.setResultPattern(pattern); final FromNode from = new FromNode( 3, dataProvider, new MockTupleSource(90), new AlphaNodeFieldConstraint[] {}, null, true, buildContext, fromCe); final MockLeftTupleSink sink = new MockLeftTupleSink(5); from.addTupleSink(sink); final FactHandle handle = workingMemory.insert("xxx"); final LeftTuple tuple1 = new LeftTupleImpl((DefaultFactHandle) handle, from, true); from.assertLeftTuple(tuple1, context, workingMemory); List asserted = sink.getAsserted(); int countHuman = 0; int countPerson = 0; int countMan = 0; for (int i = 0; i < 4; i++) { Object o = ((LeftTuple) ((Object[]) asserted.get(i))[0]).getLastHandle().getObject(); if (o.getClass() == Human.class) { countHuman++; } else if (o.getClass() == Person.class) { countPerson++; } else if (o.getClass() == Man.class) { countMan++; } } assertEquals(0, countHuman); assertEquals(2, countPerson); assertEquals(2, countMan); }
@Test public void testRestract() { final PropagationContext context = pctxFactory.createPropagationContext(0, PropagationContext.INSERTION, null, null, null); final StatefulKnowledgeSessionImpl workingMemory = new StatefulKnowledgeSessionImpl( 1L, (InternalKnowledgeBase) KnowledgeBaseFactory.newKnowledgeBase()); final ClassFieldReader extractor = store.getReader(Cheese.class, "type"); final MvelConstraint constraint = new MvelConstraintTestUtil( "type == \"stilton\"", FieldFactory.getInstance().getFieldValue("stilton"), extractor); final List list = new ArrayList(); final Cheese cheese1 = new Cheese("stilton", 5); final Cheese cheese2 = new Cheese("stilton", 15); list.add(cheese1); list.add(cheese2); final MockDataProvider dataProvider = new MockDataProvider(list); final Pattern pattern = new Pattern(0, new ClassObjectType(Cheese.class)); From fromCe = new From(dataProvider); fromCe.setResultPattern(pattern); final FromNode from = new FromNode( 3, dataProvider, new MockTupleSource(30), new AlphaNodeFieldConstraint[] {constraint}, null, true, buildContext, fromCe); final MockLeftTupleSink sink = new MockLeftTupleSink(5); from.addTupleSink(sink); final List asserted = sink.getAsserted(); final Person person1 = new Person("xxx2", 30); final FactHandle person1Handle = workingMemory.insert(person1); final LeftTuple tuple = new LeftTupleImpl((DefaultFactHandle) person1Handle, from, true); from.assertLeftTuple(tuple, context, workingMemory); assertEquals(2, asserted.size()); final FromMemory memory = (FromMemory) workingMemory.getNodeMemory(from); assertEquals(1, memory.betaMemory.getLeftTupleMemory().size()); assertNull(memory.betaMemory.getRightTupleMemory()); RightTuple rightTuple2 = tuple.getFirstChild().getRightParent(); RightTuple rightTuple1 = tuple.getFirstChild().getLeftParentNext().getRightParent(); assertFalse(rightTuple1.equals(rightTuple2)); assertNull(tuple.getFirstChild().getLeftParentNext().getLeftParentNext()); final InternalFactHandle handle2 = rightTuple2.getFactHandle(); final InternalFactHandle handle1 = rightTuple1.getFactHandle(); assertEquals(handle1.getObject(), cheese2); assertEquals(handle2.getObject(), cheese1); from.retractLeftTuple(tuple, context, workingMemory); assertEquals(0, memory.betaMemory.getLeftTupleMemory().size()); assertNull(memory.betaMemory.getRightTupleMemory()); }
@Test public void testBetaNode() { final PropagationContext context = pctxFactory.createPropagationContext(0, PropagationContext.INSERTION, null, null, null); final StatefulKnowledgeSessionImpl workingMemory = new StatefulKnowledgeSessionImpl( 1L, (InternalKnowledgeBase) KnowledgeBaseFactory.newKnowledgeBase()); final ClassFieldReader priceExtractor = store.getReader(Cheese.class, "price"); final ClassFieldReader ageExtractor = store.getReader(Person.class, "age"); final Pattern pattern = new Pattern(0, new ClassObjectType(Person.class)); final Declaration declaration = new Declaration("age", ageExtractor, pattern); MvelConstraint variableConstraint = new MvelConstraintTestUtil("price == age", declaration, priceExtractor); final RuleBaseConfiguration configuration = new RuleBaseConfiguration(); configuration.setIndexRightBetaMemory(false); configuration.setIndexLeftBetaMemory(false); final BetaConstraints betaConstraints = new SingleBetaConstraints(variableConstraint, configuration); final List list = new ArrayList(); final Cheese cheese1 = new Cheese("cheddar", 18); final Cheese cheese2 = new Cheese("brie", 12); list.add(cheese1); list.add(cheese2); final MockDataProvider dataProvider = new MockDataProvider(list); From fromCe = new From(dataProvider); fromCe.setResultPattern(new Pattern(0, new ClassObjectType(Cheese.class))); final FromNode from = new FromNode( 3, dataProvider, new MockTupleSource(40), new AlphaNodeFieldConstraint[0], betaConstraints, true, buildContext, fromCe); final MockLeftTupleSink sink = new MockLeftTupleSink(5); from.addTupleSink(sink); final Person person1 = new Person("xxx1", 30); final FactHandle person1Handle = workingMemory.insert(person1); final LeftTuple tuple1 = new LeftTupleImpl((DefaultFactHandle) person1Handle, from, true); from.assertLeftTuple(tuple1, context, workingMemory); // nothing should be asserted, as cheese1 is cheddar and we are filtering on stilton assertEquals(0, sink.getAsserted().size()); // Set cheese1 to stilton and it should now propagate cheese1.setPrice(30); final Person person2 = new Person("xxx2", 30); final FactHandle person2Handle = workingMemory.insert(person2); final LeftTuple tuple2 = new LeftTupleImpl((DefaultFactHandle) person2Handle, from, true); from.assertLeftTuple(tuple2, context, workingMemory); final List asserted = sink.getAsserted(); assertEquals(1, asserted.size()); Tuple tuple = (Tuple) ((Object[]) asserted.get(0))[0]; assertSame(person2, tuple.toFactHandles()[0].getObject()); assertSame(cheese1, tuple.toFactHandles()[1].getObject()); cheese2.setPrice(30); final Person person3 = new Person("xxx2", 30); final FactHandle person3Handle = workingMemory.insert(person3); final LeftTuple tuple3 = new LeftTupleImpl((DefaultFactHandle) person3Handle, from, true); from.assertLeftTuple(tuple3, context, workingMemory); assertEquals(3, asserted.size()); tuple = (Tuple) ((Object[]) asserted.get(1))[0]; assertSame(person3, tuple.toFactHandles()[0].getObject()); assertSame(cheese1, tuple.toFactHandles()[1].getObject()); tuple = (Tuple) ((Object[]) asserted.get(2))[0]; assertSame(person3, tuple.toFactHandles()[0].getObject()); assertSame(cheese2, tuple.toFactHandles()[1].getObject()); assertNotSame(cheese1, cheese2); }