Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
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
}
Exemple #4
0
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;
}