You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2012/03/20 23:39:21 UTC

[10/12] git commit: Fixed IpMap::mark

Fixed IpMap::mark


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

Branch: refs/heads/master
Commit: c12f06103773471396de6f62f8763e845253ed65
Parents: 7bbd783
Author: Alan M. Carroll <am...@network-geographics.com>
Authored: Sun Mar 18 21:40:36 2012 -0500
Committer: Alan M. Carroll <am...@network-geographics.com>
Committed: Sun Mar 18 21:40:36 2012 -0500

----------------------------------------------------------------------
 lib/ts/IpMap.cc |   47 +++++++++++++++++++++++------------------------
 1 files changed, 23 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c12f0610/lib/ts/IpMap.cc
----------------------------------------------------------------------
diff --git a/lib/ts/IpMap.cc b/lib/ts/IpMap.cc
index 3a72c78..34009f7 100644
--- a/lib/ts/IpMap.cc
+++ b/lib/ts/IpMap.cc
@@ -710,8 +710,10 @@ template < typename N > IpMapBase<N>&
 IpMapBase<N>::mark(ArgType min, ArgType max, void* payload) {
   N* n = this->lowerBound(min); // current node.
   N* x = 0; // New node, gets set if we re-use an existing one.
+  N* y = 0; // Temporary for removing and advancing.
 
-  // Several places it is handy to have max+1.
+  // Several places it is handy to have max+1. Must be careful
+  // about wrapping.
   Metric max_plus = N::deref(max);
   N::inc(max_plus);
 
@@ -731,11 +733,13 @@ IpMapBase<N>::mark(ArgType min, ArgType max, void* payload) {
       allocation by re-using an existing node as often as possible.
   */
   if (n) {
+    // Watch for wrap.
     Metric min_1 = N::deref(min);
     N::dec(min_1);
     if (n->_min == min) {
       // Could be another span further left which is adjacent.
-      // Coalesce if the data is the same.
+      // Coalesce if the data is the same. min_1 is OK because
+      // if there is a previous range, min is not zero.
       N* p = prev(n);
       if (p && p->_data == payload && p->_max == min_1) {
         x = p;
@@ -755,6 +759,7 @@ IpMapBase<N>::mark(ArgType min, ArgType max, void* payload) {
         return *this;
       }
     } else if (n->_data == payload && n->_max >= min_1) {
+      // min_1 is safe here because n->_min < min so min is not zero.
       x = n;
       // If the existing span covers the requested span, we're done.
       if (x->_max >= max) return *this;
@@ -772,6 +777,7 @@ IpMapBase<N>::mark(ArgType min, ArgType max, void* payload) {
     } else {
       // Existing span covers new span but with a different payload.
       // We split it, put the new span in between and we're done.
+      // max_plus is valid because n->_max > max.
       N* r;
       x = new N(min, max, payload);
       r = new N(max_plus, n->_max, n->_data);
@@ -786,9 +792,9 @@ IpMapBase<N>::mark(ArgType min, ArgType max, void* payload) {
       if (n) this->insertBefore(n, x);
       else this->append(x); // note that since n == 0 we'll just return.
     }
-  } else if (0 != (n = this->getHead()) &&
-    n->_data == payload &&
-    n->_min <= max_plus
+  } else if (0 != (n = this->getHead()) && // at least one node in tree.
+             n->_data == payload && // payload matches
+             (n->_max <= max || n->_min <= max_plus) // overlap or adj.
   ) {
     // Same payload with overlap, re-use.
     x = n;
@@ -803,26 +809,19 @@ IpMapBase<N>::mark(ArgType min, ArgType max, void* payload) {
   // At this point, @a x has the node for this span and all existing spans of
   // interest start at or past this span.
   while (n) {
-    if (n->_data == payload) {
-      if (n->_max <= max_plus) { // completely covered, drop span, continue
-        N* r = next(n);
-        this->remove(n);
-        n = r;
-      } else if (n->_min <= max_plus) {// skew overlap on the right.
-        x->setMax(n->_max);
-        this->remove(n);
-        break;
-      } else { // no overlap, done
-        break;
-      }
-    } else if (n->_max <= max) { // covered, discard and continue.
-      N* r = next(n);
-      this->remove(n);
-      n = r;
-    } else if (n->_min <= max) { // skew overlap, clip and done.
-      n->setMin(max_plus);
+    if (n->_max <= max) { // completely covered, drop span, continue
+      y = n;
+      n = next(n);
+      this->remove(y);
+    } else if (max_plus < n->_min) { // no overlap, done.
       break;
-    } else { // no overlap, done.
+    } else if (n->_data == payload) { // skew overlap same payload
+      x->setMax(n->_max);
+      y = n;
+      n = next(n);
+      this->remove(y);
+    } else if (n->_min <= max) { // skew overlap different payload
+      n->setMin(max_plus);
       break;
     }
   }