public BaseNode getMatchingNode(BaseNode candidate) { if (this.otherSinks != null) { for (ObjectSinkNode sink = this.otherSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode()) { if (sink.thisNodeEquals(candidate)) { return (BaseNode) sink; } } } if (this.hashableSinks != null) { for (ObjectSinkNode sink = this.hashableSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode()) { if (sink.thisNodeEquals(candidate)) { return (BaseNode) sink; } } } if (this.hashedSinkMap != null) { final Iterator it = this.hashedSinkMap.newIterator(); for (ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it.next()) { final ObjectSink sink = (ObjectSink) entry.getValue(); if (sink.thisNodeEquals(candidate)) { return (BaseNode) sink; } } } return null; }
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 ObjectSink[] getSinks() { if (this.sinks != null) { return sinks; } ObjectSink[] sinks = new ObjectSink[size()]; int at = 0; 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 int index = fieldIndex.getIndex(); final Iterator it = this.hashedSinkMap.newIterator(); for (ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it.next()) { HashKey hashKey = (HashKey) entry.getKey(); if (hashKey.getIndex() == index) { sinks[at++] = (ObjectSink) entry.getValue(); } } } } if (this.hashableSinks != null) { for (ObjectSinkNode sink = this.hashableSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode()) { sinks[at++] = sink; } } if (this.otherSinks != null) { for (ObjectSinkNode sink = this.otherSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode()) { sinks[at++] = sink; } } this.sinks = sinks; return sinks; }
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); } } }
public void doUnlinkRiaNode(InternalWorkingMemory wm) { if (this.otherSinks != null) { // this is only used for ria nodes when exists are shared, we know there is no indexing for // those for (ObjectSinkNode sink = this.otherSinks.getFirst(); sink != null; sink = sink.getNextObjectSinkNode()) { SingleObjectSinkAdapter.staticDoUnlinkRiaNode(sink, wm); } } }
void hashSinks(final FieldIndex fieldIndex) { if (this.hashedSinkMap == null) { this.hashedSinkMap = new ObjectHashMap(); } final int index = fieldIndex.getIndex(); final InternalReadAccessor fieldReader = fieldIndex.getFieldExtractor(); ObjectSinkNode currentSink = this.hashableSinks.getFirst(); while (currentSink != null) { final AlphaNode alphaNode = (AlphaNode) currentSink; final AlphaNodeFieldConstraint fieldConstraint = alphaNode.getConstraint(); final IndexableConstraint indexableConstraint = (IndexableConstraint) fieldConstraint; // position to the next sink now because alphaNode may be removed if the index is equal. If we // were to do this // afterwards, currentSink.nextNode would be null currentSink = currentSink.getNextObjectSinkNode(); // only alpha nodes that have an Operator.EQUAL are in hashableSinks, so only check if it is // the right field index if (index == indexableConstraint.getFieldExtractor().getIndex()) { final FieldValue value = indexableConstraint.getField(); this.hashedSinkMap.put(new HashKey(index, value, fieldReader), alphaNode); // remove the alpha from the possible candidates of hashable sinks since it is now hashed hashableSinks.remove(alphaNode); } } if (this.hashableSinks.isEmpty()) { this.hashableSinks = null; } fieldIndex.setHashed(true); }