]> mj.ucw.cz Git - libucw.git/blob - lib/redblack.h
69230f7f5d447c8e1f9ab2e4a58118e4573a20bf
[libucw.git] / lib / redblack.h
1 /*
2  *      Red-black trees
3  *
4  *      (c) 2002, Robert Spalek <robert@ucw.cz>
5  *
6  *      Skeleton based on hash-tables by:
7  *
8  *      (c) 2002, Martin Mares <mj@ucw.cz>
9  *
10  */
11
12 /*
13  * Data structure description:
14  *
15  * A red-black tree is a binary search tree, where records are stored
16  * in nodes (may be also leaves).  Every node has a colour.  The
17  * following restrictions hold:
18  * 
19  * - a parent of a red node is black
20  * - every path from the root to a node with less than 2 children
21  *   contains the same number of black nodes
22  *
23  * A usual interpretation is, that leaves are intervals between records
24  * and contain no data.  Every leaf is black.  This is equivalent, but
25  * saves the space.
26  */
27
28 /*
29  *  This is not a normal header file, it's a generator of red-black trees.
30  *  Each time you include it with parameters set in the corresponding
31  *  preprocessor macros, it generates a tree structure with the parameters
32  *  given.
33  *
34  *  You need to specify:
35  *
36  *  TREE_NODE           data type where a node dwells (usually a struct).
37  *  TREE_PREFIX(x)      macro to add a name prefix (used on all global names
38  *                      defined by the tree generator).
39  *
40  *  Then decide on type of keys:
41  *
42  *  TREE_KEY_ATOMIC=f   use node->f as a key of an atomic type (i.e.,
43  *                      a type which can be compared using '>', `==', and '<')
44  *                      & TREE_ATOMIC_TYPE (defaults to int).
45  *  | TREE_KEY_STRING=f use node->f as a string key, allocated
46  *                      separately from the rest of the node.
47  *  | TREE_KEY_ENDSTRING=f use node->f as a string key, allocated
48  *                      automatically at the end of the node struct
49  *                      (to be declared as "char f[1]" at the end).
50  *  | TREE_KEY_COMPLEX  use a multi-component key; as the name suggests,
51  *                      the passing of parameters is a bit complex then.
52  *                      The TREE_KEY_COMPLEX(x) macro should expand to
53  *                      `x k1, x k2, ... x kn' and you should also define:
54  *    & TREE_KEY_DECL   declaration of function parameters in which key
55  *                      should be passed to all tree operations.
56  *                      That is, `type1 k1, type2 k2, ... typen kn'.
57  *                      With complex keys, TREE_GIVE_CMP is mandatory.
58  *
59  *  Then specify what operations you request (all names are automatically
60  *  prefixed by calling TREE_PREFIX):
61  *
62  *  <always defined>    init() -- initialize the tree.
63  *  TREE_WANT_CLEANUP   cleanup() -- deallocate the tree.
64  *  TREE_WANT_FIND      node *find(key) -- find first node with the specified
65  *                      key, return NULL if no such node exists.
66  *  TREE_WANT_FIND_NEXT node *find(node *start) -- find next node with the
67  *                      specified key, return NULL if no such node exists.
68  *  TREE_WANT_SEARCH    node *search(key) -- find the node with the specified
69  *                      or, if it does not exist, the nearest one.
70  *  TREE_WANT_ADJACENT  node *adjacent(node *) -- finds next/previous node.
71  *  TREE_WANT_NEW       node *new(key) -- create new node with given key.
72  *                      If it already exists, it is created as the last one.
73  *  TREE_WANT_LOOKUP    node *lookup(key) -- find node with given key,
74  *                      if it doesn't exist, create it. Defining
75  *                      TREE_GIVE_INIT_DATA is strongly recommended.
76  *  TREE_WANT_DELETE    int delete(key) -- delete and deallocate node
77  *                      with given key. Returns success.
78  *  TREE_WANT_REMOVE    remove(node *) -- delete and deallocate given node.
79  *
80  *  TREE_WANT_DUMP      dump() -- dumps the whole tree to stdout
81  *
82  *  You can also supply several functions:
83  *
84  *  TREE_GIVE_CMP       int cmp(key1, key2) -- return -1, 0, and 1 according to
85  *                      the relation of keys.  By default, we use <, ==, > for
86  *                      atomic types and either strcmp or strcasecmp for
87  *                      strings.
88  *  TREE_GIVE_EXTRA_SIZE int extra_size(key) -- returns how many bytes after the
89  *                      node should be allocated for dynamic data. Default=0
90  *                      or length of the string with TREE_KEY_ENDSTRING.
91  *  TREE_GIVE_INIT_KEY  void init_key(node *,key) -- initialize key in a newly
92  *                      created node. Defaults: assignment for atomic keys
93  *                      and static strings, strcpy for end-allocated strings.
94  *  TREE_GIVE_INIT_DATA void init_data(node *) -- initialize data fields in a
95  *                      newly created node. Very useful for lookup operations.
96  *  TREE_GIVE_ALLOC     void *alloc(unsigned int size) -- allocate space for
97  *                      a node. Default is either normal or pooled allocation
98  *                      depending on whether we want deletions.
99  *                      void free(void *) -- the converse.
100  *
101  *  ... and a couple of extra parameters:
102  *
103  *  TREE_NOCASE         string comparisons should be case-insensitive.
104  *  TREE_ATOMIC_TYPE=t  Atomic values are of type `t' instead of int.
105  *  TREE_USE_POOL=pool  Allocate all nodes from given mempool.
106  *                      Collides with delete/remove functions.
107  *  TREE_GLOBAL         Functions are exported (i.e., not static).
108  *  TREE_CONSERVE_SPACE Use as little space as possible at the price of a
109  *                      little slowdown.
110  *  TREE_MAX_DEPTH      Maximal depth of a tree (for stack allocation).
111  *
112  *  If you set TREE_WANT_ITERATOR, you also get a iterator macro at no
113  *  extra charge:
114  *
115  *  TREE_FOR_ALL(tree_prefix, tree_pointer, variable)
116  *    {
117  *      // node *variable gets declared automatically
118  *      do_something_with_node(variable);
119  *      // use TREE_BREAK and TREE_CONTINUE instead of break and continue
120  *      // you must not alter contents of the tree here
121  *    }
122  *  TREE_END_FOR;
123  *
124  *  Then include "lib/redblack.h" and voila, you have a tree suiting all your
125  *  needs (at least those which you've revealed :) ).
126  *
127  *  After including this file, all parameter macros are automatically
128  *  undef'd.
129  */
130
131 #include <string.h>
132
133 #if !defined(TREE_NODE) || !defined(TREE_PREFIX)
134 #error Some of the mandatory configuration macros are missing.
135 #endif
136
137 #define P(x) TREE_PREFIX(x)
138
139 /* Declare buckets and the tree.  */
140
141 typedef TREE_NODE P(node);
142
143 #if defined(TREE_WANT_FIND_NEXT) || defined(TREE_WANT_ADJACENT) || defined(TREE_WANT_ITERATOR) || defined(TREE_WANT_REMOVE)
144 #       define TREE_STORE_PARENT
145 #endif
146
147 typedef struct P(bucket) {
148         struct P(bucket) *son[2];
149 #ifdef TREE_STORE_PARENT
150         struct P(bucket) *parent;
151 #endif
152 #if !defined(TREE_CONSERVE_SPACE) && (defined(TREE_GIVE_EXTRA_SIZE) || defined(TREE_KEY_ENDSTRING))
153         uns red_flag:1;
154 #endif
155         P(node) n;
156 #if !defined(TREE_CONSERVE_SPACE) && !defined(TREE_GIVE_EXTRA_SIZE) && !defined(TREE_KEY_ENDSTRING)
157         uns red_flag:1;
158 #endif
159 } P(bucket);
160
161 struct P(tree) {
162         uns count;
163         uns height;                     /* of black nodes */
164         P(bucket) *root;
165 };
166
167 typedef struct P(stack_entry) {
168         P(bucket) *buck;
169         uns son;
170 } P(stack_entry);
171
172 #define T struct P(tree)
173
174 /* Preset parameters */
175
176 #if defined(TREE_KEY_ATOMIC)
177
178 #define TREE_KEY(x) x TREE_KEY_ATOMIC
179
180 #ifndef TREE_ATOMIC_TYPE
181 #       define TREE_ATOMIC_TYPE int
182 #endif
183 #define TREE_KEY_DECL TREE_ATOMIC_TYPE TREE_KEY()
184
185 #ifndef TREE_GIVE_CMP
186 #       define TREE_GIVE_CMP
187         static inline int P(cmp) (TREE_ATOMIC_TYPE x, TREE_ATOMIC_TYPE y)
188         {
189                 if (x < y)
190                         return -1;
191                 else if (x > y)
192                         return 1;
193                 else
194                         return 0;
195         }
196 #endif
197
198 #ifndef TREE_GIVE_INIT_KEY
199 #       define TREE_GIVE_INIT_KEY
200         static inline void P(init_key) (P(node) *n, TREE_ATOMIC_TYPE k)
201         { TREE_KEY(n->) = k; }
202 #endif
203
204 #elif defined(TREE_KEY_STRING) || defined(TREE_KEY_ENDSTRING)
205
206 #ifdef TREE_KEY_STRING
207 #       define TREE_KEY(x) x TREE_KEY_STRING
208 #       ifndef TREE_GIVE_INIT_KEY
209 #               define TREE_GIVE_INIT_KEY
210                 static inline void P(init_key) (P(node) *n, char *k)
211                 { TREE_KEY(n->) = k; }
212 #       endif
213 #else
214 #       define TREE_KEY(x) x TREE_KEY_ENDSTRING
215 #       define TREE_GIVE_EXTRA_SIZE
216         static inline int P(extra_size) (char *k)
217         { return strlen(k); }
218 #       ifndef TREE_GIVE_INIT_KEY
219 #               define TREE_GIVE_INIT_KEY
220                 static inline void P(init_key) (P(node) *n, char *k)
221                 { strcpy(TREE_KEY(n->), k); }
222 #       endif
223 #endif
224 #define TREE_KEY_DECL char *TREE_KEY()
225
226 #ifndef TREE_GIVE_CMP
227 #       define TREE_GIVE_CMP
228         static inline int P(cmp) (char *x, char *y)
229         {
230 #               ifdef TREE_NOCASE
231                         return strcasecmp(x,y);
232 #               else
233                         return strcmp(x,y);
234 #               endif
235         }
236 #endif
237
238 #elif defined(TREE_KEY_COMPLEX)
239
240 #define TREE_KEY(x) TREE_KEY_COMPLEX(x)
241
242 #else
243 #error You forgot to set the tree key type.
244 #endif
245
246 #ifndef TREE_CONSERVE_SPACE
247         static inline uns P(red_flag) (P(bucket) *node)
248         { return node->red_flag; }
249         static inline void P(set_red_flag) (P(bucket) *node, uns flag)
250         { node->red_flag = flag; }
251         static inline P(bucket) * P(tree_son) (P(bucket) *node, uns id)
252         { return node->son[id]; }
253         static inline void P(set_tree_son) (P(bucket) *node, uns id, P(bucket) *son)
254         { node->son[id] = son; }
255 #else
256         /* Pointers are aligned, hence we can use lower bits.  */
257         static inline uns P(red_flag) (P(bucket) *node)
258         { return ((long) node->son[0]) & 1L; }
259         static inline void P(set_red_flag) (P(bucket) *node, uns flag)
260         { (long) node->son[0] = (((long) node->son[0]) & ~1L) | (flag & 1L); }
261         static inline P(bucket) * P(tree_son) (P(bucket) *node, uns id)
262         { return (void *) (((long) node->son[id]) & ~1L); }
263         static inline void P(set_tree_son) (P(bucket) *node, uns id, P(bucket) *son)
264         { node->son[id] = (void *) ((long) son | (((long) node->son[id]) & 1L) ); }
265 #endif
266
267 /* Defaults for missing parameters.  */
268
269 #ifndef TREE_GIVE_CMP
270 #error Unable to determine how to compare two keys.
271 #endif
272
273 #ifdef TREE_GIVE_EXTRA_SIZE
274 /* This trickery is needed to avoid `unused parameter' warnings */
275 #       define TREE_EXTRA_SIZE P(extra_size)
276 #else
277 /*
278  *  Beware, C macros are expanded iteratively, not recursively,
279  *  hence we get only a _single_ argument, although the expansion
280  *  of TREE_KEY contains commas.
281  */
282 #       define TREE_EXTRA_SIZE(x) 0
283 #endif
284
285 #ifndef TREE_GIVE_INIT_KEY
286 #       error Unable to determine how to initialize keys.
287 #endif
288
289 #ifndef TREE_GIVE_INIT_DATA
290 static inline void P(init_data) (P(node) *n UNUSED)
291 {
292 }
293 #endif
294
295 #include <stdlib.h>
296
297 #ifndef TREE_GIVE_ALLOC
298 #       ifdef TREE_USE_POOL
299                 static inline void * P(alloc) (unsigned int size)
300                 { return mp_alloc_fast(TREE_USE_POOL, size); }
301 #               define TREE_SAFE_FREE(x)
302 #       else
303                 static inline void * P(alloc) (unsigned int size)
304                 { return xmalloc(size); }
305
306                 static inline void P(free) (void *x)
307                 { xfree(x); }
308 #       endif
309 #endif
310
311 #ifndef TREE_SAFE_FREE
312 #       define TREE_SAFE_FREE(x)        P(free) (x)
313 #endif
314
315 #ifdef TREE_GLOBAL
316 #       define STATIC
317 #else
318 #       define STATIC static
319 #endif
320
321 #ifndef TREE_MAX_DEPTH
322 #       define TREE_MAX_DEPTH 64
323 #endif
324
325 /* Now the operations */
326
327 STATIC void P(init) (T *t)
328 {
329         t->count = t->height = 0;
330         t->root = NULL;
331 }
332
333 #ifdef TREE_WANT_CLEANUP
334 static void P(cleanup_subtree) (T *t, P(bucket) *node)
335 {
336         if (!node)
337                 return;
338         P(cleanup_subtree) (t, P(tree_son) (node, 0));
339         P(cleanup_subtree) (t, P(tree_son) (node, 1));
340         P(free) (node);
341         t->count--;
342 }
343
344 STATIC void P(cleanup) (T *t)
345 {
346         P(cleanup_subtree) (t, t->root);
347         ASSERT(!t->count);
348         t->height = 0;
349 }
350 #endif
351
352 static uns P(fill_stack) (P(stack_entry) *stack, uns max_depth, P(bucket) *node, TREE_KEY_DECL, uns son_id UNUSED)
353 {
354         uns i;
355         stack[0].buck = node;
356         for (i=0; stack[i].buck; i++)
357         {
358                 int cmp;
359                 cmp = P(cmp) (TREE_KEY(), TREE_KEY(stack[i].buck->n.));
360                 if (cmp == 0)
361                         break;
362                 else if (cmp < 0)
363                         stack[i].son = 0;
364                 else
365                         stack[i].son = 1;
366                 ASSERT(i+1 < max_depth);
367                 stack[i+1].buck = P(tree_son) (stack[i].buck, stack[i].son);
368         }
369 #ifdef TREE_WANT_FIND_NEXT
370         if (stack[i].buck)
371         {
372                 uns idx;
373                 /* Find first/last of equal keys according to son_id.  */
374                 idx = P(fill_stack) (stack+i+1, max_depth-i-1,
375                         P(tree_son) (stack[i].buck, son_id), TREE_KEY(), son_id);
376                 if (stack[i+1+idx].buck)
377                 {
378                         stack[i].son = son_id;
379                         i = i+1+idx;
380                 }
381         }
382 #endif
383         stack[i].son = 10;
384         return i;
385 }
386
387 #if defined(TREE_WANT_FIND) || defined(TREE_WANT_LOOKUP)
388 STATIC P(node) * P(find) (T *t, TREE_KEY_DECL)
389 {
390         P(stack_entry) stack[TREE_MAX_DEPTH];
391         uns depth;
392         depth = P(fill_stack) (stack, TREE_MAX_DEPTH, t->root, TREE_KEY(), 0);
393         return stack[depth].buck ? &stack[depth].buck->n : NULL;
394 }
395 #endif
396
397 #ifdef TREE_STORE_PARENT
398 STATIC P(node) * P(adjacent) (P(node) *start, uns direction)
399 {
400         P(bucket) *node = SKIP_BACK(P(bucket), n, start);
401         P(bucket) *next = P(tree_son) (node, direction);
402         if (next)
403         {
404                 while (1)
405                 {
406                         node = P(tree_son) (next, 1 - direction);
407                         if (!node)
408                                 break;
409                         next = node;
410                 }
411         }
412         else
413         {
414                 next = node->parent;
415                 while (next && node == P(tree_son) (next, direction))
416                 {
417                         node = next;
418                         next = node->parent;
419                 }
420                 if (!next)
421                         return NULL;
422                 ASSERT(node == P(tree_son) (next, 1 - direction));
423         }
424         return &next->n;
425 }
426 #endif
427
428 #if defined(TREE_WANT_FIND_NEXT) || defined(TREE_WANT_DELETE) || defined(TREE_WANT_REMOVE)
429 static int P(find_next_node) (P(stack_entry) *stack, uns max_depth, uns direction)
430 {
431         uns depth = 0;
432         if (stack[0].buck)
433         {
434                 ASSERT(depth+1 < max_depth);
435                 stack[depth].son = direction;
436                 stack[depth+1].buck = P(tree_son) (stack[depth].buck, direction);
437                 depth++;
438                 while (stack[depth].buck)
439                 {
440                         ASSERT(depth+1 < max_depth);
441                         stack[depth].son = 1 - direction;
442                         stack[depth+1].buck = P(tree_son) (stack[depth].buck, 1 - direction);
443                         depth++;
444                 }
445         }
446         return depth;
447 }
448 #endif
449
450 #ifdef TREE_WANT_FIND_NEXT
451 STATIC P(node) * P(find_next) (P(node) *start)
452 {
453         P(node) *next = P(adjacent) (start, 1);
454         if (next && P(cmp) (TREE_KEY(start->), TREE_KEY(next->)) == 0)
455                 return next;
456         else
457                 return NULL;
458
459 }
460 #endif
461
462 #ifdef TREE_WANT_SEARCH
463 STATIC P(node) * P(search) (T *t, TREE_KEY_DECL)
464 {
465         P(stack_entry) stack[TREE_MAX_DEPTH];
466         uns depth;
467         depth = P(fill_stack) (stack, TREE_MAX_DEPTH, t->root, TREE_KEY(), 0);
468         if (!stack[depth].buck)
469         {
470                 if (depth > 0)
471                         depth--;
472                 else
473                         return NULL;
474         }
475         return &stack[depth].buck->n;
476 }
477 #endif
478
479 #if 0
480 #define TREE_TRACE(txt...) do { printf(txt); fflush(stdout); } while (0)
481 #else
482 #define TREE_TRACE(txt...)
483 #endif
484
485 static inline P(bucket) * P(rotation) (P(bucket) *node, uns son_id)
486 {
487         /* Destroys red_flag's in node, son.  Returns new root.  */
488         P(bucket) *son = P(tree_son) (node, son_id);
489         TREE_TRACE("Rotation (node %d, son %d), direction %d\n", node->n.key, son->n.key, son_id);
490         node->son[son_id] = P(tree_son) (son, 1-son_id);
491         son->son[1-son_id] = node;
492 #ifdef TREE_STORE_PARENT
493         if (node->son[son_id])
494                 node->son[son_id]->parent = node;
495         son->parent = node->parent;
496         node->parent = son;
497 #endif
498         return son;
499 }
500
501 static void P(rotate_after_insert) (T *t, P(stack_entry) *stack, uns depth)
502 {
503         P(bucket) *node;
504         P(bucket) *parent, *grand, *uncle;
505         int s1, s2;
506 try_it_again:
507         node = stack[depth].buck;
508         ASSERT(P(red_flag) (node));
509         /* At this moment, node became red.  The paths sum have
510          * been preserved, but we have to check the parental
511          * condition.  */
512         if (depth == 0)
513         {
514                 ASSERT(t->root == node);
515                 return;
516         }
517         parent = stack[depth-1].buck;
518         if (!P(red_flag) (parent))
519                 return;
520         if (depth == 1)
521         {
522                 ASSERT(t->root == parent);
523                 P(set_red_flag) (parent, 0);
524                 t->height++;
525                 return;
526         }
527         grand = stack[depth-2].buck;
528         ASSERT(!P(red_flag) (grand));
529         /* The parent is also red, the grandparent exists and it
530          * is black.  */
531         s1 = stack[depth-1].son;
532         s2 = stack[depth-2].son;
533         uncle = P(tree_son) (grand, 1-s2);
534         if (uncle && P(red_flag) (uncle))
535         {
536                 /* Red parent and uncle, black grandparent.
537                  * Exchange and try another iteration. */
538                 P(set_red_flag) (parent, 0);
539                 P(set_red_flag) (uncle, 0);
540                 P(set_red_flag) (grand, 1);
541                 depth -= 2;
542                 TREE_TRACE("Swapping colours (parent %d, uncle %d, grand %d), passing thru\n", parent->n.key, uncle->n.key, grand->n.key);
543                 goto try_it_again;
544         }
545         /* Black uncle and grandparent, we need to rotate.  Test
546          * the direction.  */
547         if (s1 == s2)
548         {
549                 node = P(rotation) (grand, s2);
550                 P(set_red_flag) (parent, 0);
551                 P(set_red_flag) (grand, 1);
552         }
553         else
554         {
555                 grand->son[s2] = P(rotation) (parent, s1);
556                 node = P(rotation) (grand, s2);
557                 P(set_red_flag) (grand, 1);
558                 P(set_red_flag) (parent, 1);
559                 P(set_red_flag) (node, 0);
560         }
561         if (depth >= 3)
562                 P(set_tree_son) (stack[depth-3].buck, stack[depth-3].son, node);
563         else
564                 t->root = node;
565 }
566
567 #if defined(TREE_WANT_NEW) || defined(TREE_WANT_LOOKUP)
568 STATIC P(node) * P(new) (T *t, TREE_KEY_DECL)
569 {
570         P(stack_entry) stack[TREE_MAX_DEPTH];
571         P(bucket) *added;
572         uns depth;
573         depth = P(fill_stack) (stack, TREE_MAX_DEPTH, t->root, TREE_KEY(), 1);
574 #ifdef TREE_WANT_FIND_NEXT
575         /* It is the last found value, hence everything in the right subtree is
576          * strongly _bigger_.  */
577         depth += P(find_next_node) (stack+depth, TREE_MAX_DEPTH-depth, 1);
578 #endif
579         ASSERT(!stack[depth].buck);
580         /* We are in a leaf, hence we can easily append a new leaf to it.  */
581         added = P(alloc) (sizeof(struct P(bucket)) + TREE_EXTRA_SIZE(TREE_KEY()) );
582         added->son[0] = added->son[1] = NULL;
583         stack[depth].buck = added;
584         if (depth > 0)
585         {
586 #ifdef TREE_STORE_PARENT
587                 added->parent = stack[depth-1].buck;
588 #endif
589                 P(set_tree_son) (stack[depth-1].buck, stack[depth-1].son, added);
590         }
591         else
592         {
593 #ifdef TREE_STORE_PARENT
594                 added->parent = NULL;
595 #endif
596                 t->root = added;
597         }
598         P(set_red_flag) (added, 1);     /* Set it red to not disturb the path sum.  */
599         P(init_key) (&added->n, TREE_KEY());
600         P(init_data) (&added->n);
601         t->count++;
602         /* Let us reorganize the red_flag's and the structure of the tree.  */
603         P(rotate_after_insert) (t, stack, depth);
604         return &added->n;
605 }
606 #endif
607
608 #ifdef TREE_WANT_LOOKUP
609 STATIC P(node) * P(lookup) (T *t, TREE_KEY_DECL)
610 {
611         P(node) *node;
612         node = P(find) (t, TREE_KEY());
613         if (node)
614                 return node;
615         return P(new) (t, TREE_KEY());
616 }
617 #endif
618
619 #if defined(TREE_WANT_REMOVE) || defined(TREE_WANT_DELETE)
620 static void P(rotate_after_delete) (T *t, P(stack_entry) *stack, int depth)
621 {
622         uns iteration = 0;
623         P(bucket) *parent, *sibling, *instead;
624         uns parent_red, del_son, sibl_red;
625 missing_black:
626         if (depth < 0)
627         {
628                 t->height--;
629                 return;
630         }
631         parent = stack[depth].buck;
632         parent_red = P(red_flag) (parent);
633         del_son = stack[depth].son;
634         /* For the 1st iteration: we have deleted parent->son[del_son], which
635          * was a black node with no son.  Hence there is one mising black
636          * vertex in that path, which we are going to fix now.
637          *
638          * For other iterations: in that path, there is also missing a black
639          * node.  */
640         if (!iteration)
641                 ASSERT(!P(tree_son) (parent, del_son));
642         sibling = P(tree_son) (parent, 1-del_son);
643         ASSERT(sibling);
644         sibl_red = P(red_flag) (sibling);
645         instead = NULL;
646         if (!sibl_red)
647         {
648                 P(bucket) *son[2];
649                 uns red[2];
650                 son[0] = P(tree_son) (sibling, 0);
651                 son[1] = P(tree_son) (sibling, 1);
652                 red[0] = son[0] ? P(red_flag) (son[0]) : 0;
653                 red[1] = son[1] ? P(red_flag) (son[1]) : 0;
654                 if (!red[0] && !red[1])
655                 {
656                         P(set_red_flag) (sibling, 1);
657                         P(set_red_flag) (parent, 0);
658                         if (parent_red)
659                                 return;
660                         else
661                         {
662                                 depth--;
663                                 iteration++;
664                                 TREE_TRACE("Swapping colours (parent %d, sibling %d), passing thru\n", parent->n.key, sibling->n.key);
665                                 goto missing_black;
666                         }
667                 } else if (!red[del_son])
668                 {
669                         instead = P(rotation) (parent, 1-del_son);
670                         P(set_red_flag) (instead, parent_red);
671                         P(set_red_flag) (parent, 0);
672                         P(set_red_flag) (son[1-del_son], 0);
673                 } else /* red[del_son] */
674                 {
675                         parent->son[1-del_son] = P(rotation) (sibling, del_son);
676                         instead = P(rotation) (parent, 1-del_son);
677                         P(set_red_flag) (instead, parent_red);
678                         P(set_red_flag) (parent, 0);
679                         P(set_red_flag) (sibling, 0);
680                 }
681         } else /* sibl_red */
682         {
683                 P(bucket) *grand[2], *son;
684                 uns red[2];
685                 ASSERT(!parent_red);
686                 son = P(tree_son) (sibling, del_son);
687                 ASSERT(son && !P(red_flag) (son));
688                 grand[0] = P(tree_son) (son, 0);
689                 grand[1] = P(tree_son) (son, 1);
690                 red[0] = grand[0] ? P(red_flag) (grand[0]) : 0;
691                 red[1] = grand[1] ? P(red_flag) (grand[1]) : 0;
692                 if (!red[0] && !red[1])
693                 {
694                         instead = P(rotation) (parent, 1-del_son);
695                         P(set_red_flag) (instead, 0);
696                         P(set_red_flag) (parent, 0);
697                         P(set_red_flag) (son, 1);
698                 }
699                 else if (!red[del_son])
700                 {
701                         parent->son[1-del_son] = P(rotation) (sibling, del_son);
702                         instead = P(rotation) (parent, 1-del_son);
703                         P(set_red_flag) (instead, 0);
704                         P(set_red_flag) (parent, 0);
705                         P(set_red_flag) (sibling, 1);
706                         P(set_red_flag) (grand[1-del_son], 0);
707                 } else /* red[del_son] */
708                 {
709                         sibling->son[del_son] = P(rotation) (son, del_son);
710                         parent->son[1-del_son] = P(rotation) (sibling, del_son);
711                         instead = P(rotation) (parent, 1-del_son);
712                         P(set_red_flag) (instead, 0);
713                         P(set_red_flag) (parent, 0);
714                         P(set_red_flag) (sibling, 1);
715                         P(set_red_flag) (son, 0);
716                 }
717         }
718         /* We have performed all desired rotations and need to store the new
719          * pointer to the subtree.  */
720         ASSERT(instead);
721         if (depth > 0)
722                 P(set_tree_son) (stack[depth-1].buck, stack[depth-1].son, instead);
723         else
724                 t->root = instead;
725 }
726
727 static void P(remove_by_stack) (T *t, P(stack_entry) *stack, uns depth)
728 {
729         P(bucket) *node = stack[depth].buck;
730         P(bucket) *son;
731         uns i;
732         for (i=0; i<depth; i++)
733                 ASSERT(P(tree_son) (stack[i].buck, stack[i].son) == stack[i+1].buck);
734         if (P(tree_son) (node, 0) && P(tree_son) (node, 1))
735         {
736                 P(bucket) *xchg;
737                 uns flag_node, flag_xchg;
738                 uns d = P(find_next_node) (stack+depth, TREE_MAX_DEPTH-depth, 1);
739
740                 ASSERT(d >= 2);
741                 d--;
742                 xchg = stack[depth+d].buck;
743                 flag_node = P(red_flag) (node);
744                 flag_xchg = P(red_flag) (xchg);
745                 ASSERT(!P(tree_son) (xchg, 0));
746                 son = P(tree_son) (xchg, 1);
747                 stack[depth].buck = xchg;       /* Magic iff d == 1.  */
748                 stack[depth+d].buck = node;
749                 xchg->son[0] = P(tree_son) (node, 0);
750                 xchg->son[1] = P(tree_son) (node, 1);
751                 if (depth > 0)
752                         P(set_tree_son) (stack[depth-1].buck, stack[depth-1].son, xchg);
753                 else
754                         t->root = xchg;
755                 node->son[0] = NULL;
756                 node->son[1] = son;
757                 P(set_tree_son) (stack[depth+d-1].buck, stack[depth+d-1].son, node);
758 #ifdef TREE_STORE_PARENT
759                 xchg->parent = depth > 0 ? stack[depth-1].buck : NULL;
760                 xchg->son[0]->parent = xchg;
761                 xchg->son[1]->parent = xchg;
762                 node->parent = stack[depth+d-1].buck;
763                 if (son)
764                         son->parent = node;
765 #endif
766                 P(set_red_flag) (xchg, flag_node);
767                 P(set_red_flag) (node, flag_xchg);
768                 depth += d;
769         }
770         else if (P(tree_son) (node, 0))
771                 son = P(tree_son) (node, 0);
772         else
773                 son = P(tree_son) (node, 1);
774         /* At this moment, stack[depth].buck == node and it has at most one son
775          * and it is stored in the variable son.  */
776         t->count--;
777         if (depth > 0)
778         {
779                 P(set_tree_son) (stack[depth-1].buck, stack[depth-1].son, son);
780 #ifdef TREE_STORE_PARENT
781                 if (son)
782                         son->parent = stack[depth-1].buck;
783 #endif
784         }
785         else
786         {
787                 t->root = son;
788 #ifdef TREE_STORE_PARENT
789                 if (son)
790                         son->parent = NULL;
791 #endif
792         }
793         if (P(red_flag) (node))
794         {
795                 ASSERT(!son);
796                 return;
797         }
798         TREE_SAFE_FREE(node);
799         /* We have deleted a black node.  */
800         if (son)
801         {
802                 ASSERT(P(red_flag) (son));
803                 P(set_red_flag) (son, 0);
804                 return;
805         }
806         P(rotate_after_delete) (t, stack, (int) depth - 1);
807 }
808 #endif
809
810 #ifdef TREE_WANT_REMOVE
811 STATIC void P(remove) (T *t, P(node) *Node)
812 {
813         P(stack_entry) stack[TREE_MAX_DEPTH];
814         P(bucket) *node = SKIP_BACK(P(bucket), n, Node);
815         uns depth = 0, i;
816         stack[0].buck = node;
817         stack[0].son = 10;
818         while (node->parent)
819         {
820                 depth++;
821                 ASSERT(depth < TREE_MAX_DEPTH);
822                 stack[depth].buck = node->parent;
823                 stack[depth].son = P(tree_son) (node->parent, 0) == node ? 0 : 1;
824                 node = node->parent;
825         }
826         for (i=0; i<(depth+1)/2; i++)
827         {
828                 P(stack_entry) tmp = stack[i];
829                 stack[i] = stack[depth-i];
830                 stack[depth-i] = tmp;
831         }
832         P(remove_by_stack) (t, stack, depth);
833 }
834 #endif
835
836 #ifdef TREE_WANT_DELETE
837 STATIC int P(delete) (T *t, TREE_KEY_DECL)
838 {
839         P(stack_entry) stack[TREE_MAX_DEPTH];
840         uns depth;
841         depth = P(fill_stack) (stack, TREE_MAX_DEPTH, t->root, TREE_KEY(), 1);
842         if (stack[depth].buck)
843         {
844                 P(remove_by_stack) (t, stack, depth);
845                 return 1;
846         }
847         else
848                 return 0;
849 }
850 #endif
851
852 #ifdef TREE_WANT_DUMP
853 static void P(dump_subtree) (struct fastbuf *fb, T *t, P(bucket) *node, P(bucket) *parent, int cmp_res, int level, uns black)
854 {
855         uns flag;
856         int i;
857         if (!node)
858         {
859                 ASSERT(black == t->height);
860                 return;
861         }
862         flag = P(red_flag) (node);
863 #ifdef TREE_STORE_PARENT
864         ASSERT(node->parent == parent);
865 #endif
866         if (parent)
867         {
868                 ASSERT(!flag || !P(red_flag) (parent));
869                 cmp_res *= P(cmp) (TREE_KEY(node->n.), TREE_KEY(parent->n.));
870 #ifdef TREE_WANT_FIND_NEXT
871                 ASSERT(cmp_res >= 0);
872 #else
873                 ASSERT(cmp_res > 0);
874 #endif
875         }
876         P(dump_subtree) (fb, t, P(tree_son) (node, 0), node, -1, level+1, black + (1-flag));
877         if (fb)
878         {
879                 char tmp[20];
880                 for (i=0; i<level; i++)
881                         bputs(fb, "  ");
882                 sprintf(tmp, "L%d %c\t", level, flag ? 'R' : 'B');
883                 bputs(fb, tmp);
884                 P(dump_key) (fb, &node->n);
885                 P(dump_data) (fb, &node->n);
886                 bputs(fb, "\n");
887         }
888         P(dump_subtree) (fb, t, P(tree_son) (node, 1), node, +1, level+1, black + (1-flag));
889 }
890
891 STATIC void P(dump) (struct fastbuf *fb, T *t)
892 {
893         if (fb)
894         {
895                 char tmp[50];
896                 sprintf(tmp, "Tree of %d nodes and height %d\n", t->count, t->height);
897                 bputs(fb, tmp);
898         }
899         P(dump_subtree) (fb, t, t->root, NULL, 0, 0, 0);
900         if (fb)
901         {
902                 bputs(fb, "\n");
903                 bflush(fb);
904         }
905 }
906 #endif
907
908 /* And the iterator */
909
910 #ifdef TREE_WANT_ITERATOR
911 static P(node) * P(first_node) (T *t, uns direction)
912 {
913         P(bucket) *node = t->root, *prev = NULL;
914         while (node)
915         {
916                 prev = node;
917                 node = P(tree_son) (node, direction);
918         }
919         return prev ? &prev->n : NULL;
920 }
921
922 #ifndef TREE_FOR_ALL
923
924 #define TREE_FOR_ALL(t_px, t_ptr, t_var)                                                \
925 do                                                                                      \
926 {                                                                                       \
927         TREE_GLUE(t_px,node) *t_var = TREE_GLUE(t_px,first_node)(t_ptr, 0);             \
928         for (; t_var; t_var = TREE_GLUE(t_px,adjacent)(t_var, 1))                       \
929         {
930 #define TREE_END_FOR } } while(0)
931 #define TREE_BREAK break
932 #define TREE_CONTINUE continue
933 #define TREE_GLUE(x,y) x##_##y
934
935 #endif
936 #endif
937
938 /* Finally, undefine all the parameters */
939
940 #undef P
941 #undef T
942
943 #undef TREE_NODE
944 #undef TREE_PREFIX
945 #undef TREE_KEY_ATOMIC
946 #undef TREE_KEY_STRING
947 #undef TREE_KEY_ENDSTRING
948 #undef TREE_KEY_COMPLEX
949 #undef TREE_KEY_DECL
950 #undef TREE_WANT_CLEANUP
951 #undef TREE_WANT_FIND
952 #undef TREE_WANT_FIND_NEXT
953 #undef TREE_WANT_SEARCH
954 #undef TREE_WANT_ADJACENT
955 #undef TREE_WANT_NEW
956 #undef TREE_WANT_LOOKUP
957 #undef TREE_WANT_DELETE
958 #undef TREE_WANT_REMOVE
959 #undef TREE_WANT_DUMP
960 #undef TREE_WANT_ITERATOR
961 #undef TREE_GIVE_CMP
962 #undef TREE_GIVE_EXTRA_SIZE
963 #undef TREE_GIVE_INIT_KEY
964 #undef TREE_GIVE_INIT_DATA
965 #undef TREE_GIVE_ALLOC
966 #undef TREE_NOCASE
967 #undef TREE_ATOMIC_TYPE
968 #undef TREE_USE_POOL
969 #undef TREE_STATIC
970 #undef TREE_CONSERVE_SPACE
971 #undef TREE_MAX_DEPTH
972 #undef TREE_STORE_PARENT
973 #undef TREE_KEY
974 #undef TREE_EXTRA_SIZE
975 #undef TREE_SAFE_FREE
976 #undef TREE_TRACE
977 #undef STATIC