00001 # include "IpMap.h"
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 namespace ts { namespace detail {
00049 
00050 
00051 
00052 inline int cmp(sockaddr_in6 const& lhs, sockaddr_in6 const& rhs) {
00053   return memcmp(lhs.sin6_addr.s6_addr, rhs.sin6_addr.s6_addr, TS_IP6_SIZE);
00054 }
00055 
00056 
00057 inline bool operator<(sockaddr_in6 const& lhs, sockaddr_in6 const& rhs) {
00058   return ts::detail::cmp(lhs, rhs) < 0;
00059 }
00060 inline bool operator<(sockaddr_in6 const* lhs, sockaddr_in6 const& rhs) {
00061   return ts::detail::cmp(*lhs, rhs) < 0;
00062 }
00063 
00064 inline bool operator<(sockaddr_in6 const& lhs, sockaddr_in6 const* rhs) {
00065   return ts::detail::cmp(lhs, *rhs) < 0;
00066 }
00067 
00068 inline bool operator==(sockaddr_in6 const& lhs, sockaddr_in6 const* rhs) {
00069   return ts::detail::cmp(lhs, *rhs) == 0;
00070 }
00071 
00072 inline bool operator==(sockaddr_in6 const* lhs, sockaddr_in6 const& rhs) {
00073   return ts::detail::cmp(*lhs, rhs) == 0;
00074 }
00075 
00076 inline bool operator==(sockaddr_in6 const& lhs, sockaddr_in6 const& rhs) {
00077   return ts::detail::cmp(lhs, rhs) == 0;
00078 }
00079 
00080 inline bool operator<=(sockaddr_in6 const& lhs, sockaddr_in6 const* rhs) {
00081   return ts::detail::cmp(lhs, *rhs) <= 0;
00082 }
00083 
00084 inline bool operator<=(sockaddr_in6 const& lhs, sockaddr_in6 const& rhs) {
00085   return ts::detail::cmp(lhs, rhs) <= 0;
00086 }
00087 
00088 inline bool operator>=(sockaddr_in6 const& lhs, sockaddr_in6 const& rhs) {
00089   return ts::detail::cmp(lhs, rhs) >= 0;
00090 }
00091 
00092 inline bool operator>=(sockaddr_in6 const& lhs, sockaddr_in6 const* rhs) {
00093   return ts::detail::cmp(lhs, *rhs) >= 0;
00094 }
00095 
00096 inline bool operator>(sockaddr_in6 const& lhs, sockaddr_in6 const* rhs) {
00097   return ts::detail::cmp(lhs, *rhs) > 0;
00098 }
00099 
00100 
00101 
00102 
00103 inline bool operator == ( RBNode* n, RBNode::Color c ) {
00104   return c == ( n ? n->getColor() : RBNode::BLACK);
00105 }
00106 
00107 
00108 
00109 inline bool operator == ( RBNode::Color c, RBNode* n ) {
00110   return n == c;
00111 }
00112 
00113 inline RBNode*
00114 RBNode::getChild(Direction d) const {
00115   return d == RIGHT ? _right
00116     : d == LEFT ? _left
00117     : 0
00118     ;
00119 }
00120 
00121 RBNode*
00122 RBNode::rotate(Direction d) {
00123   self* parent = _parent; 
00124   Direction child_dir = _parent ? _parent->getChildDirection(this) : NONE;
00125   Direction other_dir = this->flip(d);
00126   self* child = this;
00127 
00128   if (d != NONE && this->getChild(other_dir)) {
00129     child = this->getChild(other_dir);
00130     this->clearChild(other_dir);
00131     this->setChild(child->getChild(d), other_dir);
00132     child->clearChild(d);
00133     child->setChild(this, d);
00134     child->structureFixup();
00135     this->structureFixup();
00136     if (parent) {
00137       parent->clearChild(child_dir);
00138       parent->setChild(child, child_dir);
00139     } else {
00140       child->_parent = 0;
00141     }
00142   }
00143   return child;
00144 }
00145 
00146 RBNode*
00147 RBNode::setChild(self* n, Direction d) {
00148   if (n) n->_parent = this;
00149   if (d == RIGHT) _right = n;
00150   else if (d == LEFT) _left = n;
00151   return n;
00152 }
00153 
00154 
00155 RBNode*
00156 RBNode::rippleStructureFixup() {
00157   self* root = this; 
00158   self* p = this;
00159   while (p) {
00160     p->structureFixup();
00161     root = p;
00162     p = root->_parent;
00163   }
00164   return root;
00165 }
00166 
00167 void
00168 RBNode::replaceWith(self* n) {
00169   n->_color = _color;
00170   if (_parent) {
00171     Direction d = _parent->getChildDirection(this);
00172     _parent->setChild(0, d);
00173     if (_parent != n) _parent->setChild(n, d);
00174   } else {
00175     n->_parent = 0;
00176   }
00177   n->_left = n->_right = 0;
00178   if (_left && _left != n) n->setChild(_left, LEFT);
00179   if (_right && _right != n) n->setChild(_right, RIGHT);
00180   _left = _right = 0;
00181 }
00182 
00183 
00184 RBNode*
00185 RBNode::rebalanceAfterInsert() {
00186   self* x(this); 
00187 
00188   while (x && x->_parent == RED) {
00189     Direction child_dir = NONE;
00190         
00191     if (x->_parent->_parent)
00192       child_dir = x->_parent->_parent->getChildDirection(x->_parent);
00193     else
00194       break;
00195     Direction other_dir(flip(child_dir));
00196         
00197     self* y = x->_parent->_parent->getChild(other_dir);
00198     if (y == RED) {
00199       x->_parent->_color = BLACK;
00200       y->_color = BLACK;
00201       x = x->_parent->_parent;
00202       x->_color = RED;
00203     } else {
00204       if (x->_parent->getChild(other_dir) == x) {
00205         x = x->_parent;
00206         x->rotate(child_dir);
00207       }
00208       
00209       x->_parent->_color = BLACK;
00210       x->_parent->_parent->_color = RED;
00211       x->_parent->_parent->rotate(other_dir);
00212     }
00213   }
00214     
00215   
00216   
00217   
00218   self* root = this->rippleStructureFixup();
00219   root->_color = BLACK;
00220 
00221   return root;
00222 }
00223 
00224 
00225 
00226 RBNode*
00227 RBNode::remove() {
00228   self* root = 0; 
00229 
00230   
00231 
00232 
00233 
00234   if (!_parent && !(_left && _right)) {
00235     if (_left) {
00236       _left->_parent = 0;
00237       root = _left;
00238       root->_color = BLACK;
00239     } else if (_right) {
00240       _right->_parent = 0;
00241       root = _right;
00242       root->_color = BLACK;
00243     } 
00244     return root;
00245   }
00246 
00247   
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258   self* remove_node(_left && _right ? _next : this);
00259 
00260   
00261   
00262   Color remove_color = remove_node->_color;
00263   
00264   Direction d(NONE);
00265 
00266   
00267   
00268   
00269   
00270   self* splice_node(remove_node->_left
00271     ? remove_node->_left
00272     : remove_node->_right
00273   );
00274 
00275   if (splice_node) {
00276     
00277     
00278     remove_color = splice_node->_color;
00279     remove_node->replaceWith(splice_node);
00280   } else {
00281     
00282     
00283     
00284     splice_node = remove_node->_parent;
00285     
00286     d = splice_node->getChildDirection(remove_node);
00287     splice_node->setChild(0, d);
00288   }
00289 
00290   
00291   
00292   
00293   if (remove_node != this) {
00294     
00295     if (splice_node == this) splice_node = remove_node;
00296     this->replaceWith(remove_node);
00297   }
00298 
00299   root = splice_node->rebalanceAfterRemove(remove_color, d);
00300   root->_color = BLACK;
00301   return root;
00302 }
00303 
00304 
00305 
00306 
00307 
00308 
00309 RBNode*
00310 RBNode::rebalanceAfterRemove(
00311   Color c, 
00312   Direction d 
00313 ) {
00314   self* root;
00315 
00316   if (BLACK == c) { 
00317     self* n = this;
00318     self* parent = n->_parent;
00319 
00320     
00321     
00322     if (NONE != d) {
00323       parent = n;
00324       n = 0;
00325     }
00326 
00327     while (parent) { 
00328       
00329       if (n == RED) {
00330         n->_color = BLACK;
00331         break;
00332       } else {
00333         
00334         
00335         
00336         Direction near(LEFT), far(RIGHT);
00337         if (
00338           (NONE == d && parent->getChildDirection(n) == RIGHT)
00339           || RIGHT == d
00340         ) {
00341           near = RIGHT;
00342           far = LEFT;
00343         }
00344 
00345         self* w = parent->getChild(far); 
00346 
00347         if (w->_color == RED) {
00348           w->_color = BLACK;
00349           parent->_color = RED;
00350           parent->rotate(near);
00351           w = parent->getChild(far);
00352         }
00353 
00354         self* wfc = w->getChild(far);
00355         if (w->getChild(near) == BLACK && wfc == BLACK) {
00356           w->_color = RED;
00357           n = parent;
00358           parent = n->_parent;
00359           d = NONE; 
00360         } else {
00361           if (wfc->_color == BLACK) {
00362             w->getChild(near)->_color = BLACK;
00363             w->_color = RED;
00364             w->rotate(far);
00365             w = parent->getChild(far);
00366             wfc = w->getChild(far); 
00367           }
00368           w->_color = parent->_color;
00369           parent->_color = BLACK;
00370           wfc->_color = BLACK;
00371           parent->rotate(near);
00372           break;
00373         }
00374       }
00375     }
00376   }
00377   root = this->rippleStructureFixup();
00378   return root;
00379 }
00380 
00381 
00382 
00383 
00384 
00385 int
00386 RBNode::validate() {
00387 # if 0
00388   int black_ht = 0;
00389   int black_ht1, black_ht2;
00390 
00391   if (_left) {
00392     black_ht1 = _left->validate();
00393   }
00394   else
00395     black_ht1 = 1;
00396 
00397   if (black_ht1 > 0 && _right)
00398     black_ht2 = _right->validate();
00399   else
00400     black_ht2 = 1;
00401 
00402   if (black_ht1 == black_ht2) {
00403     black_ht = black_ht1;
00404     if (this->_color == BLACK)
00405       ++black_ht;
00406     else {      
00407       if (_left == RED)
00408         black_ht = 0;
00409       else if (_right == RED)
00410         black_ht = 0;
00411       if (black_ht == 0)
00412         std::cout << "Red-red child\n";
00413     }
00414   } else {
00415     std::cout << "Height mismatch " << black_ht1 << " " << black_ht2 << "\n";
00416   }
00417   if (black_ht > 0 && !this->structureValidate())
00418     black_ht = 0;
00419 
00420   return black_ht;
00421 # else
00422   return 0;
00423 # endif
00424 }
00425 
00426 
00427 
00428 
00429 
00430 
00431 
00432 template <
00433   typename N 
00434 > struct IpMapBase {
00435   friend class ::IpMap;
00436   
00437   typedef IpMapBase self; 
00438   typedef typename N::ArgType ArgType; 
00439   typedef typename N::Metric Metric;   
00440 
00441   IpMapBase() : _root(0) {}
00442   ~IpMapBase() { this->clear(); }
00443 
00444 
00445 
00446 
00447 
00448   self& mark(
00449     ArgType min, 
00450     ArgType max, 
00451     void* data = 0     
00452   );
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460   self& unmark(
00461     ArgType min,
00462     ArgType max
00463   );
00464 
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475   self& fill(
00476     ArgType min,
00477     ArgType max,
00478     void* data = 0
00479   );
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487   bool contains(
00488     ArgType target, 
00489     void **ptr = 0 
00490   ) const;
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499   self& clear();
00500 
00501 
00502 
00503 
00504 
00505   N* lowerBound(ArgType target);
00506 
00507 
00508 
00509 
00510 
00511   void insertAfter(
00512     N* spot, 
00513     N* n 
00514   );
00515 
00516 
00517 
00518 
00519   void insertBefore(
00520     N* spot, 
00521     N* n 
00522   );
00523 
00524   void prepend(
00525     N* n
00526   );
00527 
00528   void append(
00529     N* n
00530   );
00531 
00532   void remove(
00533     N* n 
00534   );
00535 
00536 
00537 
00538 
00539   void validate();
00540 
00541 
00542   size_t getCount() const;
00543 
00544 
00545 
00546   self& print();
00547   
00548   
00549   N* prev(RBNode* n) const { return static_cast<N*>(n->_prev); }
00550   N* next(RBNode* n) const { return static_cast<N*>(n->_next); }
00551   N* parent(RBNode* n) const { return static_cast<N*>(n->_parent); }
00552   N* left(RBNode* n) const { return static_cast<N*>(n->_left); }
00553   N* right(RBNode* n) const { return static_cast<N*>(n->_right); }
00554   N* getHead() { return static_cast<N*>(_list.getHead()); }
00555   N* getTail() { return static_cast<N*>(_list.getTail()); }
00556 
00557   N* _root; 
00558 
00559 
00560 
00561   typedef IntrusiveDList<RBNode, &RBNode::_next, &RBNode::_prev> NodeList;
00562 
00563 
00564   NodeList _list;
00565 };
00566 
00567 template < typename N > N*
00568 IpMapBase<N>::lowerBound(ArgType target) {
00569   N* n = _root; 
00570   N* zret = 0; 
00571   while (n) {
00572     if (target < n->_min) n = left(n);
00573     else {
00574       zret = n; 
00575       if (n->_max < target) n = right(n);
00576       else break;
00577     }
00578   }
00579   return zret;
00580 }
00581 
00582 template < typename N > IpMapBase<N>&
00583 IpMapBase<N>::clear() {
00584   
00585   N* n = static_cast<N*>(_list.getHead());
00586   while (n) {
00587     N* x = n;
00588     n = next(n);
00589     delete x;
00590   }
00591   _list.clear();
00592   _root = 0;
00593   return *this;
00594 }
00595 
00596 template < typename N > IpMapBase<N>&
00597 IpMapBase<N>::fill(ArgType rmin, ArgType rmax, void* payload) {
00598   
00599   N* n = this->lowerBound(rmin);
00600   N* x = 0; 
00601   
00602   Metric min = N::deref(rmin);
00603   Metric max = N::deref(rmax);
00604 
00605   
00606   
00607   if (n) {
00608     if (n->_min < min) {
00609       Metric min_1 = min;
00610       N::dec(min_1);  
00611       if (n->_max < min_1) { 
00612         n = next(n);
00613       } else if (n->_max >= max) { 
00614         return *this;
00615       } else if (n->_data != payload) { 
00616         min = n->_max;
00617         N::inc(min);
00618         n = next(n);
00619       } else { 
00620         x = n;
00621         n = next(n);
00622       }
00623     }
00624   } else {
00625     n = this->getHead();
00626   }
00627 
00628   
00629   
00630 
00631   
00632   
00633   
00634   
00635   Metric max_plus1 = max;
00636   N::inc(max_plus1);
00637   
00638 
00639 
00640 
00641   while (n) {
00642     if (n->_data == payload) {
00643       if (x) {
00644         if (n->_max <= max) {
00645           
00646           this->remove(n);
00647           n = next(x);
00648         } else if (n->_min <= max_plus1) {
00649           
00650           x->setMax(n->_max);
00651           this->remove(n);
00652           return *this;
00653         } else {
00654           
00655           x->setMax(max);
00656           return *this;
00657         }
00658       } else { 
00659         if (n->_max <= max) { 
00660           x = n;
00661           x->setMin(min);
00662           n = next(n);
00663         } else if (n->_min <= max_plus1) {
00664           n->setMin(min);
00665           return *this;
00666         } else { 
00667           this->insertBefore(n, new N(min, max, payload));
00668           return *this;
00669         }
00670       }
00671     } else { 
00672       if (x) {
00673         if (max < n->_min) { 
00674           x->setMax(max);
00675           return *this;
00676         } else if (max <= n->_max) { 
00677           x->setMaxMinusOne(n->_min);
00678           return *this;
00679         } else { 
00680           x->setMaxMinusOne(n->_min);
00681           x = 0;
00682           min = n->_max;
00683           N::inc(min); 
00684           n = next(n);
00685         }
00686       } else { 
00687         if (max < n->_min) { 
00688           this->insertBefore(n, new N(min, max, payload));
00689           return *this;
00690         } else {
00691           if (min < n->_min) { 
00692             N* y = new N(min, n->_min, payload);
00693             y->decrementMax();
00694             this->insertBefore(n, y);
00695           }
00696           if (max <= n->_max) 
00697             return *this;
00698           min = n->_max;
00699           N::inc(min);
00700           n = next(n);
00701         }
00702       }
00703     }
00704   }
00705   
00706   if (x) {
00707     x->setMax(max);
00708   } else {
00709     this->append(new N(min, max, payload));
00710   }
00711   return *this;
00712 }
00713 
00714 template < typename N > IpMapBase<N>&
00715 IpMapBase<N>::mark(ArgType min, ArgType max, void* payload) {
00716   N* n = this->lowerBound(min); 
00717   N* x = 0; 
00718   N* y = 0; 
00719 
00720   
00721   
00722   Metric max_plus = N::deref(max);
00723   N::inc(max_plus);
00724 
00725   
00726 
00727 
00728 
00729 
00730 
00731 
00732 
00733 
00734 
00735 
00736 
00737   
00738 
00739 
00740   if (n) {
00741     
00742     Metric min_1 = N::deref(min);
00743     N::dec(min_1);
00744     if (n->_min == min) {
00745       
00746       
00747       
00748       N* p = prev(n);
00749       if (p && p->_data == payload && p->_max == min_1) {
00750         x = p;
00751         n = x; 
00752         x->setMax(max);
00753       } else if (n->_max <= max) {
00754         
00755         x = n;
00756         x->setMax(max).setData(payload);
00757       } else if (n->_data == payload) {
00758         return *this; 
00759       } else {
00760         
00761         x = new N(min, max, payload); 
00762         n->setMin(max_plus); 
00763         this->insertBefore(n, x);
00764         return *this;
00765       }
00766     } else if (n->_data == payload && n->_max >= min_1) {
00767       
00768       x = n;
00769       
00770       if (x->_max >= max) return *this;
00771       x->setMax(max);
00772     } else if (n->_max <= max) {
00773       
00774       
00775       if (n->_max >= min) n->setMax(min_1);
00776       else if (next(n) && n->_max <= max) {
00777         
00778         x = next(n);
00779         x->setMin(min).setMax(max).setData(payload);
00780         n = x; 
00781       }
00782     } else {
00783       
00784       
00785       
00786       N* r;
00787       x = new N(min, max, payload);
00788       r = new N(max_plus, n->_max, n->_data);
00789       n->setMax(min_1);
00790       this->insertAfter(n, x);
00791       this->insertAfter(x, r);
00792       return *this; 
00793     }
00794     n = next(n); 
00795     if (!x) {
00796       x = new N(min, max, payload);
00797       if (n) this->insertBefore(n, x);
00798       else this->append(x); 
00799     }
00800   } else if (0 != (n = this->getHead()) && 
00801              n->_data == payload && 
00802              (n->_max <= max || n->_min <= max_plus) 
00803   ) {
00804     
00805     x = n;
00806     n = next(n);
00807     x->setMin(min);
00808     if (x->_max < max) x->setMax(max);
00809   } else {
00810     x = new N(min, max, payload);
00811     this->prepend(x);
00812   }
00813 
00814   
00815   
00816   while (n) {
00817     if (n->_max <= max) { 
00818       y = n;
00819       n = next(n);
00820       this->remove(y);
00821     } else if (max_plus < n->_min) { 
00822       break;
00823     } else if (n->_data == payload) { 
00824       x->setMax(n->_max);
00825       y = n;
00826       n = next(n);
00827       this->remove(y);
00828     } else if (n->_min <= max) { 
00829       n->setMin(max_plus);
00830       break;
00831     }
00832   }
00833 
00834   return *this;
00835 }
00836 
00837 template <typename N> IpMapBase<N>&
00838 IpMapBase<N>::unmark(ArgType min, ArgType max) {
00839   N* n = this->lowerBound(min);
00840   N* x; 
00841 
00842   
00843   if (n && n->_min < min) {
00844     if (n->_max >= min) { 
00845       if (n->_max > max) {
00846         
00847         x = new N(max, N::argue(n->_max), n->_data);
00848         x->incrementMin();
00849         n->setMaxMinusOne(N::deref(min));
00850         this->insertAfter(n, x);
00851         return *this; 
00852       } else {
00853         n->setMaxMinusOne(N::deref(min)); 
00854       }
00855     } 
00856     n = next(n);
00857   }
00858   
00859   while (n) {
00860     x = n;
00861     n = next(n);
00862     if (x->_max <= max) {
00863       this->remove(x);
00864     } else {
00865       if (x->_min <= max) { 
00866         x->setMinPlusOne(N::deref(max));
00867       }
00868       break;
00869     }
00870   }
00871   return *this;
00872 }
00873 
00874 template <typename N> void
00875 IpMapBase<N>::insertAfter(N* spot, N* n) {
00876   N* c = right(spot);
00877   if (!c) spot->setChild(n, N::RIGHT);
00878   else spot->_next->setChild(n, N::LEFT);
00879 
00880   _list.insertAfter(spot, n);
00881   _root = static_cast<N*>(n->rebalanceAfterInsert());
00882 }
00883 
00884 template <typename N> void
00885 IpMapBase<N>::insertBefore(N* spot, N* n) {
00886   N* c = left(spot);
00887   if (!c) spot->setChild(n, N::LEFT);
00888   else spot->_prev->setChild(n, N::RIGHT);
00889 
00890   _list.insertBefore(spot, n);
00891   _root = static_cast<N*>(n->rebalanceAfterInsert());
00892 }
00893 
00894 template <typename N> void
00895 IpMapBase<N>::prepend(N* n) {
00896   if (!_root) _root = n;
00897   else _root = static_cast<N*>(_list.getHead()->setChild(n, N::LEFT)->rebalanceAfterInsert());
00898   _list.prepend(n);
00899 }
00900 
00901 template <typename N> void
00902 IpMapBase<N>::append(N* n) {
00903   if (!_root) _root = n;
00904   else _root = static_cast<N*>(_list.getTail()->setChild(n, N::RIGHT)->rebalanceAfterInsert());
00905   _list.append(n);
00906 }
00907 
00908 template <typename N> void
00909 IpMapBase<N>::remove(N* n) {
00910   _root = static_cast<N*>(n->remove());
00911   _list.take(n);
00912   delete n;
00913 }
00914 
00915 template <typename N> bool
00916 IpMapBase<N>::contains(ArgType x, void** ptr) const {
00917   bool zret = false;
00918   N* n = _root; 
00919   while (n) {
00920     if (x < n->_min) n = left(n);
00921     else if (n->_max < x) n = right(n);
00922     else {
00923       if (ptr) *ptr = n->_data;
00924       zret = true;
00925       break;
00926     }
00927   }
00928   return zret;
00929 }
00930 
00931 template < typename N > size_t IpMapBase<N>::getCount() const { return _list.getCount(); }
00932 
00933 template <typename N> void
00934 IpMapBase<N>::validate() {
00935 # if 0
00936   if (_root) _root->validate();
00937   for ( Node* n = _list.getHead() ; n ; n = n->_next ) {
00938     Node* x;
00939     if (0 != (x = n->_next)) {
00940       if (x->_prev != n)
00941         std::cout << "Broken list" << std::endl;
00942       if (n->_max >= x->_min)
00943         std::cout << "Out of order - " << n->_max << " > " << x->_min << std::endl;
00944       if (n->_parent == n || n->_left == n || n->_right == n)
00945         std::cout << "Looped node" << std::endl;
00946     }
00947   }
00948 # endif
00949 }
00950 
00951 template <typename N> IpMapBase<N>&
00952 IpMapBase<N>::print() {
00953 # if 0
00954   for ( Node* n = _list.getHead() ; n ; n = n->_next ) {
00955     std::cout
00956       << n << ": " << n->_min << '-' << n->_max << " [" << n->_data << "] "
00957       << (n->_color == Node::BLACK ? "Black " : "Red   ") << "P=" << n->_parent << " L=" << n->_left << " R=" << n->_right
00958       << std::endl;
00959   }
00960 # endif
00961   return *this;
00962 }
00963 
00964 
00965 typedef Interval<in_addr_t, in_addr_t> Ip4Span;
00966 
00967 
00968 
00969 
00970 
00971 
00972 class Ip4Node : public IpMap::Node, protected Ip4Span {
00973   friend struct IpMapBase<Ip4Node>;
00974 public:
00975   typedef Ip4Node self; 
00976 
00977 
00978   Ip4Node(
00979     ArgType min, 
00980     ArgType max, 
00981     void* data 
00982   ) : Node(data), Ip4Span(min, max) {
00983     ats_ip4_set(ats_ip_sa_cast(&_sa._min), htonl(min));
00984     ats_ip4_set(ats_ip_sa_cast(&_sa._max), htonl(max));
00985   }
00986 
00987   virtual sockaddr const* min() const {
00988     return ats_ip_sa_cast(&_sa._min);
00989   }
00990 
00991   virtual sockaddr const* max() const {
00992     return ats_ip_sa_cast(&_sa._max);
00993   }
00994 
00995   self& setData(
00996     void* data 
00997   ) {
00998     _data = data;
00999     return *this;
01000   }
01001 protected:
01002   
01003 
01004 
01005   self& setMin(
01006     ArgType min 
01007   ) {
01008     _min = min;
01009     _sa._min.sin_addr.s_addr = htonl(min);
01010     return *this;
01011   }
01012   
01013 
01014 
01015   self& setMax(
01016     ArgType max 
01017   ) {
01018     _max = max;
01019     _sa._max.sin_addr.s_addr = htonl(max);
01020     return *this;
01021   }
01022   
01023 
01024 
01025 
01026   self& setMaxMinusOne(
01027     ArgType max 
01028   ) {
01029     return this->setMax(max-1);
01030   }
01031 
01032 
01033 
01034   self& setMinPlusOne(
01035     ArgType min 
01036   ) {
01037     return this->setMin(min+1);
01038   }
01039 
01040 
01041 
01042   self& decrementMax() {
01043     this->setMax(_max-1);
01044     return *this;
01045   }
01046 
01047 
01048 
01049   self& incrementMin() {
01050     this->setMin(_min+1);
01051     return *this;
01052   }
01053 
01054 
01055   static void inc(
01056     Metric& m 
01057   ) {
01058     ++m;
01059   }
01060   
01061 
01062   static void dec(
01063     Metric& m 
01064   ) {
01065     --m;
01066   }
01067   
01068 
01069   static Metric deref(
01070     ArgType addr 
01071   ) {
01072     return addr;
01073   }
01074 
01075 
01076   static ArgType argue(
01077     Metric const& metric
01078   ) {
01079     return metric;
01080   }
01081   
01082   struct {
01083     sockaddr_in _min;
01084     sockaddr_in _max;
01085   } _sa; 
01086 
01087 };
01088 
01089 class Ip4Map : public IpMapBase<Ip4Node> {
01090   friend class ::IpMap;
01091 };
01092 
01093 
01094 typedef Interval<sockaddr_in6> Ip6Span;
01095 
01096 
01097 
01098 class Ip6Node : public IpMap::Node, protected Ip6Span {
01099   friend struct IpMapBase<Ip6Node>;
01100 public:
01101   typedef Ip6Node self; 
01102 
01103 
01104   typedef Metric const* ArgType;
01105 
01106 
01107   Ip6Node(
01108     ArgType min, 
01109     ArgType max, 
01110     void* data 
01111   ) : Node(data), Ip6Span(*min, *max) {
01112   }
01113 
01114   Ip6Node(
01115     Metric const& min, 
01116     Metric const& max, 
01117     void* data 
01118   ) : Node(data), Ip6Span(min, max) {
01119   }
01120 
01121   virtual sockaddr const* min() const {
01122     return ats_ip_sa_cast(&_min);
01123   }
01124 
01125   virtual sockaddr const* max() const {
01126     return ats_ip_sa_cast(&_max);
01127   }
01128 
01129   self& setData(
01130     void* data 
01131   ) {
01132     _data = data;
01133     return *this;
01134   }
01135 protected:
01136   
01137 
01138 
01139   self& setMin(
01140     ArgType min 
01141   ) {
01142     ats_ip_copy(ats_ip_sa_cast(&_min), ats_ip_sa_cast(min));
01143     return *this;
01144   }
01145   
01146 
01147 
01148 
01149   self& setMin(
01150     Metric const& min 
01151   ) {
01152     return this->setMin(&min);
01153   }
01154   
01155 
01156 
01157   self& setMax(
01158     ArgType max 
01159   ) {
01160     ats_ip_copy(ats_ip_sa_cast(&_max), ats_ip_sa_cast(max));
01161     return *this;
01162   }
01163 
01164 
01165 
01166   self& setMax(
01167     Metric const& max 
01168   ) {
01169     return this->setMax(&max);
01170   }
01171 
01172 
01173 
01174   self& setMaxMinusOne(
01175     Metric const& max 
01176   ) {
01177     this->setMax(max);
01178     dec(_max);
01179     return *this;
01180   }
01181 
01182 
01183 
01184   self& setMinPlusOne(
01185     Metric const& min 
01186   ) {
01187     this->setMin(min);
01188     inc(_min);
01189     return *this;
01190   }
01191 
01192 
01193 
01194   self& decrementMax() { dec(_max); return *this; }
01195 
01196 
01197 
01198   self& incrementMin() { inc(_min); return *this; }
01199   
01200 
01201   static void inc(
01202     Metric& m 
01203   ) {
01204     uint8_t* addr = m.sin6_addr.s6_addr;
01205     uint8_t* b = addr + TS_IP6_SIZE;
01206     
01207     
01208     do {
01209       ++*--b;
01210     } while (b > addr && 0 == *b);
01211   }
01212   
01213 
01214   static void dec(
01215     Metric& m 
01216   ) {
01217     uint8_t* addr = m.sin6_addr.s6_addr;
01218     uint8_t* b = addr + TS_IP6_SIZE;
01219     
01220     
01221     do {
01222       --*--b;
01223     } while (b > addr && static_cast<uint8_t>(0xFF) == *b);
01224   }
01225 
01226   static Metric const& deref(
01227     ArgType addr 
01228   ) {
01229     return *addr;
01230   }
01231   
01232 
01233   static ArgType argue(
01234     Metric const& metric
01235   ) {
01236     return &metric;
01237   }
01238   
01239 };
01240 
01241 
01242 
01243 
01244 class Ip6Map : public IpMapBase<Ip6Node> {
01245   friend class ::IpMap;
01246 };
01247 
01248 }} 
01249 
01250 IpMap::~IpMap() {
01251   delete _m4;
01252   delete _m6;
01253 }
01254 
01255 inline ts::detail::Ip4Map*
01256 IpMap::force4() {
01257   if (!_m4) _m4 = new ts::detail::Ip4Map;
01258   return _m4;
01259 }
01260 
01261 inline ts::detail::Ip6Map*
01262 IpMap::force6() {
01263   if (!_m6) _m6 = new ts::detail::Ip6Map;
01264   return _m6;
01265 }
01266 
01267 bool
01268 IpMap::contains(sockaddr const* target, void** ptr) const {
01269   bool zret = false;
01270   if (AF_INET == target->sa_family) {
01271     zret = _m4 && _m4->contains(ntohl(ats_ip4_addr_cast(target)), ptr);
01272   } else if (AF_INET6 == target->sa_family) {
01273     zret = _m6 && _m6->contains(ats_ip6_cast(target), ptr);
01274   }
01275   return zret;
01276 }
01277 
01278 bool
01279 IpMap::contains(in_addr_t target, void** ptr) const {
01280   return _m4 && _m4->contains(ntohl(target), ptr);
01281 }
01282 
01283 IpMap&
01284 IpMap::mark(
01285   sockaddr const* min,
01286   sockaddr const* max,
01287   void* data
01288 ) {
01289   ink_assert(min->sa_family == max->sa_family);
01290   if (AF_INET == min->sa_family) {
01291     this->force4()->mark(
01292       ntohl(ats_ip4_addr_cast(min)),
01293       ntohl(ats_ip4_addr_cast(max)),
01294       data
01295     );
01296   } else if (AF_INET6 == min->sa_family) {
01297     this->force6()->mark(ats_ip6_cast(min), ats_ip6_cast(max), data);
01298   }
01299   return *this;
01300 }
01301 
01302 IpMap&
01303 IpMap::mark(in_addr_t min, in_addr_t max, void* data) {
01304   this->force4()->mark(ntohl(min), ntohl(max), data);
01305   return *this;
01306 }
01307 
01308 IpMap&
01309 IpMap::unmark(
01310   sockaddr const* min,
01311   sockaddr const* max
01312 ) {
01313   ink_assert(min->sa_family == max->sa_family);
01314   if (AF_INET == min->sa_family) {
01315     if (_m4)
01316       _m4->unmark(
01317         ntohl(ats_ip4_addr_cast(min)),
01318         ntohl(ats_ip4_addr_cast(max))
01319       );
01320   } else if (AF_INET6 == min->sa_family) {
01321     if (_m6) _m6->unmark(ats_ip6_cast(min), ats_ip6_cast(max));
01322   }
01323   return *this;
01324 }
01325 
01326 IpMap&
01327 IpMap::unmark(in_addr_t min, in_addr_t max) {
01328   if (_m4) _m4->unmark(ntohl(min), ntohl(max));
01329   return *this;
01330 }
01331 
01332 IpMap&
01333 IpMap::fill(
01334   sockaddr const* min,
01335   sockaddr const* max,
01336   void* data
01337 ) {
01338   ink_assert(min->sa_family == max->sa_family);
01339   if (AF_INET == min->sa_family) {
01340     this->force4()->fill(
01341       ntohl(ats_ip4_addr_cast(min)),
01342       ntohl(ats_ip4_addr_cast(max)),
01343       data
01344     );
01345   } else if (AF_INET6 == min->sa_family) {
01346     this->force6()->fill(ats_ip6_cast(min), ats_ip6_cast(max), data);
01347   }
01348   return *this;
01349 }
01350 
01351 IpMap&
01352 IpMap::fill(in_addr_t min, in_addr_t max, void* data) {
01353   this->force4()->fill(ntohl(min), ntohl(max), data);
01354   return *this;
01355 }
01356 
01357 size_t
01358 IpMap::getCount() const {
01359   size_t zret = 0;
01360   if (_m4) zret += _m4->getCount();
01361   if (_m6) zret += _m6->getCount();
01362   return zret;
01363 }
01364 
01365 IpMap&
01366 IpMap::clear() {
01367   if (_m4) _m4->clear();
01368   if (_m6) _m6->clear();
01369   return *this;
01370 }
01371 
01372 IpMap::iterator
01373 IpMap::begin() const {
01374   Node* x = 0;
01375   if (_m4) x = _m4->getHead();
01376   if (!x && _m6) x = _m6->getHead();
01377   return iterator(this, x);
01378 }
01379 
01380 IpMap::iterator&
01381 IpMap::iterator::operator ++ () {
01382   if (_node) {
01383     
01384     
01385     Node* x = static_cast<Node*>(_node->_next);
01386     if (!x && _tree->_m4 && _tree->_m6 && _node == _tree->_m4->getTail())
01387       x = _tree->_m6->getHead();
01388     _node = x;
01389   }
01390   return *this;
01391 }
01392 
01393 inline IpMap::iterator&
01394 IpMap::iterator::operator--() {
01395   if (_node) {
01396     
01397     
01398     Node* x = static_cast<Node*>(_node->_prev);
01399     if (!x && _tree->_m4 && _tree->_m6 && _node == _tree->_m6->getHead())
01400       x = _tree->_m4->getTail();
01401     _node = x;
01402   } else if (_tree) {
01403     
01404     if (_tree->_m6) _node = _tree->_m6->getTail();
01405     if (!_node && _tree->_m4) _node = _tree->_m4->getTail();
01406   }
01407   return *this;
01408 }
01409 
01410 
01411 
01412 
01413