1 // SPDX-License-Identifier: Unlicense
2 //
3 // Based on Julienne Walker's <http://eternallyconfuzzled.com/> rb_tree
4 // implementation.
5 //
6 // Modified by Mirek Rusin <http://github.com/mirek/rb_tree>.
7 //
8 // This is free and unencumbered software released into the public domain.
9 //
10 // Anyone is free to copy, modify, publish, use, compile, sell, or
11 // distribute this software, either in source code form or as a compiled
12 // binary, for any purpose, commercial or non-commercial, and by any
13 // means.
14 //
15 // In jurisdictions that recognize copyright laws, the author or authors
16 // of this software dedicate any and all copyright interest in the
17 // software to the public domain. We make this dedication for the benefit
18 // of the public at large and to the detriment of our heirs and
19 // successors. We intend this dedication to be an overt act of
20 // relinquishment in perpetuity of all present and future rights to this
21 // software under copyright law.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
27 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29 // OTHER DEALINGS IN THE SOFTWARE.
30 //
31 // For more information, please refer to <http://unlicense.org/>
32 //
33
34 #include "rb_tree.h"
35
36 // rb_node
37
38 struct rb_node *
rb_node_alloc()39 rb_node_alloc () {
40 return malloc(sizeof(struct rb_node));
41 }
42
43 struct rb_node *
rb_node_init(struct rb_node * self,void * value)44 rb_node_init (struct rb_node *self, void *value) {
45 if (self) {
46 self->red = 1;
47 self->link[0] = self->link[1] = NULL;
48 self->value = value;
49 }
50 return self;
51 }
52
53 struct rb_node *
rb_node_create(void * value)54 rb_node_create (void *value) {
55 return rb_node_init(rb_node_alloc(), value);
56 }
57
58 void
rb_node_dealloc(struct rb_node * self)59 rb_node_dealloc (struct rb_node *self) {
60 if (self) {
61 free(self);
62 }
63 }
64
65 static int
rb_node_is_red(const struct rb_node * self)66 rb_node_is_red (const struct rb_node *self) {
67 return self ? self->red : 0;
68 }
69
70 static struct rb_node *
rb_node_rotate(struct rb_node * self,int dir)71 rb_node_rotate (struct rb_node *self, int dir) {
72 struct rb_node *result = NULL;
73 if (self) {
74 result = self->link[!dir];
75 self->link[!dir] = result->link[dir];
76 result->link[dir] = self;
77 self->red = 1;
78 result->red = 0;
79 }
80 return result;
81 }
82
83 static struct rb_node *
rb_node_rotate2(struct rb_node * self,int dir)84 rb_node_rotate2 (struct rb_node *self, int dir) {
85 struct rb_node *result = NULL;
86 if (self) {
87 self->link[!dir] = rb_node_rotate(self->link[!dir], !dir);
88 result = rb_node_rotate(self, dir);
89 }
90 return result;
91 }
92
93 // rb_tree - default callbacks
94
95 int
rb_tree_node_cmp_ptr_cb(struct rb_tree * self,struct rb_node * a,struct rb_node * b)96 rb_tree_node_cmp_ptr_cb (struct rb_tree *self, struct rb_node *a, struct rb_node *b) {
97 return (a->value > b->value) - (a->value < b->value);
98 }
99
100 void
rb_tree_node_dealloc_cb(struct rb_tree * self,struct rb_node * node)101 rb_tree_node_dealloc_cb (struct rb_tree *self, struct rb_node *node) {
102 if (self) {
103 if (node) {
104 rb_node_dealloc(node);
105 }
106 }
107 }
108
109 // rb_tree
110
111 struct rb_tree *
rb_tree_alloc()112 rb_tree_alloc () {
113 return malloc(sizeof(struct rb_tree));
114 }
115
116 struct rb_tree *
rb_tree_init(struct rb_tree * self,rb_tree_node_cmp_f node_cmp_cb)117 rb_tree_init (struct rb_tree *self, rb_tree_node_cmp_f node_cmp_cb) {
118 if (self) {
119 self->root = NULL;
120 self->size = 0;
121 self->cmp = node_cmp_cb ? node_cmp_cb : rb_tree_node_cmp_ptr_cb;
122 }
123 return self;
124 }
125
126 struct rb_tree *
rb_tree_create(rb_tree_node_cmp_f node_cb)127 rb_tree_create (rb_tree_node_cmp_f node_cb) {
128 return rb_tree_init(rb_tree_alloc(), node_cb);
129 }
130
131 void
rb_tree_dealloc(struct rb_tree * self,rb_tree_node_f node_cb)132 rb_tree_dealloc (struct rb_tree *self, rb_tree_node_f node_cb) {
133 if (self) {
134 if (node_cb) {
135 struct rb_node *node = self->root;
136 struct rb_node *save = NULL;
137
138 // Rotate away the left links so that
139 // we can treat this like the destruction
140 // of a linked list
141 while (node) {
142 if (node->link[0] == NULL) {
143
144 // No left links, just kill the node and move on
145 save = node->link[1];
146 node_cb(self, node);
147 node = NULL;
148 } else {
149
150 // Rotate away the left link and check again
151 save = node->link[0];
152 node->link[0] = save->link[1];
153 save->link[1] = node;
154 }
155 node = save;
156 }
157 }
158 free(self);
159 }
160 }
161
162 int
rb_tree_test(struct rb_tree * self,struct rb_node * root)163 rb_tree_test (struct rb_tree *self, struct rb_node *root) {
164 int lh, rh;
165
166 if ( root == NULL )
167 return 1;
168 else {
169 struct rb_node *ln = root->link[0];
170 struct rb_node *rn = root->link[1];
171
172 /* Consecutive red links */
173 if (rb_node_is_red(root)) {
174 if (rb_node_is_red(ln) || rb_node_is_red(rn)) {
175 printf("Red violation");
176 return 0;
177 }
178 }
179
180 lh = rb_tree_test(self, ln);
181 rh = rb_tree_test(self, rn);
182
183 /* Invalid binary search tree */
184 if ( ( ln != NULL && self->cmp(self, ln, root) >= 0 )
185 || ( rn != NULL && self->cmp(self, rn, root) <= 0))
186 {
187 puts ( "Binary tree violation" );
188 return 0;
189 }
190
191 /* Black height mismatch */
192 if ( lh != 0 && rh != 0 && lh != rh ) {
193 puts ( "Black violation" );
194 return 0;
195 }
196
197 /* Only count black links */
198 if ( lh != 0 && rh != 0 )
199 return rb_node_is_red ( root ) ? lh : lh + 1;
200 else
201 return 0;
202 }
203 }
204
205 void *
rb_tree_find(struct rb_tree * self,void * value)206 rb_tree_find(struct rb_tree *self, void *value) {
207 void *result = NULL;
208 if (self) {
209 struct rb_node node = { .value = value };
210 struct rb_node *it = self->root;
211 int cmp = 0;
212 while (it) {
213 if ((cmp = self->cmp(self, it, &node))) {
214
215 // If the tree supports duplicates, they should be
216 // chained to the right subtree for this to work
217 it = it->link[cmp < 0];
218 } else {
219 break;
220 }
221 }
222 result = it ? it->value : NULL;
223 }
224 return result;
225 }
226
227 // Creates (malloc'ates)
228 int
rb_tree_insert(struct rb_tree * self,void * value)229 rb_tree_insert (struct rb_tree *self, void *value) {
230 return rb_tree_insert_node(self, rb_node_create(value));
231 }
232
233 // Returns 1 on success, 0 otherwise.
234 int
rb_tree_insert_node(struct rb_tree * self,struct rb_node * node)235 rb_tree_insert_node (struct rb_tree *self, struct rb_node *node) {
236 if (self && node) {
237 if (self->root == NULL) {
238 self->root = node;
239 } else {
240 struct rb_node head = { 0 }; // False tree root
241 struct rb_node *g, *t; // Grandparent & parent
242 struct rb_node *p, *q; // Iterator & parent
243 int dir = 0, last = 0;
244
245 // Set up our helpers
246 t = &head;
247 g = p = NULL;
248 q = t->link[1] = self->root;
249
250 // Search down the tree for a place to insert
251 while (1) {
252 if (q == NULL) {
253
254 // Insert node at the first null link.
255 p->link[dir] = q = node;
256 } else if (rb_node_is_red(q->link[0]) && rb_node_is_red(q->link[1])) {
257
258 // Simple red violation: color flip
259 q->red = 1;
260 q->link[0]->red = 0;
261 q->link[1]->red = 0;
262 }
263
264 if (rb_node_is_red(q) && rb_node_is_red(p)) {
265
266 // Hard red violation: rotations necessary
267 int dir2 = t->link[1] == g;
268 if (q == p->link[last]) {
269 t->link[dir2] = rb_node_rotate(g, !last);
270 } else {
271 t->link[dir2] = rb_node_rotate2(g, !last);
272 }
273 }
274
275 // Stop working if we inserted a node. This
276 // check also disallows duplicates in the tree
277 if (self->cmp(self, q, node) == 0) {
278 break;
279 }
280
281 last = dir;
282 dir = self->cmp(self, q, node) < 0;
283
284 // Move the helpers down
285 if (g != NULL) {
286 t = g;
287 }
288
289 g = p, p = q;
290 q = q->link[dir];
291 }
292
293 // Update the root (it may be different)
294 self->root = head.link[1];
295 }
296
297 // Make the root black for simplified logic
298 self->root->red = 0;
299 ++self->size;
300 return 1;
301 }
302 return 0;
303 }
304
305 // Returns 1 if the value was removed, 0 otherwise. Optional node callback
306 // can be provided to dealloc node and/or user data. Use rb_tree_node_dealloc
307 // default callback to deallocate node created by rb_tree_insert(...).
308 int
rb_tree_remove_with_cb(struct rb_tree * self,void * value,rb_tree_node_f node_cb)309 rb_tree_remove_with_cb (struct rb_tree *self, void *value, rb_tree_node_f node_cb) {
310 if (self->root != NULL) {
311 struct rb_node head = {0}; // False tree root
312 struct rb_node node = { .value = value }; // Value wrapper node
313 struct rb_node *q, *p, *g; // Helpers
314 struct rb_node *f = NULL; // Found item
315 int dir = 1;
316
317 // Set up our helpers
318 q = &head;
319 g = p = NULL;
320 q->link[1] = self->root;
321
322 // Search and push a red node down
323 // to fix red violations as we go
324 while (q->link[dir] != NULL) {
325 int last = dir;
326
327 // Move the helpers down
328 g = p, p = q;
329 q = q->link[dir];
330 dir = self->cmp(self, q, &node) < 0;
331
332 // Save the node with matching value and keep
333 // going; we'll do removal tasks at the end
334 if (self->cmp(self, q, &node) == 0) {
335 f = q;
336 }
337
338 // Push the red node down with rotations and color flips
339 if (!rb_node_is_red(q) && !rb_node_is_red(q->link[dir])) {
340 if (rb_node_is_red(q->link[!dir])) {
341 p = p->link[last] = rb_node_rotate(q, dir);
342 } else if (!rb_node_is_red(q->link[!dir])) {
343 struct rb_node *s = p->link[!last];
344 if (s) {
345 if (!rb_node_is_red(s->link[!last]) && !rb_node_is_red(s->link[last])) {
346
347 // Color flip
348 p->red = 0;
349 s->red = 1;
350 q->red = 1;
351 } else {
352 int dir2 = g->link[1] == p;
353 if (rb_node_is_red(s->link[last])) {
354 g->link[dir2] = rb_node_rotate2(p, last);
355 } else if (rb_node_is_red(s->link[!last])) {
356 g->link[dir2] = rb_node_rotate(p, last);
357 }
358
359 // Ensure correct coloring
360 q->red = g->link[dir2]->red = 1;
361 g->link[dir2]->link[0]->red = 0;
362 g->link[dir2]->link[1]->red = 0;
363 }
364 }
365 }
366 }
367 }
368
369 // Replace and remove the saved node
370 if (f) {
371 void *tmp = f->value;
372 f->value = q->value;
373 q->value = tmp;
374
375 p->link[p->link[1] == q] = q->link[q->link[0] == NULL];
376
377 if (node_cb) {
378 node_cb(self, q);
379 }
380 q = NULL;
381 }
382
383 // Update the root (it may be different)
384 self->root = head.link[1];
385
386 // Make the root black for simplified logic
387 if (self->root != NULL) {
388 self->root->red = 0;
389 }
390
391 --self->size;
392 }
393 return 1;
394 }
395
396 int
rb_tree_remove(struct rb_tree * self,void * value)397 rb_tree_remove (struct rb_tree *self, void *value) {
398 int result = 0;
399 if (self) {
400 result = rb_tree_remove_with_cb(self, value, rb_tree_node_dealloc_cb);
401 }
402 return result;
403 }
404
405 size_t
rb_tree_size(struct rb_tree * self)406 rb_tree_size (struct rb_tree *self) {
407 size_t result = 0;
408 if (self) {
409 result = self->size;
410 }
411 return result;
412 }
413
414 // rb_iter
415
416 struct rb_iter *
rb_iter_alloc()417 rb_iter_alloc () {
418 return malloc(sizeof(struct rb_iter));
419 }
420
421 struct rb_iter *
rb_iter_init(struct rb_iter * self)422 rb_iter_init (struct rb_iter *self) {
423 if (self) {
424 self->tree = NULL;
425 self->node = NULL;
426 self->top = 0;
427 }
428 return self;
429 }
430
431 struct rb_iter *
rb_iter_create()432 rb_iter_create () {
433 return rb_iter_init(rb_iter_alloc());
434 }
435
436 void
rb_iter_dealloc(struct rb_iter * self)437 rb_iter_dealloc (struct rb_iter *self) {
438 if (self) {
439 free(self);
440 }
441 }
442
443 // Internal function, init traversal object, dir determines whether
444 // to begin traversal at the smallest or largest valued node.
445 static void *
rb_iter_start(struct rb_iter * self,struct rb_tree * tree,int dir)446 rb_iter_start (struct rb_iter *self, struct rb_tree *tree, int dir) {
447 void *result = NULL;
448 if (self) {
449 self->tree = tree;
450 self->node = tree->root;
451 self->top = 0;
452
453 // Save the path for later selfersal
454 if (self->node != NULL) {
455 while (self->node->link[dir] != NULL) {
456 self->path[self->top++] = self->node;
457 self->node = self->node->link[dir];
458 }
459 }
460
461 result = self->node == NULL ? NULL : self->node->value;
462 }
463 return result;
464 }
465
466 // Traverse a red black tree in the user-specified direction (0 asc, 1 desc)
467 static void *
rb_iter_move(struct rb_iter * self,int dir)468 rb_iter_move (struct rb_iter *self, int dir) {
469 if (self->node->link[dir] != NULL) {
470
471 // Continue down this branch
472 self->path[self->top++] = self->node;
473 self->node = self->node->link[dir];
474 while ( self->node->link[!dir] != NULL ) {
475 self->path[self->top++] = self->node;
476 self->node = self->node->link[!dir];
477 }
478 } else {
479
480 // Move to the next branch
481 struct rb_node *last = NULL;
482 do {
483 if (self->top == 0) {
484 self->node = NULL;
485 break;
486 }
487 last = self->node;
488 self->node = self->path[--self->top];
489 } while (last == self->node->link[dir]);
490 }
491 return self->node == NULL ? NULL : self->node->value;
492 }
493
494 void *
rb_iter_first(struct rb_iter * self,struct rb_tree * tree)495 rb_iter_first (struct rb_iter *self, struct rb_tree *tree) {
496 return rb_iter_start(self, tree, 0);
497 }
498
499 void *
rb_iter_last(struct rb_iter * self,struct rb_tree * tree)500 rb_iter_last (struct rb_iter *self, struct rb_tree *tree) {
501 return rb_iter_start(self, tree, 1);
502 }
503
504 void *
rb_iter_next(struct rb_iter * self)505 rb_iter_next (struct rb_iter *self) {
506 return rb_iter_move(self, 1);
507 }
508
509 void *
rb_iter_prev(struct rb_iter * self)510 rb_iter_prev (struct rb_iter *self) {
511 return rb_iter_move(self, 0);
512 }
513