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
37static 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
74static dnode_t *dnode_alloc(void *context);
75static 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 */
83static 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 */
111static 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 */
136static 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
154static 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 */
188static 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 */
218static 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 */
234static 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 */
248dict_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 */
272void 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 */
288void 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 */
299void 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 */
312void 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 */
324dict_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 */
344void 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 */
364static 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
381int 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 */
412int 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 */
439dnode_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 */
477dnode_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 */
508dnode_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 */
543void 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 */
640dnode_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 */
814int 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
827void 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 */
838dnode_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 */
853dnode_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 */
870dnode_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 */
895dnode_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
916void 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
928dictcount_t dict_count(dict_t *dict)
929{
930	return dict->nodecount;
931}
932
933int dict_isempty(dict_t *dict)
934{
935	return dict->nodecount == 0;
936}
937
938int dict_isfull(dict_t *dict)
939{
940	return dict->nodecount == dict->maxcount;
941}
942
943int dict_contains(dict_t *dict, dnode_t *node)
944{
945	return verify_dict_has_node(dict_nil(dict), dict_root(dict), node);
946}
947
948static dnode_t *dnode_alloc(void *UNUSED(context))
949{
950	return malloc(sizeof *dnode_alloc(NULL));
951}
952
953static void dnode_free(dnode_t *node, void *UNUSED(context))
954{
955	free(node);
956}
957
958dnode_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
970dnode_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
979void dnode_destroy(dnode_t *dnode)
980{
981	dict_assert(!dnode_is_in_a_dict(dnode));
982	free(dnode);
983}
984
985void *dnode_get(dnode_t *dnode)
986{
987	return dnode->data;
988}
989
990const void *dnode_getkey(dnode_t *dnode)
991{
992	return dnode->key;
993}
994
995#ifdef FSCK_NOTUSED
996void dnode_put(dnode_t *dnode, void *data)
997{
998	dnode->data = data;
999}
1000#endif
1001
1002#ifndef DICT_NODEBUG
1003int 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
1010void 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
1024static 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
1031void 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
1037void 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
1061void 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
1142void 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
1170copyleft:
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
1181copyright:
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
1205typedef char input_t[256];
1206
1207static 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
1234static int comparef(const void *key1, const void *key2)
1235{
1236	return strcmp(key1, key2);
1237}
1238
1239static 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
1248static 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
1259static void del_node(dnode_t *n, void *c)
1260{
1261}
1262
1263static int prompt = 0;
1264
1265static 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
1330int 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