1 /* 2 * Dictionary Abstract Data Type 3 * Copyright (C) 1997 Kaz Kylheku <kaz (at) ashi.footprints.net> 4 * 5 * Free Software License: 6 * 7 * All rights are reserved by the author, with the following exceptions: 8 * Permission is granted to freely reproduce and distribute this software, 9 * possibly in exchange for a fee, provided that this copyright notice appears 10 * intact. Permission is also granted to adapt this software to produce 11 * derivative works, as long as the modified versions carry this copyright 12 * notice and additional notices stating that the work has been modified. 13 * This source code may be translated into executable form and incorporated 14 * into proprietary software; there is no requirement for such software to 15 * contain a copyright notice related to this source. 16 * 17 * $Id: dict.c,v 1.40.2.7 2000/11/13 01:36:44 kaz Exp $ 18 * $Name: kazlib_1_20 $ 19 */ 20 21 #define DICT_NODEBUG 22 23 #ifdef __GNUC__ 24 #define EXT2FS_ATTR(x) __attribute__(x) 25 #else 26 #define EXT2FS_ATTR(x) 27 #endif 28 29 #include "config.h" 30 #include <stdlib.h> 31 #include <stddef.h> 32 #ifdef DICT_NODEBUG 33 #define dict_assert(x) 34 #else 35 #include <assert.h> 36 #define dict_assert(x) assert(x) 37 #endif 38 #define DICT_IMPLEMENTATION 39 #include "dict.h" 40 41 #ifdef KAZLIB_RCSID 42 static const char rcsid[] = "$Id: dict.c,v 1.40.2.7 2000/11/13 01:36:44 kaz Exp $"; 43 #endif 44 45 /* 46 * These macros provide short convenient names for structure members, 47 * which are embellished with dict_ prefixes so that they are 48 * properly confined to the documented namespace. It's legal for a 49 * program which uses dict to define, for instance, a macro called ``parent''. 50 * Such a macro would interfere with the dnode_t struct definition. 51 * In general, highly portable and reusable C modules which expose their 52 * structures need to confine structure member names to well-defined spaces. 53 * The resulting identifiers aren't necessarily convenient to use, nor 54 * readable, in the implementation, however! 55 */ 56 57 #define left dict_left 58 #define right dict_right 59 #define parent dict_parent 60 #define color dict_color 61 #define key dict_key 62 #define data dict_data 63 64 #define nilnode dict_nilnode 65 #define nodecount dict_nodecount 66 #define maxcount dict_maxcount 67 #define compare dict_compare 68 #define allocnode dict_allocnode 69 #define freenode dict_freenode 70 #define context dict_context 71 #define dupes dict_dupes 72 73 #define dictptr dict_dictptr 74 75 #define dict_root(D) ((D)->nilnode.left) 76 #define dict_nil(D) (&(D)->nilnode) 77 #define DICT_DEPTH_MAX 64 78 79 static dnode_t *dnode_alloc(void *context); 80 static void dnode_free(dnode_t *node, void *context); 81 82 /* 83 * Perform a ``left rotation'' adjustment on the tree. The given node P and 84 * its right child C are rearranged so that the P instead becomes the left 85 * child of C. The left subtree of C is inherited as the new right subtree 86 * for P. The ordering of the keys within the tree is thus preserved. 87 */ 88 89 static void rotate_left(dnode_t *upper) 90 { 91 dnode_t *lower, *lowleft, *upparent; 92 93 lower = upper->right; 94 upper->right = lowleft = lower->left; 95 lowleft->parent = upper; 96 97 lower->parent = upparent = upper->parent; 98 99 /* don't need to check for root node here because root->parent is 100 the sentinel nil node, and root->parent->left points back to root */ 101 102 if (upper == upparent->left) { 103 upparent->left = lower; 104 } else { 105 dict_assert (upper == upparent->right); 106 upparent->right = lower; 107 } 108 109 lower->left = upper; 110 upper->parent = lower; 111 } 112 113 /* 114 * This operation is the ``mirror'' image of rotate_left. It is 115 * the same procedure, but with left and right interchanged. 116 */ 117 118 static void rotate_right(dnode_t *upper) 119 { 120 dnode_t *lower, *lowright, *upparent; 121 122 lower = upper->left; 123 upper->left = lowright = lower->right; 124 lowright->parent = upper; 125 126 lower->parent = upparent = upper->parent; 127 128 if (upper == upparent->right) { 129 upparent->right = lower; 130 } else { 131 dict_assert (upper == upparent->left); 132 upparent->left = lower; 133 } 134 135 lower->right = upper; 136 upper->parent = lower; 137 } 138 139 /* 140 * Do a postorder traversal of the tree rooted at the specified 141 * node and free everything under it. Used by dict_free(). 142 */ 143 144 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil) 145 { 146 if (node == nil) 147 return; 148 free_nodes(dict, node->left, nil); 149 free_nodes(dict, node->right, nil); 150 dict->freenode(node, dict->context); 151 } 152 153 /* 154 * This procedure performs a verification that the given subtree is a binary 155 * search tree. It performs an inorder traversal of the tree using the 156 * dict_next() successor function, verifying that the key of each node is 157 * strictly lower than that of its successor, if duplicates are not allowed, 158 * or lower or equal if duplicates are allowed. This function is used for 159 * debugging purposes. 160 */ 161 #ifndef DICT_NODEBUG 162 static int verify_bintree(dict_t *dict) 163 { 164 dnode_t *first, *next; 165 166 first = dict_first(dict); 167 168 if (dict->dupes) { 169 while (first && (next = dict_next(dict, first))) { 170 if (dict->compare(first->key, next->key) > 0) 171 return 0; 172 first = next; 173 } 174 } else { 175 while (first && (next = dict_next(dict, first))) { 176 if (dict->compare(first->key, next->key) >= 0) 177 return 0; 178 first = next; 179 } 180 } 181 return 1; 182 } 183 184 /* 185 * This function recursively verifies that the given binary subtree satisfies 186 * three of the red black properties. It checks that every red node has only 187 * black children. It makes sure that each node is either red or black. And it 188 * checks that every path has the same count of black nodes from root to leaf. 189 * It returns the blackheight of the given subtree; this allows blackheights to 190 * be computed recursively and compared for left and right siblings for 191 * mismatches. It does not check for every nil node being black, because there 192 * is only one sentinel nil node. The return value of this function is the 193 * black height of the subtree rooted at the node ``root'', or zero if the 194 * subtree is not red-black. 195 */ 196 197 static unsigned int verify_redblack(dnode_t *nil, dnode_t *root) 198 { 199 unsigned height_left, height_right; 200 201 if (root != nil) { 202 height_left = verify_redblack(nil, root->left); 203 height_right = verify_redblack(nil, root->right); 204 if (height_left == 0 || height_right == 0) 205 return 0; 206 if (height_left != height_right) 207 return 0; 208 if (root->color == dnode_red) { 209 if (root->left->color != dnode_black) 210 return 0; 211 if (root->right->color != dnode_black) 212 return 0; 213 return height_left; 214 } 215 if (root->color != dnode_black) 216 return 0; 217 return height_left + 1; 218 } 219 return 1; 220 } 221 222 /* 223 * Compute the actual count of nodes by traversing the tree and 224 * return it. This could be compared against the stored count to 225 * detect a mismatch. 226 */ 227 228 static dictcount_t verify_node_count(dnode_t *nil, dnode_t *root) 229 { 230 if (root == nil) 231 return 0; 232 else 233 return 1 + verify_node_count(nil, root->left) 234 + verify_node_count(nil, root->right); 235 } 236 #endif 237 238 /* 239 * Verify that the tree contains the given node. This is done by 240 * traversing all of the nodes and comparing their pointers to the 241 * given pointer. Returns 1 if the node is found, otherwise 242 * returns zero. It is intended for debugging purposes. 243 */ 244 245 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node) 246 { 247 if (root != nil) { 248 return root == node 249 || verify_dict_has_node(nil, root->left, node) 250 || verify_dict_has_node(nil, root->right, node); 251 } 252 return 0; 253 } 254 255 256 #ifdef E2FSCK_NOTUSED 257 /* 258 * Dynamically allocate and initialize a dictionary object. 259 */ 260 261 dict_t *dict_create(dictcount_t maxcount, dict_comp_t comp) 262 { 263 dict_t *new = malloc(sizeof *new); 264 265 if (new) { 266 new->compare = comp; 267 new->allocnode = dnode_alloc; 268 new->freenode = dnode_free; 269 new->context = NULL; 270 new->nodecount = 0; 271 new->maxcount = maxcount; 272 new->nilnode.left = &new->nilnode; 273 new->nilnode.right = &new->nilnode; 274 new->nilnode.parent = &new->nilnode; 275 new->nilnode.color = dnode_black; 276 new->dupes = 0; 277 } 278 return new; 279 } 280 #endif /* E2FSCK_NOTUSED */ 281 282 /* 283 * Select a different set of node allocator routines. 284 */ 285 286 void dict_set_allocator(dict_t *dict, dnode_alloc_t al, 287 dnode_free_t fr, void *context) 288 { 289 dict_assert (dict_count(dict) == 0); 290 dict_assert ((al == NULL && fr == NULL) || (al != NULL && fr != NULL)); 291 292 dict->allocnode = al ? al : dnode_alloc; 293 dict->freenode = fr ? fr : dnode_free; 294 dict->context = context; 295 } 296 297 #ifdef E2FSCK_NOTUSED 298 /* 299 * Free a dynamically allocated dictionary object. Removing the nodes 300 * from the tree before deleting it is required. 301 */ 302 303 void dict_destroy(dict_t *dict) 304 { 305 dict_assert (dict_isempty(dict)); 306 free(dict); 307 } 308 #endif 309 310 /* 311 * Free all the nodes in the dictionary by using the dictionary's 312 * installed free routine. The dictionary is emptied. 313 */ 314 315 void dict_free_nodes(dict_t *dict) 316 { 317 dnode_t *nil = dict_nil(dict), *root = dict_root(dict); 318 free_nodes(dict, root, nil); 319 dict->nodecount = 0; 320 dict->nilnode.left = &dict->nilnode; 321 dict->nilnode.right = &dict->nilnode; 322 } 323 324 #ifdef E2FSCK_NOTUSED 325 /* 326 * Obsolescent function, equivalent to dict_free_nodes 327 */ 328 void dict_free(dict_t *dict) 329 { 330 #ifdef KAZLIB_OBSOLESCENT_DEBUG 331 dict_assert ("call to obsolescent function dict_free()" && 0); 332 #endif 333 dict_free_nodes(dict); 334 } 335 #endif 336 337 /* 338 * Initialize a user-supplied dictionary object. 339 */ 340 341 dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp) 342 { 343 dict->compare = comp; 344 dict->allocnode = dnode_alloc; 345 dict->freenode = dnode_free; 346 dict->context = NULL; 347 dict->nodecount = 0; 348 dict->maxcount = maxcount; 349 dict->nilnode.left = &dict->nilnode; 350 dict->nilnode.right = &dict->nilnode; 351 dict->nilnode.parent = &dict->nilnode; 352 dict->nilnode.color = dnode_black; 353 dict->dupes = 0; 354 return dict; 355 } 356 357 #ifdef E2FSCK_NOTUSED 358 /* 359 * Initialize a dictionary in the likeness of another dictionary 360 */ 361 362 void dict_init_like(dict_t *dict, const dict_t *template) 363 { 364 dict->compare = template->compare; 365 dict->allocnode = template->allocnode; 366 dict->freenode = template->freenode; 367 dict->context = template->context; 368 dict->nodecount = 0; 369 dict->maxcount = template->maxcount; 370 dict->nilnode.left = &dict->nilnode; 371 dict->nilnode.right = &dict->nilnode; 372 dict->nilnode.parent = &dict->nilnode; 373 dict->nilnode.color = dnode_black; 374 dict->dupes = template->dupes; 375 376 dict_assert (dict_similar(dict, template)); 377 } 378 379 /* 380 * Remove all nodes from the dictionary (without freeing them in any way). 381 */ 382 383 static void dict_clear(dict_t *dict) 384 { 385 dict->nodecount = 0; 386 dict->nilnode.left = &dict->nilnode; 387 dict->nilnode.right = &dict->nilnode; 388 dict->nilnode.parent = &dict->nilnode; 389 dict_assert (dict->nilnode.color == dnode_black); 390 } 391 #endif /* E2FSCK_NOTUSED */ 392 393 394 /* 395 * Verify the integrity of the dictionary structure. This is provided for 396 * debugging purposes, and should be placed in assert statements. Just because 397 * this function succeeds doesn't mean that the tree is not corrupt. Certain 398 * corruptions in the tree may simply cause undefined behavior. 399 */ 400 #ifndef DICT_NODEBUG 401 int dict_verify(dict_t *dict) 402 { 403 dnode_t *nil = dict_nil(dict), *root = dict_root(dict); 404 405 /* check that the sentinel node and root node are black */ 406 if (root->color != dnode_black) 407 return 0; 408 if (nil->color != dnode_black) 409 return 0; 410 if (nil->right != nil) 411 return 0; 412 /* nil->left is the root node; check that its parent pointer is nil */ 413 if (nil->left->parent != nil) 414 return 0; 415 /* perform a weak test that the tree is a binary search tree */ 416 if (!verify_bintree(dict)) 417 return 0; 418 /* verify that the tree is a red-black tree */ 419 if (!verify_redblack(nil, root)) 420 return 0; 421 if (verify_node_count(nil, root) != dict_count(dict)) 422 return 0; 423 return 1; 424 } 425 #endif /* DICT_NODEBUG */ 426 427 #ifdef E2FSCK_NOTUSED 428 /* 429 * Determine whether two dictionaries are similar: have the same comparison and 430 * allocator functions, and same status as to whether duplicates are allowed. 431 */ 432 int dict_similar(const dict_t *left, const dict_t *right) 433 { 434 if (left->compare != right->compare) 435 return 0; 436 437 if (left->allocnode != right->allocnode) 438 return 0; 439 440 if (left->freenode != right->freenode) 441 return 0; 442 443 if (left->context != right->context) 444 return 0; 445 446 if (left->dupes != right->dupes) 447 return 0; 448 449 return 1; 450 } 451 #endif /* E2FSCK_NOTUSED */ 452 453 /* 454 * Locate a node in the dictionary having the given key. 455 * If the node is not found, a null a pointer is returned (rather than 456 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the 457 * located node is returned. 458 */ 459 460 dnode_t *dict_lookup(dict_t *dict, const void *key) 461 { 462 dnode_t *root = dict_root(dict); 463 dnode_t *nil = dict_nil(dict); 464 dnode_t *saved; 465 int result; 466 467 /* simple binary search adapted for trees that contain duplicate keys */ 468 469 while (root != nil) { 470 result = dict->compare(key, root->key); 471 if (result < 0) 472 root = root->left; 473 else if (result > 0) 474 root = root->right; 475 else { 476 if (!dict->dupes) { /* no duplicates, return match */ 477 return root; 478 } else { /* could be dupes, find leftmost one */ 479 do { 480 saved = root; 481 root = root->left; 482 while (root != nil && dict->compare(key, root->key)) 483 root = root->right; 484 } while (root != nil); 485 return saved; 486 } 487 } 488 } 489 490 return NULL; 491 } 492 493 #ifdef E2FSCK_NOTUSED 494 /* 495 * Look for the node corresponding to the lowest key that is equal to or 496 * greater than the given key. If there is no such node, return null. 497 */ 498 499 dnode_t *dict_lower_bound(dict_t *dict, const void *key) 500 { 501 dnode_t *root = dict_root(dict); 502 dnode_t *nil = dict_nil(dict); 503 dnode_t *tentative = 0; 504 505 while (root != nil) { 506 int result = dict->compare(key, root->key); 507 508 if (result > 0) { 509 root = root->right; 510 } else if (result < 0) { 511 tentative = root; 512 root = root->left; 513 } else { 514 if (!dict->dupes) { 515 return root; 516 } else { 517 tentative = root; 518 root = root->left; 519 } 520 } 521 } 522 523 return tentative; 524 } 525 526 /* 527 * Look for the node corresponding to the greatest key that is equal to or 528 * lower than the given key. If there is no such node, return null. 529 */ 530 531 dnode_t *dict_upper_bound(dict_t *dict, const void *key) 532 { 533 dnode_t *root = dict_root(dict); 534 dnode_t *nil = dict_nil(dict); 535 dnode_t *tentative = 0; 536 537 while (root != nil) { 538 int result = dict->compare(key, root->key); 539 540 if (result < 0) { 541 root = root->left; 542 } else if (result > 0) { 543 tentative = root; 544 root = root->right; 545 } else { 546 if (!dict->dupes) { 547 return root; 548 } else { 549 tentative = root; 550 root = root->right; 551 } 552 } 553 } 554 555 return tentative; 556 } 557 #endif 558 559 /* 560 * Insert a node into the dictionary. The node should have been 561 * initialized with a data field. All other fields are ignored. 562 * The behavior is undefined if the user attempts to insert into 563 * a dictionary that is already full (for which the dict_isfull() 564 * function returns true). 565 */ 566 567 void dict_insert(dict_t *dict, dnode_t *node, const void *key) 568 { 569 dnode_t *where = dict_root(dict), *nil = dict_nil(dict); 570 dnode_t *parent = nil, *uncle, *grandpa; 571 int result = -1; 572 573 node->key = key; 574 575 dict_assert (!dict_isfull(dict)); 576 dict_assert (!dict_contains(dict, node)); 577 dict_assert (!dnode_is_in_a_dict(node)); 578 579 /* basic binary tree insert */ 580 581 while (where != nil) { 582 parent = where; 583 result = dict->compare(key, where->key); 584 /* trap attempts at duplicate key insertion unless it's explicitly allowed */ 585 dict_assert (dict->dupes || result != 0); 586 if (result < 0) 587 where = where->left; 588 else 589 where = where->right; 590 } 591 592 dict_assert (where == nil); 593 594 if (result < 0) 595 parent->left = node; 596 else 597 parent->right = node; 598 599 node->parent = parent; 600 node->left = nil; 601 node->right = nil; 602 603 dict->nodecount++; 604 605 /* red black adjustments */ 606 607 node->color = dnode_red; 608 609 while (parent->color == dnode_red) { 610 grandpa = parent->parent; 611 if (parent == grandpa->left) { 612 uncle = grandpa->right; 613 if (uncle->color == dnode_red) { /* red parent, red uncle */ 614 parent->color = dnode_black; 615 uncle->color = dnode_black; 616 grandpa->color = dnode_red; 617 node = grandpa; 618 parent = grandpa->parent; 619 } else { /* red parent, black uncle */ 620 if (node == parent->right) { 621 rotate_left(parent); 622 parent = node; 623 dict_assert (grandpa == parent->parent); 624 /* rotation between parent and child preserves grandpa */ 625 } 626 parent->color = dnode_black; 627 grandpa->color = dnode_red; 628 rotate_right(grandpa); 629 break; 630 } 631 } else { /* symmetric cases: parent == parent->parent->right */ 632 uncle = grandpa->left; 633 if (uncle->color == dnode_red) { 634 parent->color = dnode_black; 635 uncle->color = dnode_black; 636 grandpa->color = dnode_red; 637 node = grandpa; 638 parent = grandpa->parent; 639 } else { 640 if (node == parent->left) { 641 rotate_right(parent); 642 parent = node; 643 dict_assert (grandpa == parent->parent); 644 } 645 parent->color = dnode_black; 646 grandpa->color = dnode_red; 647 rotate_left(grandpa); 648 break; 649 } 650 } 651 } 652 653 dict_root(dict)->color = dnode_black; 654 655 dict_assert (dict_verify(dict)); 656 } 657 658 #ifdef E2FSCK_NOTUSED 659 /* 660 * Delete the given node from the dictionary. If the given node does not belong 661 * to the given dictionary, undefined behavior results. A pointer to the 662 * deleted node is returned. 663 */ 664 665 dnode_t *dict_delete(dict_t *dict, dnode_t *delete) 666 { 667 dnode_t *nil = dict_nil(dict), *child, *delparent = delete->parent; 668 669 /* basic deletion */ 670 671 dict_assert (!dict_isempty(dict)); 672 dict_assert (dict_contains(dict, delete)); 673 674 /* 675 * If the node being deleted has two children, then we replace it with its 676 * successor (i.e. the leftmost node in the right subtree.) By doing this, 677 * we avoid the traditional algorithm under which the successor's key and 678 * value *only* move to the deleted node and the successor is spliced out 679 * from the tree. We cannot use this approach because the user may hold 680 * pointers to the successor, or nodes may be inextricably tied to some 681 * other structures by way of embedding, etc. So we must splice out the 682 * node we are given, not some other node, and must not move contents from 683 * one node to another behind the user's back. 684 */ 685 686 if (delete->left != nil && delete->right != nil) { 687 dnode_t *next = dict_next(dict, delete); 688 dnode_t *nextparent = next->parent; 689 dnode_color_t nextcolor = next->color; 690 691 dict_assert (next != nil); 692 dict_assert (next->parent != nil); 693 dict_assert (next->left == nil); 694 695 /* 696 * First, splice out the successor from the tree completely, by 697 * moving up its right child into its place. 698 */ 699 700 child = next->right; 701 child->parent = nextparent; 702 703 if (nextparent->left == next) { 704 nextparent->left = child; 705 } else { 706 dict_assert (nextparent->right == next); 707 nextparent->right = child; 708 } 709 710 /* 711 * Now that the successor has been extricated from the tree, install it 712 * in place of the node that we want deleted. 713 */ 714 715 next->parent = delparent; 716 next->left = delete->left; 717 next->right = delete->right; 718 next->left->parent = next; 719 next->right->parent = next; 720 next->color = delete->color; 721 delete->color = nextcolor; 722 723 if (delparent->left == delete) { 724 delparent->left = next; 725 } else { 726 dict_assert (delparent->right == delete); 727 delparent->right = next; 728 } 729 730 } else { 731 dict_assert (delete != nil); 732 dict_assert (delete->left == nil || delete->right == nil); 733 734 child = (delete->left != nil) ? delete->left : delete->right; 735 736 child->parent = delparent = delete->parent; 737 738 if (delete == delparent->left) { 739 delparent->left = child; 740 } else { 741 dict_assert (delete == delparent->right); 742 delparent->right = child; 743 } 744 } 745 746 delete->parent = NULL; 747 delete->right = NULL; 748 delete->left = NULL; 749 750 dict->nodecount--; 751 752 dict_assert (verify_bintree(dict)); 753 754 /* red-black adjustments */ 755 756 if (delete->color == dnode_black) { 757 dnode_t *parent, *sister; 758 759 dict_root(dict)->color = dnode_red; 760 761 while (child->color == dnode_black) { 762 parent = child->parent; 763 if (child == parent->left) { 764 sister = parent->right; 765 dict_assert (sister != nil); 766 if (sister->color == dnode_red) { 767 sister->color = dnode_black; 768 parent->color = dnode_red; 769 rotate_left(parent); 770 sister = parent->right; 771 dict_assert (sister != nil); 772 } 773 if (sister->left->color == dnode_black 774 && sister->right->color == dnode_black) { 775 sister->color = dnode_red; 776 child = parent; 777 } else { 778 if (sister->right->color == dnode_black) { 779 dict_assert (sister->left->color == dnode_red); 780 sister->left->color = dnode_black; 781 sister->color = dnode_red; 782 rotate_right(sister); 783 sister = parent->right; 784 dict_assert (sister != nil); 785 } 786 sister->color = parent->color; 787 sister->right->color = dnode_black; 788 parent->color = dnode_black; 789 rotate_left(parent); 790 break; 791 } 792 } else { /* symmetric case: child == child->parent->right */ 793 dict_assert (child == parent->right); 794 sister = parent->left; 795 dict_assert (sister != nil); 796 if (sister->color == dnode_red) { 797 sister->color = dnode_black; 798 parent->color = dnode_red; 799 rotate_right(parent); 800 sister = parent->left; 801 dict_assert (sister != nil); 802 } 803 if (sister->right->color == dnode_black 804 && sister->left->color == dnode_black) { 805 sister->color = dnode_red; 806 child = parent; 807 } else { 808 if (sister->left->color == dnode_black) { 809 dict_assert (sister->right->color == dnode_red); 810 sister->right->color = dnode_black; 811 sister->color = dnode_red; 812 rotate_left(sister); 813 sister = parent->left; 814 dict_assert (sister != nil); 815 } 816 sister->color = parent->color; 817 sister->left->color = dnode_black; 818 parent->color = dnode_black; 819 rotate_right(parent); 820 break; 821 } 822 } 823 } 824 825 child->color = dnode_black; 826 dict_root(dict)->color = dnode_black; 827 } 828 829 dict_assert (dict_verify(dict)); 830 831 return delete; 832 } 833 #endif /* E2FSCK_NOTUSED */ 834 835 /* 836 * Allocate a node using the dictionary's allocator routine, give it 837 * the data item. 838 */ 839 840 int dict_alloc_insert(dict_t *dict, const void *key, void *data) 841 { 842 dnode_t *node = dict->allocnode(dict->context); 843 844 if (node) { 845 dnode_init(node, data); 846 dict_insert(dict, node, key); 847 return 1; 848 } 849 return 0; 850 } 851 852 #ifdef E2FSCK_NOTUSED 853 void dict_delete_free(dict_t *dict, dnode_t *node) 854 { 855 dict_delete(dict, node); 856 dict->freenode(node, dict->context); 857 } 858 #endif 859 860 /* 861 * Return the node with the lowest (leftmost) key. If the dictionary is empty 862 * (that is, dict_isempty(dict) returns 1) a null pointer is returned. 863 */ 864 865 dnode_t *dict_first(dict_t *dict) 866 { 867 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left; 868 869 if (root != nil) 870 while ((left = root->left) != nil) 871 root = left; 872 873 return (root == nil) ? NULL : root; 874 } 875 876 /* 877 * Return the node with the highest (rightmost) key. If the dictionary is empty 878 * (that is, dict_isempty(dict) returns 1) a null pointer is returned. 879 */ 880 881 dnode_t *dict_last(dict_t *dict) 882 { 883 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *right; 884 885 if (root != nil) 886 while ((right = root->right) != nil) 887 root = right; 888 889 return (root == nil) ? NULL : root; 890 } 891 892 /* 893 * Return the given node's successor node---the node which has the 894 * next key in the the left to right ordering. If the node has 895 * no successor, a null pointer is returned rather than a pointer to 896 * the nil node. 897 */ 898 899 dnode_t *dict_next(dict_t *dict, dnode_t *curr) 900 { 901 dnode_t *nil = dict_nil(dict), *parent, *left; 902 903 if (curr->right != nil) { 904 curr = curr->right; 905 while ((left = curr->left) != nil) 906 curr = left; 907 return curr; 908 } 909 910 parent = curr->parent; 911 912 while (parent != nil && curr == parent->right) { 913 curr = parent; 914 parent = curr->parent; 915 } 916 917 return (parent == nil) ? NULL : parent; 918 } 919 920 /* 921 * Return the given node's predecessor, in the key order. 922 * The nil sentinel node is returned if there is no predecessor. 923 */ 924 925 dnode_t *dict_prev(dict_t *dict, dnode_t *curr) 926 { 927 dnode_t *nil = dict_nil(dict), *parent, *right; 928 929 if (curr->left != nil) { 930 curr = curr->left; 931 while ((right = curr->right) != nil) 932 curr = right; 933 return curr; 934 } 935 936 parent = curr->parent; 937 938 while (parent != nil && curr == parent->left) { 939 curr = parent; 940 parent = curr->parent; 941 } 942 943 return (parent == nil) ? NULL : parent; 944 } 945 946 void dict_allow_dupes(dict_t *dict) 947 { 948 dict->dupes = 1; 949 } 950 951 #undef dict_count 952 #undef dict_isempty 953 #undef dict_isfull 954 #undef dnode_get 955 #undef dnode_put 956 #undef dnode_getkey 957 958 dictcount_t dict_count(dict_t *dict) 959 { 960 return dict->nodecount; 961 } 962 963 int dict_isempty(dict_t *dict) 964 { 965 return dict->nodecount == 0; 966 } 967 968 int dict_isfull(dict_t *dict) 969 { 970 return dict->nodecount == dict->maxcount; 971 } 972 973 int dict_contains(dict_t *dict, dnode_t *node) 974 { 975 return verify_dict_has_node(dict_nil(dict), dict_root(dict), node); 976 } 977 978 static dnode_t *dnode_alloc(void *context EXT2FS_ATTR((unused))) 979 { 980 return malloc(sizeof *dnode_alloc(NULL)); 981 } 982 983 static void dnode_free(dnode_t *node, void *context EXT2FS_ATTR((unused))) 984 { 985 free(node); 986 } 987 988 dnode_t *dnode_create(void *data) 989 { 990 dnode_t *new = malloc(sizeof *new); 991 if (new) { 992 new->data = data; 993 new->parent = NULL; 994 new->left = NULL; 995 new->right = NULL; 996 } 997 return new; 998 } 999 1000 dnode_t *dnode_init(dnode_t *dnode, void *data) 1001 { 1002 dnode->data = data; 1003 dnode->parent = NULL; 1004 dnode->left = NULL; 1005 dnode->right = NULL; 1006 return dnode; 1007 } 1008 1009 void dnode_destroy(dnode_t *dnode) 1010 { 1011 dict_assert (!dnode_is_in_a_dict(dnode)); 1012 free(dnode); 1013 } 1014 1015 void *dnode_get(dnode_t *dnode) 1016 { 1017 return dnode->data; 1018 } 1019 1020 const void *dnode_getkey(dnode_t *dnode) 1021 { 1022 return dnode->key; 1023 } 1024 1025 #ifdef E2FSCK_NOTUSED 1026 void dnode_put(dnode_t *dnode, void *data) 1027 { 1028 dnode->data = data; 1029 } 1030 #endif 1031 1032 #ifndef DICT_NODEBUG 1033 int dnode_is_in_a_dict(dnode_t *dnode) 1034 { 1035 return (dnode->parent && dnode->left && dnode->right); 1036 } 1037 #endif 1038 1039 #ifdef E2FSCK_NOTUSED 1040 void dict_process(dict_t *dict, void *context, dnode_process_t function) 1041 { 1042 dnode_t *node = dict_first(dict), *next; 1043 1044 while (node != NULL) { 1045 /* check for callback function deleting */ 1046 /* the next node from under us */ 1047 dict_assert (dict_contains(dict, node)); 1048 next = dict_next(dict, node); 1049 function(dict, node, context); 1050 node = next; 1051 } 1052 } 1053 1054 static void load_begin_internal(dict_load_t *load, dict_t *dict) 1055 { 1056 load->dictptr = dict; 1057 load->nilnode.left = &load->nilnode; 1058 load->nilnode.right = &load->nilnode; 1059 } 1060 1061 void dict_load_begin(dict_load_t *load, dict_t *dict) 1062 { 1063 dict_assert (dict_isempty(dict)); 1064 load_begin_internal(load, dict); 1065 } 1066 1067 void dict_load_next(dict_load_t *load, dnode_t *newnode, const void *key) 1068 { 1069 dict_t *dict = load->dictptr; 1070 dnode_t *nil = &load->nilnode; 1071 1072 dict_assert (!dnode_is_in_a_dict(newnode)); 1073 dict_assert (dict->nodecount < dict->maxcount); 1074 1075 #ifndef DICT_NODEBUG 1076 if (dict->nodecount > 0) { 1077 if (dict->dupes) 1078 dict_assert (dict->compare(nil->left->key, key) <= 0); 1079 else 1080 dict_assert (dict->compare(nil->left->key, key) < 0); 1081 } 1082 #endif 1083 1084 newnode->key = key; 1085 nil->right->left = newnode; 1086 nil->right = newnode; 1087 newnode->left = nil; 1088 dict->nodecount++; 1089 } 1090 1091 void dict_load_end(dict_load_t *load) 1092 { 1093 dict_t *dict = load->dictptr; 1094 dnode_t *tree[DICT_DEPTH_MAX] = { 0 }; 1095 dnode_t *curr, *dictnil = dict_nil(dict), *loadnil = &load->nilnode, *next; 1096 dnode_t *complete = 0; 1097 dictcount_t fullcount = DICTCOUNT_T_MAX, nodecount = dict->nodecount; 1098 dictcount_t botrowcount; 1099 unsigned baselevel = 0, level = 0, i; 1100 1101 dict_assert (dnode_red == 0 && dnode_black == 1); 1102 1103 while (fullcount >= nodecount && fullcount) 1104 fullcount >>= 1; 1105 1106 botrowcount = nodecount - fullcount; 1107 1108 for (curr = loadnil->left; curr != loadnil; curr = next) { 1109 next = curr->left; 1110 1111 if (complete == NULL && botrowcount-- == 0) { 1112 dict_assert (baselevel == 0); 1113 dict_assert (level == 0); 1114 baselevel = level = 1; 1115 complete = tree[0]; 1116 1117 if (complete != 0) { 1118 tree[0] = 0; 1119 complete->right = dictnil; 1120 while (tree[level] != 0) { 1121 tree[level]->right = complete; 1122 complete->parent = tree[level]; 1123 complete = tree[level]; 1124 tree[level++] = 0; 1125 } 1126 } 1127 } 1128 1129 if (complete == NULL) { 1130 curr->left = dictnil; 1131 curr->right = dictnil; 1132 curr->color = level % 2; 1133 complete = curr; 1134 1135 dict_assert (level == baselevel); 1136 while (tree[level] != 0) { 1137 tree[level]->right = complete; 1138 complete->parent = tree[level]; 1139 complete = tree[level]; 1140 tree[level++] = 0; 1141 } 1142 } else { 1143 curr->left = complete; 1144 curr->color = (level + 1) % 2; 1145 complete->parent = curr; 1146 tree[level] = curr; 1147 complete = 0; 1148 level = baselevel; 1149 } 1150 } 1151 1152 if (complete == NULL) 1153 complete = dictnil; 1154 1155 for (i = 0; i < DICT_DEPTH_MAX; i++) { 1156 if (tree[i] != 0) { 1157 tree[i]->right = complete; 1158 complete->parent = tree[i]; 1159 complete = tree[i]; 1160 } 1161 } 1162 1163 dictnil->color = dnode_black; 1164 dictnil->right = dictnil; 1165 complete->parent = dictnil; 1166 complete->color = dnode_black; 1167 dict_root(dict) = complete; 1168 1169 dict_assert (dict_verify(dict)); 1170 } 1171 1172 void dict_merge(dict_t *dest, dict_t *source) 1173 { 1174 dict_load_t load; 1175 dnode_t *leftnode = dict_first(dest), *rightnode = dict_first(source); 1176 1177 dict_assert (dict_similar(dest, source)); 1178 1179 if (source == dest) 1180 return; 1181 1182 dest->nodecount = 0; 1183 load_begin_internal(&load, dest); 1184 1185 for (;;) { 1186 if (leftnode != NULL && rightnode != NULL) { 1187 if (dest->compare(leftnode->key, rightnode->key) < 0) 1188 goto copyleft; 1189 else 1190 goto copyright; 1191 } else if (leftnode != NULL) { 1192 goto copyleft; 1193 } else if (rightnode != NULL) { 1194 goto copyright; 1195 } else { 1196 dict_assert (leftnode == NULL && rightnode == NULL); 1197 break; 1198 } 1199 1200 copyleft: 1201 { 1202 dnode_t *next = dict_next(dest, leftnode); 1203 #ifndef DICT_NODEBUG 1204 leftnode->left = NULL; /* suppress assertion in dict_load_next */ 1205 #endif 1206 dict_load_next(&load, leftnode, leftnode->key); 1207 leftnode = next; 1208 continue; 1209 } 1210 1211 copyright: 1212 { 1213 dnode_t *next = dict_next(source, rightnode); 1214 #ifndef DICT_NODEBUG 1215 rightnode->left = NULL; 1216 #endif 1217 dict_load_next(&load, rightnode, rightnode->key); 1218 rightnode = next; 1219 continue; 1220 } 1221 } 1222 1223 dict_clear(source); 1224 dict_load_end(&load); 1225 } 1226 #endif /* E2FSCK_NOTUSED */ 1227 1228 #ifdef KAZLIB_TEST_MAIN 1229 1230 #include <stdio.h> 1231 #include <string.h> 1232 #include <ctype.h> 1233 #include <stdarg.h> 1234 1235 typedef char input_t[256]; 1236 1237 static int tokenize(char *string, ...) 1238 { 1239 char **tokptr; 1240 va_list arglist; 1241 int tokcount = 0; 1242 1243 va_start(arglist, string); 1244 tokptr = va_arg(arglist, char **); 1245 while (tokptr) { 1246 while (*string && isspace((unsigned char) *string)) 1247 string++; 1248 if (!*string) 1249 break; 1250 *tokptr = string; 1251 while (*string && !isspace((unsigned char) *string)) 1252 string++; 1253 tokptr = va_arg(arglist, char **); 1254 tokcount++; 1255 if (!*string) 1256 break; 1257 *string++ = 0; 1258 } 1259 va_end(arglist); 1260 1261 return tokcount; 1262 } 1263 1264 static int comparef(const void *key1, const void *key2) 1265 { 1266 return strcmp(key1, key2); 1267 } 1268 1269 static char *dupstring(char *str) 1270 { 1271 int sz = strlen(str) + 1; 1272 char *new = malloc(sz); 1273 if (new) 1274 memcpy(new, str, sz); 1275 return new; 1276 } 1277 1278 static dnode_t *new_node(void *c) 1279 { 1280 static dnode_t few[5]; 1281 static int count; 1282 1283 if (count < 5) 1284 return few + count++; 1285 1286 return NULL; 1287 } 1288 1289 static void del_node(dnode_t *n, void *c) 1290 { 1291 } 1292 1293 static int prompt = 0; 1294 1295 static void construct(dict_t *d) 1296 { 1297 input_t in; 1298 int done = 0; 1299 dict_load_t dl; 1300 dnode_t *dn; 1301 char *tok1, *tok2, *val; 1302 const char *key; 1303 char *help = 1304 "p turn prompt on\n" 1305 "q finish construction\n" 1306 "a <key> <val> add new entry\n"; 1307 1308 if (!dict_isempty(d)) 1309 puts("warning: dictionary not empty!"); 1310 1311 dict_load_begin(&dl, d); 1312 1313 while (!done) { 1314 if (prompt) 1315 putchar('>'); 1316 fflush(stdout); 1317 1318 if (!fgets(in, sizeof(input_t), stdin)) 1319 break; 1320 1321 switch (in[0]) { 1322 case '?': 1323 puts(help); 1324 break; 1325 case 'p': 1326 prompt = 1; 1327 break; 1328 case 'q': 1329 done = 1; 1330 break; 1331 case 'a': 1332 if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) { 1333 puts("what?"); 1334 break; 1335 } 1336 key = dupstring(tok1); 1337 val = dupstring(tok2); 1338 dn = dnode_create(val); 1339 1340 if (!key || !val || !dn) { 1341 puts("out of memory"); 1342 free((void *) key); 1343 free(val); 1344 if (dn) 1345 dnode_destroy(dn); 1346 } 1347 1348 dict_load_next(&dl, dn, key); 1349 break; 1350 default: 1351 putchar('?'); 1352 putchar('\n'); 1353 break; 1354 } 1355 } 1356 1357 dict_load_end(&dl); 1358 } 1359 1360 int main(void) 1361 { 1362 input_t in; 1363 dict_t darray[10]; 1364 dict_t *d = &darray[0]; 1365 dnode_t *dn; 1366 int i; 1367 char *tok1, *tok2, *val; 1368 const char *key; 1369 1370 char *help = 1371 "a <key> <val> add value to dictionary\n" 1372 "d <key> delete value from dictionary\n" 1373 "l <key> lookup value in dictionary\n" 1374 "( <key> lookup lower bound\n" 1375 ") <key> lookup upper bound\n" 1376 "# <num> switch to alternate dictionary (0-9)\n" 1377 "j <num> <num> merge two dictionaries\n" 1378 "f free the whole dictionary\n" 1379 "k allow duplicate keys\n" 1380 "c show number of entries\n" 1381 "t dump whole dictionary in sort order\n" 1382 "m make dictionary out of sorted items\n" 1383 "p turn prompt on\n" 1384 "s switch to non-functioning allocator\n" 1385 "q quit"; 1386 1387 for (i = 0; i < sizeof darray / sizeof *darray; i++) 1388 dict_init(&darray[i], DICTCOUNT_T_MAX, comparef); 1389 1390 for (;;) { 1391 if (prompt) 1392 putchar('>'); 1393 fflush(stdout); 1394 1395 if (!fgets(in, sizeof(input_t), stdin)) 1396 break; 1397 1398 switch(in[0]) { 1399 case '?': 1400 puts(help); 1401 break; 1402 case 'a': 1403 if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) { 1404 puts("what?"); 1405 break; 1406 } 1407 key = dupstring(tok1); 1408 val = dupstring(tok2); 1409 1410 if (!key || !val) { 1411 puts("out of memory"); 1412 free((void *) key); 1413 free(val); 1414 } 1415 1416 if (!dict_alloc_insert(d, key, val)) { 1417 puts("dict_alloc_insert failed"); 1418 free((void *) key); 1419 free(val); 1420 break; 1421 } 1422 break; 1423 case 'd': 1424 if (tokenize(in+1, &tok1, (char **) 0) != 1) { 1425 puts("what?"); 1426 break; 1427 } 1428 dn = dict_lookup(d, tok1); 1429 if (!dn) { 1430 puts("dict_lookup failed"); 1431 break; 1432 } 1433 val = dnode_get(dn); 1434 key = dnode_getkey(dn); 1435 dict_delete_free(d, dn); 1436 1437 free(val); 1438 free((void *) key); 1439 break; 1440 case 'f': 1441 dict_free(d); 1442 break; 1443 case 'l': 1444 case '(': 1445 case ')': 1446 if (tokenize(in+1, &tok1, (char **) 0) != 1) { 1447 puts("what?"); 1448 break; 1449 } 1450 dn = 0; 1451 switch (in[0]) { 1452 case 'l': 1453 dn = dict_lookup(d, tok1); 1454 break; 1455 case '(': 1456 dn = dict_lower_bound(d, tok1); 1457 break; 1458 case ')': 1459 dn = dict_upper_bound(d, tok1); 1460 break; 1461 } 1462 if (!dn) { 1463 puts("lookup failed"); 1464 break; 1465 } 1466 val = dnode_get(dn); 1467 puts(val); 1468 break; 1469 case 'm': 1470 construct(d); 1471 break; 1472 case 'k': 1473 dict_allow_dupes(d); 1474 break; 1475 case 'c': 1476 printf("%lu\n", (unsigned long) dict_count(d)); 1477 break; 1478 case 't': 1479 for (dn = dict_first(d); dn; dn = dict_next(d, dn)) { 1480 printf("%s\t%s\n", (char *) dnode_getkey(dn), 1481 (char *) dnode_get(dn)); 1482 } 1483 break; 1484 case 'q': 1485 exit(0); 1486 break; 1487 case '\0': 1488 break; 1489 case 'p': 1490 prompt = 1; 1491 break; 1492 case 's': 1493 dict_set_allocator(d, new_node, del_node, NULL); 1494 break; 1495 case '#': 1496 if (tokenize(in+1, &tok1, (char **) 0) != 1) { 1497 puts("what?"); 1498 break; 1499 } else { 1500 int dictnum = atoi(tok1); 1501 if (dictnum < 0 || dictnum > 9) { 1502 puts("invalid number"); 1503 break; 1504 } 1505 d = &darray[dictnum]; 1506 } 1507 break; 1508 case 'j': 1509 if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) { 1510 puts("what?"); 1511 break; 1512 } else { 1513 int dict1 = atoi(tok1), dict2 = atoi(tok2); 1514 if (dict1 < 0 || dict1 > 9 || dict2 < 0 || dict2 > 9) { 1515 puts("invalid number"); 1516 break; 1517 } 1518 dict_merge(&darray[dict1], &darray[dict2]); 1519 } 1520 break; 1521 default: 1522 putchar('?'); 1523 putchar('\n'); 1524 break; 1525 } 1526 } 1527 1528 return 0; 1529 } 1530 1531 #endif 1532