IpMap::fill fixed.

Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/7bbd7830
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/7bbd7830
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/7bbd7830

Branch: refs/heads/master
Commit: 7bbd7830d6b8c135c20d99549d5a1a9eabe927fa
Parents: c3673da
Author: Alan M. Carroll <[email protected]>
Authored: Fri Mar 16 22:48:26 2012 -0500
Committer: Alan M. Carroll <[email protected]>
Committed: Fri Mar 16 22:48:26 2012 -0500

----------------------------------------------------------------------
 lib/ts/IpMap.cc |   26 ++++++++++++++++++--------
 1 files changed, 18 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7bbd7830/lib/ts/IpMap.cc
----------------------------------------------------------------------
diff --git a/lib/ts/IpMap.cc b/lib/ts/IpMap.cc
index 41d79bd..3a72c78 100644
--- a/lib/ts/IpMap.cc
+++ b/lib/ts/IpMap.cc
@@ -624,6 +624,11 @@ IpMapBase<N>::fill(ArgType rmin, ArgType rmax, void* 
payload) {
 
   // Work through the rest of the nodes of interest.
   // Invariant: n->_min >= min
+
+  // Careful here -- because max_plus1 might wrap we need to use it only
+  // if we can certain it didn't. This is done by ordering the range
+  // tests so that when max_plus1 is used when we know there exists a
+  // larger value than max.
   Metric max_plus1 = max;
   N::inc(max_plus1);
   /* Notes:
@@ -633,25 +638,30 @@ IpMapBase<N>::fill(ArgType rmin, ArgType rmax, void* 
payload) {
   while (n) {
     if (n->_data == payload) {
       if (x) {
-        if (n->_min <= max_plus1) { // overlap so extend x and drop n.
-          x->setMax(n->_max);
+        if (n->_max <= max) {
+          // next range is covered, so we can remove and continue.
           this->remove(n);
-          if (x->_max >= max) return *this; // all done.
           n = next(x);
+        } else if (n->_min <= max_plus1) {
+          // Overlap or adjacent with larger max - absorb and finish.
+          x->setMax(n->_max);
+          this->remove(n);
+          return *this;
         } else {
           // have the space to finish off the range.
           x->setMax(max);
           return *this;
         }
       } else { // not carrying a span.
-        if (n->_min <= max_plus1) { // overlap, extend and continue.
+        if (n->_max <= max) { // next range is covered - use it.
           x = n;
-          x->setMin(min);
-          if (n->_max >= max) return *this; // extend n covers range.
+          n->setMin(min);
           n = next(n);
+        } else if (n->_min <= max_plus1) {
+          n->setMin(min);
+          return *this;
         } else { // no overlap, space to complete range.
-          N* y = new N(min, max, payload);
-          this->insertBefore(n, y);
+          this->insertBefore(n, new N(min, max, payload));
           return *this;
         }
       }

Reply via email to