Changeset c715e9b in mainline


Ignore:
Timestamp:
2006-03-25T15:51:02Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a2c4445
Parents:
4037847
Message:

Change B+-tree to:

  • store lesser keys in a key's left subtree
  • propagate the bigger of medians (if there are two medians) when splitting a node
File:
1 edited

Legend:

Unmodified
Added
Removed
  • generic/src/adt/btree.c

    r4037847 rc715e9b  
    4343 *        There is always pointer to the left-hand side subtree
    4444 *        (i.e. left sibling) in the parent node.
     45 *
     46 * Be carefull when using these trees. They need to allocate
     47 * and deallocate memory for their index nodes and as such
     48 * can sleep.
    4549 */
    4650
     
    5660static void node_initialize(btree_node_t *node);
    5761static void node_insert_key(btree_node_t *node, __native key, void *value, btree_node_t *rsubtree);
     62void node_remove_key(btree_node_t *node, __native key);
    5863static btree_node_t *node_split(btree_node_t *node, __native key, void *value, btree_node_t *rsubtree, __native *median);
    5964
     
    179184{
    180185        btree_node_t *cur, *next;
    181         void *val = NULL;
    182        
    183         /*
    184          * Iteratively descend to the leaf that can contain searched key.
     186       
     187        /*
     188         * Iteratively descend to the leaf that can contain the searched key.
    185189         */
    186190        for (cur = t->root; cur; cur = next) {
    187                 int i;
    188        
     191
    189192                /* Last iteration will set this with proper leaf node address. */
    190193                *leaf_node = cur;
    191                 for (i = 0; i < cur->keys; i++) {
    192                         if (key <= cur->key[i]) {
    193                                 val = cur->value[i];
    194                                 next = cur->subtree[i];
    195                                
    196                                 /*
    197                                  * Check if there is anywhere to descend.
    198                                  */
    199                                 if (!next) {
    200                                         /*
    201                                          * Leaf-level.
    202                                          */
    203                                         return (key == cur->key[i]) ? val : NULL;
    204                                 }
    205                                 goto descend;
     194               
     195                /*
     196                 * The key can be in the leftmost subtree.
     197                 * Test it separately.
     198                 */
     199                if (key < cur->key[0]) {
     200                        next = cur->subtree[0];
     201                        continue;
     202                } else {
     203                        void *val;
     204                        int i;
     205               
     206                        /*
     207                         * Now if the key is smaller than cur->key[i]
     208                         * it can only mean that the value is in cur->subtree[i]
     209                         * or it is not in the tree at all.
     210                         */
     211                        for (i = 1; i < cur->keys; i++) {
     212                                if (key < cur->key[i]) {
     213                                        next = cur->subtree[i];
     214                                        val = cur->value[i - 1];
     215
     216                                        if (LEAF_NODE(cur))
     217                                                return key == cur->key[i - 1] ? val : NULL;
     218
     219                                        goto descend;
     220                                }
    206221                        }
    207                 }
    208                 next = cur->subtree[i];
    209         descend:
    210                 ;
    211         }
    212 
    213         /*
    214          * The key was not found in the *leaf_node and is greater than any of its keys.
     222                       
     223                        /*
     224                         * Last possibility is that the key is in the rightmost subtree.
     225                         */
     226                        next = cur->subtree[i];
     227                        val = cur->value[i - 1];
     228                        if (LEAF_NODE(cur))
     229                                return key == cur->key[i - 1] ? val : NULL;
     230                }
     231                descend:
     232                        ;
     233        }
     234
     235        /*
     236         * The key was not found in the *leaf_node and is smaller than any of its keys.
    215237         */
    216238        return NULL;
     
    273295}
    274296
    275 /** Insert key-value-left-subtree triplet into B-tree non-full node.
     297/** Insert key-value-right-subtree triplet into B-tree non-full node.
    276298 *
    277299 * It is actually possible to have more keys than BTREE_MAX_KEYS.
     
    308330}
    309331
    310 /** Split full B-tree node and insert new key-value-left-subtree triplet.
     332/** Split full B-tree node and insert new key-value-right-subtree triplet.
    311333 *
    312334 * This function will split a node and return pointer to a newly created
    313  * node containing keys greater than the lesser of medians (or median)
    314  * of the old keys and the newly added key. It will also write the
    315  * median key to a memory address supplied by the caller.
    316  *
    317  * If the node being split is an index node, the median will be
    318  * removed from the original node. If the node is a leaf node,
    319  * the median will be preserved.
     335 * node containing keys greater than or equal to the greater of medians
     336 * (or median) of the old keys and the newly added key. It will also write
     337 * the median key to a memory address supplied by the caller.
     338 *
     339 * If the node being split is an index node, the median will not be
     340 * included in the new node. If the node is a leaf node,
     341 * the median will be copied there.
    320342 *
    321343 * @param node B-tree node wich is going to be split.
     
    343365         * Compute median of keys.
    344366         */
    345         *median = MEDIAN_LOW(node);
    346                
     367        *median = MEDIAN_HIGH(node);
     368               
     369        /*
     370         * Allocate and initialize new right sibling.
     371         */
    347372        rnode = (btree_node_t *) malloc(sizeof(btree_node_t), 0);
    348373        node_initialize(rnode);
     
    352377        /*
    353378         * Copy big keys, values and subtree pointers to the new right sibling.
    354          */
    355         for (i = MEDIAN_LOW_INDEX(node) + 1, j = 0; i < node->keys; i++, j++) {
     379         * If this is an index node, do not copy the median.
     380         */
     381        i = (int) INDEX_NODE(node);
     382        for (i += MEDIAN_HIGH_INDEX(node), j = 0; i < node->keys; i++, j++) {
    356383                rnode->key[j] = node->key[i];
    357384                rnode->value[j] = node->value[i];
     
    368395        if (rnode->subtree[j])
    369396                rnode->subtree[j]->parent = rnode;
    370         rnode->keys = j;
    371        
    372         /*
    373          * Shrink the old node.
    374          * If this is an index node, remove the median.
    375          */
    376         node->keys = MEDIAN_LOW_INDEX(node) + 1;
    377         if (INDEX_NODE(node))
    378                 node->keys--;
     397
     398        rnode->keys = j;        /* Set number of keys of the new node. */
     399        node->keys /= 2;        /* Shrink the old node. */
    379400               
    380401        return rnode;
     402}
     403
     404/** Remove key from B-tree node.
     405 *
     406 * @param node B-tree node.
     407 * @param key Key to be removed.
     408 */
     409void node_remove_key(btree_node_t *node, __native key)
     410{
    381411}
    382412
Note: See TracChangeset for help on using the changeset viewer.