uboot/lib/rbtree.c
<<
>>
Prefs
   1/*
   2  Red Black Trees
   3  (C) 1999  Andrea Arcangeli <andrea@suse.de>
   4  (C) 2002  David Woodhouse <dwmw2@infradead.org>
   5
   6  This program is free software; you can redistribute it and/or modify
   7  it under the terms of the GNU General Public License as published by
   8  the Free Software Foundation; either version 2 of the License, or
   9  (at your option) any later version.
  10
  11  This program is distributed in the hope that it will be useful,
  12  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14  GNU General Public License for more details.
  15
  16  You should have received a copy of the GNU General Public License
  17  along with this program; if not, write to the Free Software
  18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19
  20  linux/lib/rbtree.c
  21*/
  22
  23#include <ubi_uboot.h>
  24#include <linux/rbtree.h>
  25
  26static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
  27{
  28        struct rb_node *right = node->rb_right;
  29        struct rb_node *parent = rb_parent(node);
  30
  31        if ((node->rb_right = right->rb_left))
  32                rb_set_parent(right->rb_left, node);
  33        right->rb_left = node;
  34
  35        rb_set_parent(right, parent);
  36
  37        if (parent)
  38        {
  39                if (node == parent->rb_left)
  40                        parent->rb_left = right;
  41                else
  42                        parent->rb_right = right;
  43        }
  44        else
  45                root->rb_node = right;
  46        rb_set_parent(node, right);
  47}
  48
  49static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
  50{
  51        struct rb_node *left = node->rb_left;
  52        struct rb_node *parent = rb_parent(node);
  53
  54        if ((node->rb_left = left->rb_right))
  55                rb_set_parent(left->rb_right, node);
  56        left->rb_right = node;
  57
  58        rb_set_parent(left, parent);
  59
  60        if (parent)
  61        {
  62                if (node == parent->rb_right)
  63                        parent->rb_right = left;
  64                else
  65                        parent->rb_left = left;
  66        }
  67        else
  68                root->rb_node = left;
  69        rb_set_parent(node, left);
  70}
  71
  72void rb_insert_color(struct rb_node *node, struct rb_root *root)
  73{
  74        struct rb_node *parent, *gparent;
  75
  76        while ((parent = rb_parent(node)) && rb_is_red(parent))
  77        {
  78                gparent = rb_parent(parent);
  79
  80                if (parent == gparent->rb_left)
  81                {
  82                        {
  83                                register struct rb_node *uncle = gparent->rb_right;
  84                                if (uncle && rb_is_red(uncle))
  85                                {
  86                                        rb_set_black(uncle);
  87                                        rb_set_black(parent);
  88                                        rb_set_red(gparent);
  89                                        node = gparent;
  90                                        continue;
  91                                }
  92                        }
  93
  94                        if (parent->rb_right == node)
  95                        {
  96                                register struct rb_node *tmp;
  97                                __rb_rotate_left(parent, root);
  98                                tmp = parent;
  99                                parent = node;
 100                                node = tmp;
 101                        }
 102
 103                        rb_set_black(parent);
 104                        rb_set_red(gparent);
 105                        __rb_rotate_right(gparent, root);
 106                } else {
 107                        {
 108                                register struct rb_node *uncle = gparent->rb_left;
 109                                if (uncle && rb_is_red(uncle))
 110                                {
 111                                        rb_set_black(uncle);
 112                                        rb_set_black(parent);
 113                                        rb_set_red(gparent);
 114                                        node = gparent;
 115                                        continue;
 116                                }
 117                        }
 118
 119                        if (parent->rb_left == node)
 120                        {
 121                                register struct rb_node *tmp;
 122                                __rb_rotate_right(parent, root);
 123                                tmp = parent;
 124                                parent = node;
 125                                node = tmp;
 126                        }
 127
 128                        rb_set_black(parent);
 129                        rb_set_red(gparent);
 130                        __rb_rotate_left(gparent, root);
 131                }
 132        }
 133
 134        rb_set_black(root->rb_node);
 135}
 136
 137static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 138                             struct rb_root *root)
 139{
 140        struct rb_node *other;
 141
 142        while ((!node || rb_is_black(node)) && node != root->rb_node)
 143        {
 144                if (parent->rb_left == node)
 145                {
 146                        other = parent->rb_right;
 147                        if (rb_is_red(other))
 148                        {
 149                                rb_set_black(other);
 150                                rb_set_red(parent);
 151                                __rb_rotate_left(parent, root);
 152                                other = parent->rb_right;
 153                        }
 154                        if ((!other->rb_left || rb_is_black(other->rb_left)) &&
 155                            (!other->rb_right || rb_is_black(other->rb_right)))
 156                        {
 157                                rb_set_red(other);
 158                                node = parent;
 159                                parent = rb_parent(node);
 160                        }
 161                        else
 162                        {
 163                                if (!other->rb_right || rb_is_black(other->rb_right))
 164                                {
 165                                        struct rb_node *o_left;
 166                                        if ((o_left = other->rb_left))
 167                                                rb_set_black(o_left);
 168                                        rb_set_red(other);
 169                                        __rb_rotate_right(other, root);
 170                                        other = parent->rb_right;
 171                                }
 172                                rb_set_color(other, rb_color(parent));
 173                                rb_set_black(parent);
 174                                if (other->rb_right)
 175                                        rb_set_black(other->rb_right);
 176                                __rb_rotate_left(parent, root);
 177                                node = root->rb_node;
 178                                break;
 179                        }
 180                }
 181                else
 182                {
 183                        other = parent->rb_left;
 184                        if (rb_is_red(other))
 185                        {
 186                                rb_set_black(other);
 187                                rb_set_red(parent);
 188                                __rb_rotate_right(parent, root);
 189                                other = parent->rb_left;
 190                        }
 191                        if ((!other->rb_left || rb_is_black(other->rb_left)) &&
 192                            (!other->rb_right || rb_is_black(other->rb_right)))
 193                        {
 194                                rb_set_red(other);
 195                                node = parent;
 196                                parent = rb_parent(node);
 197                        }
 198                        else
 199                        {
 200                                if (!other->rb_left || rb_is_black(other->rb_left))
 201                                {
 202                                        register struct rb_node *o_right;
 203                                        if ((o_right = other->rb_right))
 204                                                rb_set_black(o_right);
 205                                        rb_set_red(other);
 206                                        __rb_rotate_left(other, root);
 207                                        other = parent->rb_left;
 208                                }
 209                                rb_set_color(other, rb_color(parent));
 210                                rb_set_black(parent);
 211                                if (other->rb_left)
 212                                        rb_set_black(other->rb_left);
 213                                __rb_rotate_right(parent, root);
 214                                node = root->rb_node;
 215                                break;
 216                        }
 217                }
 218        }
 219        if (node)
 220                rb_set_black(node);
 221}
 222
 223void rb_erase(struct rb_node *node, struct rb_root *root)
 224{
 225        struct rb_node *child, *parent;
 226        int color;
 227
 228        if (!node->rb_left)
 229                child = node->rb_right;
 230        else if (!node->rb_right)
 231                child = node->rb_left;
 232        else
 233        {
 234                struct rb_node *old = node, *left;
 235
 236                node = node->rb_right;
 237                while ((left = node->rb_left) != NULL)
 238                        node = left;
 239                child = node->rb_right;
 240                parent = rb_parent(node);
 241                color = rb_color(node);
 242
 243                if (child)
 244                        rb_set_parent(child, parent);
 245                if (parent == old) {
 246                        parent->rb_right = child;
 247                        parent = node;
 248                } else
 249                        parent->rb_left = child;
 250
 251                node->rb_parent_color = old->rb_parent_color;
 252                node->rb_right = old->rb_right;
 253                node->rb_left = old->rb_left;
 254
 255                if (rb_parent(old))
 256                {
 257                        if (rb_parent(old)->rb_left == old)
 258                                rb_parent(old)->rb_left = node;
 259                        else
 260                                rb_parent(old)->rb_right = node;
 261                } else
 262                        root->rb_node = node;
 263
 264                rb_set_parent(old->rb_left, node);
 265                if (old->rb_right)
 266                        rb_set_parent(old->rb_right, node);
 267                goto color;
 268        }
 269
 270        parent = rb_parent(node);
 271        color = rb_color(node);
 272
 273        if (child)
 274                rb_set_parent(child, parent);
 275        if (parent)
 276        {
 277                if (parent->rb_left == node)
 278                        parent->rb_left = child;
 279                else
 280                        parent->rb_right = child;
 281        }
 282        else
 283                root->rb_node = child;
 284
 285 color:
 286        if (color == RB_BLACK)
 287                __rb_erase_color(child, parent, root);
 288}
 289
 290/*
 291 * This function returns the first node (in sort order) of the tree.
 292 */
 293struct rb_node *rb_first(struct rb_root *root)
 294{
 295        struct rb_node  *n;
 296
 297        n = root->rb_node;
 298        if (!n)
 299                return NULL;
 300        while (n->rb_left)
 301                n = n->rb_left;
 302        return n;
 303}
 304
 305struct rb_node *rb_last(struct rb_root *root)
 306{
 307        struct rb_node  *n;
 308
 309        n = root->rb_node;
 310        if (!n)
 311                return NULL;
 312        while (n->rb_right)
 313                n = n->rb_right;
 314        return n;
 315}
 316
 317struct rb_node *rb_next(struct rb_node *node)
 318{
 319        struct rb_node *parent;
 320
 321        if (rb_parent(node) == node)
 322                return NULL;
 323
 324        /* If we have a right-hand child, go down and then left as far
 325           as we can. */
 326        if (node->rb_right) {
 327                node = node->rb_right;
 328                while (node->rb_left)
 329                        node=node->rb_left;
 330                return node;
 331        }
 332
 333        /* No right-hand children.  Everything down and left is
 334           smaller than us, so any 'next' node must be in the general
 335           direction of our parent. Go up the tree; any time the
 336           ancestor is a right-hand child of its parent, keep going
 337           up. First time it's a left-hand child of its parent, said
 338           parent is our 'next' node. */
 339        while ((parent = rb_parent(node)) && node == parent->rb_right)
 340                node = parent;
 341
 342        return parent;
 343}
 344
 345struct rb_node *rb_prev(struct rb_node *node)
 346{
 347        struct rb_node *parent;
 348
 349        if (rb_parent(node) == node)
 350                return NULL;
 351
 352        /* If we have a left-hand child, go down and then right as far
 353           as we can. */
 354        if (node->rb_left) {
 355                node = node->rb_left;
 356                while (node->rb_right)
 357                        node=node->rb_right;
 358                return node;
 359        }
 360
 361        /* No left-hand children. Go up till we find an ancestor which
 362           is a right-hand child of its parent */
 363        while ((parent = rb_parent(node)) && node == parent->rb_left)
 364                node = parent;
 365
 366        return parent;
 367}
 368
 369void rb_replace_node(struct rb_node *victim, struct rb_node *new,
 370                     struct rb_root *root)
 371{
 372        struct rb_node *parent = rb_parent(victim);
 373
 374        /* Set the surrounding nodes to point to the replacement */
 375        if (parent) {
 376                if (victim == parent->rb_left)
 377                        parent->rb_left = new;
 378                else
 379                        parent->rb_right = new;
 380        } else {
 381                root->rb_node = new;
 382        }
 383        if (victim->rb_left)
 384                rb_set_parent(victim->rb_left, new);
 385        if (victim->rb_right)
 386                rb_set_parent(victim->rb_right, new);
 387
 388        /* Copy the pointers/colour from the victim to the replacement */
 389        *new = *victim;
 390}
 391