Annotation of Gnu-Mach/kern/rbtree.c, revision 1.1.1.1

1.1       root        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)
                     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);
                     43:     assert((node == NULL) || (rbtree_parent(node) == parent));
                     44: 
                     45:     if (parent->children[RBTREE_LEFT] == node)
                     46:         return RBTREE_LEFT;
                     47: 
                     48:     assert(parent->children[RBTREE_RIGHT] == node);
                     49: 
                     50:     return RBTREE_RIGHT;
                     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_MASK;
                     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_RED;
                     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_BLACK;
                     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));
                     84:     assert(rbtree_check_alignment(parent));
                     85: 
                     86:     node->parent = (unsigned long)parent | (node->parent & RBTREE_COLOR_MASK);
                     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);
                     95:     node->parent = (node->parent & RBTREE_PARENT_MASK) | 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_RED);
                    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_BLACK);
                    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)
                    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))
                    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));
                    154:     assert(rbtree_check_alignment(node));
                    155: 
                    156:     node->parent = (unsigned long)parent | RBTREE_COLOR_RED;
                    157:     node->children[RBTREE_LEFT] = NULL;
                    158:     node->children[RBTREE_RIGHT] = NULL;
                    159: 
                    160:     if (unlikely(parent == NULL))
                    161:         tree->root = node;
                    162:     else
                    163:         parent->children[index] = node;
                    164: 
                    165:     for (;;) {
                    166:         if (parent == NULL) {
                    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);
                    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) && 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;
                    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));
                    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_LEFT] == NULL)
                    223:         child = node->children[RBTREE_RIGHT];
                    224:     else if (node->children[RBTREE_RIGHT] == NULL)
                    225:         child = node->children[RBTREE_LEFT];
                    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_RIGHT];
                    234: 
                    235:         while (successor->children[RBTREE_LEFT] != NULL)
                    236:             successor = successor->children[RBTREE_LEFT];
                    237: 
                    238:         color = rbtree_color(successor);
                    239:         child = successor->children[RBTREE_RIGHT];
                    240:         parent = rbtree_parent(node);
                    241: 
                    242:         if (unlikely(parent == NULL))
                    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_LEFT] = node->children[RBTREE_LEFT];
                    254:         rbtree_set_parent(successor->children[RBTREE_LEFT], successor);
                    255: 
                    256:         if (node == parent)
                    257:             parent = successor;
                    258:         else {
                    259:             successor->children[RBTREE_RIGHT] = node->children[RBTREE_RIGHT];
                    260:             rbtree_set_parent(successor->children[RBTREE_RIGHT], successor);
                    261:             parent->children[RBTREE_LEFT] = child;
                    262: 
                    263:             if (child != NULL)
                    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)
                    278:         rbtree_set_parent(child, parent);
                    279: 
                    280:     if (unlikely(parent == NULL))
                    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_RED)
                    291:         return;
                    292: 
                    293:     for (;;) {
                    294:         if ((child != NULL) && rbtree_is_red(child)) {
                    295:             rbtree_set_black(child);
                    296:             break;
                    297:         }
                    298: 
                    299:         if (parent == NULL)
                    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_LEFT] == NULL)
                    322:              || rbtree_is_black(brother->children[RBTREE_LEFT]))
                    323:             && ((brother->children[RBTREE_RIGHT] == NULL)
                    324:                 || rbtree_is_black(brother->children[RBTREE_RIGHT]))) {
                    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)
                    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));
                    355: }
                    356: 
                    357: struct rbtree_node * rbtree_nearest(struct rbtree_node *parent, int index,
                    358:                                     int direction)
                    359: {
                    360:     assert(rbtree_check_index(direction));
                    361: 
                    362:     if (parent == NULL)
                    363:         return NULL;
                    364: 
                    365:     assert(rbtree_check_index(index));
                    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));
                    378: 
                    379:     prev = NULL;
                    380: 
                    381:     for (cur = tree->root; cur != NULL; 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));
                    392: 
                    393:     left = direction;
                    394:     right = 1 - left;
                    395: 
                    396:     if (node == NULL)
                    397:         return NULL;
                    398: 
                    399:     if (node->children[left] != NULL) {
                    400:         node = node->children[left];
                    401: 
                    402:         while (node->children[right] != NULL)
                    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)
                    412:                 return NULL;
                    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);
                    433: 
                    434:     for (;;) {
                    435:         parent = node;
                    436:         node = node->children[RBTREE_LEFT];
                    437: 
                    438:         if (node == NULL) {
                    439:             node = parent->children[RBTREE_RIGHT];
                    440: 
                    441:             if (node == NULL)
                    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)
                    454:         return NULL;
                    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)
                    465:         return NULL;
                    466: 
                    467:     assert(node->children[RBTREE_LEFT] == NULL);
                    468:     assert(node->children[RBTREE_RIGHT] == NULL);
                    469: 
                    470:     parent = rbtree_parent(node);
                    471: 
                    472:     if (parent == NULL)
                    473:         return NULL;
                    474: 
                    475:     index = rbtree_index(node, parent);
                    476:     parent->children[index] = NULL;
                    477:     node = parent->children[RBTREE_RIGHT];
                    478: 
                    479:     if (node == NULL)
                    480:         return parent;
                    481: 
                    482:     return rbtree_find_deepest(node);
                    483: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.