You are viewing a plain text version of this content. The canonical link for it is here.
Posted to sandesha-dev@ws.apache.org by mc...@apache.org on 2007/04/25 13:56:23 UTC

svn commit: r532330 - in /webservices/sandesha/trunk/java/modules: core/src/main/java/org/apache/sandesha2/msgprocessors/ core/src/main/java/org/apache/sandesha2/util/ tests/src/org/apache/sandesha2/utils/

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: sandesha-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: sandesha-dev-help@ws.apache.org