* Insert a new node into an AVL tree at the specified (from avl_find()) place. * * Newly inserted nodes are always leaf nodes in the tree, since avl_find() * searches out to the leaf positions. The avl_index_t indicates the node * which will be the parent of the new node. * * After the node is inserted, a single rotation further up the tree may * be necessary to maintain an acceptable AVL
| 483 | * be necessary to maintain an acceptable AVL balance. |
| 484 | */ |
| 485 | void |
| 486 | avl_insert(avl_tree_t *tree, void *new_data, avl_index_t where) |
| 487 | { |
| 488 | avl_node_t *node; |
| 489 | avl_node_t *parent = AVL_INDEX2NODE(where); |
| 490 | int old_balance; |
| 491 | int new_balance; |
| 492 | int which_child = AVL_INDEX2CHILD(where); |
| 493 | size_t off = tree->avl_offset; |
| 494 | |
| 495 | ASSERT(tree); |
| 496 | #ifdef _LP64 |
| 497 | ASSERT(((uintptr_t)new_data & 0x7) == 0); |
| 498 | #endif |
| 499 | |
| 500 | node = AVL_DATA2NODE(new_data, off); |
| 501 | |
| 502 | /* |
| 503 | * First, add the node to the tree at the indicated position. |
| 504 | */ |
| 505 | ++tree->avl_numnodes; |
| 506 | |
| 507 | node->avl_child[0] = NULL; |
| 508 | node->avl_child[1] = NULL; |
| 509 | |
| 510 | AVL_SETCHILD(node, which_child); |
| 511 | AVL_SETBALANCE(node, 0); |
| 512 | AVL_SETPARENT(node, parent); |
| 513 | if (parent != NULL) { |
| 514 | ASSERT(parent->avl_child[which_child] == NULL); |
| 515 | parent->avl_child[which_child] = node; |
| 516 | } else { |
| 517 | ASSERT(tree->avl_root == NULL); |
| 518 | tree->avl_root = node; |
| 519 | } |
| 520 | /* |
| 521 | * Now, back up the tree modifying the balance of all nodes above the |
| 522 | * insertion point. If we get to a highly unbalanced ancestor, we |
| 523 | * need to do a rotation. If we back out of the tree we are done. |
| 524 | * If we brought any subtree into perfect balance (0), we are also done. |
| 525 | */ |
| 526 | for (;;) { |
| 527 | node = parent; |
| 528 | if (node == NULL) |
| 529 | return; |
| 530 | |
| 531 | /* |
| 532 | * Compute the new balance |
| 533 | */ |
| 534 | old_balance = AVL_XBALANCE(node); |
| 535 | new_balance = old_balance + avl_child2balance[which_child]; |
| 536 | |
| 537 | /* |
| 538 | * If we introduced equal balance, then we are done immediately |
| 539 | */ |
| 540 | if (new_balance == 0) { |
| 541 | AVL_SETBALANCE(node, 0); |
| 542 | return; |