public static void readFactHandles( MarshallerReaderContext context, org.drools.core.marshalling.impl.ProtobufMessages.EntryPoint _ep, ObjectStore objectStore, List<PropagationContextImpl> pctxs) throws IOException, ClassNotFoundException { InternalWorkingMemory wm = context.wm; SessionEntryPoint entryPoint = context.wm.getEntryPoints().get(_ep.getEntryPointId()); // load the handles for (ProtobufMessages.FactHandle _handle : _ep.getHandleList()) { InternalFactHandle handle = readFactHandle(context, entryPoint, _handle); context.handles.put(handle.getId(), handle); if (!_handle.getIsJustified()) { // BeliefSystem handles the Object type if (handle.getObject() != null) { objectStore.addHandle(handle, handle.getObject()); } // add handle to object type node assertHandleIntoOTN(context, wm, handle, pctxs); } } }
public boolean evaluate( InternalWorkingMemory workingMemory, final InternalReadAccessor extractor1, final InternalFactHandle handle1, final InternalReadAccessor extractor2, final InternalFactHandle handle2) { if (extractor1.isNullValue(workingMemory, handle1.getObject()) || extractor2.isNullValue(workingMemory, handle2.getObject())) { return false; } long rightTS; if (extractor1.isSelfReference()) { rightTS = ((EventFactHandle) handle1).getEndTimestamp(); } else { rightTS = extractor1.getLongValue(workingMemory, handle1.getObject()); } long leftTS; if (extractor2.isSelfReference()) { leftTS = ((EventFactHandle) handle2).getStartTimestamp(); } else { leftTS = extractor2.getLongValue(workingMemory, handle2.getObject()); } return evaluate(rightTS, leftTS); }
private static void assertHandleIntoOTN( MarshallerReaderContext context, InternalWorkingMemory wm, InternalFactHandle handle, List<PropagationContextImpl> pctxs) { Object object = handle.getObject(); InternalWorkingMemoryEntryPoint ep = (InternalWorkingMemoryEntryPoint) handle.getEntryPoint(); ObjectTypeConf typeConf = ((InternalWorkingMemoryEntryPoint) handle.getEntryPoint()) .getObjectTypeConfigurationRegistry() .getObjectTypeConf(ep.getEntryPoint(), object); PropagationContextImpl propagationContext = new PropagationContextImpl( wm.getNextPropagationIdCounter(), PropagationContext.INSERTION, null, null, handle, ep.getEntryPoint(), context); // keeping this list for a later cleanup is necessary because of the lazy propagations that // might occur pctxs.add(propagationContext); ep.getEntryPointNode().assertObject(handle, propagationContext, typeConf, wm); propagationContext.evaluateActionQueue(wm); wm.executeQueuedActions(); }
public boolean evaluate( InternalWorkingMemory workingMemory, final InternalReadAccessor extractor1, final InternalFactHandle handle1, final InternalReadAccessor extractor2, final InternalFactHandle handle2) { if (extractor1.isNullValue(workingMemory, handle1.getObject()) || extractor2.isNullValue(workingMemory, handle2.getObject())) { return false; } long rightTS; if (extractor1.isSelfReference()) { rightTS = ((EventFactHandle) handle1).getEndTimestamp(); } else { rightTS = extractor1.getLongValue(workingMemory, handle1.getObject()); } long leftTS; if (extractor2.isSelfReference()) { leftTS = ((EventFactHandle) handle2).getStartTimestamp(); } else { leftTS = extractor2.getLongValue(workingMemory, handle2.getObject()); } long dist = leftTS - rightTS; return this.getOperator().isNegated() ^ (dist >= this.initRange && dist <= this.finalRange); }
private static ProtobufMessages.NodeMemory writeRIANodeMemory( final int nodeId, final MarshallerWriteContext context, final BaseNode node, final NodeMemories memories, final Memory memory) { RightInputAdapterNode riaNode = (RightInputAdapterNode) node; ObjectSink[] sinks = riaNode.getSinkPropagator().getSinks(); BetaNode betaNode = (BetaNode) sinks[0]; Memory betaMemory = memories.peekNodeMemory(betaNode.getId()); if (betaMemory == null) { return null; } BetaMemory bm; if (betaNode.getType() == NodeTypeEnums.AccumulateNode) { bm = ((AccumulateMemory) betaMemory).getBetaMemory(); } else { bm = (BetaMemory) betaMemory; } // for RIA nodes, we need to store the ID of the created handles bm.getRightTupleMemory().iterator(); if (bm.getRightTupleMemory().size() > 0) { ProtobufMessages.NodeMemory.RIANodeMemory.Builder _ria = ProtobufMessages.NodeMemory.RIANodeMemory.newBuilder(); final org.drools.core.util.Iterator it = bm.getRightTupleMemory().iterator(); // iterates over all propagated handles and assert them to the new sink for (RightTuple entry = (RightTuple) it.next(); entry != null; entry = (RightTuple) it.next()) { LeftTuple leftTuple = (LeftTuple) entry.getFactHandle().getObject(); InternalFactHandle handle = (InternalFactHandle) leftTuple.getObject(); FactHandle _handle = ProtobufMessages.FactHandle.newBuilder() .setId(handle.getId()) .setRecency(handle.getRecency()) .build(); _ria.addContext( ProtobufMessages.NodeMemory.RIANodeMemory.RIAContext.newBuilder() .setTuple(PersisterHelper.createTuple(leftTuple)) .setResultHandle(_handle) .build()); } return ProtobufMessages.NodeMemory.newBuilder() .setNodeId(nodeId) .setNodeType(ProtobufMessages.NodeMemory.NodeType.RIA) .setRia(_ria.build()) .build(); } return null; }
public static Tuple writeTuple(LeftTuple tuple) { ProtobufMessages.Tuple.Builder _tb = ProtobufMessages.Tuple.newBuilder(); for (LeftTuple entry = tuple; entry != null; entry = entry.getParent()) { InternalFactHandle handle = entry.getLastHandle(); if (handle != null) { // can be null for eval, not and exists that have no right input _tb.addHandleId(handle.getId()); } } return _tb.build(); }
public boolean evaluate( InternalWorkingMemory workingMemory, final InternalReadAccessor extractor1, final InternalFactHandle handl1, final InternalReadAccessor extractor2, final InternalFactHandle handl2) { final Object value1 = extractor1.getValue(workingMemory, handl1.getObject()); final Object value2 = extractor2.getValue(workingMemory, handl2.getObject()); return !soundslike((String) value1, (String) value2); }
public void modifyLeftTuple( LeftTuple leftTuple, PropagationContext context, InternalWorkingMemory workingMemory) { // add it to a memory mapping InternalFactHandle handle = (InternalFactHandle) leftTuple.getObject(); // propagate it for (RightTuple rightTuple = handle.getFirstRightTuple(); rightTuple != null; rightTuple = rightTuple.getHandleNext()) { rightTuple.getRightTupleSink().modifyRightTuple(rightTuple, context, workingMemory); } }
@Override public Iterator getResults( Tuple leftTuple, InternalWorkingMemory wm, PropagationContext ctx, Object providerContext) { InternalFactHandle fh = leftTuple.getFactHandle(); Object obj = fh.getObject(); if (obj instanceof DroolsQuery) { obj = ((DroolsQuery) obj).getElements()[declaration.getPattern().getOffset()]; } return xpathEvaluator.evaluate(wm, leftTuple, obj).iterator(); }
public void closeLiveQuery(final InternalFactHandle factHandle) { try { startOperation(); this.ruleBase.readLock(); this.lock.lock(); final PropagationContext pCtx = new PropagationContextImpl( getNextPropagationIdCounter(), PropagationContext.INSERTION, null, null, factHandle, getEntryPoint()); if (this.ruleBase.getConfiguration().isPhreakEnabled()) { LeftInputAdapterNode lian = (LeftInputAdapterNode) factHandle.getFirstLeftTuple().getLeftTupleSink().getLeftTupleSource(); LiaNodeMemory lmem = (LiaNodeMemory) getNodeMemory((MemoryFactory) lian); SegmentMemory lsmem = lmem.getSegmentMemory(); LeftTuple childLeftTuple = factHandle.getFirstLeftTuple(); // there is only one, all other LTs are peers LeftInputAdapterNode.doDeleteObject( childLeftTuple, childLeftTuple.getPropagationContext(), lsmem, this, lian, false, lmem); List<PathMemory> rmems = lmem.getSegmentMemory().getPathMemories(); for (int i = 0, length = rmems.size(); i < length; i++) { PathMemory rm = rmems.get(i); RuleNetworkEvaluatorActivation evaluator = agenda.createRuleNetworkEvaluatorActivation( Integer.MAX_VALUE, rm, (TerminalNode) rm.getNetworkNode()); evaluator.evaluateNetwork(this, 0, -1); } } else { getEntryPointNode().retractQuery(factHandle, pCtx, this); pCtx.evaluateActionQueue(this); } getFactHandleFactory().destroyFactHandle(factHandle); } finally { this.lock.unlock(); this.ruleBase.readUnlock(); endOperation(); } }
public Collection<FactHandle> execute(Context context) { KieSession ksession = ((KnowledgeCommandContext) context).getKieSession(); Collection<FactHandle> disconnectedFactHandles = new ArrayList<FactHandle>(); if (filter != null) { Collection<InternalFactHandle> factHandles = ksession.getFactHandles(this.filter); if (factHandles != null && disconnected) { for (InternalFactHandle factHandle : factHandles) { InternalFactHandle handle = factHandle.clone(); handle.disconnect(); disconnectedFactHandles.add(handle); } return disconnectedFactHandles; } else { return ksession.getFactHandles(this.filter); } } else { Collection<InternalFactHandle> factHandles = ksession.getFactHandles(); if (factHandles != null && disconnected) { for (InternalFactHandle factHandle : factHandles) { InternalFactHandle handle = factHandle.clone(); handle.disconnect(); disconnectedFactHandles.add(handle); } return disconnectedFactHandles; } else { return ksession.getFactHandles(); } } }
public void execute(InternalWorkingMemory workingMemory) { DroolsQuery query = (DroolsQuery) factHandle.getObject(); RightTupleList rightTuples = query.getResultInsertRightTupleList(); query.setResultInsertRightTupleList( null); // null so further operations happen on a new stack element for (RightTuple rightTuple = rightTuples.getFirst(); rightTuple != null; ) { RightTuple tmp = (RightTuple) rightTuple.getNext(); rightTuples.remove(rightTuple); for (LeftTuple childLeftTuple = rightTuple.firstChild; childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getRightParentNext()) { node.getSinkPropagator() .doPropagateAssertLeftTuple( context, workingMemory, childLeftTuple, childLeftTuple.getLeftTupleSink()); } rightTuple = tmp; } // @FIXME, this should work, but it's closing needed fact handles // actually an evaluation 34 appears on the stack twice.... // if ( !node.isOpenQuery() ) { // workingMemory.getFactHandleFactory().destroyFactHandle( this.factHandle ); // } }
public boolean evaluateCachedLeft( InternalWorkingMemory workingMemory, final VariableContextEntry context, final InternalFactHandle right) { final String value = (String) context.extractor.getValue(workingMemory, right.getObject()); return !soundslike(value, (String) ((ObjectVariableContextEntry) context).left); }
public boolean evaluateCachedLeft( InternalWorkingMemory workingMemory, final VariableContextEntry context, final InternalFactHandle right) { if (context.leftNull || context.extractor.isNullValue(workingMemory, right.getObject())) { return false; } long leftTS = ((LeftStartRightEndContextEntry) context).timestamp; long rightTS; if (context.getFieldExtractor().isSelfReference()) { rightTS = ((EventFactHandle) right).getEndTimestamp(); } else { rightTS = context.getFieldExtractor().getLongValue(workingMemory, right.getObject()); } return evaluate(rightTS, leftTS); }
public boolean evaluateCachedLeft( InternalWorkingMemory workingMemory, final VariableContextEntry context, final InternalFactHandle right) { if (context.leftNull || context.extractor.isNullValue(workingMemory, right.getObject())) { return false; } long leftTS = ((LeftStartRightEndContextEntry) context).timestamp; long rightTS; if (context.getFieldExtractor().isSelfReference()) { rightTS = ((EventFactHandle) right).getEndTimestamp(); } else { rightTS = context.getFieldExtractor().getLongValue(workingMemory, right.getObject()); } long dist = leftTS - rightTS; return this.getOperator().isNegated() ^ (dist >= this.initRange && dist <= this.finalRange); }
private static ProtobufMessages.NodeMemory writeQueryElementNodeMemory( final int nodeId, final Memory memory, final InternalWorkingMemory wm) { org.drools.core.util.Iterator<LeftTuple> it = LeftTupleIterator.iterator(wm, ((QueryElementNodeMemory) memory).getNode()); ProtobufMessages.NodeMemory.QueryElementNodeMemory.Builder _query = ProtobufMessages.NodeMemory.QueryElementNodeMemory.newBuilder(); for (LeftTuple leftTuple = it.next(); leftTuple != null; 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; }
public boolean evaluateCachedRight( InternalWorkingMemory workingMemory, final VariableContextEntry context, final InternalFactHandle left) { final String value = (String) ((ObjectVariableContextEntry) context).right; return !soundslike( value, (String) context.declaration.getExtractor().getValue(workingMemory, left.getObject())); }
private static ProtobufMessages.FactHandle.HandleType getHandleType(InternalFactHandle handle) { if (handle instanceof EventFactHandle) { return ProtobufMessages.FactHandle.HandleType.EVENT; } else if (handle instanceof QueryElementFactHandle) { return ProtobufMessages.FactHandle.HandleType.QUERY; } else if (handle.getObject() instanceof InitialFact) { return ProtobufMessages.FactHandle.HandleType.INITIAL_FACT; } return ProtobufMessages.FactHandle.HandleType.FACT; }
public boolean evaluate( InternalWorkingMemory workingMemory, final InternalReadAccessor extractor, final InternalFactHandle handle1, final FieldValue object2) { final String value1 = (String) extractor.getValue(workingMemory, handle1.getObject()); final String value2 = (String) object2.getValue(); return !soundslike(value1, value2); }
public void modifyActivation( final InternalFactHandle factHandle, final PropagationContext context, final InternalWorkingMemory workingMemory) { if (activationNode == null) { this.activationNode = objectTypeNodes.get(ClassObjectType.Match_ObjectType); } if (activationNode != null) { ModifyPreviousTuples modifyPreviousTuples = new ModifyPreviousTuples( factHandle.getFirstLeftTuple(), factHandle.getFirstRightTuple(), unlinkingEnabled); factHandle.clearLeftTuples(); factHandle.clearRightTuples(); // There may be no queries defined this.activationNode.modifyObject(factHandle, modifyPreviousTuples, context, workingMemory); modifyPreviousTuples.retractTuples(context, workingMemory); } }
private static ProtobufMessages.FactHandle writeFactHandle( MarshallerWriteContext context, ObjectMarshallingStrategyStore objectMarshallingStrategyStore, InternalFactHandle handle) throws IOException { ProtobufMessages.FactHandle.Builder _handle = ProtobufMessages.FactHandle.newBuilder(); _handle.setType(getHandleType(handle)); _handle.setId(handle.getId()); _handle.setRecency(handle.getRecency()); if (_handle.getType() == ProtobufMessages.FactHandle.HandleType.EVENT) { // is event EventFactHandle efh = (EventFactHandle) handle; _handle.setTimestamp(efh.getStartTimestamp()); _handle.setDuration(efh.getDuration()); _handle.setIsExpired(efh.isExpired()); _handle.setActivationsCount(efh.getActivationsCount()); } if (handle.getEqualityKey() != null && handle.getEqualityKey().getStatus() == EqualityKey.JUSTIFIED) { _handle.setIsJustified(true); } else { _handle.setIsJustified(false); } Object object = handle.getObject(); if (object != null) { ObjectMarshallingStrategy strategy = objectMarshallingStrategyStore.getStrategyObject(object); Integer index = context.getStrategyIndex(strategy); _handle.setStrategyIndex(index.intValue()); _handle.setObject( ByteString.copyFrom( strategy.marshal(context.strategyContext.get(strategy), context, object))); } return _handle.build(); }
public void execute(InternalWorkingMemory workingMemory) { InternalFactHandle factHandle = (InternalFactHandle) leftTuple.getObject(); if (node.isOpenQuery()) { // iterate to the query terminal node, as the child leftTuples will get picked up there workingMemory .getEntryPointNode() .retractObject( factHandle, context, workingMemory .getObjectTypeConfigurationRegistry() .getObjectTypeConf(workingMemory.getEntryPoint(), factHandle.getObject()), workingMemory); // workingMemory.getFactHandleFactory().destroyFactHandle( factHandle ); } else { // get child left tuples, as there is no open query if (leftTuple.getFirstChild() != null) { node.getSinkPropagator().propagateRetractLeftTuple(leftTuple, context, workingMemory); } } }
/** Retracts the corresponding tuple by retrieving and retracting the fact created for it */ public void retractLeftTuple( final LeftTuple tuple, final PropagationContext context, final InternalWorkingMemory workingMemory) { // retrieve handle from memory final InternalFactHandle factHandle = (InternalFactHandle) tuple.getObject(); for (RightTuple rightTuple = factHandle.getFirstRightTuple(); rightTuple != null; rightTuple = rightTuple.getHandleNext()) { rightTuple.getRightTupleSink().retractRightTuple(rightTuple, context, workingMemory); } factHandle.clearRightTuples(); for (LeftTuple leftTuple = factHandle.getLastLeftTuple(); leftTuple != null; leftTuple = leftTuple.getLeftParentNext()) { leftTuple.getLeftTupleSink().retractLeftTuple(leftTuple, context, workingMemory); } factHandle.clearLeftTuples(); }
/** * This is the entry point into the network for all asserted Facts. Iterates a cache of matching * <code>ObjectTypdeNode</code>s asserting the Fact. If the cache does not exist it first iteraes * and builds the cache. * * @param factHandle The FactHandle of the fact to assert * @param context The <code>PropagationContext</code> of the <code>WorkingMemory</code> action * @param workingMemory The working memory session. */ public void assertObject( final InternalFactHandle factHandle, final PropagationContext context, final InternalWorkingMemory workingMemory) { EntryPointId entryPoint = context.getEntryPoint(); EntryPointNode node = this.entryPoints.get(entryPoint); ObjectTypeConf typeConf = ((InternalWorkingMemoryEntryPoint) workingMemory.getWorkingMemoryEntryPoint(entryPoint.getEntryPointId())) .getObjectTypeConfigurationRegistry() .getObjectTypeConf(entryPoint, factHandle.getObject()); node.assertObject(factHandle, context, typeConf, workingMemory); }
public void assertObject( final InternalFactHandle handle, final PropagationContext context, final ObjectTypeConf objectTypeConf, final InternalWorkingMemory workingMemory) { if (log.isTraceEnabled()) { log.trace("Insert {}", 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(); for (int i = 0, length = cachedNodes.length; i < length; i++) { cachedNodes[i].assertObject(handle, context, workingMemory); } }
private static ReteooStatefulSession createAndInitializeSession( MarshallerReaderContext context, int id, Environment environment, SessionConfiguration config, ProtobufMessages.KnowledgeSession _session) throws IOException { FactHandleFactory handleFactory = context.ruleBase.newFactHandleFactory( _session.getRuleData().getLastId(), _session.getRuleData().getLastRecency()); InternalFactHandle initialFactHandle = new DefaultFactHandle( _session.getRuleData().getInitialFact().getId(), InitialFactImpl.getInstance(), _session.getRuleData().getInitialFact().getRecency(), null); context.handles.put(initialFactHandle.getId(), initialFactHandle); DefaultAgenda agenda = context .ruleBase .getConfiguration() .getComponentFactory() .getAgendaFactory() .createAgenda(context.ruleBase, false); readAgenda(context, _session.getRuleData(), agenda); ReteooStatefulSession session = new ReteooStatefulSession( id, context.ruleBase, handleFactory, initialFactHandle, 0, config, agenda, environment); new StatefulKnowledgeSessionImpl(session); initialFactHandle.setEntryPoint( session.getEntryPoints().get(EntryPoint.DEFAULT.getEntryPointId())); return session; }
public void execute(InternalWorkingMemory workingMemory) { DroolsQuery query = (DroolsQuery) factHandle.getObject(); RightTupleList rightTuples = query.getResultRetractRightTupleList(); query.setResultRetractRightTupleList( null); // null so further operations happen on a new stack element for (RightTuple rightTuple = rightTuples.getFirst(); rightTuple != null; ) { RightTuple tmp = (RightTuple) rightTuple.getNext(); rightTuples.remove(rightTuple); this.node .getSinkPropagator() .propagateRetractRightTuple(rightTuple, context, workingMemory); rightTuple = tmp; } }
public void byPassModifyToBetaNode( final InternalFactHandle factHandle, final ModifyPreviousTuples modifyPreviousTuples, final PropagationContext context, final InternalWorkingMemory workingMemory) { final Object object = factHandle.getObject(); // We need to iterate in the same order as the assert if (this.hashedFieldIndexes != null) { // Iterate the FieldIndexes to see if any are hashed for (FieldIndex fieldIndex = this.hashedFieldIndexes.getFirst(); fieldIndex != null; fieldIndex = fieldIndex.getNext()) { if (!fieldIndex.isHashed()) { continue; } // this field is hashed so set the existing hashKey and see if there is a sink for it final AlphaNode sink = (AlphaNode) this.hashedSinkMap.get(new HashKey(fieldIndex, object)); if (sink != null) { // only alpha nodes are hashable sink.getObjectSinkPropagator() .byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory); } } } // propagate unhashed if (this.hashableSinks != null) { for (ObjectSinkNode sink = this.hashableSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode()) { // only alpha nodes are hashable ((AlphaNode) sink) .getObjectSinkPropagator() .byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory); } } if (this.otherSinks != null) { // propagate others for (ObjectSinkNode sink = this.otherSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode()) { // compound alpha, lianode or betanode sink.byPassModifyToBetaNode(factHandle, modifyPreviousTuples, context, workingMemory); } } }
public boolean evaluate( InternalWorkingMemory workingMemory, final InternalReadAccessor extractor, final InternalFactHandle object1, final FieldValue object2) { long rightTS; if (extractor.isSelfReference()) { rightTS = ((EventFactHandle) object1).getStartTimestamp(); } else { rightTS = extractor.getLongValue(workingMemory, object1.getObject()); } long leftTS = ((Date) object2.getValue()).getTime(); return evaluate(rightTS, leftTS); }
public void propagateModifyObject( final InternalFactHandle factHandle, final ModifyPreviousTuples modifyPreviousTuples, final PropagationContext context, final InternalWorkingMemory workingMemory) { final Object object = factHandle.getObject(); // Iterates the FieldIndex collection, which tells you if particularly field is hashed or not // if the field is hashed then it builds the hashkey to return the correct sink for the current // objects slot's // value, one object may have multiple fields indexed. if (this.hashedFieldIndexes != null) { // Iterate the FieldIndexes to see if any are hashed for (FieldIndex fieldIndex = this.hashedFieldIndexes.getFirst(); fieldIndex != null; fieldIndex = fieldIndex.getNext()) { if (!fieldIndex.isHashed()) { continue; } // this field is hashed so set the existing hashKey and see if there is a sink for it final AlphaNode sink = (AlphaNode) this.hashedSinkMap.get(new HashKey(fieldIndex, object)); if (sink != null) { // go straight to the AlphaNode's propagator, as we know it's true and no need to retest sink.getObjectSinkPropagator() .propagateModifyObject(factHandle, modifyPreviousTuples, context, workingMemory); } } } // propagate unhashed if (this.hashableSinks != null) { for (ObjectSinkNode sink = this.hashableSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode()) { doPropagateModifyObject(factHandle, modifyPreviousTuples, context, workingMemory, sink); } } if (this.otherSinks != null) { // propagate others for (ObjectSinkNode sink = this.otherSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode()) { doPropagateModifyObject(factHandle, modifyPreviousTuples, context, workingMemory, sink); } } }