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