Author: mckierna
Date: Wed Apr 25 04:56:22 2007
New Revision: 532330

URL: http://svn.apache.org/viewvc?view=rev&rev=532330
Log:
See http://issues.apache.org/jira/browse/SANDESHA2-87

Modified:
    
webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/msgprocessors/AcknowledgementProcessor.java
    
webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/util/Range.java
    
webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/util/RangeString.java
    
webservices/sandesha/trunk/java/modules/tests/src/org/apache/sandesha2/utils/RangeStringTest.java

Modified: 
webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/msgprocessors/AcknowledgementProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/msgprocessors/AcknowledgementProcessor.java?view=diff&rev=532330&r1=532329&r2=532330
==============================================================================
--- 
webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/msgprocessors/AcknowledgementProcessor.java
 (original)
+++ 
webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/msgprocessors/AcknowledgementProcessor.java
 Wed Apr 25 04:56:22 2007
@@ -169,18 +169,22 @@
                        AcknowledgementRange ackRange = (AcknowledgementRange) 
ackRangeIterator.next();
                        long lower = ackRange.getLowerValue();
                        long upper = ackRange.getUpperValue();
-                       
-                       // Quick check to see if the whole range is covered
-                       if(!completedMessages.isRangeCompleted(new Range(lower, 
upper))) {
-                               // We have new info, so take each message one 
at a time
-                               for (long messageNo = lower; messageNo <= 
upper; messageNo++) {
-                                       
if(!completedMessages.isMessageNumberInRanges(messageNo)) {
-                                               // We have a new message to 
consider
+                       Range ackedRange = new Range(lower, upper);
+                       // Quick check to see if the whole range is already 
covered
+                       if(!completedMessages.isRangeCompleted(ackedRange)) {
+                               //we now know that this range is complete so we 
update it. This should aggregate the
+                               //ranges together and tell us which numbers are 
newly acked
+                               Range[] newRanges = 
completedMessages.addRange(ackedRange).getRanges();
+                               
+                               // We now take each newly acked message in turn 
and see if we need to update a sender bean
+                               for (int rangeIndex=0; rangeIndex < 
newRanges.length; rangeIndex++) {
+                                       //now work on each newly acked message 
in this range
+                                       for(long messageNo = 
newRanges[rangeIndex].lowerValue; messageNo<=newRanges[rangeIndex].upperValue; 
messageNo++){
+                                               
                                                numberOfNewMessagesAcked++;
-                                               completedMessages.addRange(new 
Range(messageNo, messageNo));
-
                                                SenderBean matcher = new 
SenderBean();
                                                
matcher.setSequenceID(outSequenceId);
+                                               
                                                
matcher.setMessageNumber(messageNo);
                                                
                                                SenderBean retransmitterBean = 
retransmitterMgr.findUnique(matcher);
@@ -212,9 +216,9 @@
                                                                
storageManager.removeMessageContext(storageKey);
                                                        }
                                                }
-                                       }
-                               }
-                       }
+                                       }//end for
+                               }//end for
+                       } //end while
                }
 
                // updating the last activated time of the sequence.

Modified: 
webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/util/Range.java
URL: 
http://svn.apache.org/viewvc/webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/util/Range.java?view=diff&rev=532330&r1=532329&r2=532330
==============================================================================
--- 
webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/util/Range.java
 (original)
+++ 
webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/util/Range.java
 Wed Apr 25 04:56:22 2007
@@ -33,8 +33,8 @@
 
        private static final Log log = LogFactory.getLog(Range.class);
        
-       long lowerValue;
-       long upperValue;
+       public long lowerValue;
+       public long upperValue;
        
        /**
         * Create a range for a single number

Modified: 
webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/util/RangeString.java
URL: 
http://svn.apache.org/viewvc/webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/util/RangeString.java?view=diff&rev=532330&r1=532329&r2=532330
==============================================================================
--- 
webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/util/RangeString.java
 (original)
+++ 
webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/util/RangeString.java
 Wed Apr 25 04:56:22 2007
@@ -76,17 +76,28 @@
        
        
        private Range getNextRangeBelow(long msgNumber){
-               //start at the specified index and work down the list of ranges
-               //util we find one
-               Iterator iterator = rangeMap.keySet().iterator();
                
                long cachedKey = -1;
-               while (iterator.hasNext()) {
-                       long key = ((Long)iterator.next()).longValue();
+               //see if we get lucky on a first hit
+               if(rangeMap.containsKey(new Long(msgNumber))){
+                       cachedKey = msgNumber;
+               }
+               else{
+                       //start at the specified index and work down the list 
of ranges
+                       //utill we find one
+                       Iterator iterator = getSortedKeyList().iterator();
                        
-                       if (key > cachedKey && key <= msgNumber) {
-                               cachedKey = key;
-                       }
+                       while (iterator.hasNext()) {
+                               long key = ((Long)iterator.next()).longValue();
+                               
+                               if (key > cachedKey && key <= msgNumber) {
+                                       cachedKey = key;
+                               }
+                               else if(key > msgNumber){
+                                       //we have gone beyond the required 
point, return with what we have
+                                       break;
+                               }
+                       }//end while                    
                }
                
                if (cachedKey != -1) {
@@ -100,34 +111,50 @@
        }
        
        /**
-        * If the passed in evelopeRange encompasses several ranges, these are 
-        * removed from the map 
+        * If the passed in evelopeRange encompasses several existing ranges 
between the start and end lookup points
+        * then these are removed from the map. All other points are added to 
the ongoing newRangesAdded RangeString 
         * @param currentRange
         * @return
         */
