00001
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 #ifndef _IBSTree_h_
00034 #define _IBSTree_h_
00035
00036
00037
00038
00039
00040 #include <assert.h>
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043 #include "dyntypes.h"
00044
00045 #include <set>
00046 #include <limits>
00047
00048 using namespace std;
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 #undef min
00079 #undef max
00080
00081 namespace Dyninst {
00082
00083 namespace IBS {
00084 typedef enum { TREE_RED, TREE_BLACK } color_t;
00085 };
00086
00087 template<class T = unsigned long>
00088 class interval {
00089 public:
00090 interval() { }
00091 virtual ~interval() { }
00092
00093 virtual T low() const = 0;
00094 virtual T high() const = 0;
00095
00096 typedef T type;
00097 };
00098
00099 class SimpleInterval : public interval<int> {
00100 public:
00101 SimpleInterval( interval<int> & i, void * id ) {
00102 low_ = i.low();
00103 high_ = i.high();
00104 id_ = id;
00105 }
00106 SimpleInterval(int low, int high, void * id) {
00107 low_ = low;
00108 high_ = high;
00109 id_ = id;
00110 }
00111
00112 virtual int low() const { return low_; }
00113 virtual int high() const { return high_; }
00114
00115 private:
00116 int low_;
00117 int high_;
00118 void * id_;
00119 };
00120
00121 template<class ITYPE>
00122 class IBSTree;
00123
00124 template<class ITYPE = interval<> >
00125 class IBSNode {
00126 friend class IBSTree<ITYPE>;
00127 typedef typename ITYPE::type interval_type;
00128 public:
00129 IBSNode() :
00130 color(IBS::TREE_BLACK),
00131 left(NULL),
00132 right(NULL),
00133 parent(NULL) { }
00134
00135
00136 IBSNode(interval_type value, IBSNode *n) :
00137 val_(value),
00138 left(n),
00139 right(n),
00140 parent(NULL) { }
00141
00142 ~IBSNode() { }
00143
00144 interval_type value() const { return val_; };
00145
00146 private:
00147
00148 interval_type val_;
00149
00150
00151 set<ITYPE *> less;
00152 set<ITYPE *> greater;
00153 set<ITYPE *> equal;
00154
00155 IBS::color_t color;
00156
00157 IBSNode<ITYPE> *left;
00158 IBSNode<ITYPE> *right;
00159 IBSNode<ITYPE> *parent;
00160 };
00161
00162 template<class ITYPE = interval<> >
00163 class IBSTree {
00164 typedef typename ITYPE::type interval_type;
00165
00166 IBSNode<ITYPE> *nil;
00167
00168
00169 int treeSize;
00170
00171
00172 IBSNode<ITYPE> *root;
00173
00174
00175 void leftRotate(IBSNode<ITYPE> *);
00176
00177
00178 void rightRotate(IBSNode<ITYPE> *);
00179
00180
00181 void deleteFixup(IBSNode<ITYPE> *);
00182
00183 void removeInterval(IBSNode<ITYPE> *R, ITYPE *range);
00184
00185
00186
00187 IBSNode<ITYPE>* addLeft(ITYPE *I, IBSNode<ITYPE> *R);
00188 IBSNode<ITYPE>* addRight(ITYPE *I, IBSNode<ITYPE> *R);
00189
00190
00191
00192
00193 interval_type rightUp(IBSNode<ITYPE> *R);
00194
00195
00196 interval_type leftUp(IBSNode<ITYPE> *R);
00197
00198
00199 void insertFixup(IBSNode<ITYPE> *x);
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 void destroy(IBSNode<ITYPE> *);
00210
00211 void findIntervals(interval_type X, IBSNode<ITYPE> *R, set<ITYPE *> &S) const;
00212 void findIntervals(ITYPE *I, IBSNode<ITYPE> *R, set<ITYPE *> &S) const;
00213
00214 void PrintPreorder(IBSNode<ITYPE> *n);
00215
00216 int height(IBSNode<ITYPE> *n);
00217 int CountMarks(IBSNode<ITYPE> *R) const;
00218
00219 unsigned MemUse() const;
00220
00221 public:
00222
00223
00224
00225
00226 IBSTree() : treeSize(0) {
00227 nil = new IBSNode<ITYPE>;
00228 root = nil;
00229
00230
00231 }
00232
00233 ~IBSTree() {
00234 destroy(root);
00235 delete nil;
00236 }
00237
00238 int size() const { return treeSize; }
00239 int CountMarks() const;
00240
00241 bool empty() const { return (root == nil); }
00242
00243 void insert(ITYPE *);
00244
00245 void remove(ITYPE *);
00246
00247
00248
00249 int find(interval_type, set<ITYPE *> &) const;
00250 int find(ITYPE *I, set<ITYPE *> &) const;
00251
00252
00253
00254 void successor(interval_type X, set<ITYPE *> &) const;
00255
00256 ITYPE * successor(interval_type X) const;
00257
00258
00259 void clear();
00260
00261 void PrintPreorder() { PrintPreorder(root); }
00262 };
00263
00264 template<class ITYPE>
00265 void IBSTree<ITYPE>::rightRotate(IBSNode<ITYPE> *pivot)
00266 {
00267 if(!pivot || (pivot == nil))
00268 return;
00269
00270 IBSNode<ITYPE> *y = pivot->left;
00271 if(y == nil)
00272 return;
00273 pivot->left = y->right;
00274 if(y->right != nil)
00275 y->right->parent = pivot;
00276 y->parent = pivot->parent;
00277 if(!pivot->parent) {
00278 root = y;
00279 }
00280 else if(pivot == pivot->parent->left)
00281 pivot->parent->left = y;
00282 else
00283 pivot->parent->right = y;
00284 y->right = pivot;
00285 pivot->parent = y;
00286
00287
00288
00289
00290
00291 y->less.insert(pivot->less.begin(), pivot->less.end());
00292 y->equal.insert(pivot->less.begin(), pivot->less.end());
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 typename set< ITYPE * >::iterator it = y->greater.begin();
00305 while( it != y->greater.end() )
00306 {
00307 ITYPE *tmp = *it;
00308
00309 typename set< ITYPE *>::iterator pit = pivot->greater.find( tmp );
00310 if(pit == pivot->greater.end()) {
00311
00312 pivot->less.insert( tmp );
00313
00314
00315 typename set< ITYPE * >::iterator del = it;
00316 ++it;
00317 y->greater.erase( del );
00318 } else {
00319
00320
00321 pivot->greater.erase( pit );
00322 pit = pivot->equal.find( tmp );
00323 if(pit != pivot->equal.end())
00324 pivot->equal.erase( pit );
00325
00326 ++it;
00327 }
00328 }
00329 }
00330
00331 template<class ITYPE>
00332 void IBSTree<ITYPE>::leftRotate(IBSNode<ITYPE> *pivot)
00333 {
00334 if(!pivot || (pivot == nil))
00335 return;
00336
00337 IBSNode<ITYPE> *y = pivot->right;
00338
00339 if(y == nil)
00340 return;
00341
00342 pivot->right = y->left;
00343 if(y->left != nil)
00344 y->left->parent = pivot;
00345 y->parent = pivot->parent;
00346 if(!pivot->parent) {
00347 root = y;
00348 }
00349 else if(pivot == pivot->parent->left)
00350 pivot->parent->left = y;
00351 else
00352 pivot->parent->right = y;
00353 y->left = pivot;
00354 pivot->parent = y;
00355
00356
00357
00358
00359 y->greater.insert(pivot->greater.begin(),pivot->greater.end());
00360 y->equal.insert(pivot->greater.begin(),pivot->greater.end());
00361
00362 typename set< ITYPE * >::iterator it = y->less.begin();
00363 while( it != y->less.end() )
00364 {
00365 ITYPE *tmp = *it;
00366
00367 typename set< ITYPE *>::iterator pit = pivot->less.find( tmp );
00368 if(pit == pivot->less.end()) {
00369
00370 pivot->greater.insert( tmp );
00371
00372
00373 typename set< ITYPE * >::iterator del = it;
00374 ++it;
00375 y->less.erase( del );
00376 } else {
00377
00378
00379 pivot->less.erase( pit );
00380 pit = pivot->equal.find( tmp );
00381 if(pit != pivot->equal.end())
00382 pivot->equal.erase( pit );
00383
00384 ++it;
00385 }
00386 }
00387 }
00388
00389 template<class ITYPE>
00390 IBSNode<ITYPE>*
00391 IBSTree<ITYPE>::addLeft(ITYPE *I, IBSNode<ITYPE> *R)
00392 {
00393 IBSNode<ITYPE> *parent = NULL;
00394
00395
00396 interval_type ilow = I->low();
00397 interval_type ihigh = I->high();
00398
00399 while(1) {
00400 bool created = false;
00401 if(R == nil) {
00402
00403 IBSNode<ITYPE> *tmp = new IBSNode<ITYPE>( ilow, nil );
00404 treeSize++;
00405 created = true;
00406
00407 if(parent == NULL)
00408 root = tmp;
00409 else {
00410 tmp->parent = parent;
00411 if(tmp->value() < parent->value()) {
00412 parent->left = tmp;
00413 } else if(tmp->value() > parent->value()) {
00414 parent->right = tmp;
00415 } else {
00416 assert(0);
00417 }
00418 }
00419 R = tmp;
00420 }
00421
00422 interval_type rval = R->value();
00423
00424 if(rval == ilow) {
00425 if( rightUp(R) <= ihigh ) {
00426 R->greater.insert( I );
00427 }
00428 R->equal.insert( I );
00429
00430 if(created)
00431 return R;
00432 else
00433 return NULL;
00434 }
00435 else if(rval < ilow) {
00436 parent = R;
00437 R = R->right;
00438 continue;
00439 }
00440 else if(rval > ilow) {
00441 if(rval < ihigh) {
00442 R->equal.insert( I );
00443 }
00444 if( rightUp(R) <= ihigh ) {
00445 R->greater.insert( I );
00446 }
00447 parent = R;
00448 R = R->left;
00449 continue;
00450 } else {
00451 assert(0);
00452 return NULL;
00453 }
00454 }
00455
00456 assert(0);
00457 return NULL;
00458 }
00459
00460 template<class ITYPE>
00461 IBSNode<ITYPE> *
00462 IBSTree<ITYPE>::addRight(ITYPE *I, IBSNode<ITYPE> *R)
00463 {
00464 IBSNode<ITYPE> *parent = NULL;
00465
00466
00467 interval_type ilow = I->low();
00468 interval_type ihigh = I->high();
00469
00470 while(1)
00471 {
00472 bool created = false;
00473 if(R == nil) {
00474 IBSNode<ITYPE> *tmp = new IBSNode<ITYPE>(ihigh,nil);
00475 ++treeSize;
00476 created = true;
00477 if(parent == NULL)
00478 root = tmp;
00479 else {
00480 tmp->parent = parent;
00481 if(tmp->value() < parent->value())
00482 parent->left = tmp;
00483 else if(tmp->value() > parent->value())
00484 parent->right = tmp;
00485 else
00486 assert(0);
00487 }
00488 R = tmp;
00489 }
00490
00491 interval_type rval = R->value();
00492
00493 if(rval == ihigh) {
00494
00495
00496
00497
00498
00499
00500
00501 if(leftUp(R) >= ilow)
00502 R->less.insert(I);
00503
00504 if(created)
00505 return R;
00506 else
00507 return NULL;
00508 }
00509 else if(rval < ihigh) {
00510 if(rval > ilow) {
00511
00512 R->equal.insert( I );
00513 }
00514 if( leftUp(R) >= ilow ) {
00515
00516 R->less.insert( I );
00517 }
00518
00519 parent = R;
00520 R = R->right;
00521 continue;
00522 }
00523 else if(rval > ihigh) {
00524
00525 parent = R;
00526 R = R->left;
00527 continue;
00528 }
00529 else {
00530 assert(0);
00531 return NULL;
00532 }
00533 }
00534
00535 assert(0);
00536 return NULL;
00537 }
00538
00539
00540
00541
00542
00543 template<class ITYPE>
00544 typename ITYPE::type
00545 IBSTree<ITYPE>::rightUp(IBSNode<ITYPE> *R)
00546 {
00547 while(NULL != R->parent) {
00548 if(R->parent->left == R)
00549 return R->parent->value();
00550 R = R->parent;
00551 }
00552 return numeric_limits<interval_type>::max();
00553 }
00554
00555
00556
00557 template<class ITYPE>
00558 typename ITYPE::type
00559 IBSTree<ITYPE>::leftUp(IBSNode<ITYPE> *R)
00560 {
00561 while(NULL != R->parent) {
00562 if(R->parent->right == R)
00563 return R->parent->value();
00564 R = R->parent;
00565 }
00566
00567 return numeric_limits<interval_type>::min();
00568 }
00569
00570
00571 template<class ITYPE>
00572 void IBSTree<ITYPE>::insertFixup(IBSNode<ITYPE> *x)
00573 {
00574 x->color = IBS::TREE_RED;
00575 while((x != root) && (x->parent->color == IBS::TREE_RED)) {
00576 if(x->parent == x->parent->parent->left) {
00577 IBSNode<ITYPE>* y = x->parent->parent->right;
00578 if(y->color == IBS::TREE_RED) {
00579 x->parent->color = IBS::TREE_BLACK;
00580 y->color = IBS::TREE_BLACK;
00581 x->parent->parent->color = IBS::TREE_RED;
00582 x = x->parent->parent;
00583 }
00584 else {
00585 if(x == x->parent->right) {
00586 x = x->parent;
00587 leftRotate(x);
00588 }
00589 x->parent->color = IBS::TREE_BLACK;
00590 x->parent->parent->color = IBS::TREE_RED;
00591 rightRotate(x->parent->parent);
00592 }
00593 }
00594 else {
00595 IBSNode<ITYPE> *y = x->parent->parent->left;
00596 if(y->color == IBS::TREE_RED) {
00597 x->parent->color = IBS::TREE_BLACK;
00598 y->color = IBS::TREE_BLACK;
00599 x->parent->parent->color = IBS::TREE_RED;
00600 x = x->parent->parent;
00601 }
00602 else {
00603 if(x == x->parent->left) {
00604 x = x->parent;
00605 rightRotate(x);
00606 }
00607 x->parent->color = IBS::TREE_BLACK;
00608 x->parent->parent->color = IBS::TREE_RED;
00609 leftRotate(x->parent->parent);
00610 }
00611 }
00612 }
00613 root->color = IBS::TREE_BLACK;
00614 }
00615
00616 template<class ITYPE>
00617 void IBSTree<ITYPE>::destroy(IBSNode<ITYPE> *n)
00618 {
00619 if(!n || (n == nil))
00620 return;
00621 if(n->left != nil)
00622 destroy(n->left);
00623 if(n->right != nil)
00624 destroy(n->right);
00625 delete n;
00626 }
00627
00628
00629
00630
00631
00632
00633
00634
00635 template<class ITYPE>
00636 void IBSTree<ITYPE>::findIntervals(interval_type X, IBSNode<ITYPE> *R, set<ITYPE *> &S) const
00637 {
00638 while(R != nil) {
00639 if(X == R->value()) {
00640 S.insert(R->equal.begin(),R->equal.end());
00641 return;
00642 }
00643 else if(X < R->value()) {
00644 S.insert(R->less.begin(),R->less.end());
00645 R = R->left;
00646 } else {
00647 S.insert(R->greater.begin(),R->greater.end());
00648 R = R->right;
00649 }
00650 }
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 template<class ITYPE>
00664 void IBSTree<ITYPE>::findIntervals(ITYPE * I, IBSNode<ITYPE> *R, set<ITYPE *> &S) const
00665 {
00666 if(R == nil) return;
00667
00668 interval_type low = I->low();
00669 interval_type high = I->high();
00670
00671 if(low < R->value()) {
00672 S.insert(R->less.begin(),R->less.end());
00673 findIntervals(I,R->left,S);
00674 }
00675 if(low > R->value() || high > R->value()) {
00676 S.insert(R->greater.begin(),R->greater.end());
00677 findIntervals(I,R->right,S);
00678 }
00679 if(low <= R->value() && high > R->value()) {
00680 S.insert(R->equal.begin(),R->equal.end());
00681 }
00682 else if(low == R->value() && high == R->value()) {
00683
00684
00685 S.insert(R->equal.begin(),R->equal.end());
00686 }
00687 }
00688
00689 template<class ITYPE>
00690 void IBSTree<ITYPE>::removeInterval(IBSNode<ITYPE> *R, ITYPE *range)
00691 {
00692 if(R == nil) return;
00693
00694 interval_type low = range->low();
00695 interval_type high = range->high();
00696
00697
00698
00699 if(low < R->value()) {
00700 R->less.erase(range);
00701 removeInterval(R->left,range);
00702 }
00703 if(low > R->value() || high > R->value()) {
00704 R->greater.erase(range);
00705 removeInterval(R->right,range);
00706 }
00707 if(low <= R->value() && high > R->value()) {
00708 R->equal.erase(range);
00709 }
00710 else if(low == R->value() && high == R->value()) {
00711
00712
00713 R->equal.erase(range);
00714 }
00715 }
00716
00717 template<class ITYPE>
00718 int IBSTree<ITYPE>::CountMarks(IBSNode<ITYPE> *R) const
00719 {
00720 if(R == nil) return 0;
00721
00722 return (R->less.size() + R->greater.size() + R->equal.size()) +
00723 CountMarks(R->left) + CountMarks(R->right);
00724 }
00725
00726
00727
00728 template<class ITYPE>
00729 void IBSTree<ITYPE>::insert(ITYPE *range)
00730 {
00731
00732
00733
00734
00735 IBSNode<ITYPE> *x = addLeft(range,root);
00736 if(x) {
00737 insertFixup(x);
00738 }
00739 x = addRight(range,root);
00740 if(x) {
00741 insertFixup(x);
00742 }
00743
00744
00745 }
00746
00747 template<class ITYPE>
00748 void IBSTree<ITYPE>::remove(ITYPE * range)
00749 {
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 removeInterval(root,range);
00767
00768
00769 }
00770
00771 template<class ITYPE>
00772 int IBSTree<ITYPE>::find(interval_type X, set<ITYPE *> &out) const
00773 {
00774 unsigned size = out.size();
00775 findIntervals(X,root,out);
00776 return out.size() - size;
00777 }
00778
00779 template<class ITYPE>
00780 int IBSTree<ITYPE>::find(ITYPE * I, set<ITYPE *> &out) const
00781 {
00782 unsigned size = out.size();
00783 findIntervals(I,root,out);
00784 return out.size() - size;
00785 }
00786
00787 template<class ITYPE>
00788 void IBSTree<ITYPE>::successor(interval_type X, set<ITYPE *> &out) const
00789 {
00790 IBSNode<ITYPE> *n = root;
00791 IBSNode<ITYPE> *last = nil;
00792
00793 std::vector< IBSNode<ITYPE>* > stack;
00794
00795
00796 while(1) {
00797 if(n == nil) {
00798 if(last != nil) {
00799 typename set<ITYPE *>::iterator sit = last->equal.begin();
00800 for( ; sit != last->equal.end(); ++sit) {
00801 if((*sit)->low() == last->value()) out.insert(*sit);
00802 }
00803 if(!out.empty())
00804 break;
00805 else {
00806
00807
00808 n = last->right;
00809 if(!stack.empty()) {
00810 last = stack.back();
00811 stack.pop_back();
00812 } else {
00813 last = nil;
00814 }
00815 continue;
00816 }
00817 } else
00818 break;
00819 }
00820
00821 if(X >= n->value()) {
00822 n = n->right;
00823 } else {
00824 if(last != nil)
00825 stack.push_back(last);
00826 last = n;
00827 n = n->left;
00828 }
00829 }
00830 }
00831
00832 template<class ITYPE>
00833 ITYPE * IBSTree<ITYPE>::successor(interval_type X) const
00834 {
00835 set<ITYPE *> out;
00836 successor(X,out);
00837 assert( out.size() <= 1 );
00838 if(!out.empty())
00839 return *out.begin();
00840 else
00841 return NULL;
00842 }
00843
00844 template<class ITYPE>
00845 void IBSTree<ITYPE>::clear() {
00846 if(root == nil) return;
00847 destroy(root);
00848 root = nil;
00849 treeSize = 0;
00850 }
00851
00852 template<class ITYPE>
00853 int IBSTree<ITYPE>::height(IBSNode<ITYPE> *n)
00854 {
00855 if(!n)
00856 return 0;
00857
00858 int leftHeight = 1 + height(n->left);
00859 int rightHeight = 1 + height(n->right);
00860
00861 if(leftHeight > rightHeight)
00862 return leftHeight;
00863 else
00864 return rightHeight;
00865 }
00866
00867 template<class ITYPE>
00868 void IBSTree<ITYPE>::PrintPreorder(IBSNode<ITYPE> *n)
00869 {
00870 if(n == nil) return;
00871
00872 PrintPreorder(n->left);
00873 printf(" %d\n",n->value());
00874 PrintPreorder(n->right);
00875
00876 if(n == root) {
00877 int h = height(root);
00878 printf(" tree height: %d\n", h);
00879 }
00880 }
00881
00882 template<class ITYPE>
00883 int IBSTree<ITYPE>::CountMarks() const
00884 {
00885 return CountMarks(root);
00886 }
00887 }
00888 #endif
00889