114544Ssam #ifndef lint
2*17016Ssam static char sccsid[] = "@(#)tree.c	4.3 (Berkeley) 08/25/84";
314544Ssam #endif
410920Sshannon 
510920Sshannon #include "compact.h"
610920Sshannon 
710920Sshannon insert (ch)
8*17016Ssam 	int ch;
910920Sshannon {
1010920Sshannon 	register struct node *pp;
1110920Sshannon 	register int c;
1210920Sshannon 	union cio d;
1310920Sshannon 	register struct index *qt, *wt;
1410920Sshannon 
1510920Sshannon 	c = ch;
1610920Sshannon 	wt = NEW;
1710920Sshannon 	pp = bottom++;
18*17016Ssam 	bottom->fath.fp = pp;
19*17016Ssam 	in[c].flags = (SEEN | FBIT);
20*17016Ssam 	d.integ = bottom->sp[0].ch = pp->sp[1].ch;
21*17016Ssam 	in[c].fp = in[d.integ].fp = pp->sp[1].p = wt->pt = bottom;
22*17016Ssam 	bottom->fath.flags = (LLEAF | RLEAF | FBIT);
23*17016Ssam 	pp->fath.flags &= ~RLEAF;
24*17016Ssam 	in[d.integ].flags = SEEN;
2510920Sshannon 
26*17016Ssam 	bottom->count[0] = pp->count[1];
27*17016Ssam 	qt = pp->top[1];
28*17016Ssam 	bottom->top[0] = qt;
29*17016Ssam 	bottom->sp[1].ch = c;
30*17016Ssam 	bottom->count[1] = 0;
31*17016Ssam 	bottom->top[1] = qt->next = wt;
32*17016Ssam 	wt->next = NULL;
3310920Sshannon }
3410920Sshannon 
3510920Sshannon uptree (ch)
36*17016Ssam 	int ch;
3710920Sshannon {
3810920Sshannon 	register struct node *r;
3910920Sshannon 	union treep q, s;
4010920Sshannon 	int rs, qs, ss, ts;
4110920Sshannon 	longint rc, qc, sc;
4210920Sshannon 	struct node *t;
4310920Sshannon 	register struct index *rt, *qt, *st;
4410920Sshannon 
45*17016Ssam 	r = in[ch].fp;
46*17016Ssam 	rs = in[ch].flags & FBIT;
4710920Sshannon 
4810920Sshannon 	do {
49*17016Ssam 		rc = ++r->count[rs];
50*17016Ssam 		rt = r->top[rs];
51*17016Ssam 		for (;;) {
5210920Sshannon 			qs = ss = 1 - rs;
53*17016Ssam 			s.p = r + rs;
54*17016Ssam 			sc = s.p->count[ss];
55*17016Ssam 			st = s.p->top[ss];
5610920Sshannon 
57*17016Ssam 			if (rs) {
5810920Sshannon 				if (r == bottom) {
5910920Sshannon 					sc = rc - 2;
6010920Sshannon 					st = NULL;
6110920Sshannon 				}
62*17016Ssam 			} else {
63*17016Ssam 				if (r == dict) {
64*17016Ssam 					qc = rc + 1;
65*17016Ssam 					qt = head;
66*17016Ssam 					break;
67*17016Ssam 				}
68*17016Ssam 			}
69*17016Ssam 			q.p = r - qs;
70*17016Ssam 			qc = q.p->count[qs];
71*17016Ssam 			qt = q.p->top[qs];
72*17016Ssam 			if (rc <= qc)
7310920Sshannon 				break;
7410920Sshannon 
75*17016Ssam 			t = qt->pt;
76*17016Ssam 			ts = (rc <= t->count[0]);
7710920Sshannon 
7810920Sshannon 			/* exchange pointers of (t, ts) and (r, rs) */
79*17016Ssam 			q.ch = t->sp[ts].ch;
80*17016Ssam 			s.ch = r->sp[rs].ch;
81*17016Ssam 			t->sp[ts].ch = s.ch;
82*17016Ssam 			r->sp[rs].ch = q.ch;
83*17016Ssam 			exch(t, ts, q.ch, r, rs);
84*17016Ssam 			exch(r, rs, s.ch, t, ts);
8510920Sshannon 
8610920Sshannon 			qs = (rs ? RLEAF : LLEAF);
8710920Sshannon 			ss = (ts ? RLEAF : LLEAF);
88*17016Ssam 			if (((r->fath.flags & qs) << rs) ^ ((t->fath.flags & ss) << ts)) {
89*17016Ssam 				r->fath.flags ^= qs;
90*17016Ssam 				t->fath.flags ^= ss;
9110920Sshannon 			}
9210920Sshannon 
93*17016Ssam 			t->count[ts]++;
94*17016Ssam 			r->count[rs]--;
95*17016Ssam 			qt->pt += ts;
9610920Sshannon 			r = t;
9710920Sshannon 			rs = ts;
9810920Sshannon 		}
9910920Sshannon 
10010920Sshannon 		if (rc == qc) {
101*17016Ssam 			r->top[rs] = qt;
10210920Sshannon 			if (rc > sc + 1) {
103*17016Ssam 				qt->next = st;
10410920Sshannon 				/* dispose of rt */
105*17016Ssam 				rt->next = flist;
10610920Sshannon 				flist = rt;
107*17016Ssam 			} else
108*17016Ssam 				st->pt = s.p;
109*17016Ssam 		} else if (rc == sc + 1) {
11010920Sshannon 			/* create new index at rt */
11110920Sshannon 			rt = NEW;
112*17016Ssam 			rt->next = st;
113*17016Ssam 			rt->pt = r;
114*17016Ssam 			qt->next = rt;
115*17016Ssam 			if (st)
116*17016Ssam 				st->pt = s.p;
117*17016Ssam 			r->top[rs] = rt;
11810920Sshannon 		}
119*17016Ssam 		rs = r->fath.flags & FBIT;
120*17016Ssam 		r = r->fath.fp;
12110920Sshannon 	} while (r);
122*17016Ssam 	dirp = head->next;
123*17016Ssam 	dirq = dirp->next;
12410920Sshannon }
12510920Sshannon 
126*17016Ssam exch(v, vs, x, w, ws)
127*17016Ssam 	struct node *v, *w;
128*17016Ssam 	union treep x;
129*17016Ssam 	int vs, ws;
13010920Sshannon {
13110920Sshannon 
132*17016Ssam 	if (v->fath.flags & (vs ? RLEAF : LLEAF)) {
133*17016Ssam 		in[x.ch].fp = w;
134*17016Ssam 		in[x.ch].flags &= ~01;
135*17016Ssam 		if (ws)
136*17016Ssam 			in[x.ch].flags |= ws;
137*17016Ssam 	} else {
138*17016Ssam 		x.p->fath.fp = w;
139*17016Ssam 		x.p->fath.flags &= ~01;
140*17016Ssam 		if (ws)
141*17016Ssam 			x.p->fath.flags |= ws;
14210920Sshannon 	}
14310920Sshannon }
144