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