addrRange.h

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 #ifndef _addrRange_h_
00032 #define _addrRange_h_
00033 
00034 /*******************************************************/
00035 /*  Templated header file                               */
00036 /*******************************************************/
00037 
00038 #include <assert.h>
00039 #include <stdlib.h>
00040 #include <vector>
00041 #include "common/h/Types.h"
00042 #include "common/h/Vector.h"
00043 #include "common/h/std_namesp.h"
00044 
00045 /** template class for addrRangeTree. The implementation is based on red black
00046  * tree implementation for efficiency concerns and for getting sorted
00047  * elements easier.
00048  * There are two template types, K (key) and V (value).
00049  */
00050 
00051 /* Note: this is a near copy of BPatch_Set. That class didn't do what I needed,
00052    so... -- bernat, 10OCT03 */
00053 
00054 typedef enum { TREE_RED, TREE_BLACK } color_t;
00055 
00056 class addrRange {
00057  public:
00058    virtual Address get_address() const = 0;
00059    virtual unsigned long get_size() const = 0;
00060    virtual std::string get_name() const {
00061       return std::string("UNNAMED");
00062    }
00063    virtual ~addrRange() {
00064    };
00065 };
00066 
00067 /** 
00068  * T should inherit from addrRange
00069  **/
00070 template <class T>
00071 class addrRangeTree {
00072 
00073    /** tree implementation structure. Used to implement the RB tree */
00074    typedef struct entry {
00075       Address key;
00076       T *value;
00077       color_t color;    /* color of the node */
00078       struct entry* left; /* left child */
00079       struct entry* right; /* right child */
00080       struct entry* parent; /* parent of the node */
00081 
00082       /** constructor for structure */
00083       entry() 
00084          : color(TREE_BLACK),left(NULL),right(NULL),parent(NULL) 
00085       {
00086       }
00087 
00088       /** constructor used for non-nil elements 
00089        * @param e nil entry
00090        */     
00091       entry(entry* e) //constructor with nil entry 
00092          : color(TREE_RED), left(e), right(e), parent(NULL) 
00093       {
00094       }
00095 
00096       /** constructor
00097        * @param d data element
00098        * @param e nill entry 
00099        */
00100       entry(Address key_, T *value_, entry* e) 
00101          : key(key_), value(value_), color(TREE_RED), left(e),
00102            right(e), parent(NULL) 
00103       {
00104       }
00105 
00106       /** constructor 
00107        * @param e the entry structure that will be copied 
00108        */
00109       entry(const entry& e) : key(e.key),value(e.value),color(e.color),
00110                               left(NULL),right(NULL),parent(NULL) 
00111       {
00112       }
00113    } entry;
00114 
00115    /** pointer to define the nil element of the tree NULL is not used
00116     * since some operations need sentinel nil which may have non-nil
00117     * parent.
00118     */
00119    entry* nil;
00120 
00121    /** size of the tree */
00122    int setSize;
00123 
00124    /** pointer to the tree structure */
00125    entry* setData;
00126 
00127    // method that implements left rotation used by RB tree for balanced
00128    // tree construction and keeps the RBtree properties.
00129    void leftRotate(entry* pivot)
00130    {
00131       if(!pivot || (pivot == nil))
00132          return;
00133       entry* y = pivot->right;
00134       if(y == nil)
00135          return;
00136       pivot->right = y->left;
00137       if(y->left != nil)
00138          y->left->parent = pivot;
00139       y->parent = pivot->parent;
00140       if(!pivot->parent) {
00141          setData = y;
00142       }
00143       else if(pivot == pivot->parent->left)
00144          pivot->parent->left = y;
00145       else
00146          pivot->parent->right = y;
00147       y->left = pivot;
00148       pivot->parent = y;
00149    }
00150 
00151    // method that implements right rotattion used by RB tree for balanced
00152    // tree construction and keeps the RBtree properties.
00153    void rightRotate(entry *pivot)
00154    {
00155       if(!pivot || (pivot == nil))
00156          return;
00157       entry* x = pivot->left;
00158       if(x == nil)
00159          return;
00160       pivot->left = x->right;
00161       if(x->right != nil)
00162          x->right->parent = pivot;
00163       x->parent = pivot->parent;
00164       if(!pivot->parent) {
00165          setData = x;
00166       }
00167       else if(pivot == pivot->parent->left)
00168          pivot->parent->left = x;
00169       else
00170          pivot->parent->right = x;
00171       x->right = pivot;
00172       pivot->parent = x;
00173    }
00174 
00175    // method that modifies the tree structure after deletion for keeping
00176    // the RBtree properties.
00177    void deleteFixup(entry *x)
00178    {
00179       while((x != setData) && 
00180             (x->color == TREE_BLACK))
00181       {
00182          if(x == x->parent->left){
00183             entry* w = x->parent->right;
00184             if(w->color == TREE_RED){
00185                w->color = TREE_BLACK;
00186                x->parent->color = TREE_RED;
00187                leftRotate(x->parent);
00188                w = x->parent->right;
00189             }
00190             if((w->left->color == TREE_BLACK) &&
00191                (w->right->color == TREE_BLACK)){
00192                w->color = TREE_RED;
00193                x = x->parent;
00194             }
00195             else{
00196                if(w->right->color == TREE_BLACK){
00197                   w->left->color = TREE_BLACK;
00198                   w->color = TREE_RED;
00199                   rightRotate(w);
00200                   w = x->parent->right;
00201                }
00202                w->color = x->parent->color;
00203                x->parent->color = TREE_BLACK;
00204                w->right->color = TREE_BLACK;
00205                leftRotate(x->parent);
00206                x = setData;
00207             }
00208          }
00209          else{
00210             entry* w = x->parent->left;
00211             if(w->color == TREE_RED){
00212                w->color = TREE_BLACK;
00213                x->parent->color = TREE_RED;
00214                rightRotate(x->parent);
00215                w = x->parent->left;
00216             }
00217             if((w->right->color == TREE_BLACK) &&
00218                (w->left->color == TREE_BLACK)){
00219                w->color = TREE_RED;
00220                x = x->parent;
00221             }
00222             else{
00223                if(w->left->color == TREE_BLACK){
00224                   w->right->color = TREE_BLACK;
00225                   w->color = TREE_RED;
00226                   leftRotate(w);
00227                   w = x->parent->left;
00228                }
00229                w->color = x->parent->color;
00230                x->parent->color = TREE_BLACK;
00231                w->left->color = TREE_BLACK;
00232                rightRotate(x->parent);
00233                x = setData;
00234             }
00235          }
00236       }
00237       x->color = TREE_BLACK;
00238    }
00239 
00240 
00241    // insertion to a binary search tree. It returns the new element pointer
00242    // that is inserted. If element is already there it returns NULL
00243    entry* treeInsert(Address key, T *value)
00244    {
00245       entry* y = NULL;
00246       entry* x = setData;
00247       while(x != nil){
00248          y = x;
00249          if (key < x->key) 
00250             x = x->left;
00251          else if(key > x->key)
00252             x = x->right;
00253          else
00254             return NULL;
00255       } 
00256       entry* z = new entry(key, value, nil);
00257       z->parent = y;
00258       if(!y) {
00259          setData = z;
00260       }
00261       else {
00262          if (key < y->key)
00263             y->left = z;
00264          else if (key > y->key)
00265             y->right = z;
00266       }
00267       setSize++;
00268       return z;
00269    }
00270 
00271 
00272    // finds the elemnts in the tree that will be replaced with the element
00273    // being deleted in the  deletion. That is the element with the largest
00274    // smallest value than the element being deleted. 
00275    entry* treeSuccessor(entry *x) const
00276    {
00277       if(!x || (x == nil))
00278          return NULL;
00279       if(x->right != nil){
00280          entry* z = x->right;
00281          while(z->left != nil) z = z->left;
00282          return z;
00283       }
00284       entry* y = x->parent;
00285       while(y && (x == y->right)){
00286          x = y;
00287          y = y->parent;
00288       }
00289       return y;
00290    }
00291 
00292    // method that returns the entry pointer for the element that is searched
00293    //for. If the entry is not found then it retuns NULL
00294    entry* find_internal(Address element) const
00295    {
00296       entry* x = setData;
00297       while(x != nil){
00298          if (element < x->key) {
00299             x = x->left;
00300          }
00301          else if (element > x->key) {
00302             x = x->right;
00303          }
00304          else
00305             return x;
00306       } 
00307       return NULL;
00308    }
00309 
00310 
00311    // infix traverse of the RB tree. It traverses the tree in ascending order
00312    void traverse(T **all, entry *node, int &n) const
00313    {
00314       if(node == nil)
00315          return;
00316       if(node->left != nil)
00317          traverse(all,node->left,n);
00318       if(all)
00319          all[n++] = node->value;
00320       if(node->right != nil)
00321          traverse(all,node->right,n);
00322    }
00323 
00324 
00325    // Vector version of above
00326    // infix traverse of the RB tree. It traverses the tree in ascending order
00327    void traverse(pdvector<T *> &all, entry*node) const
00328    {
00329       if(node == nil)
00330          return;
00331       if(node->left != nil)
00332          traverse(all,node->left);
00333       all.push_back(node->value);
00334       if(node->right != nil)
00335          traverse(all,node->right);
00336    }
00337 
00338 
00339    // deletes the tree structure for deconstructor.
00340    void destroy(entry *node)
00341    {
00342       if(!node || (node == nil))
00343          return;
00344       if(node->left != nil)
00345          destroy(node->left);
00346       if(node->right != nil)
00347          destroy(node->right);
00348       delete node;
00349    }
00350 
00351    /** copy constructor */
00352    addrRangeTree(const addrRangeTree &/* y */) 
00353    {
00354    }
00355 
00356    // Similar to precessor, but returns an entry
00357    bool precessor_internal(Address key, entry * &value) const
00358    {
00359       entry *x = setData;
00360       entry *last = nil;
00361       while (x != nil) {
00362          assert(x != NULL);
00363          if (x->key == key) {
00364             value = x;
00365             return true;
00366          }
00367          else if (key < x->key) {
00368             x = x->left;
00369          }
00370          else { // key > x->key
00371             last = x;
00372             x = x->right;
00373          }
00374       }
00375       if (x == nil) {
00376          // Ran out of tree to search... get the parent
00377          assert(last != NULL);
00378          if (last != nil) {
00379             value = last;
00380             return true;
00381          }
00382          else return false;
00383       }
00384       // Should never hit here
00385       assert(0);
00386       return false;
00387    }
00388 
00389 
00390    // Similar to successor, but returns an entry
00391    bool successor_internal(Address key, entry * &value) const
00392    {
00393       entry *x = setData;
00394       entry *last = nil;
00395       while (x != nil) {
00396          if (x->key == key) {
00397             value = x;
00398             return true;
00399          }
00400          else if (key > x->key) {
00401             x = x->right;
00402          }
00403          else { // key < x->key
00404             last = x;
00405             x = x->left;
00406          }
00407       }
00408       if (x == nil) {
00409          // Ran out of tree to search... get the parent
00410          if (last != nil) {
00411             value = last;
00412             return true;
00413          }
00414          else return false;
00415       }
00416       // Should never reach this point
00417       assert(0);
00418       return false;
00419    }
00420 
00421 
00422  public:
00423 
00424    /** constructor. The default comparison structure is used */
00425    addrRangeTree() : 
00426       setSize(0) 
00427    { 
00428       nil = new entry;
00429       setData = nil;
00430    }
00431     
00432       /** destructor which deletes all tree structure and allocated entries */
00433       virtual ~addrRangeTree()
00434       {
00435          destroy(setData);
00436          delete nil;
00437       }
00438 
00439       /** returns the cardinality of the tree , number of elements */
00440       int size() const 
00441       { 
00442          return setSize; 
00443       }
00444     
00445       /** returns true if tree is empty */
00446       bool empty() const 
00447       { 
00448          return (setData == nil); 
00449       }
00450 
00451       /** inserts the element in the tree 
00452        * @param 1 element that will be inserted
00453        */
00454       void insert(T *value)
00455       {
00456          entry* x = treeInsert(value->get_address(), value);
00457          if(!x) {
00458             // We're done.
00459             return;
00460          }
00461          x->color = TREE_RED;
00462          while((x != setData) && (x->parent->color == TREE_RED)){
00463             if(x->parent == x->parent->parent->left){
00464                entry* y = x->parent->parent->right;
00465                if(y->color == TREE_RED){
00466                   x->parent->color = TREE_BLACK;
00467                   y->color = TREE_BLACK;
00468                   x->parent->parent->color = TREE_RED;
00469                   x = x->parent->parent;
00470                }
00471                else{
00472                   if(x == x->parent->right){
00473                      x = x->parent;
00474                      leftRotate(x);
00475                   }
00476                   x->parent->color = TREE_BLACK;
00477                   x->parent->parent->color = TREE_RED;
00478                   rightRotate(x->parent->parent);
00479                }
00480             }
00481             else{
00482                entry* y = x->parent->parent->left;
00483                if(y->color == TREE_RED){
00484                   x->parent->color = TREE_BLACK;
00485                   y->color = TREE_BLACK;
00486                   x->parent->parent->color = TREE_RED;
00487                   x = x->parent->parent;
00488                }
00489                else{
00490                   if(x == x->parent->left){
00491                      x = x->parent;
00492                      rightRotate(x);
00493                   }
00494                   x->parent->color = TREE_BLACK;
00495                   x->parent->parent->color = TREE_RED;
00496                   leftRotate(x->parent->parent);
00497                }
00498             }
00499          }
00500          setData->color = TREE_BLACK;
00501       }
00502 
00503       /** removes the element in the tree 
00504        * @param 1 element that will be removed  
00505        */
00506       void remove(Address key)
00507       {
00508          entry* z = find_internal(key);
00509          if(!z)
00510             return;
00511          if (z->key != key)
00512             return;
00513 
00514          entry* y=((z->left == nil)||(z->right == nil)) ? z : treeSuccessor(z);
00515          entry* x=(y->left != nil) ? y->left : y->right;
00516          x->parent = y->parent;
00517          if(!y->parent) {
00518             setData = x;
00519          }
00520          else if(y == y->parent->left)
00521             y->parent->left = x;
00522          else
00523             y->parent->right = x;
00524          if(y != z) {
00525             z->value = y->value;
00526             z->key = y->key;
00527          }
00528          if(y->color == TREE_BLACK)
00529             deleteFixup(x);
00530          setSize--;
00531          delete y;
00532       }
00533 
00534 
00535       /** returns true if the argument is member of the addrRangeTree
00536        * @param e the element that will be searched for
00537        */
00538       virtual bool find(Address key, T *& value) const
00539       {
00540          value = NULL;
00541          if (!precessor(key, value))
00542             return false;
00543          // Check to see if the range works
00544          if (!value->get_size()) {
00545             if(key > value->get_address())
00546                return false;
00547          }
00548          else if(key >= (value->get_address() + value->get_size())) {
00549             return false;
00550          }
00551          // We can also underflow
00552          if (key < value->get_address())
00553             return false;
00554          return true;
00555       }
00556 
00557 
00558       /** Fills in the vector with all address ranges that overlap
00559        * with the address range defined by (start, end]
00560        */
00561       virtual bool find(Address start, Address end, 
00562                         std::vector<T *> &ranges) const
00563       {
00564          entry *cur;
00565          bool result = precessor_internal(start, cur);
00566          if (!result || cur == nil)
00567             result = successor_internal(start, cur);
00568          if (!result || cur == nil)
00569             return false;
00570          assert(cur);
00571    
00572          if (cur->key + cur->value->get_size() < start)
00573             cur = treeSuccessor(cur);
00574          while (cur != NULL && cur != nil && cur->key < end)
00575          {
00576             ranges.push_back(cur->value);
00577             cur = treeSuccessor(cur);
00578          }
00579    
00580          return (ranges.size() != 0);
00581       }
00582 
00583 
00584       /** Returns the largest value less than or equal to the
00585        * key given
00586        */
00587       virtual bool precessor(Address key, T *& value) const
00588       {
00589          entry *val;
00590          bool result = precessor_internal(key, val);
00591          if (!result)
00592             return false;
00593          value = val->value;
00594          return true;
00595       }
00596 
00597 
00598       /** Returns the smallest value greater than or equal to the
00599        * key given
00600        */
00601       virtual bool successor(Address key, T *& value) const
00602       {
00603          entry *val;
00604          bool result = successor_internal(key, val);
00605          if (!result)
00606             return false;
00607          value = val->value;
00608          return true;
00609       }
00610 
00611       /** fill an buffer array with the sorted
00612        * elements of the addrRangeTree in ascending order according to comparison function
00613        * if the addrRangeTree is empty it retuns NULL, other wise it returns 
00614        * the input argument.
00615        */
00616       T ** elements(T ** buffer) const
00617       {
00618          if(setData == nil) return NULL;
00619          if(!buffer) return NULL;
00620          int tmp = 0;
00621          traverse(buffer,setData,tmp);  
00622          return buffer;
00623       }
00624 
00625 
00626       // And vector-style
00627       bool elements(pdvector<T *> &buffer) const
00628       {
00629          if(setData == nil) return false;
00630          traverse(buffer,setData);  
00631          return true;
00632       }
00633 
00634       // Remove all entries in the tree
00635       void clear()
00636       {
00637          if (setData == nil) return;
00638          destroy(setData);
00639          setData = nil;
00640          setSize = 0;
00641       }
00642 
00643 };
00644 
00645 #endif /* _addrRange_h_ */
00646 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1