📄 joinnode.java
字号:
* The <code>PropagationContext</code>
* @param workingMemory
* The working memory seesion.
*/
public void retractTuple(final ReteTuple leftTuple,
final PropagationContext context,
final ReteooWorkingMemory workingMemory) {
final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
memory.remove( workingMemory,
leftTuple );
final Map matches = leftTuple.getTupleMatches();
if ( !matches.isEmpty() ) {
for ( final Iterator it = matches.values().iterator(); it.hasNext(); ) {
final TupleMatch tupleMatch = (TupleMatch) it.next();
tupleMatch.getObjectMatches().remove( tupleMatch );
propagateRetractTuple( tupleMatch,
context,
workingMemory );
}
}
}
public void modifyTuple(final ReteTuple leftTuple,
final PropagationContext context,
final ReteooWorkingMemory workingMemory) {
final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
// We remove the tuple as now its modified it needs to go to the top of
// the stack, which is added back in else where
memory.remove( workingMemory,
leftTuple );
final Map matches = leftTuple.getTupleMatches();
if ( matches.isEmpty() ) {
// No child propagations, so try as a new assert, will ensure the
// tuple is added to the top of the memory
assertTuple( leftTuple,
context,
workingMemory );
} else {
// TIRELLI's NOTE: the following is necessary because in case memory
// indexing is enabled, the loop over right objects may skip some of the
// previously matched objects
final Map oldMatches = new HashMap(matches);
leftTuple.getTupleMatches().clear();
// ensure the tuple is at the top of the memory
memory.add( workingMemory,
leftTuple );
final BetaNodeBinder binder = getJoinNodeBinder();
for ( final Iterator rightIterator = memory.rightObjectIterator( workingMemory,
leftTuple ); rightIterator.hasNext(); ) {
final ObjectMatches objectMatches = (ObjectMatches) rightIterator.next();
final DefaultFactHandle handle = objectMatches.getFactHandle();
if ( binder.isAllowed( handle,
leftTuple,
workingMemory ) ) {
TupleMatch tupleMatch = (TupleMatch) oldMatches.remove( handle );
if ( tupleMatch != null ) {
// ensures tupleMatch will be in the appropriate order
objectMatches.remove( tupleMatch );
objectMatches.add( tupleMatch );
leftTuple.addTupleMatch( handle, tupleMatch );
propagateModifyTuple( tupleMatch,
context,
workingMemory );
} else {
tupleMatch = objectMatches.add( leftTuple );
leftTuple.addTupleMatch( handle,
tupleMatch );
propagateAssertTuple( new ReteTuple( leftTuple,
handle ),
tupleMatch,
context,
workingMemory );
}
} else {
final TupleMatch tupleMatch = leftTuple.removeMatch( handle );
if ( tupleMatch != null ) {
oldMatches.remove( handle );
objectMatches.remove( tupleMatch );
propagateRetractTuple( tupleMatch,
context,
workingMemory );
}
}
}
// TIRELLI's NOTE: the following is necessary because in case memory
// indexing is enabled, the loop over right objects may skip some of the
// previously matched objects
if(!oldMatches.isEmpty()) {
for(Iterator it = oldMatches.values().iterator(); it.hasNext(); ) {
final TupleMatch tupleMatch = (TupleMatch) it.next();
tupleMatch.getObjectMatches().remove( tupleMatch );
propagateRetractTuple( tupleMatch,
context,
workingMemory );
}
}
}
}
public void modifyObject(final DefaultFactHandle handle,
final PropagationContext context,
final ReteooWorkingMemory workingMemory) {
final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
// Remove and re-add the FactHandle from memory, ensures that its the latest on the list
final ObjectMatches objectMatches = memory.remove( workingMemory,
handle );
memory.add( workingMemory,
objectMatches );
TupleMatch tupleMatch = objectMatches.getFirstTupleMatch();
final BetaNodeBinder binder = getJoinNodeBinder();
for ( final Iterator it = memory.leftTupleIterator( workingMemory,
handle ); it.hasNext(); ) {
final ReteTuple leftTuple = (ReteTuple) it.next();
if ( tupleMatch != null && tupleMatch.getTuple() == leftTuple ) {
// has previous match so need to decide whether to continue
// modify or retract
// Need to get the "next" tuple match before messing with references
// using objectMatches.remove( tupleMatch ); for instance.
TupleMatch nextTupleMatch = (TupleMatch) tupleMatch.getNext();
if ( binder.isAllowed( handle,
leftTuple,
workingMemory ) ) {
propagateModifyTuple( tupleMatch,
context,
workingMemory );
} else {
leftTuple.removeMatch( handle );
objectMatches.remove( tupleMatch );
propagateRetractTuple( tupleMatch,
context,
workingMemory );
}
tupleMatch = nextTupleMatch;
} else {
// no previous join, so attempt join now
final TupleMatch newTupleMatch = attemptJoin( leftTuple,
handle,
objectMatches,
binder,
workingMemory );
if ( newTupleMatch != null ) {
propagateAssertTuple( new ReteTuple( leftTuple,
handle ),
newTupleMatch,
context,
workingMemory );
}
}
}
}
/* (non-Javadoc)
* @see org.drools.reteoo.BaseNode#updateNewNode(org.drools.reteoo.WorkingMemoryImpl, org.drools.spi.PropagationContext)
*/
public void updateNewNode(final ReteooWorkingMemory workingMemory,
final PropagationContext context) {
this.attachingNewNode = true;
final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
for ( final Iterator it = memory.getRightObjectMemory().iterator(); it.hasNext(); ) {
final ObjectMatches objectMatches = (ObjectMatches) it.next();
final DefaultFactHandle handle = objectMatches.getFactHandle();
for ( TupleMatch tupleMatch = objectMatches.getFirstTupleMatch(); tupleMatch != null; tupleMatch = (TupleMatch) tupleMatch.getNext() ) {
final ReteTuple tuple = new ReteTuple( tupleMatch.getTuple(),
handle );
final TupleSink sink = (TupleSink) this.tupleSinks.get( this.tupleSinks.size() - 1 );
if ( sink != null ) {
tupleMatch.addJoinedTuple( tuple );
sink.assertTuple( tuple,
context,
workingMemory );
} else {
throw new RuntimeException( "Possible BUG: trying to propagate an assert to a node that was the last added node" );
}
}
}
this.attachingNewNode = false;
}
/**
* @inheritDoc
*/
public List getPropagatedTuples(final ReteooWorkingMemory workingMemory,
final TupleSink sink) {
final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
final int index = this.getTupleSinks().indexOf( sink );
final List propagatedTuples = new ArrayList();
for ( final Iterator it = memory.getRightObjectMemory().iterator(); it.hasNext(); ) {
final ObjectMatches objectMatches = (ObjectMatches) it.next();
for ( TupleMatch tupleMatch = objectMatches.getFirstTupleMatch(); tupleMatch != null; tupleMatch = (TupleMatch) tupleMatch.getNext() ) {
propagatedTuples.add( tupleMatch.getJoinedTuples().get( index ) );
}
}
return propagatedTuples;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -