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