OSDN Git Service

Code drop from //branches/cupcake/...@124589
[android-x86/external-e2fsprogs.git] / e2fsck / dict.c
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
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
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
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
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
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
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
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
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
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
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
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  */
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
952 dictcount_t dict_count(dict_t *dict)
953 {
954     return dict->nodecount;
955 }
956
957 int dict_isempty(dict_t *dict)
958 {
959     return dict->nodecount == 0;
960 }
961
962 int dict_isfull(dict_t *dict)
963 {
964     return dict->nodecount == dict->maxcount;
965 }
966
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
972 static dnode_t *dnode_alloc(void *context EXT2FS_ATTR((unused)))
973 {
974     return malloc(sizeof *dnode_alloc(NULL));
975 }
976
977 static void dnode_free(dnode_t *node, void *context EXT2FS_ATTR((unused)))
978 {
979     free(node);
980 }
981
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
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
1003 void dnode_destroy(dnode_t *dnode)
1004 {
1005     assert (!dnode_is_in_a_dict(dnode));
1006     free(dnode);
1007 }
1008
1009 void *dnode_get(dnode_t *dnode)
1010 {
1011     return dnode->data;
1012 }
1013
1014 const void *dnode_getkey(dnode_t *dnode)
1015 {
1016     return dnode->key;
1017 }
1018
1019 #ifdef E2FSCK_NOTUSED
1020 void dnode_put(dnode_t *dnode, void *data)
1021 {
1022     dnode->data = data;
1023 }
1024
1025 int dnode_is_in_a_dict(dnode_t *dnode)
1026 {
1027     return (dnode->parent && dnode->left && dnode->right);
1028 }
1029
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
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
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
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
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
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
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
1254 static int comparef(const void *key1, const void *key2)
1255 {
1256     return strcmp(key1, key2);
1257 }
1258
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
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
1279 static void del_node(dnode_t *n, void *c)
1280 {
1281 }
1282
1283 static int prompt = 0;
1284
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
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