#ifndef lint static char sccsid[] = "@(#)tree.c 4.4 (Berkeley) 8/25/84"; #endif #include "compact.h" insert(ch) int ch; { register struct node *pp; register struct son *pson, *bson; union cio d; register struct index *wt; wt = NEW; pp = bottom++; pson = &pp->sons[RIGHT]; bson = &bottom->sons[LEFT]; bottom->fath.fp = pp; in[ch].flags = (SEEN | FBIT); d.integ = bson->sp.ch = pson->sp.ch; in[ch].fp = in[d.integ].fp = pson->sp.p = wt->pt = bottom; bottom->fath.flags = (LLEAF | RLEAF | FBIT); pp->fath.flags &= ~RLEAF; in[d.integ].flags = SEEN; bson->count = pson->count; bson->top = pson->top; bson++; bson->sp.ch = ch; bson->count = 0; bson->top = pson->top->next = wt; wt->next = NULL; } uptree(ch) int ch; { register struct node *r; union treep q, s; int rs, ts, rflags, tflags; longint rc, qc, sc; struct node *t; register struct son *rson, *tson; register struct index *rt, *qt, *st; r = in[ch].fp; rs = in[ch].flags & FBIT; do { rson = &r->sons[rs]; rc = ++rson->count; rt = rson->top; for (;;) { if (rs) { s.p = r + 1; if (r == bottom) { sc = rc - 2; st = NULL; } else { sc = (r+1)->sons[LEFT].count; st = (r+1)->sons[LEFT].top; } qc = r->sons[LEFT].count; qt = r->sons[LEFT].top; } else { s.p = r; sc = r->sons[RIGHT].count; st = r->sons[RIGHT].top; if (r == dict) { qc = rc + 1; qt = head; break; } else { qc = (r-1)->sons[RIGHT].count; qt = (r-1)->sons[RIGHT].top; } } if (rc <= qc) break; t = qt->pt; ts = LEFT; tson = &t->sons[LEFT]; if (rc <= tson->count) { tson++; ts++; } /* exchange pointers of (t, ts) and (r, rs) */ q.ch = tson->sp.ch; s.ch = rson->sp.ch; tson->sp.ch = s.ch; rson->sp.ch = q.ch; exch(t, ts, q.ch, r, rs); exch(r, rs, s.ch, t, ts); rflags = (rs ? RLEAF : LLEAF); tflags = (ts ? RLEAF : LLEAF); if (((r->fath.flags & rflags) << rs) ^ ((t->fath.flags & tflags) << ts)) { r->fath.flags ^= rflags; t->fath.flags ^= tflags; } tson->count++; rson->count--; if (ts) qt->pt++; r = t; rs = ts; rson = tson; } if (rc == qc) { rson->top = qt; if (rc > sc + 1) { qt->next = st; /* dispose of rt */ rt->next = flist; flist = rt; } else st->pt = s.p; } else if (rc == sc + 1) { /* create new index at rt */ rt = NEW; rt->next = st; rt->pt = r; qt->next = rt; if (st) st->pt = s.p; rson->top = rt; } rs = r->fath.flags & FBIT; r = r->fath.fp; } while (r); dirp = head->next; dirq = dirp->next; } exch(v, vs, x, w, ws) struct node *v, *w; union treep x; int vs, ws; { if (v->fath.flags & (vs ? RLEAF : LLEAF)) { in[x.ch].fp = w; in[x.ch].flags &= ~01; if (ws) in[x.ch].flags |= ws; } else { x.p->fath.fp = w; x.p->fath.flags &= ~01; if (ws) x.p->fath.flags |= ws; } }