inttree.c 28 KB

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