/* * check balances and rotate as required. */ static void rebalance(cp_avlnode **node) { if ((*node)->balance == -2) { if ((*node)->left->balance == 1) left_right_rotate(node); else right_rotate(node); } else if ((*node)->balance == 2) { if ((*node)->right->balance == -1) right_left_rotate(node); else left_rotate(node); } }
/******************************************************************************* * Fixes the tree in order to balance it. Basically, we start from 'p_entry' * * go up the chain towards parents. If a parent is disbalanced, a set of * * rotations are applied. If 'insertion_mode' is on, it means that previous * * modification was insertion of an entry. In such a case we need to perform * * only one rotation. If 'insertion_mode' is off, the last operation was * * removal and we need to go up until the root node. * *******************************************************************************/ static void fix_after_modification(map* p_map, map_entry* entry, bool insertion_mode) { map_entry* parent = entry->parent; map_entry* grand_parent; map_entry* sub_tree; while (parent) { if (height(parent->left) == height(parent->right) + 2) { grand_parent = parent->parent; if (height(parent->left->left) >= height(parent->left->right)) { sub_tree = right_rotate(parent); } else { sub_tree = left_right_rotate(parent); } if (!grand_parent) { p_map->root = sub_tree; } else if (grand_parent->left == parent) { grand_parent->left = sub_tree; } else { grand_parent->right = sub_tree; } if (grand_parent) { grand_parent->height = max(height(grand_parent->left), height(grand_parent->right)) + 1; } /* Fixing after insertion requires only one rotation. */ if (insertion_mode) { return; } } else if (height(parent->right) == height(parent->left) + 2) { grand_parent = parent->parent; if (height(parent->right->right) >= height(parent->right->left)) { sub_tree = left_rotate(parent); } else { sub_tree = right_left_rotate(parent); } if (!grand_parent) { p_map->root = sub_tree; } else if (grand_parent->left == parent) { grand_parent->left = sub_tree; } else { grand_parent->right = sub_tree; } if (grand_parent) { grand_parent->height = max(height(grand_parent->left), height(grand_parent->right)) + 1; } /* Fixing after insertion requires only one rotation. */ if (insertion_mode) { return; } } parent->height = max(height(parent->left), height(parent->right)) + 1; parent = parent->parent; } }