File: | obj/../kern/rbtree.c |
Location: | line 200, column 13 |
Description: | Value stored to 'node' is never read |
1 | /* |
2 | * Copyright (c) 2010, 2012 Richard Braun. |
3 | * All rights reserved. |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
8 | * 1. Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. |
10 | * 2. Redistributions in binary form must reproduce the above copyright |
11 | * notice, this list of conditions and the following disclaimer in the |
12 | * documentation and/or other materials provided with the distribution. |
13 | * |
14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
17 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include <kern/assert.h> |
27 | #include <kern/rbtree.h> |
28 | #include <kern/rbtree_i.h> |
29 | #include <sys/types.h> |
30 | |
31 | #define unlikely(expr)__builtin_expect(!!(expr), 0) __builtin_expect(!!(expr), 0) |
32 | |
33 | /* |
34 | * Return the index of a node in the children array of its parent. |
35 | * |
36 | * The parent parameter must not be null, and must be the parent of the |
37 | * given node. |
38 | */ |
39 | static inline int rbtree_index(const struct rbtree_node *node, |
40 | const struct rbtree_node *parent) |
41 | { |
42 | assert(parent != NULL)({ if (!(parent != ((void *) 0))) Assert("parent != NULL", "../kern/rbtree.c" , 42); }); |
43 | assert((node == NULL) || (rbtree_parent(node) == parent))({ if (!((node == ((void *) 0)) || (rbtree_parent(node) == parent ))) Assert("(node == NULL) || (rbtree_parent(node) == parent)" , "../kern/rbtree.c", 43); }); |
44 | |
45 | if (parent->children[RBTREE_LEFT0] == node) |
46 | return RBTREE_LEFT0; |
47 | |
48 | assert(parent->children[RBTREE_RIGHT] == node)({ if (!(parent->children[1] == node)) Assert("parent->children[RBTREE_RIGHT] == node" , "../kern/rbtree.c", 48); }); |
49 | |
50 | return RBTREE_RIGHT1; |
51 | } |
52 | |
53 | /* |
54 | * Return the color of a node. |
55 | */ |
56 | static inline int rbtree_color(const struct rbtree_node *node) |
57 | { |
58 | return node->parent & RBTREE_COLOR_MASK0x1UL; |
59 | } |
60 | |
61 | /* |
62 | * Return true if the node is red. |
63 | */ |
64 | static inline int rbtree_is_red(const struct rbtree_node *node) |
65 | { |
66 | return rbtree_color(node) == RBTREE_COLOR_RED0; |
67 | } |
68 | |
69 | /* |
70 | * Return true if the node is black. |
71 | */ |
72 | static inline int rbtree_is_black(const struct rbtree_node *node) |
73 | { |
74 | return rbtree_color(node) == RBTREE_COLOR_BLACK1; |
75 | } |
76 | |
77 | /* |
78 | * Set the parent of a node, retaining its current color. |
79 | */ |
80 | static inline void rbtree_set_parent(struct rbtree_node *node, |
81 | struct rbtree_node *parent) |
82 | { |
83 | assert(rbtree_check_alignment(node))({ if (!(rbtree_check_alignment(node))) Assert("rbtree_check_alignment(node)" , "../kern/rbtree.c", 83); }); |
84 | assert(rbtree_check_alignment(parent))({ if (!(rbtree_check_alignment(parent))) Assert("rbtree_check_alignment(parent)" , "../kern/rbtree.c", 84); }); |
85 | |
86 | node->parent = (unsigned long)parent | (node->parent & RBTREE_COLOR_MASK0x1UL); |
87 | } |
88 | |
89 | /* |
90 | * Set the color of a node, retaining its current parent. |
91 | */ |
92 | static inline void rbtree_set_color(struct rbtree_node *node, int color) |
93 | { |
94 | assert((color & ~RBTREE_COLOR_MASK) == 0)({ if (!((color & ~0x1UL) == 0)) Assert("(color & ~RBTREE_COLOR_MASK) == 0" , "../kern/rbtree.c", 94); }); |
95 | node->parent = (node->parent & RBTREE_PARENT_MASK(~0x3UL)) | color; |
96 | } |
97 | |
98 | /* |
99 | * Set the color of a node to red, retaining its current parent. |
100 | */ |
101 | static inline void rbtree_set_red(struct rbtree_node *node) |
102 | { |
103 | rbtree_set_color(node, RBTREE_COLOR_RED0); |
104 | } |
105 | |
106 | /* |
107 | * Set the color of a node to black, retaining its current parent. |
108 | */ |
109 | static inline void rbtree_set_black(struct rbtree_node *node) |
110 | { |
111 | rbtree_set_color(node, RBTREE_COLOR_BLACK1); |
112 | } |
113 | |
114 | /* |
115 | * Perform a tree rotation, rooted at the given node. |
116 | * |
117 | * The direction parameter defines the rotation direction and is either |
118 | * RBTREE_LEFT or RBTREE_RIGHT. |
119 | */ |
120 | static void rbtree_rotate(struct rbtree *tree, struct rbtree_node *node, |
121 | int direction) |
122 | { |
123 | struct rbtree_node *parent, *rnode; |
124 | int left, right; |
125 | |
126 | left = direction; |
127 | right = 1 - left; |
128 | parent = rbtree_parent(node); |
129 | rnode = node->children[right]; |
130 | |
131 | node->children[right] = rnode->children[left]; |
132 | |
133 | if (rnode->children[left] != NULL((void *) 0)) |
134 | rbtree_set_parent(rnode->children[left], node); |
135 | |
136 | rnode->children[left] = node; |
137 | rbtree_set_parent(rnode, parent); |
138 | |
139 | if (unlikely(parent == NULL)__builtin_expect(!!(parent == ((void *) 0)), 0)) |
140 | tree->root = rnode; |
141 | else |
142 | parent->children[rbtree_index(node, parent)] = rnode; |
143 | |
144 | rbtree_set_parent(node, rnode); |
145 | } |
146 | |
147 | void rbtree_insert_rebalance(struct rbtree *tree, struct rbtree_node *parent, |
148 | int index, struct rbtree_node *node) |
149 | { |
150 | struct rbtree_node *grand_parent, *uncle, *tmp; |
151 | int left, right; |
152 | |
153 | assert(rbtree_check_alignment(parent))({ if (!(rbtree_check_alignment(parent))) Assert("rbtree_check_alignment(parent)" , "../kern/rbtree.c", 153); }); |
154 | assert(rbtree_check_alignment(node))({ if (!(rbtree_check_alignment(node))) Assert("rbtree_check_alignment(node)" , "../kern/rbtree.c", 154); }); |
155 | |
156 | node->parent = (unsigned long)parent | RBTREE_COLOR_RED0; |
157 | node->children[RBTREE_LEFT0] = NULL((void *) 0); |
158 | node->children[RBTREE_RIGHT1] = NULL((void *) 0); |
159 | |
160 | if (unlikely(parent == NULL)__builtin_expect(!!(parent == ((void *) 0)), 0)) |
161 | tree->root = node; |
162 | else |
163 | parent->children[index] = node; |
164 | |
165 | for (;;) { |
166 | if (parent == NULL((void *) 0)) { |
167 | rbtree_set_black(node); |
168 | break; |
169 | } |
170 | |
171 | if (rbtree_is_black(parent)) |
172 | break; |
173 | |
174 | grand_parent = rbtree_parent(parent); |
175 | assert(grand_parent != NULL)({ if (!(grand_parent != ((void *) 0))) Assert("grand_parent != NULL" , "../kern/rbtree.c", 175); }); |
176 | |
177 | left = rbtree_index(parent, grand_parent); |
178 | right = 1 - left; |
179 | |
180 | uncle = grand_parent->children[right]; |
181 | |
182 | /* |
183 | * Uncle is red. Flip colors and repeat at grand parent. |
184 | */ |
185 | if ((uncle != NULL((void *) 0)) && rbtree_is_red(uncle)) { |
186 | rbtree_set_black(uncle); |
187 | rbtree_set_black(parent); |
188 | rbtree_set_red(grand_parent); |
189 | node = grand_parent; |
190 | parent = rbtree_parent(node); |
191 | continue; |
192 | } |
193 | |
194 | /* |
195 | * Node is the right child of its parent. Rotate left at parent. |
196 | */ |
197 | if (parent->children[right] == node) { |
198 | rbtree_rotate(tree, parent, left); |
199 | tmp = node; |
200 | node = parent; |
Value stored to 'node' is never read | |
201 | parent = tmp; |
202 | } |
203 | |
204 | /* |
205 | * Node is the left child of its parent. Handle colors, rotate right |
206 | * at grand parent, and leave. |
207 | */ |
208 | rbtree_set_black(parent); |
209 | rbtree_set_red(grand_parent); |
210 | rbtree_rotate(tree, grand_parent, right); |
211 | break; |
212 | } |
213 | |
214 | assert(rbtree_is_black(tree->root))({ if (!(rbtree_is_black(tree->root))) Assert("rbtree_is_black(tree->root)" , "../kern/rbtree.c", 214); }); |
215 | } |
216 | |
217 | void rbtree_remove(struct rbtree *tree, struct rbtree_node *node) |
218 | { |
219 | struct rbtree_node *child, *parent, *brother; |
220 | int color, left, right; |
221 | |
222 | if (node->children[RBTREE_LEFT0] == NULL((void *) 0)) |
223 | child = node->children[RBTREE_RIGHT1]; |
224 | else if (node->children[RBTREE_RIGHT1] == NULL((void *) 0)) |
225 | child = node->children[RBTREE_LEFT0]; |
226 | else { |
227 | struct rbtree_node *successor; |
228 | |
229 | /* |
230 | * Two-children case: replace the node with its successor. |
231 | */ |
232 | |
233 | successor = node->children[RBTREE_RIGHT1]; |
234 | |
235 | while (successor->children[RBTREE_LEFT0] != NULL((void *) 0)) |
236 | successor = successor->children[RBTREE_LEFT0]; |
237 | |
238 | color = rbtree_color(successor); |
239 | child = successor->children[RBTREE_RIGHT1]; |
240 | parent = rbtree_parent(node); |
241 | |
242 | if (unlikely(parent == NULL)__builtin_expect(!!(parent == ((void *) 0)), 0)) |
243 | tree->root = successor; |
244 | else |
245 | parent->children[rbtree_index(node, parent)] = successor; |
246 | |
247 | parent = rbtree_parent(successor); |
248 | |
249 | /* |
250 | * Set parent directly to keep the original color. |
251 | */ |
252 | successor->parent = node->parent; |
253 | successor->children[RBTREE_LEFT0] = node->children[RBTREE_LEFT0]; |
254 | rbtree_set_parent(successor->children[RBTREE_LEFT0], successor); |
255 | |
256 | if (node == parent) |
257 | parent = successor; |
258 | else { |
259 | successor->children[RBTREE_RIGHT1] = node->children[RBTREE_RIGHT1]; |
260 | rbtree_set_parent(successor->children[RBTREE_RIGHT1], successor); |
261 | parent->children[RBTREE_LEFT0] = child; |
262 | |
263 | if (child != NULL((void *) 0)) |
264 | rbtree_set_parent(child, parent); |
265 | } |
266 | |
267 | goto update_color; |
268 | } |
269 | |
270 | /* |
271 | * Node has at most one child. |
272 | */ |
273 | |
274 | color = rbtree_color(node); |
275 | parent = rbtree_parent(node); |
276 | |
277 | if (child != NULL((void *) 0)) |
278 | rbtree_set_parent(child, parent); |
279 | |
280 | if (unlikely(parent == NULL)__builtin_expect(!!(parent == ((void *) 0)), 0)) |
281 | tree->root = child; |
282 | else |
283 | parent->children[rbtree_index(node, parent)] = child; |
284 | |
285 | /* |
286 | * The node has been removed, update the colors. The child pointer can |
287 | * be null, in which case it is considered a black leaf. |
288 | */ |
289 | update_color: |
290 | if (color == RBTREE_COLOR_RED0) |
291 | return; |
292 | |
293 | for (;;) { |
294 | if ((child != NULL((void *) 0)) && rbtree_is_red(child)) { |
295 | rbtree_set_black(child); |
296 | break; |
297 | } |
298 | |
299 | if (parent == NULL((void *) 0)) |
300 | break; |
301 | |
302 | left = rbtree_index(child, parent); |
303 | right = 1 - left; |
304 | |
305 | brother = parent->children[right]; |
306 | |
307 | /* |
308 | * Brother is red. Recolor and rotate left at parent so that brother |
309 | * becomes black. |
310 | */ |
311 | if (rbtree_is_red(brother)) { |
312 | rbtree_set_black(brother); |
313 | rbtree_set_red(parent); |
314 | rbtree_rotate(tree, parent, left); |
315 | brother = parent->children[right]; |
316 | } |
317 | |
318 | /* |
319 | * Brother has no red child. Recolor and repeat at parent. |
320 | */ |
321 | if (((brother->children[RBTREE_LEFT0] == NULL((void *) 0)) |
322 | || rbtree_is_black(brother->children[RBTREE_LEFT0])) |
323 | && ((brother->children[RBTREE_RIGHT1] == NULL((void *) 0)) |
324 | || rbtree_is_black(brother->children[RBTREE_RIGHT1]))) { |
325 | rbtree_set_red(brother); |
326 | child = parent; |
327 | parent = rbtree_parent(child); |
328 | continue; |
329 | } |
330 | |
331 | /* |
332 | * Brother's right child is black. Recolor and rotate right at brother. |
333 | */ |
334 | if ((brother->children[right] == NULL((void *) 0)) |
335 | || rbtree_is_black(brother->children[right])) { |
336 | rbtree_set_black(brother->children[left]); |
337 | rbtree_set_red(brother); |
338 | rbtree_rotate(tree, brother, right); |
339 | brother = parent->children[right]; |
340 | } |
341 | |
342 | /* |
343 | * Brother's left child is black. Exchange parent and brother colors |
344 | * (we already know brother is black), set brother's right child black, |
345 | * rotate left at parent and leave. |
346 | */ |
347 | rbtree_set_color(brother, rbtree_color(parent)); |
348 | rbtree_set_black(parent); |
349 | rbtree_set_black(brother->children[right]); |
350 | rbtree_rotate(tree, parent, left); |
351 | break; |
352 | } |
353 | |
354 | assert((tree->root == NULL) || rbtree_is_black(tree->root))({ if (!((tree->root == ((void *) 0)) || rbtree_is_black(tree ->root))) Assert("(tree->root == NULL) || rbtree_is_black(tree->root)" , "../kern/rbtree.c", 354); }); |
355 | } |
356 | |
357 | struct rbtree_node * rbtree_nearest(struct rbtree_node *parent, int index, |
358 | int direction) |
359 | { |
360 | assert(rbtree_check_index(direction))({ if (!(rbtree_check_index(direction))) Assert("rbtree_check_index(direction)" , "../kern/rbtree.c", 360); }); |
361 | |
362 | if (parent == NULL((void *) 0)) |
363 | return NULL((void *) 0); |
364 | |
365 | assert(rbtree_check_index(index))({ if (!(rbtree_check_index(index))) Assert("rbtree_check_index(index)" , "../kern/rbtree.c", 365); }); |
366 | |
367 | if (index != direction) |
368 | return parent; |
369 | |
370 | return rbtree_walk(parent, direction); |
371 | } |
372 | |
373 | struct rbtree_node * rbtree_firstlast(const struct rbtree *tree, int direction) |
374 | { |
375 | struct rbtree_node *prev, *cur; |
376 | |
377 | assert(rbtree_check_index(direction))({ if (!(rbtree_check_index(direction))) Assert("rbtree_check_index(direction)" , "../kern/rbtree.c", 377); }); |
378 | |
379 | prev = NULL((void *) 0); |
380 | |
381 | for (cur = tree->root; cur != NULL((void *) 0); cur = cur->children[direction]) |
382 | prev = cur; |
383 | |
384 | return prev; |
385 | } |
386 | |
387 | struct rbtree_node * rbtree_walk(struct rbtree_node *node, int direction) |
388 | { |
389 | int left, right; |
390 | |
391 | assert(rbtree_check_index(direction))({ if (!(rbtree_check_index(direction))) Assert("rbtree_check_index(direction)" , "../kern/rbtree.c", 391); }); |
392 | |
393 | left = direction; |
394 | right = 1 - left; |
395 | |
396 | if (node == NULL((void *) 0)) |
397 | return NULL((void *) 0); |
398 | |
399 | if (node->children[left] != NULL((void *) 0)) { |
400 | node = node->children[left]; |
401 | |
402 | while (node->children[right] != NULL((void *) 0)) |
403 | node = node->children[right]; |
404 | } else { |
405 | struct rbtree_node *parent; |
406 | int index; |
407 | |
408 | for (;;) { |
409 | parent = rbtree_parent(node); |
410 | |
411 | if (parent == NULL((void *) 0)) |
412 | return NULL((void *) 0); |
413 | |
414 | index = rbtree_index(node, parent); |
415 | node = parent; |
416 | |
417 | if (index == right) |
418 | break; |
419 | } |
420 | } |
421 | |
422 | return node; |
423 | } |
424 | |
425 | /* |
426 | * Return the left-most deepest child node of the given node. |
427 | */ |
428 | static struct rbtree_node * rbtree_find_deepest(struct rbtree_node *node) |
429 | { |
430 | struct rbtree_node *parent; |
431 | |
432 | assert(node != NULL)({ if (!(node != ((void *) 0))) Assert("node != NULL", "../kern/rbtree.c" , 432); }); |
433 | |
434 | for (;;) { |
435 | parent = node; |
436 | node = node->children[RBTREE_LEFT0]; |
437 | |
438 | if (node == NULL((void *) 0)) { |
439 | node = parent->children[RBTREE_RIGHT1]; |
440 | |
441 | if (node == NULL((void *) 0)) |
442 | return parent; |
443 | } |
444 | } |
445 | } |
446 | |
447 | struct rbtree_node * rbtree_postwalk_deepest(const struct rbtree *tree) |
448 | { |
449 | struct rbtree_node *node; |
450 | |
451 | node = tree->root; |
452 | |
453 | if (node == NULL((void *) 0)) |
454 | return NULL((void *) 0); |
455 | |
456 | return rbtree_find_deepest(node); |
457 | } |
458 | |
459 | struct rbtree_node * rbtree_postwalk_unlink(struct rbtree_node *node) |
460 | { |
461 | struct rbtree_node *parent; |
462 | int index; |
463 | |
464 | if (node == NULL((void *) 0)) |
465 | return NULL((void *) 0); |
466 | |
467 | assert(node->children[RBTREE_LEFT] == NULL)({ if (!(node->children[0] == ((void *) 0))) Assert("node->children[RBTREE_LEFT] == NULL" , "../kern/rbtree.c", 467); }); |
468 | assert(node->children[RBTREE_RIGHT] == NULL)({ if (!(node->children[1] == ((void *) 0))) Assert("node->children[RBTREE_RIGHT] == NULL" , "../kern/rbtree.c", 468); }); |
469 | |
470 | parent = rbtree_parent(node); |
471 | |
472 | if (parent == NULL((void *) 0)) |
473 | return NULL((void *) 0); |
474 | |
475 | index = rbtree_index(node, parent); |
476 | parent->children[index] = NULL((void *) 0); |
477 | node = parent->children[RBTREE_RIGHT1]; |
478 | |
479 | if (node == NULL((void *) 0)) |
480 | return parent; |
481 | |
482 | return rbtree_find_deepest(node); |
483 | } |