struct interval_node *interval_insert(struct interval_node *node, struct interval_node **root) { struct interval_node **p, *parent = NULL; LASSERT(!interval_is_intree(node)); p = root; while (*p) { parent = *p; if (extent_equal(&parent->in_extent, &node->in_extent)) return parent; /* max_high field must be updated after each iteration */ if (parent->in_max_high < interval_high(node)) parent->in_max_high = interval_high(node); if (extent_compare(&node->in_extent, &parent->in_extent) < 0) p = &parent->in_left; else p = &parent->in_right; } /* link node into the tree */ node->in_parent = parent; node->in_color = INTERVAL_RED; node->in_left = NULL; node->in_right = NULL; *p = node; interval_insert_color(node, root); node->in_intree = 1; return NULL; }
/* * range destructor */ void range_destroy(struct lu_nid_range *range) { LASSERT(list_empty(&range->rn_list) == 0); LASSERT(interval_is_intree(&range->rn_node) == 0); OBD_FREE_PTR(range); }
/* * delete a range from the interval tree and any * associated nodemap references * * \param range range to remove */ void range_delete(struct lu_nid_range *range) { if (range == NULL || interval_is_intree(&range->rn_node) == 0) return; list_del(&range->rn_list); interval_erase(&range->rn_node, &range_interval_root); range_destroy(range); }
void interval_erase(struct interval_node *node, struct interval_node **root) { struct interval_node *child, *parent; int color; LASSERT(interval_is_intree(node)); node->in_intree = 0; if (!node->in_left) { child = node->in_right; } else if (!node->in_right) { child = node->in_left; } else { /* Both left and right child are not NULL */ struct interval_node *old = node; node = interval_next(node); child = node->in_right; parent = node->in_parent; color = node->in_color; if (child) child->in_parent = parent; if (parent == old) parent->in_right = child; else parent->in_left = child; node->in_color = old->in_color; node->in_right = old->in_right; node->in_left = old->in_left; node->in_parent = old->in_parent; if (old->in_parent) { if (node_is_left_child(old)) old->in_parent->in_left = node; else old->in_parent->in_right = node; } else { *root = node; } old->in_left->in_parent = node; if (old->in_right) old->in_right->in_parent = node; update_maxhigh(child ? : parent, node->in_max_high); update_maxhigh(node, old->in_max_high); if (parent == old) parent = node; goto color; } parent = node->in_parent; color = node->in_color; if (child) child->in_parent = parent; if (parent) { if (node_is_left_child(node)) parent->in_left = child; else parent->in_right = child; } else { *root = child; } update_maxhigh(child ? : parent, node->in_max_high); color: if (color == INTERVAL_BLACK) interval_erase_color(child, parent, root); }