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]