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