struct et_node * et_nca (struct et_node *n1, struct et_node *n2) { struct et_occ *o1 = n1->rightmost_occ, *o2 = n2->rightmost_occ, *om; struct et_occ *l, *r, *ret; int mn; if (n1 == n2) return n1; et_splay (o1); l = o1->prev; r = o1->next; if (l) l->parent = NULL; if (r) r->parent = NULL; et_splay (o2); if (l == o2 || (l && l->parent != NULL)) { ret = o2->next; set_prev (o1, o2); if (r) r->parent = o1; } else { ret = o2->prev; set_next (o1, o2); if (l) l->parent = o1; } if (0 < o2->depth) { om = o1; mn = o1->depth; } else { om = o2; mn = o2->depth + o1->depth; } #ifdef DEBUG_ET et_check_tree_sanity (o2); #endif if (ret && ret->min + o1->depth + o2->depth < mn) return ret->min_occ->of; else return om->of; }
bool et_below (struct et_node *down, struct et_node *up) { struct et_occ *u = up->rightmost_occ, *d = down->rightmost_occ; struct et_occ *l, *r; if (up == down) return true; et_splay (u); l = u->prev; r = u->next; if (!l) return false; l->parent = NULL; if (r) r->parent = NULL; et_splay (d); if (l == d || l->parent != NULL) { if (r) r->parent = u; set_prev (u, d); #ifdef DEBUG_ET et_check_tree_sanity (u); #endif } else { l->parent = u; /* In case O1 and O2 are in two different trees, we must just restore the original state. */ if (r && r->parent != NULL) set_next (u, d); else set_next (u, r); #ifdef DEBUG_ET et_check_tree_sanity (u); #endif return false; } if (0 >= d->depth) return false; return !d->next || d->next->min + d->depth >= 0; }
void et_set_father (struct et_node *t, struct et_node *father) { struct et_node *left, *right; struct et_occ *rmost, *left_part, *new_f_occ, *p; /* Update the path represented in the splay tree. */ new_f_occ = et_new_occ (father); rmost = father->rightmost_occ; et_splay (rmost); left_part = rmost->prev; p = t->rightmost_occ; et_splay (p); set_prev (new_f_occ, left_part); set_next (new_f_occ, p); p->depth++; p->min++; et_recomp_min (new_f_occ); set_prev (rmost, new_f_occ); if (new_f_occ->min + rmost->depth < rmost->min) { rmost->min = new_f_occ->min + rmost->depth; rmost->min_occ = new_f_occ->min_occ; } t->parent_occ = new_f_occ; /* Update the tree. */ t->father = father; right = father->son; if (right) left = right->left; else left = right = t; left->right = t; right->left = t; t->left = left; t->right = right; father->son = t; #ifdef DEBUG_ET et_check_tree_sanity (rmost); record_path_before (rmost); #endif }
void et_split (struct et_node *t) { struct et_node *father = t->father; struct et_occ *r, *l, *rmost, *p_occ; /* Update the path represented by the splay tree. */ rmost = t->rightmost_occ; et_splay (rmost); for (r = rmost->next; r->prev; r = r->prev) continue; et_splay (r); r->prev->parent = NULL; p_occ = t->parent_occ; et_splay (p_occ); t->parent_occ = NULL; l = p_occ->prev; p_occ->next->parent = NULL; set_prev (r, l); et_recomp_min (r); et_splay (rmost); rmost->depth = 0; rmost->min = 0; pool_free (et_occurrences, p_occ); /* Update the tree. */ if (father->son == t) father->son = t->right; if (father->son == t) father->son = NULL; else { t->left->right = t->right; t->right->left = t->left; } t->left = t->right = NULL; t->father = NULL; #ifdef DEBUG_ET et_check_tree_sanity (rmost); record_path_before (rmost); et_check_tree_sanity (r); record_path_before (r); #endif }
struct et_node * et_root (struct et_node *node) { struct et_occ *occ = node->rightmost_occ, *r; /* The root of the tree corresponds to the rightmost occurrence in the represented path. */ et_splay (occ); for (r = occ; r->next; r = r->next) continue; et_splay (r); return r->of; }