/src/CMake/Utilities/cmlibarchive/libarchive/archive_rb.c
Line | Count | Source |
1 | | /*- |
2 | | * Copyright (c) 2001 The NetBSD Foundation, Inc. |
3 | | * All rights reserved. |
4 | | * |
5 | | * This code is derived from software contributed to The NetBSD Foundation |
6 | | * by Matt Thomas <matt@3am-software.com>. |
7 | | * |
8 | | * Redistribution and use in source and binary forms, with or without |
9 | | * modification, are permitted provided that the following conditions |
10 | | * are met: |
11 | | * 1. Redistributions of source code must retain the above copyright |
12 | | * notice, this list of conditions and the following disclaimer. |
13 | | * 2. Redistributions in binary form must reproduce the above copyright |
14 | | * notice, this list of conditions and the following disclaimer in the |
15 | | * documentation and/or other materials provided with the distribution. |
16 | | * |
17 | | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
18 | | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
19 | | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
20 | | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
21 | | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
22 | | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
23 | | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
24 | | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
25 | | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
26 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
27 | | * POSSIBILITY OF SUCH DAMAGE. |
28 | | * |
29 | | * Based on: NetBSD: rb.c,v 1.6 2010/04/30 13:58:09 joerg Exp |
30 | | */ |
31 | | |
32 | | #include "archive_platform.h" |
33 | | |
34 | | #include <stddef.h> |
35 | | |
36 | | #include "archive_rb.h" |
37 | | |
38 | | /* Keep in sync with archive_rb.h */ |
39 | 10.3k | #define RB_DIR_LEFT 0 |
40 | 4.22k | #define RB_DIR_RIGHT 1 |
41 | 1.62k | #define RB_DIR_OTHER 1 |
42 | 3.28k | #define rb_left rb_nodes[RB_DIR_LEFT] |
43 | 4.05k | #define rb_right rb_nodes[RB_DIR_RIGHT] |
44 | | |
45 | 13.0k | #define RB_FLAG_POSITION 0x2 |
46 | 14.5k | #define RB_FLAG_RED 0x1 |
47 | 8.14k | #define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED) |
48 | | #define RB_FATHER(rb) \ |
49 | 2.39k | ((struct archive_rb_node *)((rb)->rb_info & ~RB_FLAG_MASK)) |
50 | | #define RB_SET_FATHER(rb, father) \ |
51 | 4.93k | ((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK))) |
52 | | |
53 | 20.8k | #define RB_SENTINEL_P(rb) ((rb) == NULL) |
54 | 0 | #define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left) |
55 | 0 | #define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right) |
56 | | #define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb))) |
57 | | #define RB_CHILDLESS_P(rb) \ |
58 | 0 | (RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb))) |
59 | | #define RB_TWOCHILDREN_P(rb) \ |
60 | 0 | (!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb)) |
61 | | |
62 | | #define RB_POSITION(rb) \ |
63 | 806 | (((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT) |
64 | | #define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT) |
65 | | #define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT) |
66 | 1.59k | #define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0) |
67 | 856 | #define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0) |
68 | 1.67k | #define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED)) |
69 | 2.73k | #define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED)) |
70 | | #define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED)) |
71 | 268 | #define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb)) |
72 | | #define RB_SET_POSITION(rb, position) \ |
73 | 4.13k | ((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \ |
74 | 4.13k | ((rb)->rb_info &= ~RB_FLAG_POSITION))) |
75 | | #define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK)) |
76 | | #define RB_COPY_PROPERTIES(dst, src) \ |
77 | 0 | ((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK)) |
78 | 806 | #define RB_SWAP_PROPERTIES(a, b) do { \ |
79 | 806 | uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \ |
80 | 806 | (a)->rb_info ^= xorinfo; \ |
81 | 806 | (b)->rb_info ^= xorinfo; \ |
82 | 806 | } while (/*CONSTCOND*/ 0) |
83 | | |
84 | | static void __archive_rb_tree_insert_rebalance(struct archive_rb_tree *, |
85 | | struct archive_rb_node *); |
86 | | static void __archive_rb_tree_removal_rebalance(struct archive_rb_tree *, |
87 | | struct archive_rb_node *, unsigned int); |
88 | | |
89 | 58.3k | #define RB_SENTINEL_NODE NULL |
90 | | |
91 | 3.28k | #define T 1 |
92 | 4.85k | #define F 0 |
93 | | |
94 | | void |
95 | | __archive_rb_tree_init(struct archive_rb_tree *rbt, |
96 | | const struct archive_rb_tree_ops *ops) |
97 | 58.3k | { |
98 | 58.3k | rbt->rbt_ops = ops; |
99 | 58.3k | *((struct archive_rb_node **)&rbt->rbt_root) = RB_SENTINEL_NODE; |
100 | 58.3k | } |
101 | | |
102 | | struct archive_rb_node * |
103 | | __archive_rb_tree_find_node(struct archive_rb_tree *rbt, const void *key) |
104 | 4.40k | { |
105 | 4.40k | archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key; |
106 | 4.40k | struct archive_rb_node *parent = rbt->rbt_root; |
107 | | |
108 | 5.37k | while (!RB_SENTINEL_P(parent)) { |
109 | 5.37k | const signed int diff = (*compare_key)(parent, key); |
110 | 5.37k | if (diff == 0) |
111 | 4.40k | return parent; |
112 | 972 | parent = parent->rb_nodes[diff > 0]; |
113 | 972 | } |
114 | | |
115 | 0 | return NULL; |
116 | 4.40k | } |
117 | | |
118 | | struct archive_rb_node * |
119 | | __archive_rb_tree_find_node_geq(struct archive_rb_tree *rbt, const void *key) |
120 | 0 | { |
121 | 0 | archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key; |
122 | 0 | struct archive_rb_node *parent = rbt->rbt_root; |
123 | 0 | struct archive_rb_node *last = NULL; |
124 | |
|
125 | 0 | while (!RB_SENTINEL_P(parent)) { |
126 | 0 | const signed int diff = (*compare_key)(parent, key); |
127 | 0 | if (diff == 0) |
128 | 0 | return parent; |
129 | 0 | if (diff < 0) |
130 | 0 | last = parent; |
131 | 0 | parent = parent->rb_nodes[diff > 0]; |
132 | 0 | } |
133 | | |
134 | 0 | return last; |
135 | 0 | } |
136 | | |
137 | | struct archive_rb_node * |
138 | | __archive_rb_tree_find_node_leq(struct archive_rb_tree *rbt, const void *key) |
139 | 0 | { |
140 | 0 | archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key; |
141 | 0 | struct archive_rb_node *parent = rbt->rbt_root; |
142 | 0 | struct archive_rb_node *last = NULL; |
143 | |
|
144 | 0 | while (!RB_SENTINEL_P(parent)) { |
145 | 0 | const signed int diff = (*compare_key)(parent, key); |
146 | 0 | if (diff == 0) |
147 | 0 | return parent; |
148 | 0 | if (diff > 0) |
149 | 0 | last = parent; |
150 | 0 | parent = parent->rb_nodes[diff > 0]; |
151 | 0 | } |
152 | | |
153 | 0 | return last; |
154 | 0 | } |
155 | | |
156 | | int |
157 | | __archive_rb_tree_insert_node(struct archive_rb_tree *rbt, |
158 | | struct archive_rb_node *self) |
159 | 6.44k | { |
160 | 6.44k | archive_rbto_compare_nodes_fn compare_nodes = rbt->rbt_ops->rbto_compare_nodes; |
161 | 6.44k | struct archive_rb_node *parent, *tmp; |
162 | 6.44k | unsigned int position; |
163 | 6.44k | int rebalance; |
164 | | |
165 | 6.44k | tmp = rbt->rbt_root; |
166 | | /* |
167 | | * This is a hack. Because rbt->rbt_root is just a |
168 | | * struct archive_rb_node *, just like rb_node->rb_nodes[RB_DIR_LEFT], |
169 | | * we can use this fact to avoid a lot of tests for root and know |
170 | | * that even at root, updating |
171 | | * RB_FATHER(rb_node)->rb_nodes[RB_POSITION(rb_node)] will |
172 | | * update rbt->rbt_root. |
173 | | */ |
174 | 6.44k | parent = (struct archive_rb_node *)(void *)&rbt->rbt_root; |
175 | 6.44k | position = RB_DIR_LEFT; |
176 | | |
177 | | /* |
178 | | * Find out where to place this new leaf. |
179 | | */ |
180 | 9.76k | while (!RB_SENTINEL_P(tmp)) { |
181 | 6.47k | const signed int diff = (*compare_nodes)(tmp, self); |
182 | 6.47k | if (diff == 0) { |
183 | | /* |
184 | | * Node already exists; don't insert. |
185 | | */ |
186 | 3.15k | return F; |
187 | 3.15k | } |
188 | 3.32k | parent = tmp; |
189 | 3.32k | position = (diff > 0); |
190 | 3.32k | tmp = parent->rb_nodes[position]; |
191 | 3.32k | } |
192 | | |
193 | | /* |
194 | | * Initialize the node and insert as a leaf into the tree. |
195 | | */ |
196 | 3.28k | RB_SET_FATHER(self, parent); |
197 | 3.28k | RB_SET_POSITION(self, position); |
198 | 3.28k | if (parent == (struct archive_rb_node *)(void *)&rbt->rbt_root) { |
199 | 1.69k | RB_MARK_BLACK(self); /* root is always black */ |
200 | 1.69k | rebalance = F; |
201 | 1.69k | } else { |
202 | | /* |
203 | | * All new nodes are colored red. We only need to rebalance |
204 | | * if our parent is also red. |
205 | | */ |
206 | 1.59k | RB_MARK_RED(self); |
207 | 1.59k | rebalance = RB_RED_P(parent); |
208 | 1.59k | } |
209 | 3.28k | self->rb_left = parent->rb_nodes[position]; |
210 | 3.28k | self->rb_right = parent->rb_nodes[position]; |
211 | 3.28k | parent->rb_nodes[position] = self; |
212 | | |
213 | | /* |
214 | | * Rebalance tree after insertion |
215 | | */ |
216 | 3.28k | if (rebalance) |
217 | 736 | __archive_rb_tree_insert_rebalance(rbt, self); |
218 | | |
219 | 3.28k | return T; |
220 | 6.44k | } |
221 | | |
222 | | /* |
223 | | * Swap the location and colors of 'self' and its child @ which. The child |
224 | | * can not be a sentinel node. This is our rotation function. However, |
225 | | * since it preserves coloring, it great simplifies both insertion and |
226 | | * removal since rotation almost always involves the exchanging of colors |
227 | | * as a separate step. |
228 | | */ |
229 | | /*ARGSUSED*/ |
230 | | static void |
231 | | __archive_rb_tree_reparent_nodes( |
232 | | struct archive_rb_node *old_father, const unsigned int which) |
233 | 806 | { |
234 | 806 | const unsigned int other = which ^ RB_DIR_OTHER; |
235 | 806 | struct archive_rb_node * const grandpa = RB_FATHER(old_father); |
236 | 806 | struct archive_rb_node * const old_child = old_father->rb_nodes[which]; |
237 | 806 | struct archive_rb_node * const new_father = old_child; |
238 | 806 | struct archive_rb_node * const new_child = old_father; |
239 | | |
240 | 806 | if (new_father == NULL) |
241 | 0 | return; |
242 | | /* |
243 | | * Exchange descendant linkages. |
244 | | */ |
245 | 806 | grandpa->rb_nodes[RB_POSITION(old_father)] = new_father; |
246 | 806 | new_child->rb_nodes[which] = old_child->rb_nodes[other]; |
247 | 806 | new_father->rb_nodes[other] = new_child; |
248 | | |
249 | | /* |
250 | | * Update ancestor linkages |
251 | | */ |
252 | 806 | RB_SET_FATHER(new_father, grandpa); |
253 | 806 | RB_SET_FATHER(new_child, new_father); |
254 | | |
255 | | /* |
256 | | * Exchange properties between new_father and new_child. The only |
257 | | * change is that new_child's position is now on the other side. |
258 | | */ |
259 | 806 | RB_SWAP_PROPERTIES(new_father, new_child); |
260 | 806 | RB_SET_POSITION(new_child, other); |
261 | | |
262 | | /* |
263 | | * Make sure to reparent the new child to ourself. |
264 | | */ |
265 | 806 | if (!RB_SENTINEL_P(new_child->rb_nodes[which])) { |
266 | 38 | RB_SET_FATHER(new_child->rb_nodes[which], new_child); |
267 | 38 | RB_SET_POSITION(new_child->rb_nodes[which], which); |
268 | 38 | } |
269 | | |
270 | 806 | } |
271 | | |
272 | | static void |
273 | | __archive_rb_tree_insert_rebalance(struct archive_rb_tree *rbt, |
274 | | struct archive_rb_node *self) |
275 | 736 | { |
276 | 736 | struct archive_rb_node * father = RB_FATHER(self); |
277 | 736 | struct archive_rb_node * grandpa; |
278 | 736 | struct archive_rb_node * uncle; |
279 | 736 | unsigned int which; |
280 | 736 | unsigned int other; |
281 | | |
282 | 768 | for (;;) { |
283 | | /* |
284 | | * We are red and our parent is red, therefore we must have a |
285 | | * grandfather and he must be black. |
286 | | */ |
287 | 768 | grandpa = RB_FATHER(father); |
288 | 768 | which = (father == grandpa->rb_right); |
289 | 768 | other = which ^ RB_DIR_OTHER; |
290 | 768 | uncle = grandpa->rb_nodes[other]; |
291 | | |
292 | 768 | if (RB_BLACK_P(uncle)) |
293 | 500 | break; |
294 | | |
295 | | /* |
296 | | * Case 1: our uncle is red |
297 | | * Simply invert the colors of our parent and |
298 | | * uncle and make our grandparent red. And |
299 | | * then solve the problem up at his level. |
300 | | */ |
301 | 268 | RB_MARK_BLACK(uncle); |
302 | 268 | RB_MARK_BLACK(father); |
303 | 268 | if (RB_ROOT_P(rbt, grandpa)) { |
304 | | /* |
305 | | * If our grandpa is root, don't bother |
306 | | * setting him to red, just return. |
307 | | */ |
308 | 180 | return; |
309 | 180 | } |
310 | 88 | RB_MARK_RED(grandpa); |
311 | 88 | self = grandpa; |
312 | 88 | father = RB_FATHER(self); |
313 | 88 | if (RB_BLACK_P(father)) { |
314 | | /* |
315 | | * If our great-grandpa is black, we're done. |
316 | | */ |
317 | 56 | return; |
318 | 56 | } |
319 | 88 | } |
320 | | |
321 | | /* |
322 | | * Case 2&3: our uncle is black. |
323 | | */ |
324 | 500 | if (self == father->rb_nodes[other]) { |
325 | | /* |
326 | | * Case 2: we are on the same side as our uncle |
327 | | * Swap ourselves with our parent so this case |
328 | | * becomes case 3. Basically our parent becomes our |
329 | | * child. |
330 | | */ |
331 | 306 | __archive_rb_tree_reparent_nodes(father, other); |
332 | 306 | } |
333 | | /* |
334 | | * Case 3: we are opposite a child of a black uncle. |
335 | | * Swap our parent and grandparent. Since our grandfather |
336 | | * is black, our father will become black and our new sibling |
337 | | * (former grandparent) will become red. |
338 | | */ |
339 | 500 | __archive_rb_tree_reparent_nodes(grandpa, which); |
340 | | |
341 | | /* |
342 | | * Final step: Set the root to black. |
343 | | */ |
344 | 500 | RB_MARK_BLACK(rbt->rbt_root); |
345 | 500 | } |
346 | | |
347 | | static void |
348 | | __archive_rb_tree_prune_node(struct archive_rb_tree *rbt, |
349 | | struct archive_rb_node *self, int rebalance) |
350 | 0 | { |
351 | 0 | const unsigned int which = RB_POSITION(self); |
352 | 0 | struct archive_rb_node *father = RB_FATHER(self); |
353 | | |
354 | | /* |
355 | | * Since we are childless, we know that self->rb_left is pointing |
356 | | * to the sentinel node. |
357 | | */ |
358 | 0 | father->rb_nodes[which] = self->rb_left; |
359 | | |
360 | | /* |
361 | | * Rebalance if requested. |
362 | | */ |
363 | 0 | if (rebalance) |
364 | 0 | __archive_rb_tree_removal_rebalance(rbt, father, which); |
365 | 0 | } |
366 | | |
367 | | /* |
368 | | * When deleting an interior node |
369 | | */ |
370 | | static void |
371 | | __archive_rb_tree_swap_prune_and_rebalance(struct archive_rb_tree *rbt, |
372 | | struct archive_rb_node *self, struct archive_rb_node *standin) |
373 | 0 | { |
374 | 0 | const unsigned int standin_which = RB_POSITION(standin); |
375 | 0 | unsigned int standin_other = standin_which ^ RB_DIR_OTHER; |
376 | 0 | struct archive_rb_node *standin_son; |
377 | 0 | struct archive_rb_node *standin_father = RB_FATHER(standin); |
378 | 0 | int rebalance = RB_BLACK_P(standin); |
379 | |
|
380 | 0 | if (standin_father == self) { |
381 | | /* |
382 | | * As a child of self, any children would be opposite of |
383 | | * our parent. |
384 | | */ |
385 | 0 | standin_son = standin->rb_nodes[standin_which]; |
386 | 0 | } else { |
387 | | /* |
388 | | * Since we aren't a child of self, any children would be |
389 | | * on the same side as our parent. |
390 | | */ |
391 | 0 | standin_son = standin->rb_nodes[standin_other]; |
392 | 0 | } |
393 | |
|
394 | 0 | if (RB_RED_P(standin_son)) { |
395 | | /* |
396 | | * We know we have a red child so if we flip it to black |
397 | | * we don't have to rebalance. |
398 | | */ |
399 | 0 | RB_MARK_BLACK(standin_son); |
400 | 0 | rebalance = F; |
401 | |
|
402 | 0 | if (standin_father != self) { |
403 | | /* |
404 | | * Change the son's parentage to point to his grandpa. |
405 | | */ |
406 | 0 | RB_SET_FATHER(standin_son, standin_father); |
407 | 0 | RB_SET_POSITION(standin_son, standin_which); |
408 | 0 | } |
409 | 0 | } |
410 | |
|
411 | 0 | if (standin_father == self) { |
412 | | /* |
413 | | * If we are about to delete the standin's father, then when |
414 | | * we call rebalance, we need to use ourselves as our father. |
415 | | * Otherwise remember our original father. Also, since we are |
416 | | * our standin's father we only need to reparent the standin's |
417 | | * brother. |
418 | | * |
419 | | * | R --> S | |
420 | | * | Q S --> Q T | |
421 | | * | t --> | |
422 | | * |
423 | | * Have our son/standin adopt his brother as his new son. |
424 | | */ |
425 | 0 | standin_father = standin; |
426 | 0 | } else { |
427 | | /* |
428 | | * | R --> S . | |
429 | | * | / \ | T --> / \ | / | |
430 | | * | ..... | S --> ..... | T | |
431 | | * |
432 | | * Sever standin's connection to his father. |
433 | | */ |
434 | 0 | standin_father->rb_nodes[standin_which] = standin_son; |
435 | | /* |
436 | | * Adopt the far son. |
437 | | */ |
438 | 0 | standin->rb_nodes[standin_other] = self->rb_nodes[standin_other]; |
439 | 0 | RB_SET_FATHER(standin->rb_nodes[standin_other], standin); |
440 | | /* |
441 | | * Use standin_other because we need to preserve standin_which |
442 | | * for the removal_rebalance. |
443 | | */ |
444 | 0 | standin_other = standin_which; |
445 | 0 | } |
446 | | |
447 | | /* |
448 | | * Move the only remaining son to our standin. If our standin is our |
449 | | * son, this will be the only son needed to be moved. |
450 | | */ |
451 | 0 | standin->rb_nodes[standin_other] = self->rb_nodes[standin_other]; |
452 | 0 | RB_SET_FATHER(standin->rb_nodes[standin_other], standin); |
453 | | |
454 | | /* |
455 | | * Now copy the result of self to standin and then replace |
456 | | * self with standin in the tree. |
457 | | */ |
458 | 0 | RB_COPY_PROPERTIES(standin, self); |
459 | 0 | RB_SET_FATHER(standin, RB_FATHER(self)); |
460 | 0 | RB_FATHER(standin)->rb_nodes[RB_POSITION(standin)] = standin; |
461 | |
|
462 | 0 | if (rebalance) |
463 | 0 | __archive_rb_tree_removal_rebalance(rbt, standin_father, standin_which); |
464 | 0 | } |
465 | | |
466 | | /* |
467 | | * We could do this by doing |
468 | | * __archive_rb_tree_node_swap(rbt, self, which); |
469 | | * __archive_rb_tree_prune_node(rbt, self, F); |
470 | | * |
471 | | * But it's more efficient to just evaluate and recolor the child. |
472 | | */ |
473 | | static void |
474 | | __archive_rb_tree_prune_blackred_branch( |
475 | | struct archive_rb_node *self, unsigned int which) |
476 | 0 | { |
477 | 0 | struct archive_rb_node *father = RB_FATHER(self); |
478 | 0 | struct archive_rb_node *son = self->rb_nodes[which]; |
479 | | |
480 | | /* |
481 | | * Remove ourselves from the tree and give our former child our |
482 | | * properties (position, color, root). |
483 | | */ |
484 | 0 | RB_COPY_PROPERTIES(son, self); |
485 | 0 | father->rb_nodes[RB_POSITION(son)] = son; |
486 | 0 | RB_SET_FATHER(son, father); |
487 | 0 | } |
488 | | /* |
489 | | * |
490 | | */ |
491 | | void |
492 | | __archive_rb_tree_remove_node(struct archive_rb_tree *rbt, |
493 | | struct archive_rb_node *self) |
494 | 0 | { |
495 | 0 | struct archive_rb_node *standin; |
496 | 0 | unsigned int which; |
497 | | |
498 | | /* |
499 | | * In the following diagrams, we (the node to be removed) are S. Red |
500 | | * nodes are lowercase. T could be either red or black. |
501 | | * |
502 | | * Remember the major axiom of the red-black tree: the number of |
503 | | * black nodes from the root to each leaf is constant across all |
504 | | * leaves, only the number of red nodes varies. |
505 | | * |
506 | | * Thus removing a red leaf doesn't require any other changes to a |
507 | | * red-black tree. So if we must remove a node, attempt to rearrange |
508 | | * the tree so we can remove a red node. |
509 | | * |
510 | | * The simplest case is a childless red node or a childless root node: |
511 | | * |
512 | | * | T --> T | or | R --> * | |
513 | | * | s --> * | |
514 | | */ |
515 | 0 | if (RB_CHILDLESS_P(self)) { |
516 | 0 | const int rebalance = RB_BLACK_P(self) && !RB_ROOT_P(rbt, self); |
517 | 0 | __archive_rb_tree_prune_node(rbt, self, rebalance); |
518 | 0 | return; |
519 | 0 | } |
520 | 0 | if (!RB_TWOCHILDREN_P(self)) { |
521 | | /* |
522 | | * The next simplest case is the node we are deleting is |
523 | | * black and has one red child. |
524 | | * |
525 | | * | T --> T --> T | |
526 | | * | S --> R --> R | |
527 | | * | r --> s --> * | |
528 | | */ |
529 | 0 | which = RB_LEFT_SENTINEL_P(self) ? RB_DIR_RIGHT : RB_DIR_LEFT; |
530 | 0 | __archive_rb_tree_prune_blackred_branch(self, which); |
531 | 0 | return; |
532 | 0 | } |
533 | | |
534 | | /* |
535 | | * We invert these because we prefer to remove from the inside of |
536 | | * the tree. |
537 | | */ |
538 | 0 | which = RB_POSITION(self) ^ RB_DIR_OTHER; |
539 | | |
540 | | /* |
541 | | * Let's find the node closes to us opposite of our parent |
542 | | * Now swap it with ourself, "prune" it, and rebalance, if needed. |
543 | | */ |
544 | 0 | standin = __archive_rb_tree_iterate(rbt, self, which); |
545 | 0 | __archive_rb_tree_swap_prune_and_rebalance(rbt, self, standin); |
546 | 0 | } |
547 | | |
548 | | static void |
549 | | __archive_rb_tree_removal_rebalance(struct archive_rb_tree *rbt, |
550 | | struct archive_rb_node *parent, unsigned int which) |
551 | 0 | { |
552 | |
|
553 | 0 | while (RB_BLACK_P(parent->rb_nodes[which])) { |
554 | 0 | unsigned int other = which ^ RB_DIR_OTHER; |
555 | 0 | struct archive_rb_node *brother = parent->rb_nodes[other]; |
556 | |
|
557 | 0 | if (brother == NULL) |
558 | 0 | return;/* The tree may be broken. */ |
559 | | /* |
560 | | * For cases 1, 2a, and 2b, our brother's children must |
561 | | * be black and our father must be black |
562 | | */ |
563 | 0 | if (RB_BLACK_P(parent) |
564 | 0 | && RB_BLACK_P(brother->rb_left) |
565 | 0 | && RB_BLACK_P(brother->rb_right)) { |
566 | 0 | if (RB_RED_P(brother)) { |
567 | | /* |
568 | | * Case 1: Our brother is red, swap its |
569 | | * position (and colors) with our parent. |
570 | | * This should now be case 2b (unless C or E |
571 | | * has a red child which is case 3; thus no |
572 | | * explicit branch to case 2b). |
573 | | * |
574 | | * B -> D |
575 | | * A d -> b E |
576 | | * C E -> A C |
577 | | */ |
578 | 0 | __archive_rb_tree_reparent_nodes(parent, other); |
579 | 0 | brother = parent->rb_nodes[other]; |
580 | 0 | if (brother == NULL) |
581 | 0 | return;/* The tree may be broken. */ |
582 | 0 | } else { |
583 | | /* |
584 | | * Both our parent and brother are black. |
585 | | * Change our brother to red, advance up rank |
586 | | * and go through the loop again. |
587 | | * |
588 | | * B -> *B |
589 | | * *A D -> A d |
590 | | * C E -> C E |
591 | | */ |
592 | 0 | RB_MARK_RED(brother); |
593 | 0 | if (RB_ROOT_P(rbt, parent)) |
594 | 0 | return; /* root == parent == black */ |
595 | 0 | which = RB_POSITION(parent); |
596 | 0 | parent = RB_FATHER(parent); |
597 | 0 | continue; |
598 | 0 | } |
599 | 0 | } |
600 | | /* |
601 | | * Avoid an else here so that case 2a above can hit either |
602 | | * case 2b, 3, or 4. |
603 | | */ |
604 | 0 | if (RB_RED_P(parent) |
605 | 0 | && RB_BLACK_P(brother) |
606 | 0 | && RB_BLACK_P(brother->rb_left) |
607 | 0 | && RB_BLACK_P(brother->rb_right)) { |
608 | | /* |
609 | | * We are black, our father is red, our brother and |
610 | | * both nephews are black. Simply invert/exchange the |
611 | | * colors of our father and brother (to black and red |
612 | | * respectively). |
613 | | * |
614 | | * | f --> F | |
615 | | * | * B --> * b | |
616 | | * | N N --> N N | |
617 | | */ |
618 | 0 | RB_MARK_BLACK(parent); |
619 | 0 | RB_MARK_RED(brother); |
620 | 0 | break; /* We're done! */ |
621 | 0 | } else { |
622 | | /* |
623 | | * Our brother must be black and have at least one |
624 | | * red child (it may have two). |
625 | | */ |
626 | 0 | if (RB_BLACK_P(brother->rb_nodes[other])) { |
627 | | /* |
628 | | * Case 3: our brother is black, our near |
629 | | * nephew is red, and our far nephew is black. |
630 | | * Swap our brother with our near nephew. |
631 | | * This result in a tree that matches case 4. |
632 | | * (Our father could be red or black). |
633 | | * |
634 | | * | F --> F | |
635 | | * | x B --> x B | |
636 | | * | n --> n | |
637 | | */ |
638 | 0 | __archive_rb_tree_reparent_nodes(brother, which); |
639 | 0 | brother = parent->rb_nodes[other]; |
640 | 0 | } |
641 | | /* |
642 | | * Case 4: our brother is black and our far nephew |
643 | | * is red. Swap our father and brother locations and |
644 | | * change our far nephew to black. (these can be |
645 | | * done in either order so we change the color first). |
646 | | * The result is a valid red-black tree and is a |
647 | | * terminal case. (again we don't care about the |
648 | | * father's color) |
649 | | * |
650 | | * If the father is red, we will get a red-black-black |
651 | | * tree: |
652 | | * | f -> f --> b | |
653 | | * | B -> B --> F N | |
654 | | * | n -> N --> | |
655 | | * |
656 | | * If the father is black, we will get an all black |
657 | | * tree: |
658 | | * | F -> F --> B | |
659 | | * | B -> B --> F N | |
660 | | * | n -> N --> | |
661 | | * |
662 | | * If we had two red nephews, then after the swap, |
663 | | * our former father would have a red grandson. |
664 | | */ |
665 | 0 | if (brother->rb_nodes[other] == NULL) |
666 | 0 | return;/* The tree may be broken. */ |
667 | 0 | RB_MARK_BLACK(brother->rb_nodes[other]); |
668 | 0 | __archive_rb_tree_reparent_nodes(parent, other); |
669 | 0 | break; /* We're done! */ |
670 | 0 | } |
671 | 0 | } |
672 | 0 | } |
673 | | |
674 | | struct archive_rb_node * |
675 | | __archive_rb_tree_iterate(struct archive_rb_tree *rbt, |
676 | | struct archive_rb_node *self, const unsigned int direction) |
677 | 54 | { |
678 | 54 | const unsigned int other = direction ^ RB_DIR_OTHER; |
679 | | |
680 | 54 | if (self == NULL) { |
681 | 54 | self = rbt->rbt_root; |
682 | 54 | if (RB_SENTINEL_P(self)) |
683 | 54 | return NULL; |
684 | 0 | while (!RB_SENTINEL_P(self->rb_nodes[direction])) |
685 | 0 | self = self->rb_nodes[direction]; |
686 | 0 | return self; |
687 | 54 | } |
688 | | /* |
689 | | * We can't go any further in this direction. We proceed up in the |
690 | | * opposite direction until our parent is in direction we want to go. |
691 | | */ |
692 | 0 | if (RB_SENTINEL_P(self->rb_nodes[direction])) { |
693 | 0 | while (!RB_ROOT_P(rbt, self)) { |
694 | 0 | if (other == (unsigned int)RB_POSITION(self)) |
695 | 0 | return RB_FATHER(self); |
696 | 0 | self = RB_FATHER(self); |
697 | 0 | } |
698 | 0 | return NULL; |
699 | 0 | } |
700 | | |
701 | | /* |
702 | | * Advance down one in current direction and go down as far as possible |
703 | | * in the opposite direction. |
704 | | */ |
705 | 0 | self = self->rb_nodes[direction]; |
706 | 0 | while (!RB_SENTINEL_P(self->rb_nodes[other])) |
707 | 0 | self = self->rb_nodes[other]; |
708 | 0 | return self; |
709 | 0 | } |