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