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