psync_tree *psync_tree_get_add_before(psync_tree *tree, psync_tree *node, psync_tree *newnode){ if (!tree) return psync_tree_init_node(newnode); if (!node) return psync_tree_get_add_after(tree, psync_tree_get_last(tree), newnode); newnode=psync_tree_init_node(newnode); if (node->left){ node=node->left; while (node->right) node=node->right; node->right=newnode; } else node->left=newnode; newnode->parent=node; return psync_tree_go_up_rebalance_add(tree, node); }
static psync_interval_tree_t *psync_interval_tree_get_add(psync_interval_tree_t *tree, uint64_t from, uint64_t to){ // debug(D_NOTICE, "adding interval %lu %lu", from, to); assert(to>from); if (unlikely(!tree)) return psync_interval_tree_new(from, to); else{ psync_interval_tree_t *e, *e2; e=tree; while (1){ assert(from<=to); if (e->from<=from && e->to>=from){ if (e->to>=to) return tree; e->to=to; return psync_interval_tree_consume_intervals(tree, e); } else if (e->from>from){ if (e->tree.left) e=psync_interval_tree_element(e->tree.left); else if (e->from<=to && e->to>=to){ e->from=from; return tree; } else{ e2=psync_interval_new(from, to); return psync_interval_tree_consume_intervals(psync_interval_tree_element(psync_tree_get_add_before(&tree->tree, &e->tree, &e2->tree)), e2); } } else{ assert(e->to<from); if (e->tree.right) e=psync_interval_tree_element(e->tree.right); else{ e2=psync_interval_new(from, to); return psync_interval_tree_consume_intervals(psync_interval_tree_element(psync_tree_get_add_after(&tree->tree, &e->tree, &e2->tree)), e2); } } } } }
static psync_interval_tree_t *psync_interval_tree_new(uint64_t from, uint64_t to){ psync_interval_tree_t *tree=psync_new(psync_interval_tree_t); tree->from=from; tree->to=to; return psync_interval_tree_element(psync_tree_get_add_after(PSYNC_TREE_EMPTY, NULL, &tree->tree)); }