MCPcopy Create free account
hub / github.com/F-Stack/f-stack / avl_insert

Function avl_insert

freebsd/contrib/openzfs/module/avl/avl.c:485–561  ·  view source on GitHub ↗

* 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

Source from the content-addressed store, hash-verified

483 * be necessary to maintain an acceptable AVL balance.
484 */
485void
486avl_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;

Callers 15

acevals_findFunction · 0.85
unique_insertFunction · 0.85
spa_log_errorFunction · 0.85
spa_aux_addFunction · 0.85
zfs_rangelock_add_readerFunction · 0.85
userquota_update_cacheFunction · 0.85
ddt_lookupFunction · 0.85

Calls 1

avl_rotationFunction · 0.85

Tested by 2

drain_treeFunction · 0.68
stress_treeFunction · 0.68