| File: | obj-scan-build/../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 | } |