114544Ssam #ifndef lint
2*17017Ssam static char sccsid[] = "@(#)tree.c 4.4 (Berkeley) 08/25/84";
314544Ssam #endif
410920Sshannon
510920Sshannon #include "compact.h"
610920Sshannon
insert(ch)7*17017Ssam insert(ch)
817016Ssam int ch;
910920Sshannon {
1010920Sshannon register struct node *pp;
11*17017Ssam register struct son *pson, *bson;
1210920Sshannon union cio d;
13*17017Ssam register struct index *wt;
1410920Sshannon
1510920Sshannon wt = NEW;
1610920Sshannon pp = bottom++;
17*17017Ssam pson = &pp->sons[RIGHT];
18*17017Ssam bson = &bottom->sons[LEFT];
1917016Ssam bottom->fath.fp = pp;
20*17017Ssam in[ch].flags = (SEEN | FBIT);
21*17017Ssam d.integ = bson->sp.ch = pson->sp.ch;
22*17017Ssam in[ch].fp = in[d.integ].fp = pson->sp.p = wt->pt = bottom;
2317016Ssam bottom->fath.flags = (LLEAF | RLEAF | FBIT);
2417016Ssam pp->fath.flags &= ~RLEAF;
2517016Ssam in[d.integ].flags = SEEN;
2610920Sshannon
27*17017Ssam bson->count = pson->count;
28*17017Ssam bson->top = pson->top;
29*17017Ssam bson++;
30*17017Ssam bson->sp.ch = ch;
31*17017Ssam bson->count = 0;
32*17017Ssam bson->top = pson->top->next = wt;
3317016Ssam wt->next = NULL;
3410920Sshannon }
3510920Sshannon
uptree(ch)36*17017Ssam uptree(ch)
3717016Ssam int ch;
3810920Sshannon {
3910920Sshannon register struct node *r;
4010920Sshannon union treep q, s;
41*17017Ssam int rs, ts, rflags, tflags;
4210920Sshannon longint rc, qc, sc;
4310920Sshannon struct node *t;
44*17017Ssam register struct son *rson, *tson;
4510920Sshannon register struct index *rt, *qt, *st;
4610920Sshannon
4717016Ssam r = in[ch].fp;
4817016Ssam rs = in[ch].flags & FBIT;
4910920Sshannon
5010920Sshannon do {
51*17017Ssam rson = &r->sons[rs];
52*17017Ssam rc = ++rson->count;
53*17017Ssam rt = rson->top;
5417016Ssam for (;;) {
5517016Ssam if (rs) {
56*17017Ssam s.p = r + 1;
5710920Sshannon if (r == bottom) {
5810920Sshannon sc = rc - 2;
5910920Sshannon st = NULL;
60*17017Ssam } else {
61*17017Ssam sc = (r+1)->sons[LEFT].count;
62*17017Ssam st = (r+1)->sons[LEFT].top;
6310920Sshannon }
64*17017Ssam qc = r->sons[LEFT].count;
65*17017Ssam qt = r->sons[LEFT].top;
6617016Ssam } else {
67*17017Ssam s.p = r;
68*17017Ssam sc = r->sons[RIGHT].count;
69*17017Ssam st = r->sons[RIGHT].top;
7017016Ssam if (r == dict) {
7117016Ssam qc = rc + 1;
7217016Ssam qt = head;
7317016Ssam break;
74*17017Ssam } else {
75*17017Ssam qc = (r-1)->sons[RIGHT].count;
76*17017Ssam qt = (r-1)->sons[RIGHT].top;
7717016Ssam }
7817016Ssam }
7917016Ssam if (rc <= qc)
8010920Sshannon break;
8110920Sshannon
8217016Ssam t = qt->pt;
83*17017Ssam ts = LEFT;
84*17017Ssam tson = &t->sons[LEFT];
85*17017Ssam if (rc <= tson->count) {
86*17017Ssam tson++;
87*17017Ssam ts++;
88*17017Ssam }
8910920Sshannon
9010920Sshannon /* exchange pointers of (t, ts) and (r, rs) */
91*17017Ssam q.ch = tson->sp.ch;
92*17017Ssam s.ch = rson->sp.ch;
93*17017Ssam tson->sp.ch = s.ch;
94*17017Ssam rson->sp.ch = q.ch;
9517016Ssam exch(t, ts, q.ch, r, rs);
9617016Ssam exch(r, rs, s.ch, t, ts);
9710920Sshannon
98*17017Ssam rflags = (rs ? RLEAF : LLEAF);
99*17017Ssam tflags = (ts ? RLEAF : LLEAF);
100*17017Ssam if (((r->fath.flags & rflags) << rs) ^ ((t->fath.flags & tflags) << ts)) {
101*17017Ssam r->fath.flags ^= rflags;
102*17017Ssam t->fath.flags ^= tflags;
10310920Sshannon }
10410920Sshannon
105*17017Ssam tson->count++;
106*17017Ssam rson->count--;
107*17017Ssam if (ts)
108*17017Ssam qt->pt++;
10910920Sshannon r = t;
11010920Sshannon rs = ts;
111*17017Ssam rson = tson;
11210920Sshannon }
11310920Sshannon
11410920Sshannon if (rc == qc) {
115*17017Ssam rson->top = qt;
11610920Sshannon if (rc > sc + 1) {
11717016Ssam qt->next = st;
11810920Sshannon /* dispose of rt */
11917016Ssam rt->next = flist;
12010920Sshannon flist = rt;
12117016Ssam } else
12217016Ssam st->pt = s.p;
12317016Ssam } else if (rc == sc + 1) {
12410920Sshannon /* create new index at rt */
12510920Sshannon rt = NEW;
12617016Ssam rt->next = st;
12717016Ssam rt->pt = r;
12817016Ssam qt->next = rt;
12917016Ssam if (st)
13017016Ssam st->pt = s.p;
131*17017Ssam rson->top = rt;
13210920Sshannon }
13317016Ssam rs = r->fath.flags & FBIT;
13417016Ssam r = r->fath.fp;
13510920Sshannon } while (r);
13617016Ssam dirp = head->next;
13717016Ssam dirq = dirp->next;
13810920Sshannon }
13910920Sshannon
14017016Ssam exch(v, vs, x, w, ws)
14117016Ssam struct node *v, *w;
14217016Ssam union treep x;
14317016Ssam int vs, ws;
14410920Sshannon {
14510920Sshannon
14617016Ssam if (v->fath.flags & (vs ? RLEAF : LLEAF)) {
14717016Ssam in[x.ch].fp = w;
14817016Ssam in[x.ch].flags &= ~01;
14917016Ssam if (ws)
15017016Ssam in[x.ch].flags |= ws;
15117016Ssam } else {
15217016Ssam x.p->fath.fp = w;
15317016Ssam x.p->fath.flags &= ~01;
15417016Ssam if (ws)
15517016Ssam x.p->fath.flags |= ws;
15610920Sshannon }
15710920Sshannon }
158