Changes in kernel/generic/src/adt/btree.c [1b20da0:a35b458] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/adt/btree.c
r1b20da0 ra35b458 83 83 { 84 84 unsigned int i; 85 85 86 86 node->keys = 0; 87 87 88 88 /* Clean also space for the extra key. */ 89 89 for (i = 0; i < BTREE_MAX_KEYS + 1; i++) { … … 92 92 node->subtree[i] = NULL; 93 93 } 94 94 95 95 node->subtree[i] = NULL; 96 96 node->parent = NULL; 97 97 98 98 link_initialize(&node->leaf_link); 99 99 link_initialize(&node->bfs_link); … … 122 122 { 123 123 size_t i; 124 124 125 125 if (root->keys) { 126 126 for (i = 0; i < root->keys + 1; i++) { … … 129 129 } 130 130 } 131 131 132 132 slab_free(btree_node_cache, root); 133 133 } … … 156 156 { 157 157 size_t i; 158 158 159 159 for (i = 0; i < node->keys; i++) { 160 160 if (key < node->key[i]) { 161 161 size_t j; 162 162 163 163 for (j = node->keys; j > i; j--) { 164 164 node->key[j] = node->key[j - 1]; … … 166 166 node->subtree[j + 1] = node->subtree[j]; 167 167 } 168 168 169 169 break; 170 170 } 171 171 } 172 172 173 173 node->key[i] = key; 174 174 node->value[i] = value; … … 191 191 { 192 192 size_t i; 193 193 194 194 for (i = 0; i < node->keys + 1; i++) { 195 195 if (subtree == node->subtree[i]) 196 196 return i - (int) (right != false); 197 197 } 198 198 199 199 panic("Node %p does not contain subtree %p.", node, subtree); 200 200 } … … 215 215 size_t i; 216 216 size_t j; 217 217 218 218 for (i = 0; i < node->keys; i++) { 219 219 if (key == node->key[i]) { … … 223 223 node->subtree[j - 1] = node->subtree[j]; 224 224 } 225 225 226 226 node->subtree[j - 1] = node->subtree[j]; 227 227 node->keys--; 228 228 229 229 return; 230 230 } 231 231 } 232 232 233 233 panic("Node %p does not contain key %" PRIu64 ".", node, key); 234 234 } … … 248 248 { 249 249 size_t i, j; 250 250 251 251 for (i = 0; i < node->keys; i++) { 252 252 if (key == node->key[i]) { … … 256 256 node->subtree[j] = node->subtree[j + 1]; 257 257 } 258 258 259 259 node->keys--; 260 260 return; 261 261 } 262 262 } 263 263 264 264 panic("Node %p does not contain key %" PRIu64 ".", node, key); 265 265 } … … 280 280 { 281 281 size_t i; 282 282 283 283 for (i = 0; i < node->keys; i++) { 284 284 if (key < node->key[i]) { 285 285 size_t j; 286 286 287 287 for (j = node->keys; j > i; j--) { 288 288 node->key[j] = node->key[j - 1]; … … 290 290 node->subtree[j + 1] = node->subtree[j]; 291 291 } 292 292 293 293 node->subtree[j + 1] = node->subtree[j]; 294 294 break; 295 295 } 296 296 } 297 297 298 298 node->key[i] = key; 299 299 node->value[i] = value; 300 300 node->subtree[i] = lsubtree; 301 301 302 302 node->keys++; 303 303 } … … 320 320 { 321 321 btree_key_t key = lnode->key[lnode->keys - 1]; 322 322 323 323 if (LEAF_NODE(lnode)) { 324 324 void *value = lnode->value[lnode->keys - 1]; 325 325 326 326 node_remove_key_and_rsubtree(lnode, key); 327 327 node_insert_key_and_lsubtree(rnode, key, value, NULL); … … 329 329 } else { 330 330 btree_node_t *rsubtree = lnode->subtree[lnode->keys]; 331 331 332 332 node_remove_key_and_rsubtree(lnode, key); 333 333 node_insert_key_and_lsubtree(rnode, lnode->parent->key[idx], NULL, rsubtree); 334 334 lnode->parent->key[idx] = key; 335 335 336 336 /* Fix parent link of the reconnected right subtree. */ 337 337 rsubtree->parent = rnode; … … 356 356 { 357 357 btree_key_t key = rnode->key[0]; 358 358 359 359 if (LEAF_NODE(rnode)) { 360 360 void *value = rnode->value[0]; 361 361 362 362 node_remove_key_and_lsubtree(rnode, key); 363 363 node_insert_key_and_rsubtree(lnode, key, value, NULL); … … 365 365 } else { 366 366 btree_node_t *lsubtree = rnode->subtree[0]; 367 367 368 368 node_remove_key_and_lsubtree(rnode, key); 369 369 node_insert_key_and_rsubtree(lnode, rnode->parent->key[idx], NULL, lsubtree); 370 370 rnode->parent->key[idx] = key; 371 371 372 372 /* Fix parent link of the reconnected left subtree. */ 373 373 lsubtree->parent = lnode; … … 395 395 size_t idx; 396 396 btree_node_t *lnode; 397 397 398 398 /* 399 399 * If this is root node, the rotation can not be done. … … 401 401 if (ROOT_NODE(node)) 402 402 return false; 403 403 404 404 idx = find_key_by_subtree(node->parent, node, true); 405 405 if ((int) idx == -1) { … … 410 410 return false; 411 411 } 412 412 413 413 lnode = node->parent->subtree[idx]; 414 414 if (lnode->keys < BTREE_MAX_KEYS) { … … 420 420 return true; 421 421 } 422 422 423 423 return false; 424 424 } … … 444 444 size_t idx; 445 445 btree_node_t *rnode; 446 446 447 447 /* 448 448 * If this is root node, the rotation can not be done. … … 450 450 if (ROOT_NODE(node)) 451 451 return false; 452 452 453 453 idx = find_key_by_subtree(node->parent, node, false); 454 454 if (idx == node->parent->keys) { … … 459 459 return false; 460 460 } 461 461 462 462 rnode = node->parent->subtree[idx + 1]; 463 463 if (rnode->keys < BTREE_MAX_KEYS) { … … 469 469 return true; 470 470 } 471 471 472 472 return false; 473 473 } … … 499 499 size_t i; 500 500 size_t j; 501 501 502 502 assert(median); 503 503 assert(node->keys == BTREE_MAX_KEYS); 504 504 505 505 /* 506 506 * Use the extra space to store the extra node. 507 507 */ 508 508 node_insert_key_and_rsubtree(node, key, value, rsubtree); 509 509 510 510 /* 511 511 * Compute median of keys. 512 512 */ 513 513 *median = MEDIAN_HIGH(node); 514 514 515 515 /* 516 516 * Allocate and initialize new right sibling. … … 520 520 rnode->parent = node->parent; 521 521 rnode->depth = node->depth; 522 522 523 523 /* 524 524 * Copy big keys, values and subtree pointers to the new right sibling. … … 530 530 rnode->value[j] = node->value[i]; 531 531 rnode->subtree[j] = node->subtree[i]; 532 532 533 533 /* 534 534 * Fix parent links in subtrees. … … 537 537 rnode->subtree[j]->parent = rnode; 538 538 } 539 539 540 540 rnode->subtree[j] = node->subtree[i]; 541 541 if (rnode->subtree[j]) 542 542 rnode->subtree[j]->parent = rnode; 543 543 544 544 rnode->keys = j; /* Set number of keys of the new node. */ 545 545 node->keys /= 2; /* Shrink the old node. */ 546 546 547 547 return rnode; 548 548 } … … 578 578 btree_node_t *rnode; 579 579 btree_key_t median; 580 580 581 581 /* 582 582 * Node is full and both siblings (if both exist) are full too. … … 584 584 * bigger keys (i.e. the new node) into its parent. 585 585 */ 586 586 587 587 rnode = node_split(node, key, value, rsubtree, &median); 588 588 589 589 if (LEAF_NODE(node)) { 590 590 list_insert_after(&rnode->leaf_link, &node->leaf_link); 591 591 } 592 592 593 593 if (ROOT_NODE(node)) { 594 594 /* … … 599 599 rnode->parent = t->root; 600 600 node_initialize(t->root); 601 601 602 602 /* 603 603 * Left-hand side subtree will be the old root (i.e. node). … … 605 605 */ 606 606 t->root->subtree[0] = node; 607 607 608 608 t->root->depth = node->depth + 1; 609 609 } … … 624 624 { 625 625 btree_node_t *lnode; 626 626 627 627 assert(value); 628 628 629 629 lnode = leaf_node; 630 630 if (!lnode) { … … 632 632 panic("B-tree %p already contains key %" PRIu64 ".", t, key); 633 633 } 634 634 635 635 _btree_insert(t, key, value, NULL, lnode); 636 636 } … … 648 648 size_t idx; 649 649 btree_node_t *lnode; 650 650 651 651 /* 652 652 * If this is root node, the rotation can not be done. … … 654 654 if (ROOT_NODE(rnode)) 655 655 return false; 656 656 657 657 idx = find_key_by_subtree(rnode->parent, rnode, true); 658 658 if ((int) idx == -1) { … … 663 663 return false; 664 664 } 665 665 666 666 lnode = rnode->parent->subtree[idx]; 667 667 if (lnode->keys > FILL_FACTOR) { … … 669 669 return true; 670 670 } 671 671 672 672 return false; 673 673 } … … 685 685 size_t idx; 686 686 btree_node_t *rnode; 687 687 688 688 /* 689 689 * If this is root node, the rotation can not be done. … … 691 691 if (ROOT_NODE(lnode)) 692 692 return false; 693 693 694 694 idx = find_key_by_subtree(lnode->parent, lnode, false); 695 695 if (idx == lnode->parent->keys) { … … 700 700 return false; 701 701 } 702 702 703 703 rnode = lnode->parent->subtree[idx + 1]; 704 704 if (rnode->keys > FILL_FACTOR) { … … 706 706 return true; 707 707 } 708 708 709 709 return false; 710 710 } … … 724 724 btree_node_t *rnode; 725 725 size_t i; 726 726 727 727 assert(!ROOT_NODE(node)); 728 728 729 729 idx = find_key_by_subtree(node->parent, node, false); 730 730 if (idx == node->parent->keys) { … … 737 737 } else 738 738 rnode = node->parent->subtree[idx + 1]; 739 739 740 740 /* Index nodes need to insert parent node key in between left and right node. */ 741 741 if (INDEX_NODE(node)) 742 742 node->key[node->keys++] = node->parent->key[idx]; 743 743 744 744 /* Copy the key-value-subtree triplets from the right node. */ 745 745 for (i = 0; i < rnode->keys; i++) { 746 746 node->key[node->keys + i] = rnode->key[i]; 747 747 node->value[node->keys + i] = rnode->value[i]; 748 748 749 749 if (INDEX_NODE(node)) { 750 750 node->subtree[node->keys + i] = rnode->subtree[i]; … … 752 752 } 753 753 } 754 754 755 755 if (INDEX_NODE(node)) { 756 756 node->subtree[node->keys + i] = rnode->subtree[i]; 757 757 rnode->subtree[i]->parent = node; 758 758 } 759 759 760 760 node->keys += rnode->keys; 761 761 return rnode; … … 789 789 node_remove_key_and_rsubtree(node, key); 790 790 } 791 791 792 792 return; 793 793 } 794 794 795 795 if (node->keys <= FILL_FACTOR) { 796 796 /* … … 801 801 try_rotation_from_right(node); 802 802 } 803 803 804 804 if (node->keys > FILL_FACTOR) { 805 805 size_t i; 806 806 807 807 /* 808 808 * The key can be immediately removed. … … 813 813 */ 814 814 node_remove_key_and_rsubtree(node, key); 815 815 816 816 for (i = 0; i < node->parent->keys; i++) { 817 817 if (node->parent->key[i] == key) … … 822 822 btree_node_t *rnode; 823 823 btree_node_t *parent; 824 824 825 825 /* 826 826 * The node is below the fill factor as well as its left and right sibling. … … 832 832 node_remove_key_and_rsubtree(node, key); 833 833 rnode = node_combine(node); 834 834 835 835 if (LEAF_NODE(rnode)) 836 836 list_remove(&rnode->leaf_link); 837 837 838 838 idx = find_key_by_subtree(parent, rnode, true); 839 839 assert((int) idx != -1); … … 855 855 { 856 856 btree_node_t *lnode; 857 857 858 858 lnode = leaf_node; 859 859 if (!lnode) { … … 861 861 panic("B-tree %p does not contain key %" PRIu64 ".", t, key); 862 862 } 863 863 864 864 _btree_remove(t, key, lnode); 865 865 } … … 877 877 { 878 878 btree_node_t *cur, *next; 879 879 880 880 /* 881 881 * Iteratively descend to the leaf that can contain the searched key. … … 887 887 */ 888 888 *leaf_node = cur; 889 889 890 890 if (cur->keys == 0) 891 891 return NULL; … … 901 901 void *val; 902 902 size_t i; 903 903 904 904 /* 905 905 * Now if the key is smaller than cur->key[i] … … 911 911 next = cur->subtree[i]; 912 912 val = cur->value[i - 1]; 913 913 914 914 if (LEAF_NODE(cur)) 915 915 return key == cur->key[i - 1] ? val : NULL; 916 916 917 917 goto descend; 918 918 } 919 919 } 920 920 921 921 /* 922 922 * Last possibility is that the key is … … 925 925 next = cur->subtree[i]; 926 926 val = cur->value[i - 1]; 927 927 928 928 if (LEAF_NODE(cur)) 929 929 return key == cur->key[i - 1] ? val : NULL; … … 932 932 ; 933 933 } 934 934 935 935 /* 936 936 * The key was not found in the *leaf_node and … … 952 952 { 953 953 assert(LEAF_NODE(node)); 954 954 955 955 if (node->leaf_link.prev != &t->leaf_list.head) 956 956 return list_get_instance(node->leaf_link.prev, btree_node_t, leaf_link); … … 971 971 { 972 972 assert(LEAF_NODE(node)); 973 973 974 974 if (node->leaf_link.next != &t->leaf_list.head) 975 975 return list_get_instance(node->leaf_link.next, btree_node_t, leaf_link); … … 988 988 int depth = t->root->depth; 989 989 list_t list; 990 990 991 991 printf("Printing B-tree:\n"); 992 992 list_initialize(&list); 993 993 list_append(&t->root->bfs_link, &list); 994 994 995 995 /* 996 996 * Use BFS search to print out the tree. … … 1000 1000 link_t *hlp; 1001 1001 btree_node_t *node; 1002 1002 1003 1003 hlp = list_first(&list); 1004 1004 assert(hlp != NULL); 1005 1005 node = list_get_instance(hlp, btree_node_t, bfs_link); 1006 1006 list_remove(hlp); 1007 1007 1008 1008 assert(node); 1009 1009 1010 1010 if (node->depth != depth) { 1011 1011 printf("\n"); 1012 1012 depth = node->depth; 1013 1013 } 1014 1014 1015 1015 printf("("); 1016 1016 1017 1017 for (i = 0; i < node->keys; i++) { 1018 1018 printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : ""); … … 1021 1021 } 1022 1022 } 1023 1023 1024 1024 if (node->depth && node->subtree[i]) 1025 1025 list_append(&node->subtree[i]->bfs_link, &list); 1026 1026 1027 1027 printf(")"); 1028 1028 } 1029 1029 1030 1030 printf("\n"); 1031 1031 1032 1032 printf("Printing list of leaves:\n"); 1033 1033 list_foreach(t->leaf_list, leaf_link, btree_node_t, node) { 1034 1034 assert(node); 1035 1035 1036 1036 printf("("); 1037 1037 1038 1038 for (i = 0; i < node->keys; i++) 1039 1039 printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : ""); 1040 1040 1041 1041 printf(")"); 1042 1042 } 1043 1043 1044 1044 printf("\n"); 1045 1045 }
Note:
See TracChangeset
for help on using the changeset viewer.