[jboss-svn-commits] JBL Code SVN: r31026 - in labs/jbossrules/branches/true_modify_20100104/drools-core/src: test/resources/org/drools/reteoo/test and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Jan 11 21:27:42 EST 2010


Author: tirelli
Date: 2010-01-11 21:27:42 -0500 (Mon, 11 Jan 2010)
New Revision: 31026

Modified:
   labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/CollectNode.java
   labs/jbossrules/branches/true_modify_20100104/drools-core/src/test/resources/org/drools/reteoo/test/CollectNodeAssertRetractTest.data
Log:
JBRULES-2340: implemeting proper collect node modify method

Modified: labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/CollectNode.java
===================================================================
--- labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/CollectNode.java	2010-01-11 21:58:14 UTC (rev 31025)
+++ labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/CollectNode.java	2010-01-12 02:27:42 UTC (rev 31026)
@@ -40,7 +40,6 @@
 import org.drools.spi.BetaNodeFieldConstraint;
 import org.drools.spi.PropagationContext;
 import org.drools.util.ArrayUtils;
-import org.drools.util.Entry;
 import org.drools.util.Iterator;
 import org.drools.util.ObjectHashMap.ObjectEntry;
 
@@ -179,19 +178,9 @@
             InternalFactHandle handle = rightTuple.getFactHandle();
             if ( this.constraints.isAllowedCachedLeft( memory.betaMemory.getContext(),
                                                        handle ) ) {
-                if ( this.unwrapRightObject ) {
-                    handle = ((LeftTuple) handle.getObject()).getLastHandle();
-                }
-                result.add( handle.getObject() );
-
-                // in sequential mode, we don't need to keep record of matched tuples
-                if ( this.tupleMemoryEnabled ) {
-                    // linking left and right by creating a new left tuple
-                    new LeftTuple( leftTuple,
-                                   rightTuple,
-                                   this,
-                                   this.tupleMemoryEnabled );
-                }
+                addMatch( leftTuple,
+                          rightTuple,
+                          colctx );
             }
         }
 
