Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/leptonica/src/rbtree.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /*====================================================================* | |
| 2 - Copyright (C) 2001 Leptonica. All rights reserved. | |
| 3 - | |
| 4 - Redistribution and use in source and binary forms, with or without | |
| 5 - modification, are permitted provided that the following conditions | |
| 6 - are met: | |
| 7 - 1. Redistributions of source code must retain the above copyright | |
| 8 - notice, this list of conditions and the following disclaimer. | |
| 9 - 2. Redistributions in binary form must reproduce the above | |
| 10 - copyright notice, this list of conditions and the following | |
| 11 - disclaimer in the documentation and/or other materials | |
| 12 - provided with the distribution. | |
| 13 - | |
| 14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY | |
| 18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
| 19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
| 21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
| 22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
| 23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 25 *====================================================================*/ | |
| 26 | |
| 27 /* | |
| 28 * Modified from the excellent code here: | |
| 29 * http://en.literateprograms.org/Red-black_tree_(C)?oldid=19567 | |
| 30 * which has been placed in the public domain under the Creative Commons | |
| 31 * CC0 1.0 waiver (http://creativecommons.org/publicdomain/zero/1.0/). | |
| 32 */ | |
| 33 | |
| 34 /*! | |
| 35 * \file rbtree.c | |
| 36 * <pre> | |
| 37 * | |
| 38 * Basic functions for using red-black trees. These are "nearly" balanced | |
| 39 * sorted trees with ordering by key that allows insertion, lookup and | |
| 40 * deletion of key/value pairs in log(n) time. | |
| 41 * | |
| 42 * We use red-black trees to implement our version of: | |
| 43 * * a map: a function that maps keys to values (e.g., int64 --> int64). | |
| 44 * * a set: a collection that is sorted by unique keys (without | |
| 45 * associated values) | |
| 46 * | |
| 47 * There are 5 invariant properties of RB trees: | |
| 48 * (1) Each node is either red or black. | |
| 49 * (2) The root node is black. | |
| 50 * (3) All leaves are black and contain no data (null). | |
| 51 * (4) Every red node has two children and both are black. This is | |
| 52 * equivalent to requiring the parent of every red node to be black. | |
| 53 * (5) All paths from any given node to its leaf nodes contain the | |
| 54 * same number of black nodes. | |
| 55 * | |
| 56 * Interface to red-black tree | |
| 57 * L_RBTREE *l_rbtreeCreate() | |
| 58 * RB_TYPE *l_rbtreeLookup() | |
| 59 * void l_rbtreeInsert() | |
| 60 * void l_rbtreeDelete() | |
| 61 * void l_rbtreeDestroy() | |
| 62 * L_RBTREE_NODE *l_rbtreeGetFirst() | |
| 63 * L_RBTREE_NODE *l_rbtreeGetNext() | |
| 64 * L_RBTREE_NODE *l_rbtreeGetLast() | |
| 65 * L_RBTREE_NODE *l_rbtreeGetPrev() | |
| 66 * l_int32 l_rbtreeGetCount() | |
| 67 * void l_rbtreePrint() | |
| 68 * | |
| 69 * General comparison function | |
| 70 * static l_int32 compareKeys() | |
| 71 * </pre> | |
| 72 */ | |
| 73 | |
| 74 #ifdef HAVE_CONFIG_H | |
| 75 #include <config_auto.h> | |
| 76 #endif /* HAVE_CONFIG_H */ | |
| 77 | |
| 78 #include "allheaders.h" | |
| 79 | |
| 80 /* The node color enum is only needed in the rbtree implementation */ | |
| 81 enum { | |
| 82 L_RED_NODE = 1, | |
| 83 L_BLACK_NODE = 2 | |
| 84 }; | |
| 85 | |
| 86 /* This makes it simpler to read the code */ | |
| 87 typedef L_RBTREE_NODE node; | |
| 88 | |
| 89 /* Lots of static helper functions */ | |
| 90 static void destroy_helper(node *n); | |
| 91 static void count_helper(node *n, l_int32 *pcount); | |
| 92 static void print_tree_helper(FILE *fp, node *n, l_int32 keytype, | |
| 93 l_int32 indent); | |
| 94 | |
| 95 static l_int32 compareKeys(l_int32 keytype, RB_TYPE left, RB_TYPE right); | |
| 96 | |
| 97 static node *grandparent(node *n); | |
| 98 static node *sibling(node *n); | |
| 99 static node *uncle(node *n); | |
| 100 static l_int32 node_color(node *n); | |
| 101 static node *new_node(RB_TYPE key, RB_TYPE value, l_int32 node_color, | |
| 102 node *left, node *right); | |
| 103 static node *lookup_node(L_RBTREE *t, RB_TYPE key); | |
| 104 static void rotate_left(L_RBTREE *t, node *n); | |
| 105 static void rotate_right(L_RBTREE *t, node *n); | |
| 106 static void replace_node(L_RBTREE *t, node *oldn, node *newn); | |
| 107 static void insert_case1(L_RBTREE *t, node *n); | |
| 108 static void insert_case2(L_RBTREE *t, node *n); | |
| 109 static void insert_case3(L_RBTREE *t, node *n); | |
| 110 static void insert_case4(L_RBTREE *t, node *n); | |
| 111 static void insert_case5(L_RBTREE *t, node *n); | |
| 112 static node *maximum_node(node *root); | |
| 113 static void delete_case1(L_RBTREE *t, node *n); | |
| 114 static void delete_case2(L_RBTREE *t, node *n); | |
| 115 static void delete_case3(L_RBTREE *t, node *n); | |
| 116 static void delete_case4(L_RBTREE *t, node *n); | |
| 117 static void delete_case5(L_RBTREE *t, node *n); | |
| 118 static void delete_case6(L_RBTREE *t, node *n); | |
| 119 static void verify_properties(L_RBTREE *t); | |
| 120 | |
| 121 #ifndef NO_CONSOLE_IO | |
| 122 #define VERIFY_RBTREE 0 /* only for debugging */ | |
| 123 #endif /* ~NO_CONSOLE_IO */ | |
| 124 | |
| 125 /* ------------------------------------------------------------- * | |
| 126 * Interface to Red-black Tree * | |
| 127 * ------------------------------------------------------------- */ | |
| 128 /*! | |
| 129 * \brief l_rbtreeCreate() | |
| 130 * | |
| 131 * \param[in] keytype defined by an enum for an RB_TYPE union | |
| 132 * \return rbtree container with empty ptr to the root | |
| 133 */ | |
| 134 L_RBTREE * | |
| 135 l_rbtreeCreate(l_int32 keytype) | |
| 136 { | |
| 137 L_RBTREE *t; | |
| 138 | |
| 139 if (keytype != L_INT_TYPE && keytype != L_UINT_TYPE && | |
| 140 keytype != L_FLOAT_TYPE && keytype) | |
| 141 return (L_RBTREE *)ERROR_PTR("invalid keytype", __func__, NULL); | |
| 142 | |
| 143 t = (L_RBTREE *)LEPT_CALLOC(1, sizeof(L_RBTREE)); | |
| 144 t->keytype = keytype; | |
| 145 verify_properties(t); | |
| 146 return t; | |
| 147 } | |
| 148 | |
| 149 /*! | |
| 150 * \brief l_rbtreeLookup() | |
| 151 * | |
| 152 * \param[in] t rbtree, including root node | |
| 153 * \param[in] key find a node with this key | |
| 154 * \return &value a pointer to a union, if the node exists; else NULL | |
| 155 */ | |
| 156 RB_TYPE * | |
| 157 l_rbtreeLookup(L_RBTREE *t, | |
| 158 RB_TYPE key) | |
| 159 { | |
| 160 node *n; | |
| 161 | |
| 162 if (!t) | |
| 163 return (RB_TYPE *)ERROR_PTR("tree is null\n", __func__, NULL); | |
| 164 | |
| 165 n = lookup_node(t, key); | |
| 166 return n == NULL ? NULL : &n->value; | |
| 167 } | |
| 168 | |
| 169 /*! | |
| 170 * \brief l_rbtreeInsert() | |
| 171 * | |
| 172 * \param[in] t rbtree, including root node | |
| 173 * \param[in] key insert a node with this key, if the key does not | |
| 174 * already exist in the tree | |
| 175 * \param[in] value typically an int, used for an index | |
| 176 * \return void | |
| 177 * | |
| 178 * <pre> | |
| 179 * Notes: | |
| 180 * (1) If a node with the key already exists, this just updates the value. | |
| 181 * </pre> | |
| 182 */ | |
| 183 void | |
| 184 l_rbtreeInsert(L_RBTREE *t, | |
| 185 RB_TYPE key, | |
| 186 RB_TYPE value) | |
| 187 { | |
| 188 node *n, *inserted_node; | |
| 189 | |
| 190 if (!t) { | |
| 191 L_ERROR("tree is null\n", __func__); | |
| 192 return; | |
| 193 } | |
| 194 | |
| 195 inserted_node = new_node(key, value, L_RED_NODE, NULL, NULL); | |
| 196 if (t->root == NULL) { | |
| 197 t->root = inserted_node; | |
| 198 } else { | |
| 199 n = t->root; | |
| 200 while (1) { | |
| 201 int comp_result = compareKeys(t->keytype, key, n->key); | |
| 202 if (comp_result == 0) { | |
| 203 n->value = value; | |
| 204 LEPT_FREE(inserted_node); | |
| 205 return; | |
| 206 } else if (comp_result < 0) { | |
| 207 if (n->left == NULL) { | |
| 208 n->left = inserted_node; | |
| 209 break; | |
| 210 } else { | |
| 211 n = n->left; | |
| 212 } | |
| 213 } else { /* comp_result > 0 */ | |
| 214 if (n->right == NULL) { | |
| 215 n->right = inserted_node; | |
| 216 break; | |
| 217 } else { | |
| 218 n = n->right; | |
| 219 } | |
| 220 } | |
| 221 } | |
| 222 inserted_node->parent = n; | |
| 223 } | |
| 224 insert_case1(t, inserted_node); | |
| 225 verify_properties(t); | |
| 226 } | |
| 227 | |
| 228 /*! | |
| 229 * \brief l_rbtreeDelete() | |
| 230 * | |
| 231 * \param[in] t rbtree, including root node | |
| 232 * \param[in] key delete the node with this key | |
| 233 * \return void | |
| 234 */ | |
| 235 void | |
| 236 l_rbtreeDelete(L_RBTREE *t, | |
| 237 RB_TYPE key) | |
| 238 { | |
| 239 node *n, *child; | |
| 240 | |
| 241 if (!t) { | |
| 242 L_ERROR("tree is null\n", __func__); | |
| 243 return; | |
| 244 } | |
| 245 | |
| 246 n = lookup_node(t, key); | |
| 247 if (n == NULL) return; /* Key not found, do nothing */ | |
| 248 if (n->left != NULL && n->right != NULL) { | |
| 249 /* Copy key/value from predecessor and then delete it instead */ | |
| 250 node *pred = maximum_node(n->left); | |
| 251 n->key = pred->key; | |
| 252 n->value = pred->value; | |
| 253 n = pred; | |
| 254 } | |
| 255 | |
| 256 /* n->left == NULL || n->right == NULL */ | |
| 257 child = n->right == NULL ? n->left : n->right; | |
| 258 if (node_color(n) == L_BLACK_NODE) { | |
| 259 n->color = node_color(child); | |
| 260 delete_case1(t, n); | |
| 261 } | |
| 262 replace_node(t, n, child); | |
| 263 if (n->parent == NULL && child != NULL) /* root should be black */ | |
| 264 child->color = L_BLACK_NODE; | |
| 265 LEPT_FREE(n); | |
| 266 | |
| 267 verify_properties(t); | |
| 268 } | |
| 269 | |
| 270 /*! | |
| 271 * \brief l_rbtreeDestroy() | |
| 272 * | |
| 273 * \param[in] pt pointer to tree; will be wet to null before returning | |
| 274 * \return void | |
| 275 * | |
| 276 * <pre> | |
| 277 * Notes: | |
| 278 * (1) Destroys the tree and nulls the input tree ptr. | |
| 279 * </pre> | |
| 280 */ | |
| 281 void | |
| 282 l_rbtreeDestroy(L_RBTREE **pt) | |
| 283 { | |
| 284 node *n; | |
| 285 | |
| 286 if (!pt) return; | |
| 287 if (*pt == NULL) return; | |
| 288 n = (*pt)->root; | |
| 289 destroy_helper(n); | |
| 290 LEPT_FREE(*pt); | |
| 291 *pt = NULL; | |
| 292 } | |
| 293 | |
| 294 /* postorder DFS */ | |
| 295 static void | |
| 296 destroy_helper(node *n) | |
| 297 { | |
| 298 if (!n) return; | |
| 299 destroy_helper(n->left); | |
| 300 destroy_helper(n->right); | |
| 301 LEPT_FREE(n); | |
| 302 } | |
| 303 | |
| 304 /*! | |
| 305 * \brief l_rbtreeGetFirst() | |
| 306 * | |
| 307 * \param[in] t rbtree, including root node | |
| 308 * \return first node, or NULL on error or if the tree is empty | |
| 309 * | |
| 310 * <pre> | |
| 311 * Notes: | |
| 312 * (1) This is the first node in an in-order traversal. | |
| 313 * </pre> | |
| 314 */ | |
| 315 L_RBTREE_NODE * | |
| 316 l_rbtreeGetFirst(L_RBTREE *t) | |
| 317 { | |
| 318 node *n; | |
| 319 | |
| 320 if (!t) | |
| 321 return (L_RBTREE_NODE *)ERROR_PTR("tree is null", __func__, NULL); | |
| 322 if (t->root == NULL) { | |
| 323 L_INFO("tree is empty\n", __func__); | |
| 324 return NULL; | |
| 325 } | |
| 326 | |
| 327 /* Just go down the left side as far as possible */ | |
| 328 n = t->root; | |
| 329 while (n && n->left) | |
| 330 n = n->left; | |
| 331 return n; | |
| 332 } | |
| 333 | |
| 334 /*! | |
| 335 * \brief l_rbtreeGetNext() | |
| 336 * | |
| 337 * \param[in] n current node | |
| 338 * \return next node, or NULL if it's the last node | |
| 339 * | |
| 340 * <pre> | |
| 341 * Notes: | |
| 342 * (1) This finds the next node, in an in-order traversal, from | |
| 343 * the current node. | |
| 344 * (2) It is useful as an iterator for a map. | |
| 345 * (3) Call l_rbtreeGetFirst() to get the first node. | |
| 346 * </pre> | |
| 347 */ | |
| 348 L_RBTREE_NODE * | |
| 349 l_rbtreeGetNext(L_RBTREE_NODE *n) | |
| 350 { | |
| 351 if (!n) | |
| 352 return (L_RBTREE_NODE *)ERROR_PTR("n not defined", __func__, NULL); | |
| 353 | |
| 354 /* If there is a right child, go to it, and then go left all the | |
| 355 * way to the end. Otherwise go up to the parent; continue upward | |
| 356 * as long as you're on the right branch, but stop at the parent | |
| 357 * when you hit it from the left branch. */ | |
| 358 if (n->right) { | |
| 359 n = n->right; | |
| 360 while (n->left) | |
| 361 n = n->left; | |
| 362 return n; | |
| 363 } else { | |
| 364 while (n->parent && n->parent->right == n) | |
| 365 n = n->parent; | |
| 366 return n->parent; | |
| 367 } | |
| 368 } | |
| 369 | |
| 370 /*! | |
| 371 * \brief l_rbtreeGetLast() | |
| 372 * | |
| 373 * \param[in] t rbtree, including root node | |
| 374 * \return last node, or NULL on error or if the tree is empty | |
| 375 * | |
| 376 * <pre> | |
| 377 * Notes: | |
| 378 * (1) This is the last node in an in-order traversal. | |
| 379 * </pre> | |
| 380 */ | |
| 381 L_RBTREE_NODE * | |
| 382 l_rbtreeGetLast(L_RBTREE *t) | |
| 383 { | |
| 384 node *n; | |
| 385 | |
| 386 if (!t) | |
| 387 return (L_RBTREE_NODE *)ERROR_PTR("tree is null", __func__, NULL); | |
| 388 if (t->root == NULL) { | |
| 389 L_INFO("tree is empty\n", __func__); | |
| 390 return NULL; | |
| 391 } | |
| 392 | |
| 393 /* Just go down the right side as far as possible */ | |
| 394 n = t->root; | |
| 395 while (n && n->right) | |
| 396 n = n->right; | |
| 397 return n; | |
| 398 } | |
| 399 | |
| 400 /*! | |
| 401 * \brief l_rbtreeGetPrev() | |
| 402 * | |
| 403 * \param[in] n current node | |
| 404 * \return next node, or NULL if it's the first node | |
| 405 * | |
| 406 * <pre> | |
| 407 * Notes: | |
| 408 * (1) This finds the previous node, in an in-order traversal, from | |
| 409 * the current node. | |
| 410 * (2) It is useful as an iterator for a map. | |
| 411 * (3) Call l_rbtreeGetLast() to get the last node. | |
| 412 * </pre> | |
| 413 */ | |
| 414 L_RBTREE_NODE * | |
| 415 l_rbtreeGetPrev(L_RBTREE_NODE *n) | |
| 416 { | |
| 417 if (!n) | |
| 418 return (L_RBTREE_NODE *)ERROR_PTR("n not defined", __func__, NULL); | |
| 419 | |
| 420 /* If there is a left child, go to it, and then go right all the | |
| 421 * way to the end. Otherwise go up to the parent; continue upward | |
| 422 * as long as you're on the left branch, but stop at the parent | |
| 423 * when you hit it from the right branch. */ | |
| 424 if (n->left) { | |
| 425 n = n->left; | |
| 426 while (n->right) | |
| 427 n = n->right; | |
| 428 return n; | |
| 429 } else { | |
| 430 while (n->parent && n->parent->left == n) | |
| 431 n = n->parent; | |
| 432 return n->parent; | |
| 433 } | |
| 434 } | |
| 435 | |
| 436 /*! | |
| 437 * \brief l_rbtreeGetCount() | |
| 438 * | |
| 439 * \param[in] t rbtree | |
| 440 * \return count the number of nodes in the tree, or 0 on error | |
| 441 */ | |
| 442 l_int32 | |
| 443 l_rbtreeGetCount(L_RBTREE *t) | |
| 444 { | |
| 445 l_int32 count = 0; | |
| 446 node *n; | |
| 447 | |
| 448 if (!t) return 0; | |
| 449 n = t->root; | |
| 450 count_helper(n, &count); | |
| 451 return count; | |
| 452 } | |
| 453 | |
| 454 /* preorder DFS */ | |
| 455 static void | |
| 456 count_helper(node *n, l_int32 *pcount) | |
| 457 { | |
| 458 if (n) | |
| 459 (*pcount)++; | |
| 460 else | |
| 461 return; | |
| 462 | |
| 463 count_helper(n->left, pcount); | |
| 464 count_helper(n->right, pcount); | |
| 465 } | |
| 466 | |
| 467 | |
| 468 /*! | |
| 469 * \brief l_rbtreePrint() | |
| 470 * | |
| 471 * \param[in] fp file stream | |
| 472 * \param[in] t rbtree | |
| 473 * \return void | |
| 474 */ | |
| 475 void | |
| 476 l_rbtreePrint(FILE *fp, | |
| 477 L_RBTREE *t) | |
| 478 { | |
| 479 if (!fp) { | |
| 480 L_ERROR("stream not defined\n", __func__); | |
| 481 return; | |
| 482 } | |
| 483 if (!t) { | |
| 484 L_ERROR("tree not defined\n", __func__); | |
| 485 return; | |
| 486 } | |
| 487 | |
| 488 print_tree_helper(fp, t->root, t->keytype, 0); | |
| 489 fprintf(fp, "\n"); | |
| 490 } | |
| 491 | |
| 492 #define INDENT_STEP 4 | |
| 493 | |
| 494 static void | |
| 495 print_tree_helper(FILE *fp, | |
| 496 node *n, | |
| 497 l_int32 keytype, | |
| 498 l_int32 indent) | |
| 499 { | |
| 500 l_int32 i; | |
| 501 | |
| 502 if (n == NULL) { | |
| 503 fprintf(fp, "<empty tree>"); | |
| 504 return; | |
| 505 } | |
| 506 if (n->right != NULL) { | |
| 507 print_tree_helper(fp, n->right, keytype, indent + INDENT_STEP); | |
| 508 } | |
| 509 for (i = 0; i < indent; i++) | |
| 510 fprintf(fp, " "); | |
| 511 if (n->color == L_BLACK_NODE) { | |
| 512 if (keytype == L_INT_TYPE) | |
| 513 fprintf(fp, "%lld\n", n->key.itype); | |
| 514 else if (keytype == L_UINT_TYPE) | |
| 515 fprintf(fp, "%llx\n", n->key.utype); | |
| 516 else if (keytype == L_FLOAT_TYPE) | |
| 517 fprintf(fp, "%f\n", n->key.ftype); | |
| 518 } else { | |
| 519 if (keytype == L_INT_TYPE) | |
| 520 fprintf(fp, "<%lld>\n", n->key.itype); | |
| 521 else if (keytype == L_UINT_TYPE) | |
| 522 fprintf(fp, "<%llx>\n", n->key.utype); | |
| 523 else if (keytype == L_FLOAT_TYPE) | |
| 524 fprintf(fp, "<%f>\n", n->key.ftype); | |
| 525 } | |
| 526 if (n->left != NULL) { | |
| 527 print_tree_helper(fp, n->left, keytype, indent + INDENT_STEP); | |
| 528 } | |
| 529 } | |
| 530 | |
| 531 | |
| 532 /* ------------------------------------------------------------- * | |
| 533 * Static key comparison function * | |
| 534 * ------------------------------------------------------------- */ | |
| 535 static l_int32 | |
| 536 compareKeys(l_int32 keytype, | |
| 537 RB_TYPE left, | |
| 538 RB_TYPE right) | |
| 539 { | |
| 540 if (keytype == L_INT_TYPE) { | |
| 541 if (left.itype < right.itype) | |
| 542 return -1; | |
| 543 else if (left.itype > right.itype) | |
| 544 return 1; | |
| 545 else { /* equality */ | |
| 546 return 0; | |
| 547 } | |
| 548 } else if (keytype == L_UINT_TYPE) { | |
| 549 if (left.utype < right.utype) | |
| 550 return -1; | |
| 551 else if (left.utype > right.utype) | |
| 552 return 1; | |
| 553 else { /* equality */ | |
| 554 return 0; | |
| 555 } | |
| 556 } else if (keytype == L_FLOAT_TYPE) { | |
| 557 if (left.ftype < right.ftype) | |
| 558 return -1; | |
| 559 else if (left.ftype > right.ftype) | |
| 560 return 1; | |
| 561 else { /* equality */ | |
| 562 return 0; | |
| 563 } | |
| 564 } else { | |
| 565 L_ERROR("unknown keytype %d\n", __func__, keytype); | |
| 566 return 0; | |
| 567 } | |
| 568 } | |
| 569 | |
| 570 | |
| 571 /* ------------------------------------------------------------- * | |
| 572 * Static red-black tree helpers * | |
| 573 * ------------------------------------------------------------- */ | |
| 574 static node *grandparent(node *n) { | |
| 575 if (!n || !n->parent || !n->parent->parent) { | |
| 576 L_ERROR("root and child of root have no grandparent\n", "grandparent"); | |
| 577 return NULL; | |
| 578 } | |
| 579 return n->parent->parent; | |
| 580 } | |
| 581 | |
| 582 static node *sibling(node *n) { | |
| 583 if (!n || !n->parent) { | |
| 584 L_ERROR("root has no sibling\n", "sibling"); | |
| 585 return NULL; | |
| 586 } | |
| 587 if (n == n->parent->left) | |
| 588 return n->parent->right; | |
| 589 else | |
| 590 return n->parent->left; | |
| 591 } | |
| 592 | |
| 593 static node *uncle(node *n) { | |
| 594 if (!n || !n->parent || !n->parent->parent) { | |
| 595 L_ERROR("root and child of root have no uncle\n", "uncle"); | |
| 596 return NULL; | |
| 597 } | |
| 598 return sibling(n->parent); | |
| 599 } | |
| 600 | |
| 601 static l_int32 node_color(node *n) { | |
| 602 return n == NULL ? L_BLACK_NODE : n->color; | |
| 603 } | |
| 604 | |
| 605 | |
| 606 static node *new_node(RB_TYPE key, RB_TYPE value, l_int32 node_color, | |
| 607 node *left, node *right) { | |
| 608 node *result = (node *)LEPT_CALLOC(1, sizeof(node)); | |
| 609 result->key = key; | |
| 610 result->value = value; | |
| 611 result->color = node_color; | |
| 612 result->left = left; | |
| 613 result->right = right; | |
| 614 if (left != NULL) left->parent = result; | |
| 615 if (right != NULL) right->parent = result; | |
| 616 result->parent = NULL; | |
| 617 return result; | |
| 618 } | |
| 619 | |
| 620 static node *lookup_node(L_RBTREE *t, RB_TYPE key) { | |
| 621 node *n = t->root; | |
| 622 while (n != NULL) { | |
| 623 int comp_result = compareKeys(t->keytype, key, n->key); | |
| 624 if (comp_result == 0) { | |
| 625 return n; | |
| 626 } else if (comp_result < 0) { | |
| 627 n = n->left; | |
| 628 } else { /* comp_result > 0 */ | |
| 629 n = n->right; | |
| 630 } | |
| 631 } | |
| 632 return n; | |
| 633 } | |
| 634 | |
| 635 static void rotate_left(L_RBTREE *t, node *n) { | |
| 636 node *r = n->right; | |
| 637 replace_node(t, n, r); | |
| 638 n->right = r->left; | |
| 639 if (r->left != NULL) { | |
| 640 r->left->parent = n; | |
| 641 } | |
| 642 r->left = n; | |
| 643 n->parent = r; | |
| 644 } | |
| 645 | |
| 646 static void rotate_right(L_RBTREE *t, node *n) { | |
| 647 node *L = n->left; | |
| 648 replace_node(t, n, L); | |
| 649 n->left = L->right; | |
| 650 if (L->right != NULL) { | |
| 651 L->right->parent = n; | |
| 652 } | |
| 653 L->right = n; | |
| 654 n->parent = L; | |
| 655 } | |
| 656 | |
| 657 static void replace_node(L_RBTREE *t, node *oldn, node *newn) { | |
| 658 if (oldn->parent == NULL) { | |
| 659 t->root = newn; | |
| 660 } else { | |
| 661 if (oldn == oldn->parent->left) | |
| 662 oldn->parent->left = newn; | |
| 663 else | |
| 664 oldn->parent->right = newn; | |
| 665 } | |
| 666 if (newn != NULL) { | |
| 667 newn->parent = oldn->parent; | |
| 668 } | |
| 669 } | |
| 670 | |
| 671 static void insert_case1(L_RBTREE *t, node *n) { | |
| 672 if (n->parent == NULL) | |
| 673 n->color = L_BLACK_NODE; | |
| 674 else | |
| 675 insert_case2(t, n); | |
| 676 } | |
| 677 | |
| 678 static void insert_case2(L_RBTREE *t, node *n) { | |
| 679 if (node_color(n->parent) == L_BLACK_NODE) | |
| 680 return; /* Tree is still valid */ | |
| 681 else | |
| 682 insert_case3(t, n); | |
| 683 } | |
| 684 | |
| 685 static void insert_case3(L_RBTREE *t, node *n) { | |
| 686 if (node_color(uncle(n)) == L_RED_NODE) { | |
| 687 n->parent->color = L_BLACK_NODE; | |
| 688 uncle(n)->color = L_BLACK_NODE; | |
| 689 grandparent(n)->color = L_RED_NODE; | |
| 690 insert_case1(t, grandparent(n)); | |
| 691 } else { | |
| 692 insert_case4(t, n); | |
| 693 } | |
| 694 } | |
| 695 | |
| 696 static void insert_case4(L_RBTREE *t, node *n) { | |
| 697 if (n == n->parent->right && n->parent == grandparent(n)->left) { | |
| 698 rotate_left(t, n->parent); | |
| 699 n = n->left; | |
| 700 } else if (n == n->parent->left && n->parent == grandparent(n)->right) { | |
| 701 rotate_right(t, n->parent); | |
| 702 n = n->right; | |
| 703 } | |
| 704 insert_case5(t, n); | |
| 705 } | |
| 706 | |
| 707 static void insert_case5(L_RBTREE *t, node *n) { | |
| 708 n->parent->color = L_BLACK_NODE; | |
| 709 grandparent(n)->color = L_RED_NODE; | |
| 710 if (n == n->parent->left && n->parent == grandparent(n)->left) { | |
| 711 rotate_right(t, grandparent(n)); | |
| 712 } else if (n == n->parent->right && n->parent == grandparent(n)->right) { | |
| 713 rotate_left(t, grandparent(n)); | |
| 714 } else { | |
| 715 L_ERROR("identity confusion\n", "insert_case5"); | |
| 716 } | |
| 717 } | |
| 718 | |
| 719 static node *maximum_node(node *n) { | |
| 720 if (!n) { | |
| 721 L_ERROR("n not defined\n", "maximum_node"); | |
| 722 return NULL; | |
| 723 } | |
| 724 while (n->right != NULL) { | |
| 725 n = n->right; | |
| 726 } | |
| 727 return n; | |
| 728 } | |
| 729 | |
| 730 static void delete_case1(L_RBTREE *t, node *n) { | |
| 731 if (n->parent == NULL) | |
| 732 return; | |
| 733 else | |
| 734 delete_case2(t, n); | |
| 735 } | |
| 736 | |
| 737 static void delete_case2(L_RBTREE *t, node *n) { | |
| 738 if (node_color(sibling(n)) == L_RED_NODE) { | |
| 739 n->parent->color = L_RED_NODE; | |
| 740 sibling(n)->color = L_BLACK_NODE; | |
| 741 if (n == n->parent->left) | |
| 742 rotate_left(t, n->parent); | |
| 743 else | |
| 744 rotate_right(t, n->parent); | |
| 745 } | |
| 746 delete_case3(t, n); | |
| 747 } | |
| 748 | |
| 749 static void delete_case3(L_RBTREE *t, node *n) { | |
| 750 if (node_color(n->parent) == L_BLACK_NODE && | |
| 751 node_color(sibling(n)) == L_BLACK_NODE && | |
| 752 node_color(sibling(n)->left) == L_BLACK_NODE && | |
| 753 node_color(sibling(n)->right) == L_BLACK_NODE) { | |
| 754 sibling(n)->color = L_RED_NODE; | |
| 755 delete_case1(t, n->parent); | |
| 756 } else { | |
| 757 delete_case4(t, n); | |
| 758 } | |
| 759 } | |
| 760 | |
| 761 static void delete_case4(L_RBTREE *t, node *n) { | |
| 762 if (node_color(n->parent) == L_RED_NODE && | |
| 763 node_color(sibling(n)) == L_BLACK_NODE && | |
| 764 node_color(sibling(n)->left) == L_BLACK_NODE && | |
| 765 node_color(sibling(n)->right) == L_BLACK_NODE) { | |
| 766 sibling(n)->color = L_RED_NODE; | |
| 767 n->parent->color = L_BLACK_NODE; | |
| 768 } else { | |
| 769 delete_case5(t, n); | |
| 770 } | |
| 771 } | |
| 772 | |
| 773 static void delete_case5(L_RBTREE *t, node *n) { | |
| 774 if (n == n->parent->left && | |
| 775 node_color(sibling(n)) == L_BLACK_NODE && | |
| 776 node_color(sibling(n)->left) == L_RED_NODE && | |
| 777 node_color(sibling(n)->right) == L_BLACK_NODE) { | |
| 778 sibling(n)->color = L_RED_NODE; | |
| 779 sibling(n)->left->color = L_BLACK_NODE; | |
| 780 rotate_right(t, sibling(n)); | |
| 781 } else if (n == n->parent->right && | |
| 782 node_color(sibling(n)) == L_BLACK_NODE && | |
| 783 node_color(sibling(n)->right) == L_RED_NODE && | |
| 784 node_color(sibling(n)->left) == L_BLACK_NODE) { | |
| 785 sibling(n)->color = L_RED_NODE; | |
| 786 sibling(n)->right->color = L_BLACK_NODE; | |
| 787 rotate_left(t, sibling(n)); | |
| 788 } | |
| 789 delete_case6(t, n); | |
| 790 } | |
| 791 | |
| 792 static void delete_case6(L_RBTREE *t, node *n) { | |
| 793 sibling(n)->color = node_color(n->parent); | |
| 794 n->parent->color = L_BLACK_NODE; | |
| 795 if (n == n->parent->left) { | |
| 796 if (node_color(sibling(n)->right) != L_RED_NODE) { | |
| 797 L_ERROR("right sibling is not RED", "delete_case6"); | |
| 798 return; | |
| 799 } | |
| 800 sibling(n)->right->color = L_BLACK_NODE; | |
| 801 rotate_left(t, n->parent); | |
| 802 } else { | |
| 803 if (node_color(sibling(n)->left) != L_RED_NODE) { | |
| 804 L_ERROR("left sibling is not RED", "delete_case6"); | |
| 805 return; | |
| 806 } | |
| 807 sibling(n)->left->color = L_BLACK_NODE; | |
| 808 rotate_right(t, n->parent); | |
| 809 } | |
| 810 } | |
| 811 | |
| 812 | |
| 813 /* ------------------------------------------------------------- * | |
| 814 * Debugging: verify if tree is valid * | |
| 815 * ------------------------------------------------------------- */ | |
| 816 #if VERIFY_RBTREE | |
| 817 static void verify_property_1(node *root); | |
| 818 static void verify_property_2(node *root); | |
| 819 static void verify_property_4(node *root); | |
| 820 static void verify_property_5(node *root); | |
| 821 static void verify_property_5_helper(node *n, int black_count, | |
| 822 int* black_count_path); | |
| 823 #endif | |
| 824 | |
| 825 static void verify_properties(L_RBTREE *t) { | |
| 826 #if VERIFY_RBTREE | |
| 827 verify_property_1(t->root); | |
| 828 verify_property_2(t->root); | |
| 829 /* Property 3 is implicit */ | |
| 830 verify_property_4(t->root); | |
| 831 verify_property_5(t->root); | |
| 832 #endif | |
| 833 } | |
| 834 | |
| 835 #if VERIFY_RBTREE | |
| 836 static void verify_property_1(node *n) { | |
| 837 if (node_color(n) != L_RED_NODE && node_color(n) != L_BLACK_NODE) { | |
| 838 L_ERROR("color neither RED nor BLACK\n", "verify_property_1"); | |
| 839 return; | |
| 840 } | |
| 841 if (n == NULL) return; | |
| 842 verify_property_1(n->left); | |
| 843 verify_property_1(n->right); | |
| 844 } | |
| 845 | |
| 846 static void verify_property_2(node *root) { | |
| 847 if (node_color(root) != L_BLACK_NODE) | |
| 848 L_ERROR("root is not black!\n", "verify_property_2"); | |
| 849 } | |
| 850 | |
| 851 static void verify_property_4(node *n) { | |
| 852 if (node_color(n) == L_RED_NODE) { | |
| 853 if (node_color(n->left) != L_BLACK_NODE || | |
| 854 node_color(n->right) != L_BLACK_NODE || | |
| 855 node_color(n->parent) != L_BLACK_NODE) { | |
| 856 L_ERROR("children & parent not all BLACK", "verify_property_4"); | |
| 857 return; | |
| 858 } | |
| 859 } | |
| 860 if (n == NULL) return; | |
| 861 verify_property_4(n->left); | |
| 862 verify_property_4(n->right); | |
| 863 } | |
| 864 | |
| 865 static void verify_property_5(node *root) { | |
| 866 int black_count_path = -1; | |
| 867 verify_property_5_helper(root, 0, &black_count_path); | |
| 868 } | |
| 869 | |
| 870 static void verify_property_5_helper(node *n, int black_count, | |
| 871 int* path_black_count) { | |
| 872 if (node_color(n) == L_BLACK_NODE) { | |
| 873 black_count++; | |
| 874 } | |
| 875 if (n == NULL) { | |
| 876 if (*path_black_count == -1) { | |
| 877 *path_black_count = black_count; | |
| 878 } else if (*path_black_count != black_count) { | |
| 879 L_ERROR("incorrect black count", "verify_property_5_helper"); | |
| 880 } | |
| 881 return; | |
| 882 } | |
| 883 verify_property_5_helper(n->left, black_count, path_black_count); | |
| 884 verify_property_5_helper(n->right, black_count, path_black_count); | |
| 885 } | |
| 886 #endif |
