1*14544Ssam #ifndef lint
2*14544Ssam static char sccsid[] = "@(#)tree.c	4.2 (Berkeley) 08/11/83";
3*14544Ssam #endif
410920Sshannon 
510920Sshannon #include "compact.h"
610920Sshannon 
710920Sshannon 
810920Sshannon insert (ch)
910920Sshannon int ch;
1010920Sshannon {
1110920Sshannon 	register struct node *pp;
1210920Sshannon 	register int c;
1310920Sshannon 	union cio d;
1410920Sshannon 	register struct index *qt, *wt;
1510920Sshannon 
1610920Sshannon 	c = ch;
1710920Sshannon 	wt = NEW;
1810920Sshannon 	pp = bottom++;
1910920Sshannon 	bottom -> fath . fp = pp;
2010920Sshannon 	in [c] . flags = (SEEN | FBIT);
2110920Sshannon 	d . integ = bottom -> sp [0] . ch = pp -> sp [1] . ch;
2210920Sshannon 	in [c] . fp = in [d . integ] . fp = pp -> sp [1] . p = wt -> pt = bottom;
2310920Sshannon 	bottom -> fath . flags = (LLEAF | RLEAF | FBIT);
2410920Sshannon 	pp -> fath . flags &= ~RLEAF;
2510920Sshannon 	in [d . integ] . flags = SEEN;
2610920Sshannon 
2710920Sshannon 	bottom -> count [0] = pp -> count [1];
2810920Sshannon 	qt = pp -> top [1];
2910920Sshannon 	bottom -> top [0] = qt;
3010920Sshannon 	bottom -> sp [1] . ch = c;
3110920Sshannon 	bottom -> count [1] = 0;
3210920Sshannon 	bottom -> top [1] = qt -> next = wt;
3310920Sshannon 	wt -> next = NULL;
3410920Sshannon }
3510920Sshannon 
3610920Sshannon uptree (ch)
3710920Sshannon int ch;
3810920Sshannon {
3910920Sshannon 	register struct node *r;
4010920Sshannon 	union treep q, s;
4110920Sshannon 	int rs, qs, ss, ts;
4210920Sshannon 	longint rc, qc, sc;
4310920Sshannon 	struct node *t;
4410920Sshannon 	register struct index *rt, *qt, *st;
4510920Sshannon 
4610920Sshannon 	r = in [ch] . fp;
4710920Sshannon 	rs = in [ch] . flags & FBIT;
4810920Sshannon 
4910920Sshannon 	do {
5010920Sshannon 		(r -> count [rs])++;
5110920Sshannon 		rc = r -> count [rs];
5210920Sshannon 		rt = r -> top [rs];
5310920Sshannon 
5410920Sshannon 		for ( ; ; ) {
5510920Sshannon 			qs = ss = 1 - rs;
5610920Sshannon 			s . p = r + rs;
5710920Sshannon 			sc = (s . p) -> count [ss];
5810920Sshannon 			st = (s . p) -> top [ss];
5910920Sshannon 
6010920Sshannon 			if (rs)
6110920Sshannon 				if (r == bottom) {
6210920Sshannon 					sc = rc - 2;
6310920Sshannon 					st = NULL;
6410920Sshannon 				}
6510920Sshannon 				else;
6610920Sshannon 			else if (r == dict) {
6710920Sshannon 				qc = rc + 1;
6810920Sshannon 				qt = head;
6910920Sshannon 				break;
7010920Sshannon 			}
7110920Sshannon 
7210920Sshannon 			q . p = r - qs;
7310920Sshannon 			qc = (q . p) -> count [qs];
7410920Sshannon 			qt = (q . p) -> top [qs];
7510920Sshannon 			if (rc <= qc) break;
7610920Sshannon 
7710920Sshannon 			t = qt -> pt;
7810920Sshannon 			ts = (rc <= t -> count [0] ? 1 : 0);
7910920Sshannon 
8010920Sshannon 			/* exchange pointers of (t, ts) and (r, rs) */
8110920Sshannon 
8210920Sshannon 			q . ch = t -> sp [ts] . ch;	/*  {					*/
8310920Sshannon 			s . ch = r -> sp [rs] . ch;	/*  {					*/
8410920Sshannon 			t -> sp [ts] . ch = s . ch;	/*  {					*/
8510920Sshannon 			r -> sp [rs] . ch = q . ch;	/*  { change code when Cory gets v. 7	*/
8610920Sshannon 							/*  {					*/
8710920Sshannon 			exch (t, ts, q . ch, r, rs);	/*  {					*/
8810920Sshannon 			exch (r, rs, s . ch, t, ts);	/*  {					*/
8910920Sshannon 
9010920Sshannon 			qs = (rs ? RLEAF : LLEAF);
9110920Sshannon 			ss = (ts ? RLEAF : LLEAF);
9210920Sshannon 			if (((r -> fath . flags & qs) << rs) ^ ((t -> fath . flags & ss) << ts)) {
9310920Sshannon 				r -> fath . flags ^= qs;
9410920Sshannon 				t -> fath . flags ^= ss;
9510920Sshannon 			}
9610920Sshannon 
9710920Sshannon 			(t -> count [ts])++;
9810920Sshannon 			(r -> count [rs])--;
9910920Sshannon 			(qt -> pt) += ts;
10010920Sshannon 			r = t;
10110920Sshannon 			rs = ts;
10210920Sshannon 		}
10310920Sshannon 
10410920Sshannon 		if (rc == qc) {
10510920Sshannon 			r -> top [rs] = qt;
10610920Sshannon 			if (rc > sc + 1) {
10710920Sshannon 				qt -> next = st;
10810920Sshannon 
10910920Sshannon 				/* dispose of rt */
11010920Sshannon 
11110920Sshannon 				rt -> next = flist;
11210920Sshannon 				flist = rt;
11310920Sshannon 			}
11410920Sshannon 			else st -> pt = s . p;
11510920Sshannon 		}
11610920Sshannon 
11710920Sshannon 		else if (rc == sc + 1) {
11810920Sshannon 
11910920Sshannon 			/* create new index at rt */
12010920Sshannon 
12110920Sshannon 			rt = NEW;
12210920Sshannon 			rt -> next = st;
12310920Sshannon 			rt -> pt = r;
12410920Sshannon 			qt -> next = rt;
12510920Sshannon 			if (st) st -> pt = s . p;
12610920Sshannon 			r -> top [rs] = rt;
12710920Sshannon 		}
12810920Sshannon 
12910920Sshannon 		rs = r -> fath . flags & FBIT;
13010920Sshannon 		r = r -> fath . fp;
13110920Sshannon 
13210920Sshannon 	} while (r);
13310920Sshannon 	dirp = head -> next;
13410920Sshannon 	dirq = dirp -> next;
13510920Sshannon }
13610920Sshannon 
13710920Sshannon exch (v, vs, x, w, ws)
13810920Sshannon struct node *v, *w;
13910920Sshannon union treep x;
14010920Sshannon int vs, ws;
14110920Sshannon {
14210920Sshannon 
14310920Sshannon 	if (v -> fath . flags & (vs ? RLEAF : LLEAF)) {
14410920Sshannon 		in [x . ch] . fp = w;
14510920Sshannon 		in [x . ch] . flags &= ~01;
14610920Sshannon 		if (ws) in [x . ch] . flags |= ws;
14710920Sshannon 	}
14810920Sshannon 	else {
14910920Sshannon 		(x . p) -> fath . fp = w;
15010920Sshannon 		(x . p) -> fath . flags &= ~01;
15110920Sshannon 		if (ws) (x . p) -> fath . flags |= ws;
15210920Sshannon 	}
15310920Sshannon }
154