@@ -207,6 +196,9 @@
 
     /**
      * @inheritDoc
+     * 
+     * When retracting the left tuple, clear all matches from the right tuples
+     * and if previously propagated as an assert, propagate a retract
      */
     public void retractLeftTuple(final LeftTuple leftTuple,
                                  final PropagationContext context,
@@ -216,17 +208,9 @@
         memory.betaMemory.getLeftTupleMemory().remove( leftTuple );
         final CollectContext colctx = (CollectContext) memory.betaMemory.getCreatedHandles().remove( leftTuple );
 
-        LeftTuple child = getFirstMatch( leftTuple,
-                                         colctx );
+        removePreviousMatchesForLeftTuple( leftTuple,
+                                           colctx );
 
-        // Now, unlink the matches 
-        while ( child != null ) {
-            LeftTuple tmp = child.getLeftParentNext();
-            child.unlinkFromLeftParent();
-            child.unlinkFromRightParent();
-            child = tmp;
-        }
-
         if ( colctx.propagated ) {
             // if tuple was previously propagated, retract it
             this.sink.propagateRetractLeftTupleDestroyRightTuple( leftTuple,
@@ -241,7 +225,7 @@
      *  When a new object is asserted into a CollectNode, do this:
      *
      *  1. Select all matching tuples from left memory
-     *  2. For each matching tuple, call a modify tuple
+     *  2. For each matching tuple, add the new match and evaluate the result constraints
      *
      */
     public void assertObject(final InternalFactHandle factHandle,
@@ -271,21 +255,19 @@
                                                workingMemory,
                                                factHandle );
 
-        // need to clone the tuples to avoid concurrent modification exceptions
-        // @TODO: now that we use linked lists, can we avoid the cloning?
-        Entry[] tuples = memory.betaMemory.getLeftTupleMemory().toArray();
-        for ( int i = 0; i < tuples.length; i++ ) {
-            LeftTuple tuple = (LeftTuple) tuples[i];
+        for ( LeftTuple leftTuple = memory.betaMemory.getLeftTupleMemory().getFirst( rightTuple ); leftTuple != null; leftTuple = (LeftTuple) leftTuple.getNext() ) {
             if ( this.constraints.isAllowedCachedRight( memory.betaMemory.getContext(),
-                                                        tuple ) ) {
-                modifyTuple( ActivitySource.RIGHT,
-                             true,
-                             tuple,
-                             rightTuple,
-                             null,
-                             context,
-                             workingMemory,
-                             memory );
+                                                        leftTuple ) ) {
+                final CollectContext colctx = (CollectContext) memory.betaMemory.getCreatedHandles().get( leftTuple );
+                addMatch( leftTuple,
+                          rightTuple,
+                          colctx );
+                evaluateResultConstraints( ActivitySource.RIGHT,
+                                           leftTuple,
+                                           context,
+                                           workingMemory,
+                                           memory,
+                                           colctx );
             }
         }
 
@@ -314,18 +296,11 @@
                                     workingMemory );
         memory.betaMemory.getRightTupleMemory().remove( rightTuple );
 
-        for ( LeftTuple child = rightTuple.firstChild; child != null; ) {
-            LeftTuple tmp = child.getRightParentNext();
-            this.modifyTuple( ActivitySource.RIGHT,
-                              false,
-                              child.getParent(),
-                              rightTuple,
-                              child,
-                              context,
-                              workingMemory,
-                              memory );
-            child = tmp;
-        }
+        removePreviousMatchesForRightTuple( rightTuple,
+                                            context,
+                                            workingMemory,
+                                            memory,
+                                            rightTuple.firstChild );
 
         if ( context.getType() == PropagationContext.EXPIRATION ) {
             ((PropagationContextImpl) context).setFactHandle( origin );
@@ -336,76 +311,185 @@
     public void modifyLeftTuple(LeftTuple leftTuple,
                                 PropagationContext context,
                                 InternalWorkingMemory workingMemory) {
+        final CollectMemory memory = (CollectMemory) workingMemory.getNodeMemory( this );
+        final CollectContext colctx = (CollectContext) memory.betaMemory.getCreatedHandles().get( leftTuple );
 
+        // Add and remove to make sure we are in the right bucket and at the end
+        // this is needed to fix for indexing and deterministic iteration
+        memory.betaMemory.getLeftTupleMemory().remove( leftTuple );
+        memory.betaMemory.getLeftTupleMemory().add( leftTuple );
+
+        this.constraints.updateFromTuple( memory.betaMemory.getContext(),
+                                          workingMemory,
+                                          leftTuple );
+        LeftTuple childLeftTuple = leftTuple.firstChild;
+
+        RightTupleMemory rightMemory = memory.betaMemory.getRightTupleMemory();
+
+        RightTuple rightTuple = rightMemory.getFirst( leftTuple );
+
+        // first check our index (for indexed nodes only) hasn't changed and we are returning the same bucket
+        if ( childLeftTuple != null && rightMemory.isIndexed() && rightTuple != rightMemory.getFirst( childLeftTuple.getRightParent() ) ) {
+            // our index has changed, so delete all the previous matchings
+
+            removePreviousMatchesForLeftTuple( leftTuple,
+                                               colctx );
+
+            childLeftTuple = null; // null so the next check will attempt matches for new bucket
+        }
+
+        // we can't do anything if RightTupleMemory is empty
+        if ( rightTuple != null ) {
+            if ( childLeftTuple == null ) {
+                // either we are indexed and changed buckets or
+                // we had no children before, but there is a bucket to potentially match, so try as normal assert
+                for ( ; rightTuple != null; rightTuple = (RightTuple) rightTuple.getNext() ) {
+                    final InternalFactHandle handle = rightTuple.getFactHandle();
+                    if ( this.constraints.isAllowedCachedLeft( memory.betaMemory.getContext(),
+                                                               handle ) ) {
+                        // add a new match
+                        addMatch( leftTuple,
+                                  rightTuple,
+                                  colctx );
+
+                    }
+                }
+            } else {
+                // in the same bucket, so iterate and compare
+                for ( ; rightTuple != null; rightTuple = (RightTuple) rightTuple.getNext() ) {
+                    final InternalFactHandle handle = rightTuple.getFactHandle();
+
+                    if ( this.constraints.isAllowedCachedLeft( memory.betaMemory.getContext(),
+                                                               handle ) ) {
+                        if ( childLeftTuple != null && childLeftTuple.getRightParent() != rightTuple ) {
+                            // add a new match
+                            addMatch( leftTuple,
+                                      rightTuple,
+                                      colctx );
+                        } else {
+                            // we must re-add this to ensure deterministic iteration
+                            childLeftTuple.reAddLeft();
+                        }
+                    } else if ( childLeftTuple != null && childLeftTuple.getRightParent() == rightTuple ) {
+                        // remove the match
+                        removeMatch( rightTuple,
+                                     childLeftTuple,
+                                     colctx );
+                    }
+                    // else do nothing, was false before and false now.
+                }
+            }
+        }
+
+        this.constraints.resetTuple( memory.betaMemory.getContext() );
+
     }
 
     public void modifyRightTuple(RightTuple rightTuple,
                                  PropagationContext context,
                                  InternalWorkingMemory workingMemory) {
-        // TODO Auto-generated method stub
+        final CollectMemory memory = (CollectMemory) workingMemory.getNodeMemory( this );
 
-    }
+        // Add and remove to make sure we are in the right bucket and at the end
+        // this is needed to fix for indexing and deterministic iteration
+        memory.betaMemory.getRightTupleMemory().remove( rightTuple );
+        memory.betaMemory.getRightTupleMemory().add( rightTuple );
 
-    /**
-     * Modifies the results match for a tuple, retracting it and repropagating
-     * if constraints allow it
-     *
-     * @param leftTuple
-     * @param handle
-     * @param context
-     * @param workingMemory
-     */
-    @SuppressWarnings("unchecked")
-    public void modifyTuple(final ActivitySource activitySource,
-                            final boolean isAssert,
-                            final LeftTuple leftTuple,
-                            final RightTuple rightTuple,
-                            final LeftTuple match,
-                            final PropagationContext context,
-                            final InternalWorkingMemory workingMemory,
-                            final CollectMemory memory) {
+        // WTD here
+        //                if ( !behavior.assertRightTuple( memory.getBehaviorContext(),
+        //                                                 rightTuple,
+        //                                                 workingMemory ) ) {
+        //                    // destroy right tuple
+        //                    rightTuple.unlinkFromRightParent();
+        //                    return;
+        //                }
 
-        final CollectContext colctx = (CollectContext) memory.betaMemory.getCreatedHandles().get( leftTuple );
+        LeftTuple childLeftTuple = rightTuple.firstChild;
 
-        if ( isAssert ) {
-            // linking left and right by creating a new left tuple
-            new LeftTuple( leftTuple,
-                           rightTuple,
-                           this,
-                           this.tupleMemoryEnabled );
-        } else {
-            if ( match != null ) {
-                // removing link between left and right
-                match.unlinkFromLeftParent();
-                match.unlinkFromRightParent();
-            }
-        }
+        LeftTupleMemory leftMemory = memory.betaMemory.getLeftTupleMemory();
 
-        // if there is a subnetwork, we need to unwrap the object from inside the tuple
-        InternalFactHandle handle = rightTuple.getFactHandle();
-        if ( this.unwrapRightObject ) {
-            handle = ((LeftTuple) handle.getObject()).getLastHandle();
+        LeftTuple leftTuple = leftMemory.getFirst( rightTuple );
+
+        this.constraints.updateFromFactHandle( memory.betaMemory.getContext(),
+                                               workingMemory,
+                                               rightTuple.getFactHandle() );
+
+        // first check our index (for indexed nodes only) hasn't changed and we are returning the same bucket
+        if ( childLeftTuple != null && leftMemory.isIndexed() && leftTuple != leftMemory.getFirst( childLeftTuple.getLeftParent() ) ) {
+            // our index has changed, so delete all the previous matches
+            removePreviousMatchesForRightTuple( rightTuple,
+                                                context,
+                                                workingMemory,
+                                                memory,
+                                                childLeftTuple );
+            childLeftTuple = null; // null so the next check will attempt matches for new bucket
         }
 
-        if ( context.getType() == PropagationContext.ASSERTION ) {
-            ((Collection) colctx.resultTuple.getFactHandle().getObject()).add( handle.getObject() );
-        } else if ( context.getType() == PropagationContext.RETRACTION || context.getType() == PropagationContext.EXPIRATION ) {
-            ((Collection) colctx.resultTuple.getFactHandle().getObject()).remove( handle.getObject() );
-        } else if ( context.getType() == PropagationContext.MODIFICATION || context.getType() == PropagationContext.RULE_ADDITION || context.getType() == PropagationContext.RULE_REMOVAL ) {
-            // TODO: need to review this
-            if ( isAssert ) {
-                ((Collection) colctx.resultTuple.getFactHandle().getObject()).add( handle.getObject() );
+        // if LeftTupleMemory is empty, there are no matches to modify
+        if ( leftTuple != null ) {
+            if ( childLeftTuple == null ) {
+                // either we are indexed and changed buckets or
+                // we had no children before, but there is a bucket to potentially match, so try as normal assert
+                for ( ; leftTuple != null; leftTuple = (LeftTuple) leftTuple.getNext() ) {
+                    if ( this.constraints.isAllowedCachedRight( memory.betaMemory.getContext(),
+                                                                leftTuple ) ) {
+                        final CollectContext colctx = (CollectContext) memory.betaMemory.getCreatedHandles().get( leftTuple );
+                        // add a new match
+                        addMatch( leftTuple,
+                                  rightTuple,
+                                  colctx );
+                        evaluateResultConstraints( ActivitySource.RIGHT,
+                                                   leftTuple,
+                                                   context,
+                                                   workingMemory,
+                                                   memory,
+                                                   colctx );
+                    }
+                }
             } else {
-                ((Collection) colctx.resultTuple.getFactHandle().getObject()).remove( handle.getObject() );
+                // in the same bucket, so iterate and compare
+                for ( ; leftTuple != null; leftTuple = (LeftTuple) leftTuple.getNext() ) {
+                    if ( this.constraints.isAllowedCachedRight( memory.betaMemory.getContext(),
+                                                                leftTuple ) ) {
+                        if ( childLeftTuple != null && childLeftTuple.getLeftParent() != leftTuple ) {
+                            final CollectContext colctx = (CollectContext) memory.betaMemory.getCreatedHandles().get( leftTuple );
+                            // add a new match
+                            addMatch( leftTuple,
+                                      rightTuple,
+                                      colctx );
+                            evaluateResultConstraints( ActivitySource.RIGHT,
+                                                       leftTuple,
+                                                       context,
+                                                       workingMemory,
+                                                       memory,
+                                                       colctx );
+                        } else {
+                            // we must re-add this to ensure deterministic iteration
+                            childLeftTuple.reAddRight();
+                        }
+                    } else if ( childLeftTuple != null && childLeftTuple.getLeftParent() == leftTuple ) {
+
+                        LeftTuple temp = childLeftTuple.getRightParentNext();
+                        final CollectContext colctx = (CollectContext) memory.betaMemory.getCreatedHandles().get( leftTuple );
+                        // remove the match
+                        removeMatch( rightTuple,
+                                     childLeftTuple,
+                                     colctx );
+                        evaluateResultConstraints( ActivitySource.RIGHT,
+                                                   leftTuple,
+                                                   context,
+                                                   workingMemory,
+                                                   memory,
+                                                   colctx );
+
+                        childLeftTuple = temp;
+                    }
+                    // else do nothing, was false before and false now.
+                }
             }
         }
 
-        evaluateResultConstraints( activitySource,
-                                   leftTuple,
-                                   context,
-                                   workingMemory,
-                                   memory,
-                                   colctx );
+        this.constraints.resetFactHandle( memory.betaMemory.getContext() );
     }
 
     /**
@@ -521,12 +605,17 @@
         for ( LeftTuple leftTuple = (LeftTuple) tupleIter.next(); leftTuple != null; leftTuple = (LeftTuple) tupleIter.next() ) {
             CollectContext colctx = (CollectContext) memory.betaMemory.getCreatedHandles().get( leftTuple );
             if ( colctx.propagated ) {
+                // temporarily break the linked list to avoid wrong interactions
+                LeftTuple[] matchings = splitList( leftTuple,
+                                                   colctx );
                 sink.assertLeftTuple( new LeftTuple( leftTuple,
                                                      colctx.resultTuple,
                                                      sink,
                                                      this.tupleMemoryEnabled ),
                                       context,
                                       workingMemory );
+                restoreList( leftTuple,
+                             matchings );
             }
         }
     }
@@ -540,35 +629,10 @@
         }
     }
 
-    /* (non-Javadoc)
-     * @see org.drools.reteoo.BaseNode#hashCode()
-     */
-    public int hashCode() {
-        return this.leftInput.hashCode() ^ this.rightInput.hashCode() ^ this.collect.hashCode() ^ this.resultsBinder.hashCode() ^ ArrayUtils.hashCode( this.resultConstraints );
+    public short getType() {
+        return NodeTypeEnums.CollectNode;
     }
 
-    /* (non-Javadoc)
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    public boolean equals(final Object object) {
-        if ( this == object ) {
-            return true;
-        }
-
-        if ( object == null || !(object instanceof CollectNode) ) {
-            return false;
-        }
-
-        final CollectNode other = (CollectNode) object;
-
-        if ( this.getClass() != other.getClass() || (!this.leftInput.equals( other.leftInput )) || (!this.rightInput.equals( other.rightInput )) || (!this.constraints.equals( other.constraints )) ) {
-            return false;
-        }
-
-        return this.collect.equals( other.collect ) && resultsBinder.equals( other.resultsBinder ) && Arrays.equals( this.resultConstraints,
-                                                                                                                     other.resultConstraints );
-    }
-
     /**
      * Creates a BetaMemory for the BetaNode's memory.
      */
@@ -584,10 +648,95 @@
         return memory;
     }
 
-    public short getType() {
-        return NodeTypeEnums.CollectNode;
+    /**
+     * Adds a match between left and right tuple
+     * 
+     * @param leftTuple
+     * @param rightTuple
+     * @param colctx
+     */
+    @SuppressWarnings("unchecked")
+    private void addMatch(final LeftTuple leftTuple,
+                          final RightTuple rightTuple,
+                          final CollectContext colctx) {
+        InternalFactHandle handle = rightTuple.getFactHandle();
+        if ( this.unwrapRightObject ) {
+            handle = ((LeftTuple) handle.getObject()).getLastHandle();
+        }
+        ((Collection<Object>) colctx.resultTuple.getFactHandle().getObject()).add( handle.getObject() );
+
+        // in sequential mode, we don't need to keep record of matched tuples
+        if ( this.tupleMemoryEnabled ) {
+            // linking left and right by creating a new left tuple
+            new LeftTuple( leftTuple,
+                           rightTuple,
+                           this,
+                           this.tupleMemoryEnabled );
+        }
     }
 
+    /**
+     * Removes a match between left and right tuple
+     *
+     * @param rightTuple
+     * @param match
+     * @param result
+     */
+    @SuppressWarnings("unchecked")
+    public void removeMatch(final RightTuple rightTuple,
+                            final LeftTuple match,
+                            final CollectContext colctx) {
+        if ( match != null ) {
+            // removing link between left and right
+            match.unlinkFromLeftParent();
+            match.unlinkFromRightParent();
+        }
+
+        // if there is a subnetwork, we need to unwrap the object from inside the tuple
+        InternalFactHandle handle = rightTuple.getFactHandle();
+        if ( this.unwrapRightObject ) {
+            handle = ((LeftTuple) handle.getObject()).getLastHandle();
+        }
+
+        ((Collection<Object>) colctx.resultTuple.getFactHandle().getObject()).remove( handle.getObject() );
+    }
+
+    private void removePreviousMatchesForLeftTuple(final LeftTuple leftTuple,
+                                                   final CollectContext colctx) {
+        // It is cheaper to simply wipe out the matchings from the end of the list than
+        // going through element by element doing proper removal
+
+        // so we just split the list keeping the head 
+        LeftTuple[] matchings = splitList( leftTuple,
+                                           colctx );
+        for ( LeftTuple match = matchings[0]; match != null; match = match.getLeftParentNext() ) {
+            // no need to unlink from the left parent as the left parent is being wiped out
+            match.unlinkFromRightParent();
+        }
+    }
+
+    private void removePreviousMatchesForRightTuple(RightTuple rightTuple,
+                                                    PropagationContext context,
+                                                    InternalWorkingMemory workingMemory,
+                                                    final CollectMemory memory,
+                                                    LeftTuple firstChild) {
+        for ( LeftTuple match = firstChild; match != null; ) {
+            final LeftTuple tmp = match.getRightParentNext();
+            final LeftTuple parent = match.getLeftParent();
+            final CollectContext colctx = (CollectContext) memory.betaMemory.getCreatedHandles().get( parent );
+            removeMatch( rightTuple,
+                         match,
+                         colctx );
+            evaluateResultConstraints( ActivitySource.RIGHT,
+                                       parent,
+                                       context,
+                                       workingMemory,
+                                       memory,
+                                       colctx );
+            match = tmp;
+        }
+    }
+
     private LeftTuple[] splitList(final LeftTuple parent,
                                   final CollectContext colctx) {
         LeftTuple[] matchings = new LeftTuple[2];
@@ -603,6 +752,9 @@
                 parent.firstChild = null;
             }
             parent.lastChild = matchings[0].getLeftParentPrevious();
+            if( parent.lastChild != null ) {
+                parent.lastChild.setLeftParentNext( null );
+            }
         }
 
         return matchings;
@@ -621,6 +773,35 @@
         }
     }
 
+    /* (non-Javadoc)
+     * @see org.drools.reteoo.BaseNode#hashCode()
+     */
+    public int hashCode() {
+        return this.leftInput.hashCode() ^ this.rightInput.hashCode() ^ this.collect.hashCode() ^ this.resultsBinder.hashCode() ^ ArrayUtils.hashCode( this.resultConstraints );
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals(final Object object) {
+        if ( this == object ) {
+            return true;
+        }
+
+        if ( object == null || !(object instanceof CollectNode) ) {
+            return false;
+        }
+
+        final CollectNode other = (CollectNode) object;
+
+        if ( this.getClass() != other.getClass() || (!this.leftInput.equals( other.leftInput )) || (!this.rightInput.equals( other.rightInput )) || (!this.constraints.equals( other.constraints )) ) {
+            return false;
+        }
+
+        return this.collect.equals( other.collect ) && resultsBinder.equals( other.resultsBinder ) && Arrays.equals( this.resultConstraints,
+                                                                                                                     other.resultConstraints );
+    }
+
     public static class CollectMemory
         implements
         Externalizable {

Modified: labs/jbossrules/branches/true_modify_20100104/drools-core/src/test/resources/org/drools/reteoo/test/CollectNodeAssertRetractTest.data
===================================================================
--- labs/jbossrules/branches/true_modify_20100104/drools-core/src/test/resources/org/drools/reteoo/test/CollectNodeAssertRetractTest.data	2010-01-11 21:58:14 UTC (rev 31025)
+++ labs/jbossrules/branches/true_modify_20100104/drools-core/src/test/resources/org/drools/reteoo/test/CollectNodeAssertRetractTest.data	2010-01-12 02:27:42 UTC (rev 31026)
@@ -118,100 +118,3 @@
 col1
     leftMemory []  
     rightMemory []  
-
-/**    
- * assert two right and two left, with incremental last removal
- *
-assert
-    otnRight1 [h2, h3]
-    otnLeft1 [h0, h1]
-join1
-    leftMemory [[h0], [h1]]  
-    rightMemory [h2, h3]  
-join2
-    leftMemory [[h0, h2], [h0, h3],
-                [h1, h2], [h1, h3]]        
-retract
-    otnLeft1 [h1]
-join1
-    leftMemory [[h0]]
-    rightMemory [h2, h3]  
-join2
-    leftMemory [[h0, h2], [h0, h3]]               
-retract
-    otnRight1 [h3]	
-join1
-    leftMemory [[h0]]  
-    rightMemory [h2]  
-join2
-    leftMemory [[h0, h2]]   
-retract
-    otnLeft1 [h0] 
-    otnRight1 [h2] 
-join1
-    leftMemory []  
-    rightMemory []  
-join2
-    leftMemory []    
-
-/**   
- * assert three left and three right, middle two are removed, and then iterated in reverse order
- *
-assert
-    otnLeft1 [h0, h5, h2]
-    otnRight1 [h3, h4, h1]
-join1
-    leftMemory [[h0], [h5], [h2]]
-    rightMemory [h3, h4, h1]      
-join2
-    leftMemory [[h0, h3], [h5, h3], [h2, h3],
-                [h0, h4], [h5, h4], [h2, h4],
-                [h0, h1], [h5, h1], [h2, h1]] 
-    rightMemory []
-retract        
-    otnLeft1 [h5]
-join1
-    leftMemory [[h0], [h2]]
-    rightMemory [h3, h4, h1]      
-join2
-    leftMemory [[h0, h3], [h2, h3],
-                [h0, h4], [h2, h4],
-                [h0, h1], [h2, h1]] 
-    rightMemory []  
-retract        
-    otnRight1 [h4]  
-join1
-    leftMemory [[h0], [h2]]
-    rightMemory [h3, h1]      
-join2
-    leftMemory [[h0, h3], [h2, h3],
-                [h0, h1], [h2, h1]] 
-    rightMemory []   
-assert
-    otnLeft1 [h5]
-    otnRight1 [h4]  
-join1
-    leftMemory [[h0], [h2], [h5]]
-    rightMemory [h3, h1, h4]          
-join2
-    leftMemory [[h0, h3], [h2, h3],
-                [h0, h1], [h2, h1],                
-                [h5, h3], [h5, h1],
-                [h0, h4], [h2, h4], [h5, h4] ]
-retract        
-    otnRight1 [h4] 
-join1
-    leftMemory [[h0], [h2], [h5]]
-    rightMemory [h3, h1]          
-join2
-    leftMemory [[h0, h3], [h2, h3],
-                [h0, h1], [h2, h1],                
-                [h5, h3], [h5, h1] ]      
-retract        
-    otnLeft1 [h5]
-join1
-    leftMemory [[h0], [h2]]
-    rightMemory [h3, h1]          
-join2
-    leftMemory [[h0, h3], [h2, h3],
-                [h0, h1], [h2, h1]]              */               
\ No newline at end of file



More information about the jboss-svn-commits mailing list