Home | History | Annotate | Download | only in libyasm
      1 #include "util.h"
      2 
      3 #include <stdlib.h>
      4 #include <stdio.h>
      5 #include <limits.h>
      6 #include <math.h>
      7 #include "coretype.h"
      8 #include "inttree.h"
      9 
     10 #define VERIFY(condition) \
     11 if (!(condition)) { \
     12 fprintf(stderr, "Assumption \"%s\"\nFailed in file %s: at line:%i\n", \
     13 #condition,__FILE__,__LINE__); \
     14 abort();}
     15 
     16 /*#define DEBUG_ASSERT 1*/
     17 
     18 #ifdef DEBUG_ASSERT
     19 static void Assert(int assertion, const char *error)
     20 {
     21     if (!assertion) {
     22         fprintf(stderr, "Assertion Failed: %s\n", error);
     23         abort();
     24     }
     25 }
     26 #endif
     27 
     28 /* If the symbol CHECK_INTERVAL_TREE_ASSUMPTIONS is defined then the
     29  * code does a lot of extra checking to make sure certain assumptions
     30  * are satisfied.  This only needs to be done if you suspect bugs are
     31  * present or if you make significant changes and want to make sure
     32  * your changes didn't mess anything up.
     33  */
     34 /*#define CHECK_INTERVAL_TREE_ASSUMPTIONS 1*/
     35 
     36 static IntervalTreeNode *ITN_create(long low, long high, void *data);
     37 
     38 static void LeftRotate(IntervalTree *, IntervalTreeNode *);
     39 static void RightRotate(IntervalTree *, IntervalTreeNode *);
     40 static void TreeInsertHelp(IntervalTree *, IntervalTreeNode *);
     41 static void TreePrintHelper(const IntervalTree *, IntervalTreeNode *);
     42 static void FixUpMaxHigh(IntervalTree *, IntervalTreeNode *);
     43 static void DeleteFixUp(IntervalTree *, IntervalTreeNode *);
     44 #ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
     45 static void CheckMaxHighFields(const IntervalTree *, IntervalTreeNode *);
     46 static int CheckMaxHighFieldsHelper(const IntervalTree *, IntervalTreeNode *y,
     47                                     const int currentHigh, int match);
     48 static void IT_CheckAssumptions(const IntervalTree *);
     49 #endif
     50 
     51 /* define a function to find the maximum of two objects. */
     52 #define ITMax(a, b) ( (a > b) ? a : b )
     53 
     54 IntervalTreeNode *
     55 ITN_create(long low, long high, void *data)
     56 {
     57     IntervalTreeNode *itn = yasm_xmalloc(sizeof(IntervalTreeNode));
     58     itn->data = data;
     59     if (low < high) {
     60         itn->low = low;
     61         itn->high = high;
     62     } else {
     63         itn->low = high;
     64         itn->high = low;
     65     }
     66     itn->maxHigh = high;
     67     return itn;
     68 }
     69 
     70 IntervalTree *
     71 IT_create(void)
     72 {
     73     IntervalTree *it = yasm_xmalloc(sizeof(IntervalTree));
     74 
     75     it->nil = ITN_create(LONG_MIN, LONG_MIN, NULL);
     76     it->nil->left = it->nil;
     77     it->nil->right = it->nil;
     78     it->nil->parent = it->nil;
     79     it->nil->red = 0;
     80 
     81     it->root = ITN_create(LONG_MAX, LONG_MAX, NULL);
     82     it->root->left = it->nil;
     83     it->root->right = it->nil;
     84     it->root->parent = it->nil;
     85     it->root->red = 0;
     86 
     87     /* the following are used for the Enumerate function */
     88     it->recursionNodeStackSize = 128;
     89     it->recursionNodeStack = (it_recursion_node *)
     90         yasm_xmalloc(it->recursionNodeStackSize*sizeof(it_recursion_node));
     91     it->recursionNodeStackTop = 1;
     92     it->recursionNodeStack[0].start_node = NULL;
     93 
     94     return it;
     95 }
     96 
     97 /***********************************************************************/
     98 /*  FUNCTION:  LeftRotate */
     99 /**/
    100 /*  INPUTS:  the node to rotate on */
    101 /**/
    102 /*  OUTPUT:  None */
    103 /**/
    104 /*  Modifies Input: this, x */
    105 /**/
    106 /*  EFFECTS:  Rotates as described in _Introduction_To_Algorithms by */
    107 /*            Cormen, Leiserson, Rivest (Chapter 14).  Basically this */
    108 /*            makes the parent of x be to the left of x, x the parent of */
    109 /*            its parent before the rotation and fixes other pointers */
    110 /*            accordingly. Also updates the maxHigh fields of x and y */
    111 /*            after rotation. */
    112 /***********************************************************************/
    113 
    114 static void
    115 LeftRotate(IntervalTree *it, IntervalTreeNode *x)
    116 {
    117     IntervalTreeNode *y;
    118 
    119     /* I originally wrote this function to use the sentinel for
    120      * nil to avoid checking for nil.  However this introduces a
    121      * very subtle bug because sometimes this function modifies
    122      * the parent pointer of nil.  This can be a problem if a
    123      * function which calls LeftRotate also uses the nil sentinel
    124      * and expects the nil sentinel's parent pointer to be unchanged
    125      * after calling this function.  For example, when DeleteFixUP
    126      * calls LeftRotate it expects the parent pointer of nil to be
    127      * unchanged.
    128      */
    129 
    130     y=x->right;
    131     x->right=y->left;
    132 
    133     if (y->left != it->nil)
    134         y->left->parent=x; /* used to use sentinel here */
    135     /* and do an unconditional assignment instead of testing for nil */
    136 
    137     y->parent=x->parent;
    138 
    139     /* Instead of checking if x->parent is the root as in the book, we
    140      * count on the root sentinel to implicitly take care of this case
    141      */
    142     if (x == x->parent->left)
    143         x->parent->left=y;
    144     else
    145         x->parent->right=y;
    146     y->left=x;
    147     x->parent=y;
    148 
    149     x->maxHigh=ITMax(x->left->maxHigh,ITMax(x->right->maxHigh,x->high));
    150     y->maxHigh=ITMax(x->maxHigh,ITMax(y->right->maxHigh,y->high));
    151 #ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
    152     IT_CheckAssumptions(it);
    153 #elif defined(DEBUG_ASSERT)
    154     Assert(!it->nil->red,"nil not red in ITLeftRotate");
    155     Assert((it->nil->maxHigh=LONG_MIN),
    156            "nil->maxHigh != LONG_MIN in ITLeftRotate");
    157 #endif
    158 }
    159 
    160 
    161 /***********************************************************************/
    162 /*  FUNCTION:  RightRotate */
    163 /**/
    164 /*  INPUTS:  node to rotate on */
    165 /**/
    166 /*  OUTPUT:  None */
    167 /**/
    168 /*  Modifies Input?: this, y */
    169 /**/
    170 /*  EFFECTS:  Rotates as described in _Introduction_To_Algorithms by */
    171 /*            Cormen, Leiserson, Rivest (Chapter 14).  Basically this */
    172 /*            makes the parent of x be to the left of x, x the parent of */
    173 /*            its parent before the rotation and fixes other pointers */
    174 /*            accordingly. Also updates the maxHigh fields of x and y */
    175 /*            after rotation. */
    176 /***********************************************************************/
    177 
    178 
    179 static void
    180 RightRotate(IntervalTree *it, IntervalTreeNode *y)
    181 {
    182     IntervalTreeNode *x;
    183 
    184     /* I originally wrote this function to use the sentinel for
    185      * nil to avoid checking for nil.  However this introduces a
    186      * very subtle bug because sometimes this function modifies
    187      * the parent pointer of nil.  This can be a problem if a
    188      * function which calls LeftRotate also uses the nil sentinel
    189      * and expects the nil sentinel's parent pointer to be unchanged
    190      * after calling this function.  For example, when DeleteFixUP
    191      * calls LeftRotate it expects the parent pointer of nil to be
    192      * unchanged.
    193      */
    194 
    195     x=y->left;
    196     y->left=x->right;
    197 
    198     if (it->nil != x->right)
    199         x->right->parent=y; /*used to use sentinel here */
    200     /* and do an unconditional assignment instead of testing for nil */
    201 
    202     /* Instead of checking if x->parent is the root as in the book, we
    203      * count on the root sentinel to implicitly take care of this case
    204      */
    205     x->parent=y->parent;
    206     if (y == y->parent->left)
    207         y->parent->left=x;
    208     else
    209         y->parent->right=x;
    210     x->right=y;
    211     y->parent=x;
    212 
    213     y->maxHigh=ITMax(y->left->maxHigh,ITMax(y->right->maxHigh,y->high));
    214     x->maxHigh=ITMax(x->left->maxHigh,ITMax(y->maxHigh,x->high));
    215 #ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
    216     IT_CheckAssumptions(it);
    217 #elif defined(DEBUG_ASSERT)
    218     Assert(!it->nil->red,"nil not red in ITRightRotate");
    219     Assert((it->nil->maxHigh=LONG_MIN),
    220            "nil->maxHigh != LONG_MIN in ITRightRotate");
    221 #endif
    222 }
    223 
    224 /***********************************************************************/
    225 /*  FUNCTION:  TreeInsertHelp  */
    226 /**/
    227 /*  INPUTS:  z is the node to insert */
    228 /**/
    229 /*  OUTPUT:  none */
    230 /**/
    231 /*  Modifies Input:  this, z */
    232 /**/
    233 /*  EFFECTS:  Inserts z into the tree as if it were a regular binary tree */
    234 /*            using the algorithm described in _Introduction_To_Algorithms_ */
    235 /*            by Cormen et al.  This funciton is only intended to be called */
    236 /*            by the InsertTree function and not by the user */
    237 /***********************************************************************/
    238 
    239 static void
    240 TreeInsertHelp(IntervalTree *it, IntervalTreeNode *z)
    241 {
    242     /*  This function should only be called by InsertITTree (see above) */
    243     IntervalTreeNode* x;
    244     IntervalTreeNode* y;
    245 
    246     z->left=z->right=it->nil;
    247     y=it->root;
    248     x=it->root->left;
    249     while( x != it->nil) {
    250         y=x;
    251         if (x->low > z->low)
    252             x=x->left;
    253         else /* x->low <= z->low */
    254             x=x->right;
    255     }
    256     z->parent=y;
    257     if ((y == it->root) || (y->low > z->low))
    258         y->left=z;
    259     else
    260         y->right=z;
    261 
    262 #if defined(DEBUG_ASSERT)
    263     Assert(!it->nil->red,"nil not red in ITTreeInsertHelp");
    264     Assert((it->nil->maxHigh=INT_MIN),
    265            "nil->maxHigh != INT_MIN in ITTreeInsertHelp");
    266 #endif
    267 }
    268 
    269 
    270 /***********************************************************************/
    271 /*  FUNCTION:  FixUpMaxHigh  */
    272 /**/
    273 /*  INPUTS:  x is the node to start from*/
    274 /**/
    275 /*  OUTPUT:  none */
    276 /**/
    277 /*  Modifies Input:  this */
    278 /**/
    279 /*  EFFECTS:  Travels up to the root fixing the maxHigh fields after */
    280 /*            an insertion or deletion */
    281 /***********************************************************************/
    282 
    283 static void
    284 FixUpMaxHigh(IntervalTree *it, IntervalTreeNode *x)
    285 {
    286     while(x != it->root) {
    287         x->maxHigh=ITMax(x->high,ITMax(x->left->maxHigh,x->right->maxHigh));
    288         x=x->parent;
    289     }
    290 #ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
    291     IT_CheckAssumptions(it);
    292 #endif
    293 }
    294 
    295 /*  Before calling InsertNode  the node x should have its key set */
    296 
    297 /***********************************************************************/
    298 /*  FUNCTION:  InsertNode */
    299 /**/
    300 /*  INPUTS:  newInterval is the interval to insert*/
    301 /**/
    302 /*  OUTPUT:  This function returns a pointer to the newly inserted node */
    303 /*           which is guarunteed to be valid until this node is deleted. */
    304 /*           What this means is if another data structure stores this */
    305 /*           pointer then the tree does not need to be searched when this */
    306 /*           is to be deleted. */
    307 /**/
    308 /*  Modifies Input: tree */
    309 /**/
    310 /*  EFFECTS:  Creates a node node which contains the appropriate key and */
    311 /*            info pointers and inserts it into the tree. */
    312 /***********************************************************************/
    313 
    314 IntervalTreeNode *
    315 IT_insert(IntervalTree *it, long low, long high, void *data)
    316 {
    317     IntervalTreeNode *x, *y, *newNode;
    318 
    319     x = ITN_create(low, high, data);
    320     TreeInsertHelp(it, x);
    321     FixUpMaxHigh(it, x->parent);
    322     newNode = x;
    323     x->red=1;
    324     while(x->parent->red) { /* use sentinel instead of checking for root */
    325         if (x->parent == x->parent->parent->left) {
    326             y=x->parent->parent->right;
    327             if (y->red) {
    328                 x->parent->red=0;
    329                 y->red=0;
    330                 x->parent->parent->red=1;
    331                 x=x->parent->parent;
    332             } else {
    333                 if (x == x->parent->right) {
    334                     x=x->parent;
    335                     LeftRotate(it, x);
    336                 }
    337                 x->parent->red=0;
    338                 x->parent->parent->red=1;
    339                 RightRotate(it, x->parent->parent);
    340             }
    341         } else { /* case for x->parent == x->parent->parent->right */
    342              /* this part is just like the section above with */
    343              /* left and right interchanged */
    344             y=x->parent->parent->left;
    345             if (y->red) {
    346                 x->parent->red=0;
    347                 y->red=0;
    348                 x->parent->parent->red=1;
    349                 x=x->parent->parent;
    350             } else {
    351                 if (x == x->parent->left) {
    352                     x=x->parent;
    353                     RightRotate(it, x);
    354                 }
    355                 x->parent->red=0;
    356                 x->parent->parent->red=1;
    357                 LeftRotate(it, x->parent->parent);
    358             }
    359         }
    360     }
    361     it->root->left->red=0;
    362 
    363 #ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
    364     IT_CheckAssumptions(it);
    365 #elif defined(DEBUG_ASSERT)
    366     Assert(!it->nil->red,"nil not red in ITTreeInsert");
    367     Assert(!it->root->red,"root not red in ITTreeInsert");
    368     Assert((it->nil->maxHigh=LONG_MIN),
    369            "nil->maxHigh != LONG_MIN in ITTreeInsert");
    370 #endif
    371     return newNode;
    372 }
    373 
    374 /***********************************************************************/
    375 /*  FUNCTION:  GetSuccessorOf  */
    376 /**/
    377 /*    INPUTS:  x is the node we want the succesor of */
    378 /**/
    379 /*    OUTPUT:  This function returns the successor of x or NULL if no */
    380 /*             successor exists. */
    381 /**/
    382 /*    Modifies Input: none */
    383 /**/
    384 /*    Note:  uses the algorithm in _Introduction_To_Algorithms_ */
    385 /***********************************************************************/
    386 
    387 IntervalTreeNode *
    388 IT_get_successor(const IntervalTree *it, IntervalTreeNode *x)
    389 {
    390     IntervalTreeNode *y;
    391 
    392     if (it->nil != (y = x->right)) { /* assignment to y is intentional */
    393         while(y->left != it->nil) /* returns the minium of the right subtree of x */
    394             y=y->left;
    395         return y;
    396     } else {
    397         y=x->parent;
    398         while(x == y->right) { /* sentinel used instead of checking for nil */
    399             x=y;
    400             y=y->parent;
    401         }
    402         if (y == it->root)
    403             return(it->nil);
    404         return y;
    405     }
    406 }
    407 
    408 /***********************************************************************/
    409 /*  FUNCTION:  GetPredecessorOf  */
    410 /**/
    411 /*    INPUTS:  x is the node to get predecessor of */
    412 /**/
    413 /*    OUTPUT:  This function returns the predecessor of x or NULL if no */
    414 /*             predecessor exists. */
    415 /**/
    416 /*    Modifies Input: none */
    417 /**/
    418 /*    Note:  uses the algorithm in _Introduction_To_Algorithms_ */
    419 /***********************************************************************/
    420 
    421 IntervalTreeNode *
    422 IT_get_predecessor(const IntervalTree *it, IntervalTreeNode *x)
    423 {
    424     IntervalTreeNode *y;
    425 
    426     if (it->nil != (y = x->left)) { /* assignment to y is intentional */
    427         while(y->right != it->nil) /* returns the maximum of the left subtree of x */
    428             y=y->right;
    429         return y;
    430     } else {
    431         y=x->parent;
    432         while(x == y->left) {
    433             if (y == it->root)
    434                 return(it->nil);
    435             x=y;
    436             y=y->parent;
    437         }
    438         return y;
    439     }
    440 }
    441 
    442 /***********************************************************************/
    443 /*  FUNCTION:  Print */
    444 /**/
    445 /*    INPUTS:  none */
    446 /**/
    447 /*    OUTPUT:  none  */
    448 /**/
    449 /*    EFFECTS:  This function recursively prints the nodes of the tree */
    450 /*              inorder. */
    451 /**/
    452 /*    Modifies Input: none */
    453 /**/
    454 /*    Note:    This function should only be called from ITTreePrint */
    455 /***********************************************************************/
    456 
    457 static void
    458 ITN_print(const IntervalTreeNode *itn, IntervalTreeNode *nil,
    459           IntervalTreeNode *root)
    460 {
    461     printf(", l=%li, h=%li, mH=%li", itn->low, itn->high, itn->maxHigh);
    462     printf("  l->low=");
    463     if (itn->left == nil)
    464         printf("NULL");
    465     else
    466         printf("%li", itn->left->low);
    467     printf("  r->low=");
    468     if (itn->right == nil)
    469         printf("NULL");
    470     else
    471         printf("%li", itn->right->low);
    472     printf("  p->low=");
    473     if (itn->parent == root)
    474         printf("NULL");
    475     else
    476         printf("%li", itn->parent->low);
    477     printf("  red=%i\n", itn->red);
    478 }
    479 
    480 static void
    481 TreePrintHelper(const IntervalTree *it, IntervalTreeNode *x)
    482 {
    483     if (x != it->nil) {
    484         TreePrintHelper(it, x->left);
    485         ITN_print(x, it->nil, it->root);
    486         TreePrintHelper(it, x->right);
    487     }
    488 }
    489 
    490 void
    491 IT_destroy(IntervalTree *it)
    492 {
    493     IntervalTreeNode *x = it->root->left;
    494     SLIST_HEAD(node_head, nodeent)
    495         stuffToFree = SLIST_HEAD_INITIALIZER(stuffToFree);
    496     struct nodeent {
    497         SLIST_ENTRY(nodeent) link;
    498         struct IntervalTreeNode *node;
    499     } *np;
    500 
    501     if (x != it->nil) {
    502         if (x->left != it->nil) {
    503             np = yasm_xmalloc(sizeof(struct nodeent));
    504             np->node = x->left;
    505             SLIST_INSERT_HEAD(&stuffToFree, np, link);
    506         }
    507         if (x->right != it->nil) {
    508             np = yasm_xmalloc(sizeof(struct nodeent));
    509             np->node = x->right;
    510             SLIST_INSERT_HEAD(&stuffToFree, np, link);
    511         }
    512         yasm_xfree(x);
    513         while (!SLIST_EMPTY(&stuffToFree)) {
    514             np = SLIST_FIRST(&stuffToFree);
    515             x = np->node;
    516             SLIST_REMOVE_HEAD(&stuffToFree, link);
    517             yasm_xfree(np);
    518 
    519             if (x->left != it->nil) {
    520                 np = yasm_xmalloc(sizeof(struct nodeent));
    521                 np->node = x->left;
    522                 SLIST_INSERT_HEAD(&stuffToFree, np, link);
    523             }
    524             if (x->right != it->nil) {
    525                 np = yasm_xmalloc(sizeof(struct nodeent));
    526                 np->node = x->right;
    527                 SLIST_INSERT_HEAD(&stuffToFree, np, link);
    528             }
    529             yasm_xfree(x);
    530         }
    531     }
    532 
    533     yasm_xfree(it->nil);
    534     yasm_xfree(it->root);
    535     yasm_xfree(it->recursionNodeStack);
    536     yasm_xfree(it);
    537 }
    538 
    539 
    540 /***********************************************************************/
    541 /*  FUNCTION:  Print */
    542 /**/
    543 /*    INPUTS:  none */
    544 /**/
    545 /*    OUTPUT:  none */
    546 /**/
    547 /*    EFFECT:  This function recursively prints the nodes of the tree */
    548 /*             inorder. */
    549 /**/
    550 /*    Modifies Input: none */
    551 /**/
    552 /***********************************************************************/
    553 
    554 void
    555 IT_print(const IntervalTree *it)
    556 {
    557     TreePrintHelper(it, it->root->left);
    558 }
    559 
    560 /***********************************************************************/
    561 /*  FUNCTION:  DeleteFixUp */
    562 /**/
    563 /*    INPUTS:  x is the child of the spliced */
    564 /*             out node in DeleteNode. */
    565 /**/
    566 /*    OUTPUT:  none */
    567 /**/
    568 /*    EFFECT:  Performs rotations and changes colors to restore red-black */
    569 /*             properties after a node is deleted */
    570 /**/
    571 /*    Modifies Input: this, x */
    572 /**/
    573 /*    The algorithm from this function is from _Introduction_To_Algorithms_ */
    574 /***********************************************************************/
    575 
    576 static void
    577 DeleteFixUp(IntervalTree *it, IntervalTreeNode *x)
    578 {
    579     IntervalTreeNode *w;
    580     IntervalTreeNode *rootLeft = it->root->left;
    581 
    582     while ((!x->red) && (rootLeft != x)) {
    583         if (x == x->parent->left) {
    584             w=x->parent->right;
    585             if (w->red) {
    586                 w->red=0;
    587                 x->parent->red=1;
    588                 LeftRotate(it, x->parent);
    589                 w=x->parent->right;
    590             }
    591             if ( (!w->right->red) && (!w->left->red) ) {
    592                 w->red=1;
    593                 x=x->parent;
    594             } else {
    595                 if (!w->right->red) {
    596                     w->left->red=0;
    597                     w->red=1;
    598                     RightRotate(it, w);
    599                     w=x->parent->right;
    600                 }
    601                 w->red=x->parent->red;
    602                 x->parent->red=0;
    603                 w->right->red=0;
    604                 LeftRotate(it, x->parent);
    605                 x=rootLeft; /* this is to exit while loop */
    606             }
    607         } else { /* the code below is has left and right switched from above */
    608             w=x->parent->left;
    609             if (w->red) {
    610                 w->red=0;
    611                 x->parent->red=1;
    612                 RightRotate(it, x->parent);
    613                 w=x->parent->left;
    614             }
    615             if ((!w->right->red) && (!w->left->red)) {
    616                 w->red=1;
    617                 x=x->parent;
    618             } else {
    619                 if (!w->left->red) {
    620                     w->right->red=0;
    621                     w->red=1;
    622                     LeftRotate(it, w);
    623                     w=x->parent->left;
    624                 }
    625                 w->red=x->parent->red;
    626                 x->parent->red=0;
    627                 w->left->red=0;
    628                 RightRotate(it, x->parent);
    629                 x=rootLeft; /* this is to exit while loop */
    630             }
    631         }
    632     }
    633     x->red=0;
    634 
    635 #ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
    636     IT_CheckAssumptions(it);
    637 #elif defined(DEBUG_ASSERT)
    638     Assert(!it->nil->red,"nil not black in ITDeleteFixUp");
    639     Assert((it->nil->maxHigh=LONG_MIN),
    640            "nil->maxHigh != LONG_MIN in ITDeleteFixUp");
    641 #endif
    642 }
    643 
    644 
    645 /***********************************************************************/
    646 /*  FUNCTION:  DeleteNode */
    647 /**/
    648 /*    INPUTS:  tree is the tree to delete node z from */
    649 /**/
    650 /*    OUTPUT:  returns the Interval stored at deleted node */
    651 /**/
    652 /*    EFFECT:  Deletes z from tree and but don't call destructor */
    653 /*             Then calls FixUpMaxHigh to fix maxHigh fields then calls */
    654 /*             ITDeleteFixUp to restore red-black properties */
    655 /**/
    656 /*    Modifies Input:  z */
    657 /**/
    658 /*    The algorithm from this function is from _Introduction_To_Algorithms_ */
    659 /***********************************************************************/
    660 
    661 void *
    662 IT_delete_node(IntervalTree *it, IntervalTreeNode *z, long *low, long *high)
    663 {
    664     IntervalTreeNode *x, *y;
    665     void *returnValue = z->data;
    666     if (low)
    667         *low = z->low;
    668     if (high)
    669         *high = z->high;
    670 
    671     y= ((z->left == it->nil) || (z->right == it->nil)) ?
    672         z : IT_get_successor(it, z);
    673     x= (y->left == it->nil) ? y->right : y->left;
    674     if (it->root == (x->parent = y->parent))
    675         /* assignment of y->p to x->p is intentional */
    676         it->root->left=x;
    677     else {
    678         if (y == y->parent->left)
    679             y->parent->left=x;
    680         else
    681             y->parent->right=x;
    682     }
    683     if (y != z) { /* y should not be nil in this case */
    684 
    685 #ifdef DEBUG_ASSERT
    686         Assert( (y!=it->nil),"y is nil in DeleteNode \n");
    687 #endif
    688         /* y is the node to splice out and x is its child */
    689 
    690         y->maxHigh = INT_MIN;
    691         y->left=z->left;
    692         y->right=z->right;
    693         y->parent=z->parent;
    694         z->left->parent=z->right->parent=y;
    695         if (z == z->parent->left)
    696             z->parent->left=y;
    697         else
    698             z->parent->right=y;
    699         FixUpMaxHigh(it, x->parent);
    700         if (!(y->red)) {
    701             y->red = z->red;
    702             DeleteFixUp(it, x);
    703         } else
    704             y->red = z->red;
    705         yasm_xfree(z);
    706 #ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
    707         IT_CheckAssumptions(it);
    708 #elif defined(DEBUG_ASSERT)
    709         Assert(!it->nil->red,"nil not black in ITDelete");
    710         Assert((it->nil->maxHigh=LONG_MIN),"nil->maxHigh != LONG_MIN in ITDelete");
    711 #endif
    712     } else {
    713         FixUpMaxHigh(it, x->parent);
    714         if (!(y->red))
    715             DeleteFixUp(it, x);
    716         yasm_xfree(y);
    717 #ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
    718         IT_CheckAssumptions(it);
    719 #elif defined(DEBUG_ASSERT)
    720         Assert(!it->nil->red,"nil not black in ITDelete");
    721         Assert((it->nil->maxHigh=LONG_MIN),"nil->maxHigh != LONG_MIN in ITDelete");
    722 #endif
    723     }
    724     return returnValue;
    725 }
    726 
    727 
    728 /***********************************************************************/
    729 /*  FUNCTION:  Overlap */
    730 /**/
    731 /*    INPUTS:  [a1,a2] and [b1,b2] are the low and high endpoints of two */
    732 /*             closed intervals.  */
    733 /**/
    734 /*    OUTPUT:  stack containing pointers to the nodes between [low,high] */
    735 /**/
    736 /*    Modifies Input: none */
    737 /**/
    738 /*    EFFECT:  returns 1 if the intervals overlap, and 0 otherwise */
    739 /***********************************************************************/
    740 
    741 static int
    742 Overlap(int a1, int a2, int b1, int b2)
    743 {
    744     if (a1 <= b1)
    745         return (b1 <= a2);
    746     else
    747         return (a1 <= b2);
    748 }
    749 
    750 
    751 /***********************************************************************/
    752 /*  FUNCTION:  Enumerate */
    753 /**/
    754 /*    INPUTS:  tree is the tree to look for intervals overlapping the */
    755 /*             closed interval [low,high]  */
    756 /**/
    757 /*    OUTPUT:  stack containing pointers to the nodes overlapping */
    758 /*             [low,high] */
    759 /**/
    760 /*    Modifies Input: none */
    761 /**/
    762 /*    EFFECT:  Returns a stack containing pointers to nodes containing */
    763 /*             intervals which overlap [low,high] in O(max(N,k*log(N))) */
    764 /*             where N is the number of intervals in the tree and k is  */
    765 /*             the number of overlapping intervals                      */
    766 /**/
    767 /*    Note:    This basic idea for this function comes from the  */
    768 /*              _Introduction_To_Algorithms_ book by Cormen et al, but */
    769 /*             modifications were made to return all overlapping intervals */
    770 /*             instead of just the first overlapping interval as in the */
    771 /*             book.  The natural way to do this would require recursive */
    772 /*             calls of a basic search function.  I translated the */
    773 /*             recursive version into an interative version with a stack */
    774 /*             as described below. */
    775 /***********************************************************************/
    776 
    777 
    778 
    779 /* The basic idea for the function below is to take the IntervalSearch
    780  * function from the book and modify to find all overlapping intervals
    781  * instead of just one.  This means that any time we take the left
    782  * branch down the tree we must also check the right branch if and only if
    783  * we find an overlapping interval in that left branch.  Note this is a
    784  * recursive condition because if we go left at the root then go left
    785  * again at the first left child and find an overlap in the left subtree
    786  * of the left child of root we must recursively check the right subtree
    787  * of the left child of root as well as the right child of root.
    788  */
    789 void
    790 IT_enumerate(IntervalTree *it, long low, long high, void *cbd,
    791              void (*callback) (IntervalTreeNode *node, void *cbd))
    792 {
    793     IntervalTreeNode *x=it->root->left;
    794     int stuffToDo = (x != it->nil);
    795 
    796     /* Possible speed up: add min field to prune right searches */
    797 
    798 #ifdef DEBUG_ASSERT
    799     Assert((it->recursionNodeStackTop == 1),
    800            "recursionStack not empty when entering IntervalTree::Enumerate");
    801 #endif
    802     it->currentParent = 0;
    803 
    804     while (stuffToDo) {
    805         if (Overlap(low,high,x->low,x->high) ) {
    806             callback(x, cbd);
    807             it->recursionNodeStack[it->currentParent].tryRightBranch=1;
    808         }
    809         if(x->left->maxHigh >= low) { /* implies x != nil */
    810             if (it->recursionNodeStackTop == it->recursionNodeStackSize) {
    811                 it->recursionNodeStackSize *= 2;
    812                 it->recursionNodeStack = (it_recursion_node *)
    813                     yasm_xrealloc(it->recursionNodeStack,
    814                                   it->recursionNodeStackSize * sizeof(it_recursion_node));
    815             }
    816             it->recursionNodeStack[it->recursionNodeStackTop].start_node = x;
    817             it->recursionNodeStack[it->recursionNodeStackTop].tryRightBranch = 0;
    818             it->recursionNodeStack[it->recursionNodeStackTop].parentIndex = it->currentParent;
    819             it->currentParent = it->recursionNodeStackTop++;
    820             x = x->left;
    821         } else {
    822             x = x->right;
    823         }
    824         stuffToDo = (x != it->nil);
    825         while (!stuffToDo && (it->recursionNodeStackTop > 1)) {
    826             if (it->recursionNodeStack[--it->recursionNodeStackTop].tryRightBranch) {
    827                 x=it->recursionNodeStack[it->recursionNodeStackTop].start_node->right;
    828                 it->currentParent=it->recursionNodeStack[it->recursionNodeStackTop].parentIndex;
    829                 it->recursionNodeStack[it->currentParent].tryRightBranch=1;
    830                 stuffToDo = (x != it->nil);
    831             }
    832         }
    833     }
    834 #ifdef DEBUG_ASSERT
    835     Assert((it->recursionNodeStackTop == 1),
    836            "recursionStack not empty when exiting IntervalTree::Enumerate");
    837 #endif
    838 }
    839 
    840 #ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
    841 
    842 static int
    843 CheckMaxHighFieldsHelper(const IntervalTree *it, IntervalTreeNode *y,
    844                          int currentHigh, int match)
    845 {
    846     if (y != it->nil) {
    847         match = CheckMaxHighFieldsHelper(it, y->left, currentHigh, match) ?
    848             1 : match;
    849         VERIFY(y->high <= currentHigh);
    850         if (y->high == currentHigh)
    851             match = 1;
    852         match = CheckMaxHighFieldsHelper(it, y->right, currentHigh, match) ?
    853             1 : match;
    854     }
    855     return match;
    856 }
    857 
    858 
    859 
    860 /* Make sure the maxHigh fields for everything makes sense. *
    861  * If something is wrong, print a warning and exit */
    862 static void
    863 CheckMaxHighFields(const IntervalTree *it, IntervalTreeNode *x)
    864 {
    865     if (x != it->nil) {
    866         CheckMaxHighFields(it, x->left);
    867         if(!(CheckMaxHighFieldsHelper(it, x, x->maxHigh, 0) > 0)) {
    868             fprintf(stderr, "error found in CheckMaxHighFields.\n");
    869             abort();
    870         }
    871         CheckMaxHighFields(it, x->right);
    872     }
    873 }
    874 
    875 static void
    876 IT_CheckAssumptions(const IntervalTree *it)
    877 {
    878     VERIFY(it->nil->low == INT_MIN);
    879     VERIFY(it->nil->high == INT_MIN);
    880     VERIFY(it->nil->maxHigh == INT_MIN);
    881     VERIFY(it->root->low == INT_MAX);
    882     VERIFY(it->root->high == INT_MAX);
    883     VERIFY(it->root->maxHigh == INT_MAX);
    884     VERIFY(it->nil->data == NULL);
    885     VERIFY(it->root->data == NULL);
    886     VERIFY(it->nil->red == 0);
    887     VERIFY(it->root->red == 0);
    888     CheckMaxHighFields(it, it->root->left);
    889 }
    890 #endif
    891 
    892