PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
rbtree.c
Go to the documentation of this file.
2
3#include <assert.h>
4
5static inline void rbtree_update(rbtree_t* tree, rbnode_t* node)
6{
7 if (tree == NULL || node == NULL || tree->update == NULL)
8 {
9 return;
10 }
11
12 tree->update(node);
13}
14
15/// @todo This could be optimized to avoid updating nodes multiple times for overlapping paths.
16static inline void rbtree_update_to_root(rbtree_t* tree, rbnode_t* node)
17{
18 if (tree == NULL || node == NULL || tree->update == NULL)
19 {
20 return;
21 }
22
23 while (node != NULL)
24 {
25 rbtree_update(tree, node);
26 node = node->parent;
27 }
28}
29
31{
32 assert(tree != NULL);
33 assert(compare != NULL);
34
35 tree->root = NULL;
36 tree->compare = compare;
37 tree->update = update;
38}
39
41{
42 assert(tree != NULL);
43 assert(node != NULL);
44 assert(direction == RBNODE_LEFT || direction == RBNODE_RIGHT);
45
46 rbnode_direction_t opposite = RBNODE_OPPOSITE(direction);
47
48 rbnode_t* parent = node->parent;
49 rbnode_t* newRoot = node->children[opposite];
50 assert(newRoot != NULL);
51 rbnode_t* newChild = newRoot->children[direction];
52
53 node->children[opposite] = newChild;
54 if (newChild != NULL)
55 {
56 newChild->parent = node;
57 }
58
59 newRoot->children[direction] = node;
60
61 newRoot->parent = parent;
62 node->parent = newRoot;
63 if (parent != NULL)
64 {
65 if (node == parent->children[RBNODE_RIGHT])
66 {
67 parent->children[RBNODE_RIGHT] = newRoot;
68 }
69 else
70 {
71 parent->children[RBNODE_LEFT] = newRoot;
72 }
73 }
74 else
75 {
76 tree->root = newRoot;
77 }
78
79 rbtree_update_to_root(tree, node);
80 rbtree_update_to_root(tree, newRoot);
81
82 return newRoot;
83}
84
85static void rbtree_insert_at(rbtree_t* tree, rbnode_t* parent, rbnode_t* node, rbnode_direction_t direction)
86{
87 assert(node != NULL);
88 assert(direction == RBNODE_LEFT || direction == RBNODE_RIGHT);
89
90 node->color = RBNODE_RED;
91 node->parent = parent;
92
93 if (parent == NULL)
94 {
95 tree->root = node;
96 return;
97 }
98
99 assert(parent->children[direction] == NULL);
100 parent->children[direction] = node;
101
102 rbtree_update_to_root(tree, node);
103
104 while (true)
105 {
106 if (parent->color == RBNODE_BLACK)
107 {
108 break;
109 }
110
111 rbnode_t* grandparent = parent->parent;
112 if (grandparent == NULL)
113 {
114 parent->color = RBNODE_BLACK;
115 return;
116 }
117
118 assert(grandparent->children[RBNODE_LEFT] == parent || grandparent->children[RBNODE_RIGHT] == parent);
119 rbnode_direction_t fromParent = RBNODE_FROM_PARENT(parent);
120 rbnode_t* uncle = grandparent->children[RBNODE_OPPOSITE(fromParent)];
121 if (uncle == NULL || uncle->color == RBNODE_BLACK)
122 {
123 if (node == parent->children[RBNODE_OPPOSITE(fromParent)])
124 {
125 rbtree_rotate(tree, parent, fromParent);
126 parent = grandparent->children[fromParent];
127 }
128
129 rbtree_rotate(tree, grandparent, RBNODE_OPPOSITE(fromParent));
130 parent->color = RBNODE_BLACK;
131 grandparent->color = RBNODE_RED;
132 break;
133 }
134
135 parent->color = RBNODE_BLACK;
136 uncle->color = RBNODE_BLACK;
137 grandparent->color = RBNODE_RED;
138 node = grandparent;
139
140 parent = node->parent;
141 if (parent == NULL)
142 {
143 break;
144 }
145 assert(parent->children[RBNODE_LEFT] == node || parent->children[RBNODE_RIGHT] == node);
146 }
147}
148
150{
151 assert(tree != NULL);
152 assert(node != NULL);
153 assert(node->parent == NULL);
154 assert(node->children[RBNODE_LEFT] == NULL);
155 assert(node->children[RBNODE_RIGHT] == NULL);
156
157 rbnode_t* current = tree->root;
158 rbnode_t* parent = NULL;
159
161 while (current != NULL)
162 {
163 parent = current;
164 if (tree->compare(node, current) < 0)
165 {
166 direction = RBNODE_LEFT;
167 current = current->children[RBNODE_LEFT];
168 }
169 else
170 {
171 direction = RBNODE_RIGHT;
172 current = current->children[RBNODE_RIGHT];
173 }
174 }
175
176 rbtree_insert_at(tree, parent, node, direction);
177
178 if (tree->root != NULL)
179 {
180 tree->root->color = RBNODE_BLACK;
181 }
182}
183
185{
186 if (node == NULL)
187 {
188 return NULL;
189 }
190
191 rbnode_t* current = node;
192 while (current->children[RBNODE_LEFT] != NULL)
193 {
194 current = current->children[RBNODE_LEFT];
195 }
196 return current;
197}
198
200{
201 if (node == NULL)
202 {
203 return NULL;
204 }
205
206 rbnode_t* current = node;
207 while (current->children[RBNODE_RIGHT] != NULL)
208 {
209 current = current->children[RBNODE_RIGHT];
210 }
211 return current;
212}
213
215{
216 assert(tree != NULL);
217 assert(a != NULL);
218 assert(b != NULL);
219
220 if (a == b)
221 {
222 return;
223 }
224
225 assert(a->parent == NULL || a->parent->children[RBNODE_LEFT] == a || a->parent->children[RBNODE_RIGHT] == a);
226 assert(b->parent == NULL || b->parent->children[RBNODE_LEFT] == b || b->parent->children[RBNODE_RIGHT] == b);
227
228 rbnode_color_t tempColor = a->color;
229 a->color = b->color;
230 b->color = tempColor;
231
232 if (a->parent == b)
233 {
234 rbnode_t* temp = a;
235 a = b;
236 b = temp;
237 }
238
239 if (b->parent == a)
240 {
241 rbnode_t* aParent = a->parent;
242
244
245 rbnode_t* otherChild = a->children[RBNODE_OPPOSITE(sideB)];
246 rbnode_t* bLeft = b->children[RBNODE_LEFT];
247 rbnode_t* bRight = b->children[RBNODE_RIGHT];
248
249 b->parent = aParent;
250 if (aParent != NULL)
251 {
252 if (aParent->children[RBNODE_LEFT] == a)
253 {
254 aParent->children[RBNODE_LEFT] = b;
255 }
256 else
257 {
258 aParent->children[RBNODE_RIGHT] = b;
259 }
260 }
261 else
262 {
263 tree->root = b;
264 }
265
266 b->children[sideB] = a;
267 a->parent = b;
268
269 b->children[RBNODE_OPPOSITE(sideB)] = otherChild;
270 if (otherChild != NULL)
271 {
272 otherChild->parent = b;
273 }
274
275 a->children[RBNODE_LEFT] = bLeft;
276 if (bLeft != NULL)
277 {
278 bLeft->parent = a;
279 }
280
281 a->children[RBNODE_RIGHT] = bRight;
282 if (bRight != NULL)
283 {
284 bRight->parent = a;
285 }
286 }
287 else
288 {
289 rbnode_t* aParent = a->parent;
290 rbnode_t* bParent = b->parent;
291 rbnode_t* aLeft = a->children[RBNODE_LEFT];
292 rbnode_t* aRight = a->children[RBNODE_RIGHT];
293 rbnode_t* bLeft = b->children[RBNODE_LEFT];
294 rbnode_t* bRight = b->children[RBNODE_RIGHT];
295
296 a->parent = bParent;
297 if (bParent != NULL)
298 {
299 if (bParent->children[RBNODE_LEFT] == b)
300 {
301 bParent->children[RBNODE_LEFT] = a;
302 }
303 else
304 {
305 bParent->children[RBNODE_RIGHT] = a;
306 }
307 }
308 else
309 {
310 tree->root = a;
311 }
312 a->children[RBNODE_LEFT] = bLeft;
313 if (bLeft != NULL)
314 {
315 bLeft->parent = a;
316 }
317 a->children[RBNODE_RIGHT] = bRight;
318 if (bRight != NULL)
319 {
320 bRight->parent = a;
321 }
322
323 b->parent = aParent;
324 if (aParent != NULL)
325 {
326 if (aParent->children[RBNODE_LEFT] == a)
327 {
328 aParent->children[RBNODE_LEFT] = b;
329 }
330 else
331 {
332 aParent->children[RBNODE_RIGHT] = b;
333 }
334 }
335 else
336 {
337 tree->root = b;
338 }
339 b->children[RBNODE_LEFT] = aLeft;
340 if (aLeft != NULL)
341 {
342 aLeft->parent = b;
343 }
344 b->children[RBNODE_RIGHT] = aRight;
345 if (aRight != NULL)
346 {
347 aRight->parent = b;
348 }
349 }
350
351 rbtree_update_to_root(tree, a);
352 rbtree_update_to_root(tree, b);
353}
354
355static void rbtree_remove_sanitize(rbtree_t* tree, rbnode_t* node)
356{
357 assert(node->parent == NULL ||
358 (node->parent->children[RBNODE_LEFT] != node && node->parent->children[RBNODE_RIGHT] != node));
359 assert(node->children[RBNODE_LEFT] == NULL || (node->children[RBNODE_LEFT]->parent != node));
360 assert(node->children[RBNODE_RIGHT] == NULL || (node->children[RBNODE_RIGHT]->parent != node));
361
362 rbtree_update_to_root(tree, node->parent);
363
364 node->parent = NULL;
365 node->children[RBNODE_LEFT] = NULL;
366 node->children[RBNODE_RIGHT] = NULL;
367 node->color = RBNODE_RED;
368}
369
371{
372 assert(tree != NULL);
373 assert(node != NULL);
374
375 if (node != tree->root && node->parent == NULL)
376 {
377 return;
378 }
379
380 assert(node == tree->root || node->parent->children[RBNODE_LEFT] == node ||
381 node->parent->children[RBNODE_RIGHT] == node);
382
383 if (node->children[RBNODE_LEFT] != NULL && node->children[RBNODE_RIGHT] != NULL)
384 {
385 rbnode_t* successor = rbtree_find_min(node->children[RBNODE_RIGHT]);
386 assert(successor != NULL);
387 assert(successor->children[RBNODE_LEFT] == NULL);
388 rbtree_swap(tree, node, successor);
389 rbtree_remove(tree, node);
390 return;
391 }
392
393 rbnode_t* child = node->children[RBNODE_LEFT] != NULL ? node->children[RBNODE_LEFT] : node->children[RBNODE_RIGHT];
394 assert(!(node->children[RBNODE_LEFT] != NULL && node->children[RBNODE_RIGHT] != NULL));
395
396 if (node->color == RBNODE_RED)
397 {
398 assert(child == NULL);
399
400 if (node->parent == NULL)
401 {
402 tree->root = NULL;
403 }
404 else
405 {
406 rbnode_direction_t fromParent = RBNODE_FROM_PARENT(node);
407 assert(node->parent->children[fromParent] == node);
408 node->parent->children[fromParent] = NULL;
409 }
410
411 rbtree_remove_sanitize(tree, node);
412 return;
413 }
414
415 if (child != NULL)
416 {
417 assert(child->color == RBNODE_RED);
418 assert(child->parent == node);
419
420 if (node->parent == NULL)
421 {
422 tree->root = child;
423 }
424 else
425 {
426 node->parent->children[RBNODE_FROM_PARENT(node)] = child;
427 }
428
429 child->parent = node->parent;
430 child->color = RBNODE_BLACK;
431
432 rbtree_remove_sanitize(tree, node);
433 return;
434 }
435
436 rbnode_t* parent = node->parent;
437
438 if (parent == NULL)
439 {
440 tree->root = NULL;
441 rbtree_remove_sanitize(tree, node);
442 return;
443 }
444
445 rbnode_direction_t fromParent = RBNODE_FROM_PARENT(node);
446 assert(parent->children[fromParent] == node);
447 parent->children[fromParent] = NULL;
448
449 rbtree_remove_sanitize(tree, node);
450
451 // Do this very complex fixup stuff
452 rbnode_t* curr = NULL;
453 while (true)
454 {
455 rbnode_t* sibling = parent->children[RBNODE_OPPOSITE(fromParent)];
456 assert(sibling != NULL);
457
458 if (sibling->color == RBNODE_RED)
459 {
460 assert(parent->color == RBNODE_BLACK);
461 rbtree_rotate(tree, parent, fromParent);
462 parent->color = RBNODE_RED;
463 sibling->color = RBNODE_BLACK;
464 sibling = parent->children[RBNODE_OPPOSITE(fromParent)];
465 assert(sibling != NULL);
466 assert(sibling->color == RBNODE_BLACK);
467 }
468
469 rbnode_t* distantNephew = sibling->children[RBNODE_OPPOSITE(fromParent)];
470 rbnode_t* closeNephew = sibling->children[fromParent];
471
472 if ((distantNephew == NULL || distantNephew->color == RBNODE_BLACK) &&
473 (closeNephew == NULL || closeNephew->color == RBNODE_BLACK))
474 {
475 sibling->color = RBNODE_RED;
476 curr = parent;
477 parent = curr->parent;
478
479 if (parent == NULL)
480 {
481 break;
482 }
483
484 assert(parent->children[RBNODE_LEFT] == curr || parent->children[RBNODE_RIGHT] == curr);
485
486 if (curr->color == RBNODE_RED)
487 {
488 curr->color = RBNODE_BLACK;
489 break;
490 }
491
492 fromParent = RBNODE_FROM_PARENT(curr);
493 continue;
494 }
495
496 if (distantNephew == NULL || distantNephew->color == RBNODE_BLACK)
497 {
498 assert(closeNephew != NULL);
499 assert(closeNephew->color == RBNODE_RED);
500 rbtree_rotate(tree, sibling, RBNODE_OPPOSITE(fromParent));
501 sibling->color = RBNODE_RED;
502 closeNephew->color = RBNODE_BLACK;
503
504 distantNephew = sibling; // For clarity
505 sibling = closeNephew;
506 }
507
508 assert(sibling->children[RBNODE_OPPOSITE(fromParent)] != NULL);
509 assert(sibling->children[RBNODE_OPPOSITE(fromParent)]->color == RBNODE_RED);
510 rbtree_rotate(tree, parent, fromParent);
511 sibling->color = parent->color;
512 parent->color = RBNODE_BLACK;
513 if (sibling->children[RBNODE_OPPOSITE(fromParent)] != NULL)
514 {
515 sibling->children[RBNODE_OPPOSITE(fromParent)]->color = RBNODE_BLACK;
516 }
517 break;
518 }
519
520 if (tree->root != NULL)
521 {
522 tree->root->color = RBNODE_BLACK;
523 }
524}
525
526void rbtree_fix(rbtree_t* tree, rbnode_t* node)
527{
528 assert(tree != NULL);
529 assert(node != NULL);
530
531 while (true)
532 {
533 rbnode_t* next = rbtree_next(node);
534 if (next != NULL && tree->compare(node, next) > 0)
535 {
536 rbtree_swap(tree, node, next);
537 continue;
538 }
539
540 rbnode_t* prev = rbtree_prev(node);
541 if (prev != NULL && tree->compare(node, prev) < 0)
542 {
543 rbtree_swap(tree, node, prev);
544 continue;
545 }
546
547 break;
548 }
549
550 rbtree_update_to_root(tree, node);
551}
552
553bool rbtree_is_empty(const rbtree_t* tree)
554{
555 assert(tree != NULL);
556 return tree->root == NULL;
557}
558
560{
561 if (node == NULL)
562 {
563 return NULL;
564 }
565
566 if (node->children[RBNODE_RIGHT] != NULL)
567 {
569 }
570
571 rbnode_t* parent = node->parent;
572 while (parent != NULL && node == parent->children[RBNODE_RIGHT])
573 {
574 node = parent;
575 parent = parent->parent;
576 }
577
578 return parent;
579}
580
582{
583 if (node == NULL)
584 {
585 return NULL;
586 }
587
588 if (node->children[RBNODE_LEFT] != NULL)
589 {
590 return rbtree_find_max(node->children[RBNODE_LEFT]);
591 }
592
593 rbnode_t* parent = node->parent;
594 while (parent != NULL && node == parent->children[RBNODE_LEFT])
595 {
596 node = parent;
597 parent = parent->parent;
598 }
599
600 return parent;
601}
#define assert(expression)
Definition assert.h:29
void(* rbnode_update_t)(rbnode_t *node)
Update function for Red-Black Tree nodes.
Definition rbtree.h:131
rbnode_t * rbtree_next(const rbnode_t *node)
Get the next node in the tree, in predecessor order.
Definition rbtree.c:559
#define RBNODE_OPPOSITE(direction)
Get the opposite direction (left <-> right).
Definition rbtree.h:74
int64_t(* rbnode_compare_t)(const rbnode_t *a, const rbnode_t *b)
Comparison function for Red-Black Tree nodes.
Definition rbtree.h:122
void rbtree_swap(rbtree_t *tree, rbnode_t *a, rbnode_t *b)
Swap two nodes in the Red-Black Tree.
Definition rbtree.c:214
rbnode_t * rbtree_find_min(rbnode_t *node)
Find the minimum node in a subtree.
Definition rbtree.c:184
rbnode_color_t
Red-Black Tree Node Colors.
Definition rbtree.h:50
rbnode_direction_t
Red-Black Tree Node Directions.
Definition rbtree.h:62
rbnode_t * rbtree_rotate(rbtree_t *tree, rbnode_t *node, rbnode_direction_t direction)
Rotate a node in the Red-Black Tree.
Definition rbtree.c:40
void rbtree_init(rbtree_t *tree, rbnode_compare_t compare, rbnode_update_t update)
Initialize a Red-Black Tree.
Definition rbtree.c:30
rbnode_t * rbtree_prev(const rbnode_t *node)
Get the previous node in the tree, in predecessor order.
Definition rbtree.c:581
void rbtree_remove(rbtree_t *tree, rbnode_t *node)
Remove a node from the Red-Black Tree.
Definition rbtree.c:370
void rbtree_insert(rbtree_t *tree, rbnode_t *node)
Insert a node into the Red-Black Tree.
Definition rbtree.c:149
rbnode_t * rbtree_find_max(rbnode_t *node)
Find the maximum node in a subtree.
Definition rbtree.c:199
void rbtree_fix(rbtree_t *tree, rbnode_t *node)
Move the node to its correct position in the Red-Black Tree.
Definition rbtree.c:526
#define RBNODE_FROM_PARENT(node)
Get the direction of a node from its parent.
Definition rbtree.h:82
bool rbtree_is_empty(const rbtree_t *tree)
Check if the Red-Black Tree is empty.
Definition rbtree.c:553
@ RBNODE_BLACK
Definition rbtree.h:52
@ RBNODE_RED
Definition rbtree.h:51
@ RBNODE_RIGHT
Definition rbtree.h:64
@ RBNODE_LEFT
Definition rbtree.h:63
#define NULL
Pointer error value.
Definition NULL.h:25
static atomic_long next
Definition main.c:12
static void rbtree_remove_sanitize(rbtree_t *tree, rbnode_t *node)
Definition rbtree.c:355
static void rbtree_update(rbtree_t *tree, rbnode_t *node)
Definition rbtree.c:5
static void rbtree_update_to_root(rbtree_t *tree, rbnode_t *node)
Definition rbtree.c:16
static void rbtree_insert_at(rbtree_t *tree, rbnode_t *parent, rbnode_t *node, rbnode_direction_t direction)
Definition rbtree.c:85
Red-Black Tree Node.
Definition rbtree.h:93
rbnode_t * parent
Definition rbtree.h:94
rbnode_t * children[RBNODE_AMOUNT]
Definition rbtree.h:95
rbnode_color_t color
Definition rbtree.h:96
Red-Black Tree.
Definition rbtree.h:138
rbnode_update_t update
Definition rbtree.h:141
rbnode_compare_t compare
Definition rbtree.h:140
rbnode_t * root
Definition rbtree.h:139