-       private void cleanUpRangesEnveloped(Range envelopeRange){
-               //see if there are any ranges that start at some point between 
-               //immediately above the start of the envelope range up to 
-               //its end 
-               long startOfRangeLookup = envelopeRange.lowerValue + 1;
-               long endOfRangeLookup = envelopeRange.upperValue;
-               // Iterator over the available ranges.
-               Iterator ranges = rangeMap.keySet().iterator();
-               while (ranges.hasNext()) {
-                       // Get the key
-                       long key = ((Long)ranges.next()).longValue();
-                       if (key >= startOfRangeLookup && key <= 
endOfRangeLookup) {
-                               Range removedRange = (Range)rangeMap.get(new 
Long(key));
-                               
-                               if(removedRange!=null && 
removedRange.upperValue>envelopeRange.upperValue){
-                                       //this range started in our envelope 
but stretched out beyond it so we
-                                       //can absorb its upper value
-                                       envelopeRange.upperValue = 
removedRange.upperValue;
+       private void cleanUpRangesEnvelopedAndDiscoverNewRangesAdded(Range 
envelopeRange, long startOfRangeLookup, long endOfRangeLookup, RangeString 
newRangesAdded){
+               
+               boolean checkRequired = !rangeMap.isEmpty();
+               if(checkRequired){
+                       for(long index = startOfRangeLookup; 
index<=endOfRangeLookup && index>0; index++ )
+                       {
+                               Long currentKey = new Long(index);
+                               Range existingRange = 
(Range)rangeMap.get(currentKey);
+                               if(existingRange!=null){
+                                       if( 
existingRange.upperValue>envelopeRange.upperValue){
+                                               //this range started in our 
envelope but stretched out beyond it so we
+                                               //can absorb its upper value
+                                               envelopeRange.upperValue = 
existingRange.upperValue;
+                                               //we are guaranteed that there 
are no other ranges present underneath this existing range
+                                               //as they would have been 
removed when it was first added. Therefore we can now jump our
+                                               //pointer so that the next 
range we look at is after the existing range
+                                               index = 
existingRange.upperValue; 
+                                       }
+                                       //Remove the current range from the 
HashMap.
+                                       rangeMap.remove(currentKey);
                                }
-                               // Remove the current range from the HashMap.
-                               ranges.remove();
-                       }
+                               else{
+                                       //This range has not been enveloped, 
and therefore this is a new Range added
+                                       if(newRangesAdded!=null){
+                                               newRangesAdded.addRange(new 
Range(index, index),
+                                                                               
                                                                false); //every 
range added will be new so there is no need for this
+                                       }
+                               }               
+                       }                       
+               }
+               else{
+                       //no check required - this must be a new range
+                       if(newRangesAdded!=null){
+                               newRangesAdded.addRange(new 
Range(startOfRangeLookup, endOfRangeLookup),
+                                                                               
                                                false); //every range added 
will be new so there is no need for this
+                       }                       
                }
+
+
        }
        
        /**
@@ -233,67 +260,119 @@
                return returnList;
        }
        
-       public void addRange(Range r){
+       /**
+        * Adds the Range into the existing RangeString
+        * Any existing Ranges that are encompassed in this new Range are 
removed.
+        * Any existing Ranges that are on either side of this Range (i.e. if 
this Range plugs a gap) are joined.
+        * The method returns a RangeString consisting of all the Ranges that 
were added that were not present previously
+        * i.e. all the new Ranges
+        * @param r
+        * @return
+        */
+       public RangeString addRange(Range r){
+               return addRange(r, true);
+       }
+
+       /**
+        * Adds the Range into the existing RangeString
+        * Any existing Ranges that are encompassed in this new Range are 
removed.
+        * Any existing Ranges that are on either side of this Range (i.e. if 
this Range plugs a gap) are joined.
+        * If newRangeProcessingRequired is set, the method returns a 
RangeString 
+        * consisting of all the Ranges that were added that were not present 
previously
+        * i.e. all the new Ranges
+        * @param r
+        * @return
+        */
+       private RangeString addRange(Range r, boolean 
newRangeProcessingRequired){
                
                Range finalRange = r; //we use this to keep track of the final 
range
                //as we might aggregate this new range with existing ranges
                
+               RangeString newRangesAdded = null;
+               if(newRangeProcessingRequired){
+                       newRangesAdded = new RangeString(); //keep track of the 
ranges that have been newly filled
+               }
+               
+               long envelopCheckingStartPoint = r.lowerValue; //used to help 
remove existing ranges that have been enveloped 
+               
                //first we try to aggregate existing ranges
                boolean rangeAdded = false;
                long indexKey = r.lowerValue;
                //see if there is a range below that we can extend up
                Range below = getNextRangeBelow(indexKey);
                if(below!=null){
-                       if(below.upperValue == (r.lowerValue -1)){
-                               //we can extend this range up
+                       if(below.equals(r)){
+                               //nothing to do
+                               return newRangesAdded;
+                       }
+                       if(below.upperValue<r.upperValue && below.upperValue >= 
(r.lowerValue -1)){
+                               long startingRange = below.upperValue + 1;
+                               //we can extend this lower range up
                                below.upperValue = r.upperValue;
+
                                //we do not quit yet, as maybe this has plugged 
a gap between
                                //an upper range. But we should mark the range 
as added.
                                rangeAdded = true;
                                finalRange = below; //as below now encompasses 
both ranges agrregated together 
+                               
+                               //this action might have caused some existing 
ranges to be enveloped
+                               //so cleanup anything existing between 
startingRange to r.upper
+                               //add every other number to the newRanges string
+                               
cleanUpRangesEnvelopedAndDiscoverNewRangesAdded(finalRange, startingRange, 
r.upperValue, newRangesAdded);
+                               envelopCheckingStartPoint = r.upperValue + 1;   
                                
+                               
                        }
-                       else if(below.upperValue > r.lowerValue){
-                               //the range below extends over this one - this 
range
+                       else if(below.upperValue >= r.upperValue){
+                               //the range below already covers this one - 
this range
                                //is already complete, so we do not need to add 
it at all.
-                               return;
+                               return newRangesAdded;
                        }
                }
                
                //see if we can extend another range down
-               Range above = getRangeImmediatelyAbove(r);
+               Range above = getRangeImmediatelyAbove(finalRange);
                if(above!=null){
-                       //we can extend this down
-                       //first remove it. Then we will either add it under its 
new key or 
-                       //keep it removed
-                       rangeMap.remove(new Long(above.lowerValue));
-                       above.lowerValue = r.lowerValue; //extend down
+                       //we can extend down. Since the lower ranges take 
precedence, the upper range will eventually be removed.
+                       //Before that we might add it under a new, lower key
+                       Long removeKey = new Long(above.lowerValue);
                        if(rangeAdded){
-                               //we extend down and up - join two ranges 
together
-                               //Sicne we have removed the upper, we simply do 
not add it again and set the
-                               //below range to encompass both of them
-                               below.upperValue = above.upperValue;
-                               //NOTE: finalRange has already been set when 
extending up
+                               //this means we extend up before. Now we are 
extending down to - join two ranges together.
+                               
+                               //Since we will later remove the upper, we 
simply set the below range to encompass both of them
+                               finalRange.upperValue = above.upperValue;
+                               //NOTE: finalRange is still what was 'below' 
when extending up
+                               
+                               //we need to check that there are no existing 
ranges from envelopCheckingStartPoint to above.lower
+                               //Any non-existing ranges get added to the 
newRangesAdded string
+                               
cleanUpRangesEnvelopedAndDiscoverNewRangesAdded(finalRange, 
envelopCheckingStartPoint, above.lowerValue, newRangesAdded);
                        }
                        else{
                                //we did not extend up but we can extend down. 
-                               //Add the upper range back under its new key
+                               //Add the upper range under its new key NOTE: 
we will remove it from under the old key later
                                rangeAdded = true;                              
+                               //we need to check that there are no existing 
ranges from r.lower to above.lower
+                               //Any non-existing ranges get added to the 
newRangesAdded string
+                               
cleanUpRangesEnvelopedAndDiscoverNewRangesAdded(above, r.lowerValue, 
r.upperValue, newRangesAdded);
+                               
+                               above.lowerValue = r.lowerValue; //extend down
                                rangeMap.put(new Long(above.lowerValue), above);
                                finalRange = above;
                        }
-
+                       //finally we do the remove of the above range under its 
old key
+                       rangeMap.remove(removeKey);
                }
                
                if(!rangeAdded){
+                       Long newIndex = new Long(r.lowerValue);
+                       //A simple add.
+                       //First cleanup and add from r.lower to r.upper
+                       cleanUpRangesEnvelopedAndDiscoverNewRangesAdded(r, 
r.lowerValue, r.upperValue, newRangesAdded);
                        //if we got here and did not add a range then we need 
to 
                        //genuinely add a new range object
-                       rangeMap.put(new Long(r.lowerValue), r);
+                       rangeMap.put(new Long(r.lowerValue), r);                
                
                }
                
-               //finally, we go through the new range we have added to make 
sure it
-               //does not now encompass any smaller ranges that were there 
before (but
-               //that could not be extended up or down)
-               cleanUpRangesEnveloped(finalRange);
+               return newRangesAdded;
                
        }
        

Modified: 
webservices/sandesha/trunk/java/modules/tests/src/org/apache/sandesha2/utils/RangeStringTest.java
URL: 
http://svn.apache.org/viewvc/webservices/sandesha/trunk/java/modules/tests/src/org/apache/sandesha2/utils/RangeStringTest.java?view=diff&rev=532330&r1=532329&r2=532330
==============================================================================
--- 
webservices/sandesha/trunk/java/modules/tests/src/org/apache/sandesha2/utils/RangeStringTest.java
 (original)
+++ 
webservices/sandesha/trunk/java/modules/tests/src/org/apache/sandesha2/utils/RangeStringTest.java
 Wed Apr 25 04:56:22 2007
@@ -70,19 +70,60 @@
                String msgs = "[1,1][10,10]";
                
                RangeString rString = new RangeString(msgs);
-               rString.addRange(new Range(2,2)); //msg 2 arrives
-               rString.addRange(new Range(8,9)); //msgs 8 and 9 arrive
-               rString.addRange(new Range(6,6)); // msg 6 arrives
-               rString.addRange(new Range(3,5)); //msgs 3,4 and 5 arrive
-               rString.addRange(new Range(3,4)); //msgs 3,4 are duplicated
-               rString.addRange(new Range(7,7)); //finally msg 7
+               
+               //msg 2 arrives
+               {
+                       Range ackedMsgRange = new Range(1,2);
+                       Range[] newRanges = 
rString.addRange(ackedMsgRange).getRanges();
+                       assertEquals(newRanges.length,1);
+                       assertEquals(newRanges[0],new Range(2,2));
+               }
+               
+               //msgs 8 and 9 arrive
+               {
+                       Range ackedMsgRange = new Range(8,9);
+                       Range[] newRanges = 
rString.addRange(ackedMsgRange).getRanges();
+                       assertEquals(newRanges.length,1);
+                       assertEquals(newRanges[0],ackedMsgRange);
+               }
+               
+               // msg 6 arrives
+               {
+                       Range ackedMsgRange = new Range(6,6);
+                       Range[] newRanges = 
rString.addRange(ackedMsgRange).getRanges();
+                       assertEquals(newRanges.length,1);
+                       assertEquals(newRanges[0],ackedMsgRange);
+               }
+               
+               //msgs 3,4 and 5 arrive
+               {
+                       Range ackedMsgRange = new Range(1,5);
+                       Range[] newRanges = 
rString.addRange(ackedMsgRange).getRanges();
+                       assertEquals(newRanges.length,1);
+                       assertEquals(newRanges[0],new Range(3,5));
+               }
+               
+               //msgs 3,4 are duplicated
+               {
+                       Range ackedMsgRange = new Range(3,4);
+                       Range[] newRanges = 
rString.addRange(ackedMsgRange).getRanges();
+                       assertEquals(newRanges.length,0); //no new information
+               }
+               
+               //finally msg 7
+               {
+                       Range ackedMsgRange = new Range(7,7);
+                       Range[] newRanges = 
rString.addRange(ackedMsgRange).getRanges();
+                       assertEquals(newRanges.length,1);
+                       assertEquals(newRanges[0],ackedMsgRange);
+               }
                
                //all msgs have now arrived
                assertEquals("[1,10]", rString.toString());
                
-               //all messages are duplicated
-               rString.addRange(new Range(1,10)); 
-               //cehck we handle duplicates
+               //all messages are duplicated - ensure this is detected
+               assertEquals(rString.addRange(new 
Range(1,10)).getRanges().length, 0);  
+               //check we handle duplicates i.e. the string is still correct
                assertEquals("[1,10]", rString.toString());
        }
        
@@ -101,4 +142,4 @@
        }
        
        
-}
\ No newline at end of file
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to