/** * In an augmented interval tree, each node saves the maximum edge of its child subtrees * This function compares the children max_edge with the current max_edge * and propagates any change to the parent nodes. */ static void update_max_edge(wmem_tree_node_t *node) { wmem_range_t *range; const wmem_range_t *range_l; const wmem_range_t *range_r; guint64 maxEdge = 0; if(!node) { return ; } range = (wmem_range_t *)node->key; range_l = (node->left) ? (const wmem_range_t *) (node->left->key) : NULL; range_r = (node->right) ? (const wmem_range_t *) (node->right->key) : NULL; maxEdge = range->high; if(range_r) { maxEdge = MAX(maxEdge, range_r->max_edge) ; } if(range_l) { maxEdge = MAX(maxEdge, range_l->max_edge) ; } /* update the parent nodes only if a change happened (optimization) */ if(range->max_edge != maxEdge) { range->max_edge = maxEdge; update_max_edge(node->parent); } }
/** * In an augmented interval tree, each node saves the maximum edge of its child subtrees * This function compares the children max_edge with the current max_edge * and propagates any change to the parent nodes. */ static void update_max_edge(wmem_tree_node_t *node) { wmem_range_t *range; wmem_range_t *range_l; wmem_range_t *range_r; guint64 maxEdge = 0; if(!node) { return ; } range = (wmem_range_t *)node->key; range_l = (node->left) ? (wmem_range_t *) (node->left->key) : NULL; range_r = (node->right) ? (wmem_range_t *) (node->right->key) : NULL; maxEdge = range->max_edge; if(range_r) { maxEdge = MAX(maxEdge, range_r->max_edge) ; } if(range_l) { maxEdge = MAX(maxEdge, range_l->max_edge) ; } /* a change was made, update the parent nodes */ if(range->max_edge != maxEdge) { range->max_edge = maxEdge; update_max_edge(node->parent); } }
void wmem_itree_insert(wmem_itree_t *tree, const guint64 low, const guint64 high, void *data) { wmem_tree_node_t *node; wmem_range_t *range = (wmem_range_t *)wmem_new(tree->allocator, wmem_range_t); g_assert(low <= high); range->low = low; range->high = high; range->max_edge = 0; node = wmem_tree_insert(tree, range, data, (compare_func)wmem_tree_compare_ranges); /* in absence of rotation, we still need to update max_edge */ update_max_edge(node); }
/* after a rotation, some of the children nodes might (dis)appear, thus we need * to refresh children max_edge. Changes will propagate to parents */ static void update_edges_after_rotation(wmem_tree_node_t *node) { if(node->left) update_max_edge(node->left); if(node->right) update_max_edge(node->right); }