public void propagateModifyChildLeftTuple( LeftTuple leftTuple, PropagationContext context, InternalWorkingMemory workingMemory, boolean tupleMemoryEnabled) { for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) { childLeftTuple.getLeftTupleSink().modifyLeftTuple(childLeftTuple, context, workingMemory); } }
private void restoreList(final LeftTuple parent, final LeftTuple[] matchings) { // concatenate matchings list at the end of the children list if (parent.getFirstChild() == null) { parent.setFirstChild(matchings[0]); parent.setLastChild(matchings[1]); } else if (matchings[0] != null) { parent.getLastChild().setLeftParentNext(matchings[0]); matchings[0].setLeftParentPrevious(parent.getLastChild()); parent.setLastChild(matchings[1]); } }
public void propagateRetractLeftTuple( final LeftTuple leftTuple, final PropagationContext context, final InternalWorkingMemory workingMemory) { LeftTuple child = leftTuple.getFirstChild(); while (child != null) { LeftTuple temp = child.getLeftParentNext(); doPropagateRetractLeftTuple(context, workingMemory, child, child.getLeftTupleSink()); child.unlinkFromRightParent(); child.unlinkFromLeftParent(); child = temp; } }
public void propagateRetractLeftTupleDestroyRightTuple( final LeftTuple leftTuple, final PropagationContext context, final InternalWorkingMemory workingMemory) { LeftTuple child = leftTuple.getFirstChild(); InternalFactHandle rightParent = child.getRightParent().getFactHandle(); while (child != null) { LeftTuple temp = child.getLeftParentNext(); doPropagateRetractLeftTuple(context, workingMemory, child, child.getLeftTupleSink()); child.unlinkFromRightParent(); child.unlinkFromLeftParent(); child = temp; } workingMemory.getFactHandleFactory().destroyFactHandle(rightParent); }
/** * Skips the propagated tuple handles and return the first handle in the list that correspond to a * match * * @param leftTuple * @param accctx * @return */ private LeftTuple getFirstMatch( final LeftTuple leftTuple, final AccumulateContext accctx, final boolean isUpdatingSink) { // unlink all right matches LeftTuple child = leftTuple.getFirstChild(); if (accctx.propagated) { // To do that, we need to skip the first N children that are in fact // the propagated tuples int target = isUpdatingSink ? this.sink.size() - 1 : this.sink.size(); for (int i = 0; i < target; i++) { child = child.getLeftParentNext(); } } return child; }
private static ProtobufMessages.NodeMemory writeQueryElementNodeMemory( final int nodeId, final Memory memory, final InternalWorkingMemory wm) { LeftTupleIterator it = LeftTupleIterator.iterator(wm, ((QueryElementNodeMemory) memory).node); ProtobufMessages.NodeMemory.QueryElementNodeMemory.Builder _query = ProtobufMessages.NodeMemory.QueryElementNodeMemory.newBuilder(); for (LeftTuple leftTuple = (LeftTuple) it.next(); leftTuple != null; leftTuple = (LeftTuple) it.next()) { InternalFactHandle handle = (InternalFactHandle) leftTuple.getObject(); FactHandle _handle = ProtobufMessages.FactHandle.newBuilder() .setId(handle.getId()) .setRecency(handle.getRecency()) .build(); ProtobufMessages.NodeMemory.QueryElementNodeMemory.QueryContext.Builder _context = ProtobufMessages.NodeMemory.QueryElementNodeMemory.QueryContext.newBuilder() .setTuple(PersisterHelper.createTuple(leftTuple)) .setHandle(_handle); LeftTuple childLeftTuple = leftTuple.getFirstChild(); while (childLeftTuple != null) { RightTuple rightParent = childLeftTuple.getRightParent(); _context.addResult( ProtobufMessages.FactHandle.newBuilder() .setId(rightParent.getFactHandle().getId()) .setRecency(rightParent.getFactHandle().getRecency()) .build()); while (childLeftTuple != null && childLeftTuple.getRightParent() == rightParent) { // skip to the next child that has a different right parent childLeftTuple = childLeftTuple.getLeftParentNext(); } } _query.addContext(_context.build()); } return _query.getContextCount() > 0 ? ProtobufMessages.NodeMemory.newBuilder() .setNodeId(nodeId) .setNodeType(ProtobufMessages.NodeMemory.NodeType.QUERY_ELEMENT) .setQueryElement(_query.build()) .build() : null; }
protected LeftTuple[] splitList( final LeftTuple parent, final AccumulateContext accctx, final boolean isUpdatingSink) { LeftTuple[] matchings = new LeftTuple[2]; // save the matchings list matchings[0] = getFirstMatch(parent, accctx, isUpdatingSink); matchings[1] = matchings[0] != null ? parent.getLastChild() : null; // update the tuple for the actual propagations if (matchings[0] != null) { if (parent.getFirstChild() == matchings[0]) { parent.setFirstChild(null); } parent.setLastChild(matchings[0].getLeftParentPrevious()); if (parent.getLastChild() != null) { parent.getLastChild().setLeftParentNext(null); matchings[0].setLeftParentPrevious(null); } } return matchings; }
public void updateSink( final LeftTupleSink sink, final PropagationContext context, final InternalWorkingMemory workingMemory) { LeftTupleIterator it = LeftTupleIterator.iterator(workingMemory, this); for (LeftTuple leftTuple = (LeftTuple) it.next(); leftTuple != null; leftTuple = (LeftTuple) it.next()) { LeftTuple childLeftTuple = leftTuple.getFirstChild(); while (childLeftTuple != null) { RightTuple rightParent = childLeftTuple.getRightParent(); sink.assertLeftTuple( sink.createLeftTuple(leftTuple, rightParent, childLeftTuple, null, sink, true), context, workingMemory); while (childLeftTuple != null && childLeftTuple.getRightParent() == rightParent) { // skip to the next child that has a different right parent childLeftTuple = childLeftTuple.getLeftParentNext(); } } } }
public static void writeLeftTuple( LeftTuple leftTuple, MarshallerWriteContext context, boolean recurse) throws IOException { ObjectOutputStream stream = context.stream; InternalRuleBase ruleBase = context.ruleBase; InternalWorkingMemory wm = context.wm; LeftTupleSink sink = leftTuple.getLeftTupleSink(); switch (sink.getType()) { case NodeTypeEnums.JoinNode: { // context.out.println( "JoinNode" ); for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) { stream.writeShort(PersisterEnums.RIGHT_TUPLE); int childSinkId = childLeftTuple.getLeftTupleSink().getId(); stream.writeInt(childSinkId); stream.writeInt(childLeftTuple.getRightParent().getFactHandle().getId()); // context.out.println( "RightTuple int:" + childLeftTuple.getLeftTupleSink().getId() + // " int:" + childLeftTuple.getRightParent().getFactHandle().getId() ); writeLeftTuple(childLeftTuple, context, recurse); } stream.writeShort(PersisterEnums.END); // context.out.println( "JoinNode --- END" ); break; } case NodeTypeEnums.QueryRiaFixerNode: case NodeTypeEnums.EvalConditionNode: { // context.out.println( ".... EvalConditionNode" ); for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) { stream.writeShort(PersisterEnums.LEFT_TUPLE); stream.writeInt(childLeftTuple.getLeftTupleSink().getId()); writeLeftTuple(childLeftTuple, context, recurse); } stream.writeShort(PersisterEnums.END); // context.out.println( "---- EvalConditionNode --- END" ); break; } case NodeTypeEnums.NotNode: case NodeTypeEnums.ForallNotNode: { if (leftTuple.getBlocker() == null) { // is not blocked so has children stream.writeShort(PersisterEnums.LEFT_TUPLE_NOT_BLOCKED); for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) { stream.writeShort(PersisterEnums.LEFT_TUPLE); stream.writeInt(childLeftTuple.getLeftTupleSink().getId()); writeLeftTuple(childLeftTuple, context, recurse); } stream.writeShort(PersisterEnums.END); } else { stream.writeShort(PersisterEnums.LEFT_TUPLE_BLOCKED); stream.writeInt(leftTuple.getBlocker().getFactHandle().getId()); } break; } case NodeTypeEnums.ExistsNode: { if (leftTuple.getBlocker() == null) { // is blocked so has children stream.writeShort(PersisterEnums.LEFT_TUPLE_NOT_BLOCKED); } else { stream.writeShort(PersisterEnums.LEFT_TUPLE_BLOCKED); stream.writeInt(leftTuple.getBlocker().getFactHandle().getId()); for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) { stream.writeShort(PersisterEnums.LEFT_TUPLE); stream.writeInt(childLeftTuple.getLeftTupleSink().getId()); writeLeftTuple(childLeftTuple, context, recurse); } stream.writeShort(PersisterEnums.END); } break; } case NodeTypeEnums.AccumulateNode: { // context.out.println( ".... AccumulateNode" ); // accumulate nodes generate new facts on-demand and need special procedures when // serializing to persistent storage AccumulateMemory memory = (AccumulateMemory) context.wm.getNodeMemory((BetaNode) sink); AccumulateContext accctx = (AccumulateContext) leftTuple.getObject(); // first we serialize the generated fact handle writeFactHandle( context, stream, context.objectMarshallingStrategyStore, accctx.result.getFactHandle()); // then we serialize the associated accumulation context stream.writeObject(accctx.context); // then we serialize the boolean propagated flag stream.writeBoolean(accctx.propagated); // then we serialize all the propagated tuples for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) { if (leftTuple.getLeftTupleSink().getId() == childLeftTuple.getLeftTupleSink().getId()) { // this is a matching record, so, associate the right tuples // context.out.println( "RightTuple(match) int:" + // childLeftTuple.getLeftTupleSink().getId() + " int:" + // childLeftTuple.getRightParent().getFactHandle().getId() ); stream.writeShort(PersisterEnums.RIGHT_TUPLE); stream.writeInt(childLeftTuple.getRightParent().getFactHandle().getId()); } else { // this is a propagation record // context.out.println( "RightTuple(propagation) int:" + // childLeftTuple.getLeftTupleSink().getId() + " int:" + // childLeftTuple.getRightParent().getFactHandle().getId() ); stream.writeShort(PersisterEnums.LEFT_TUPLE); int sinkId = childLeftTuple.getLeftTupleSink().getId(); stream.writeInt(sinkId); writeLeftTuple(childLeftTuple, context, recurse); } } stream.writeShort(PersisterEnums.END); // context.out.println( "---- AccumulateNode --- END" ); break; } case NodeTypeEnums.RightInputAdaterNode: { // context.out.println( ".... RightInputAdapterNode" ); // RIANs generate new fact handles on-demand to wrap tuples and need special procedures // when serializing to persistent storage ObjectHashMap memory = (ObjectHashMap) context.wm.getNodeMemory((NodeMemory) sink); InternalFactHandle ifh = (InternalFactHandle) memory.get(leftTuple); // first we serialize the generated fact handle ID // context.out.println( "FactHandle id:"+ifh.getId() ); stream.writeInt(ifh.getId()); stream.writeLong(ifh.getRecency()); writeRightTuples(ifh, context); stream.writeShort(PersisterEnums.END); // context.out.println( "---- RightInputAdapterNode --- END" ); break; } case NodeTypeEnums.FromNode: { // context.out.println( ".... FromNode" ); // FNs generate new fact handles on-demand to wrap objects and need special procedures // when serializing to persistent storage FromMemory memory = (FromMemory) context.wm.getNodeMemory((NodeMemory) sink); Map<Object, RightTuple> matches = (Map<Object, RightTuple>) leftTuple.getObject(); for (RightTuple rightTuples : matches.values()) { // first we serialize the generated fact handle ID stream.writeShort(PersisterEnums.FACT_HANDLE); writeFactHandle( context, stream, context.objectMarshallingStrategyStore, rightTuples.getFactHandle()); writeRightTuples(rightTuples.getFactHandle(), context); } stream.writeShort(PersisterEnums.END); for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) { stream.writeShort(PersisterEnums.RIGHT_TUPLE); stream.writeInt(childLeftTuple.getLeftTupleSink().getId()); stream.writeInt(childLeftTuple.getRightParent().getFactHandle().getId()); // context.out.println( "RightTuple int:" + childLeftTuple.getLeftTupleSink().getId() + // " int:" + childLeftTuple.getRightParent().getFactHandle().getId() ); writeLeftTuple(childLeftTuple, context, recurse); } stream.writeShort(PersisterEnums.END); // context.out.println( "---- FromNode --- END" ); break; } case NodeTypeEnums.UnificationNode: { // context.out.println( ".... UnificationNode" ); QueryElementNode node = (QueryElementNode) sink; boolean isOpen = node.isOpenQuery(); context.writeBoolean(isOpen); if (isOpen) { InternalFactHandle factHandle = (InternalFactHandle) leftTuple.getObject(); DroolsQuery query = (DroolsQuery) factHandle.getObject(); // context.out.println( "factHandle:" + factHandle ); factHandle.setObject(null); writeFactHandle(context, stream, context.objectMarshallingStrategyStore, 0, factHandle); factHandle.setObject(query); writeLeftTuples(context, new InternalFactHandle[] {factHandle}); } else { for (LeftTuple childLeftTuple = leftTuple.getFirstChild(); childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext()) { stream.writeShort(PersisterEnums.LEFT_TUPLE); stream.writeInt(childLeftTuple.getLeftTupleSink().getId()); InternalFactHandle factHandle = childLeftTuple.getLastHandle(); writeFactHandle( context, stream, context.objectMarshallingStrategyStore, 1, factHandle); writeLeftTuple(childLeftTuple, context, recurse); } stream.writeShort(PersisterEnums.END); } // context.out.println( "---- EvalConditionNode --- END" ); break; } case NodeTypeEnums.RuleTerminalNode: { // context.out.println( "RuleTerminalNode" ); int pos = context.terminalTupleMap.size(); context.terminalTupleMap.put(leftTuple, pos); break; } case NodeTypeEnums.QueryTerminalNode: { // context.out.println( ".... QueryTerminalNode" ); // LeftTuple entry = leftTuple; // // // find the DroolsQuery object // while ( entry.getParent() != null ) { // entry = entry.getParent(); // } // // // Now output all the child tuples in the caller network // DroolsQuery query = (DroolsQuery) entry.getLastHandle().getObject(); // if ( query.getQueryResultCollector() instanceof // UnificationNodeViewChangedEventListener ) { // context.writeBoolean( true ); // UnificationNodeViewChangedEventListener collector = // (UnificationNodeViewChangedEventListener) query.getQueryResultCollector(); // leftTuple = collector.getLeftTuple(); // context.writeBoolean(true); RightTuple rightTuple = (RightTuple) leftTuple.getObject(); // context.out.println( "rightTuple:" + rightTuple.getFactHandle() ); writeFactHandle( context, stream, context.objectMarshallingStrategyStore, 1, rightTuple.getFactHandle()); for (LeftTuple childLeftTuple = rightTuple.firstChild; childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getRightParentNext()) { stream.writeShort(PersisterEnums.LEFT_TUPLE); stream.writeInt(childLeftTuple.getLeftTupleSink().getId()); writeLeftTuple(childLeftTuple, context, recurse); } // for ( LeftTuple childLeftTuple = leftTuple.getFirstChild(); // childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext() // ) { // stream.writeShort( PersisterEnums.LEFT_TUPLE ); // stream.writeInt( childLeftTuple.getLeftTupleSink().getId() ); // writeFactHandle( context, // stream, // context.objectMarshallingStrategyStore, // 1, // childLeftTuple.getLastHandle() ); // writeLeftTuple( childLeftTuple, // context, // recurse ); // } // } else { // context.writeBoolean( false ); // } stream.writeShort(PersisterEnums.END); // context.out.println( "---- QueryTerminalNode --- END" ); break; } } }
protected void doRemove( final RuleRemovalContext context, final ReteooBuilder builder, final BaseNode node, final InternalWorkingMemory[] workingMemories) { if (!node.isInUse()) { removeTupleSink((LeftTupleSink) node); } if (!this.isInUse() || context.getCleanupAdapter() != null) { for (InternalWorkingMemory workingMemory : workingMemories) { BetaMemory memory; Object object = workingMemory.getNodeMemory(this); // handle special cases for Accumulate to make sure they tidy up their specific data // like destroying the local FactHandles if (object instanceof AccumulateMemory) { memory = ((AccumulateMemory) object).betaMemory; } else { memory = (BetaMemory) object; } FastIterator it = memory.getLeftTupleMemory().fullFastIterator(); for (LeftTuple leftTuple = getFirstLeftTuple(memory.getLeftTupleMemory(), it); leftTuple != null; ) { LeftTuple tmp = (LeftTuple) it.next(leftTuple); if (context.getCleanupAdapter() != null) { LeftTuple child; while ((child = leftTuple.getFirstChild()) != null) { if (child.getLeftTupleSink() == this) { // this is a match tuple on collect and accumulate nodes, so just unlink it child.unlinkFromLeftParent(); child.unlinkFromRightParent(); } else { // the cleanupAdapter will take care of the unlinking context.getCleanupAdapter().cleanUp(child, workingMemory); } } } memory.getLeftTupleMemory().remove(leftTuple); leftTuple.unlinkFromLeftParent(); leftTuple.unlinkFromRightParent(); leftTuple = tmp; } // handle special cases for Accumulate to make sure they tidy up their specific data // like destroying the local FactHandles if (object instanceof AccumulateMemory) { ((AccumulateNode) this).doRemove(workingMemory, (AccumulateMemory) object); } if (!this.isInUse()) { it = memory.getRightTupleMemory().fullFastIterator(); for (RightTuple rightTuple = getFirstRightTuple(memory.getRightTupleMemory(), it); rightTuple != null; ) { RightTuple tmp = (RightTuple) it.next(rightTuple); if (rightTuple.getBlocked() != null) { // special case for a not, so unlink left tuple from here, as they aren't in the left // memory for (LeftTuple leftTuple = rightTuple.getBlocked(); leftTuple != null; ) { LeftTuple temp = leftTuple.getBlockedNext(); leftTuple.setBlocker(null); leftTuple.setBlockedPrevious(null); leftTuple.setBlockedNext(null); leftTuple.unlinkFromLeftParent(); leftTuple = temp; } } memory.getRightTupleMemory().remove(rightTuple); rightTuple.unlinkFromRightParent(); rightTuple = tmp; } workingMemory.clearNodeMemory(this); } } context.setCleanupAdapter(null); } this.rightInput.remove(context, builder, this, workingMemories); this.leftInput.remove(context, builder, this, workingMemories); }
public void modifyLeftTuple( LeftTuple leftTuple, PropagationContext context, InternalWorkingMemory workingMemory) { final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory(this); RightTupleMemory rightMemory = memory.getRightTupleMemory(); FastIterator rightIt = getRightIterator(rightMemory); RightTuple firstRightTuple = getFirstRightTuple(leftTuple, rightMemory, context, rightIt); // If in memory, remove it, because we'll need to add it anyway if it's not blocked, to ensure // iteration order RightTuple blocker = leftTuple.getBlocker(); if (blocker == null) { memory.getLeftTupleMemory().remove(leftTuple); } else { // check if we changed bucket if (rightMemory.isIndexed() && !rightIt.isFullIterator()) { // if newRightTuple is null, we assume there was a bucket change and that bucket is empty if (firstRightTuple == null || firstRightTuple.getMemory() != blocker.getMemory()) { // we changed bucket, so blocker no longer blocks blocker.removeBlocked(leftTuple); leftTuple.setBlocker(null); leftTuple.setBlockedPrevious(null); leftTuple.setBlockedNext(null); blocker = null; } } } this.constraints.updateFromTuple(memory.getContext(), workingMemory, leftTuple); // if we where not blocked before (or changed buckets), or the previous blocker no longer // blocks, then find the next blocker if (blocker == null || !this.constraints.isAllowedCachedLeft(memory.getContext(), blocker.getFactHandle())) { if (blocker != null) { // remove previous blocker if it exists, as we know it doesn't block any more blocker.removeBlocked(leftTuple); leftTuple.setBlocker(null); leftTuple.setBlockedPrevious(null); leftTuple.setBlockedNext(null); } FastIterator it = memory.getRightTupleMemory().fastIterator(); // find first blocker, because it's a modify, we need to start from the beginning again for (RightTuple newBlocker = firstRightTuple; newBlocker != null; newBlocker = (RightTuple) rightIt.next(newBlocker)) { if (this.constraints.isAllowedCachedLeft(memory.getContext(), newBlocker.getFactHandle())) { leftTuple.setBlocker(newBlocker); newBlocker.addBlocked(leftTuple); break; } } } if (leftTuple.getBlocker() == null) { // not blocked memory .getLeftTupleMemory() .add(leftTuple); // add to memory so other fact handles can attempt to match if (leftTuple.getFirstChild() != null) { // with previous children, retract this.sink.propagateRetractLeftTuple(leftTuple, context, workingMemory); } // with no previous children. do nothing. } else if (leftTuple.getFirstChild() == null) { // blocked, with no previous children, assert this.sink.propagateAssertLeftTuple(leftTuple, context, workingMemory, true); } else { // blocked, with previous children, modify this.sink.propagateModifyChildLeftTuple(leftTuple, context, workingMemory, true); } this.constraints.resetTuple(memory.getContext()); }
public void modifyLeftTuple( LeftTuple leftTuple, PropagationContext context, InternalWorkingMemory workingMemory) { boolean executeAsOpenQuery = openQuery; if (executeAsOpenQuery) { // There is no point in doing an open query if the caller is a non-open query. Object object = ((InternalFactHandle) leftTuple.get(0)).getObject(); if (object instanceof DroolsQuery && !((DroolsQuery) object).isOpen()) { executeAsOpenQuery = false; } } if (!executeAsOpenQuery) { // Was never open so execute as a retract + assert if (leftTuple.getFirstChild() != null) { this.sink.propagateRetractLeftTuple(leftTuple, context, workingMemory); } assertLeftTuple(leftTuple, context, workingMemory); return; } InternalFactHandle handle = (InternalFactHandle) leftTuple.getObject(); DroolsQuery queryObject = (DroolsQuery) handle.getObject(); if (queryObject.getAction() != null) { // we already have an insert scheduled for this query, but have re-entered it // do nothing return; } Object[] argTemplate = this.queryElement.getArgTemplate(); // an array of declr, variable and literals Object[] args = new Object[argTemplate.length]; // the actual args, to be created from the template // first copy everything, so that we get the literals. We will rewrite the declarations and // variables next System.arraycopy(argTemplate, 0, args, 0, args.length); int[] declIndexes = this.queryElement.getDeclIndexes(); for (int i = 0, length = declIndexes.length; i < length; i++) { Declaration declr = (Declaration) argTemplate[declIndexes[i]]; Object tupleObject = leftTuple.get(declr).getObject(); Object o; if (tupleObject instanceof DroolsQuery) { // If the query passed in a Variable, we need to use it ArrayElementReader arrayReader = (ArrayElementReader) declr.getExtractor(); if (((DroolsQuery) tupleObject).getVariables()[arrayReader.getIndex()] != null) { o = Variable.v; } else { o = declr.getValue(workingMemory, tupleObject); } } else { o = declr.getValue(workingMemory, tupleObject); } args[declIndexes[i]] = o; } int[] varIndexes = this.queryElement.getVariableIndexes(); for (int i = 0, length = varIndexes.length; i < length; i++) { if (argTemplate[varIndexes[i]] == Variable.v) { // Need to check against the arg template, as the varIndexes also includes re-declared // declarations args[varIndexes[i]] = Variable.v; } } queryObject.setParameters(args); ((UnificationNodeViewChangedEventListener) queryObject.getQueryResultCollector()) .setVariables(varIndexes); QueryUpdateAction action = new QueryUpdateAction(context, handle, leftTuple, this); context.getQueue1().addFirst(action); }
/** * Evaluate result constraints and propagate assert in case they are true * * @param leftTuple * @param context * @param workingMemory * @param memory * @param accresult * @param handle */ public void evaluateResultConstraints( final ActivitySource source, final LeftTuple leftTuple, final PropagationContext context, final InternalWorkingMemory workingMemory, final AccumulateMemory memory, final AccumulateContext accctx, final boolean useLeftMemory) { // get the actual result final Object[] resultArray = this.accumulate.getResult( memory.workingMemoryContext, accctx.context, leftTuple, workingMemory); Object result = this.accumulate.isMultiFunction() ? resultArray : resultArray[0]; if (result == null) { return; } if (accctx.result == null) { final InternalFactHandle handle = createResultFactHandle(context, workingMemory, leftTuple, result); accctx.result = createRightTuple(handle, this, context); } else { accctx.result.getFactHandle().setObject(result); } // First alpha node filters boolean isAllowed = result != null; for (int i = 0, length = this.resultConstraints.length; isAllowed && i < length; i++) { if (!this.resultConstraints[i].isAllowed( accctx.result.getFactHandle(), workingMemory, memory.alphaContexts[i])) { isAllowed = false; } } if (isAllowed) { this.resultBinder.updateFromTuple(memory.resultsContext, workingMemory, leftTuple); if (!this.resultBinder.isAllowedCachedLeft( memory.resultsContext, accctx.result.getFactHandle())) { isAllowed = false; } this.resultBinder.resetTuple(memory.resultsContext); } if (accctx.propagated == true) { // temporarily break the linked list to avoid wrong interactions LeftTuple[] matchings = splitList(leftTuple, accctx, false); if (isAllowed) { // modify if (ActivitySource.LEFT.equals(source)) { this.sink.propagateModifyChildLeftTuple( leftTuple.getFirstChild(), leftTuple, context, workingMemory, useLeftMemory); } else { this.sink.propagateModifyChildLeftTuple( leftTuple.getFirstChild(), accctx.result, context, workingMemory, useLeftMemory); } } else { // retract this.sink.propagateRetractLeftTuple(leftTuple, context, workingMemory); accctx.propagated = false; } // restore the matchings list restoreList(leftTuple, matchings); } else if (isAllowed) { // temporarily break the linked list to avoid wrong interactions LeftTuple[] matchings = splitList(leftTuple, accctx, false); // assert this.sink.propagateAssertLeftTuple( leftTuple, accctx.result, null, null, context, workingMemory, useLeftMemory); accctx.propagated = true; // restore the matchings list restoreList(leftTuple, matchings); } }