|
|
1.1 ! root 1: #include "cbt.h" ! 2: #include "pr.h" ! 3: ! 4: typedef union { ! 5: ndaddr na; ! 6: lfaddr la; ! 7: } addr; ! 8: static char splitting[MXHT+1]; ! 9: extern bfile *curbf; ! 10: extern ndaddr oldnode(), newnode(); ! 11: extern char *malloc(); ! 12: ! 13: extern long brecwrite(); ! 14: ! 15: bwrite(bf, key, rec) mbuf key, rec; bfile *bf; ! 16: { addr u; ! 17: int n; ! 18: if(bf == NULL) ! 19: return(EOF); ! 20: if(!bf->rdwrt) { ! 21: errno = BNOWRITE; ! 22: return(EOF); ! 23: } ! 24: if(notran(bf)) ! 25: return(EOF); ! 26: if(key.mlen > MAXKLEN) ! 27: return(EOF); ! 28: if(!treeonly(bf)) { ! 29: u.la.llen = rec.mlen; ! 30: u.la.lloc = brecwrite(rec); ! 31: if(u.la.lloc == EOF) ! 32: return(EOF); ! 33: } ! 34: if(desce(bf, key, (private *)NULL) == EOF) ! 35: return(EOF); ! 36: n = xinsert(0, key, u); ! 37: (void) bseek(bf, key); ! 38: return(n); ! 39: } ! 40: ! 41: fixpath(bf) ! 42: bfile *bf; ! 43: { addr u; ! 44: hdr *b; ! 45: int i, n, j; ! 46: for(i = 0; i < bf->height; i++) { ! 47: if(!mustwrite(bf, i)) ! 48: continue; ! 49: n = bf->loc[i]; ! 50: if((u.na = oldnode(i)) == EOF) ! 51: return(EOF); ! 52: b = bf->path[i+1]; ! 53: for(j = 0; j <= b->kcnt; j++) ! 54: if(*ndadr(b, j) == n) ! 55: break; ! 56: if(j > b->kcnt){ /* curtains, the parent doesn't point to us */ ! 57: errno = BFATAL; ! 58: return(EOF); ! 59: } ! 60: *ndadr(b, j) = u.na; ! 61: mustwrite(bf, i + 1) = 1; ! 62: } ! 63: return(0); ! 64: } ! 65: ! 66: xinsert(lev, key, u) mbuf key; addr u; ! 67: { private x; ! 68: int n, dellen; ! 69: hdr *b = curbf->path[lev]; ! 70: char ba[NDSZ], bb[NDSZ]; ! 71: dkey *dx, *dy; ! 72: if(splitting[lev]) ! 73: if(desce(curbf, key, (private *)NULL) == EOF) ! 74: return(EOF); ! 75: n = xscan(b, key, &x); ! 76: if(x.match == FOUND) { ! 77: if(treeonly(curbf)) ! 78: return(FOUND); ! 79: else if(lev) ! 80: *ndadr(b, n) = u.na; ! 81: else ! 82: *lfadr(b, n) = u.la; ! 83: mustwrite(curbf, lev) = 1; ! 84: return(FOUND); ! 85: } ! 86: dx = (dkey *)ba; ! 87: dy = (dkey *)bb; ! 88: dellen = newx(&x, key, dx, dy); ! 89: if(lev) ! 90: dellen += sizeof(ndaddr); ! 91: else if(!treeonly(curbf)) ! 92: dellen += sizeof(lfaddr); ! 93: if(dellen > nfree(b)) { ! 94: if(nsplit(lev) == EOF) ! 95: return(EOF); ! 96: splitting[lev] = 1; ! 97: n = xinsert(lev, key, u); ! 98: splitting[lev] = 0; ! 99: return(n); ! 100: } ! 101: b = curbf->path[lev]; /* with thanks to brian meekings */ ! 102: addaddr(b, n, u); ! 103: newkeys(b, &x, dx, dy); ! 104: b->kcnt++; ! 105: nfree(b) -= dellen; ! 106: mustwrite(curbf, lev) = 1; ! 107: return(NOTFOUND); ! 108: } ! 109: ! 110: newx(x, key, c, d) private *x; mbuf key; dkey *c, *d; ! 111: { int i, j; ! 112: if(x->match != EOF) ! 113: c->dcom = x->ocom; ! 114: else c->dcom = x->ncom; ! 115: i = key.mlen - c->dcom; ! 116: c->dlen = DKEYSZ + i; ! 117: mvgbt(c->dkey, key.mdata + c->dcom, i); ! 118: if(x->match == EOF) ! 119: return(c->dlen); ! 120: j = x->ncom - x->d->dcom; ! 121: d->dcom = x->ncom; ! 122: d->dlen = x->d->dlen - j; ! 123: mvgbt(d->dkey, x->d->dkey + j, d->dlen - DKEYSZ); ! 124: return(c->dlen - j); ! 125: } ! 126: ! 127: addaddr(b, n, u) ! 128: hdr *b; ! 129: addr u; ! 130: { ! 131: if(b->hlev) { ! 132: mvgbt((char *)ndadr(b, b->kcnt + 1), ! 133: (char *)ndadr(b, b->kcnt), ! 134: sizeof(ndaddr) * (b->kcnt + 1 - n) ); ! 135: *ndadr(b, n) = u.na; ! 136: return; ! 137: } ! 138: if(treeonly(curbf)) ! 139: return; ! 140: mvgbt((char *)lfadr(b, b->kcnt), (char *)lfadr(b, b->kcnt - 1), ! 141: sizeof(lfaddr) * (b->kcnt - n)); ! 142: *lfadr(b, n) = u.la; ! 143: } ! 144: ! 145: newkeys(b, x, c, d) ! 146: hdr *b; ! 147: private *x; ! 148: dkey *c, *d; ! 149: { int n; ! 150: char *ffree; ! 151: if(b->hlev) ! 152: ffree = (char *)ndadr(b, b->kcnt) - nfree(b); ! 153: else if(treeonly(curbf)) ! 154: ffree = (char *)&nfree(b) - nfree(b); ! 155: else ! 156: ffree = (char *)lfadr(b, b->kcnt - 1) - nfree(b); ! 157: if(x->match != EOF) { ! 158: n = c->dlen + d->dlen; ! 159: n -= x->d->dlen; ! 160: mvgbt((char *)x->d + n, (char *)x->d, ffree - (char *)x->d); ! 161: mvgbt((char *)x->d, (char *)c, c->dlen); ! 162: mvgbt((char *)x->d + c->dlen, (char *)d, d->dlen); ! 163: } ! 164: else if(b->kcnt > 0) ! 165: mvgbt((char *)x->d + x->d->dlen, (char *)c, c->dlen); ! 166: else ! 167: mvgbt((char *)x->d, (char *)c, c->dlen); ! 168: } ! 169: ! 170: nsplit(lev) ! 171: { dkey *tod, *fromd; ! 172: char prefix[MAXKLEN + 10]; ! 173: hdr *b = curbf->path[lev]; ! 174: mbuf key; ! 175: addr u; ! 176: union { ! 177: lfaddr *la; ! 178: ndaddr *na; ! 179: } from, to; ! 180: int mvd, x, i, count, n; ! 181: hdr *ha; ! 182: char a[NDSZ]; ! 183: ! 184: x = (NDSZ - sizeof(hdr) - sizeof(trailer)) / 2; ! 185: ha = (hdr *) a; ! 186: mvd = count = 0; ! 187: tod = (dkey *)(ha + 1); ! 188: fromd = (dkey *)(b + 1); ! 189: if(lev == 0) { ! 190: to.la = lfadr(ha, 0); ! 191: from.la = lfadr(b, 0); ! 192: } ! 193: else { ! 194: to.na = ndadr(ha, 0); ! 195: from.na = ndadr(b, 0); ! 196: } ! 197: *ha = *b; ! 198: n = (b->kcnt + 1)/2; ! 199: if(lev && b->kcnt - n <= 1) ! 200: n--; ! 201: for(; count < n && mvd <= x; count++) { ! 202: mvgbt((char *)tod, (char *)fromd, fromd->dlen); ! 203: mvd += fromd->dlen; ! 204: tod = (dkey *)((char *)tod + fromd->dlen); ! 205: fromd = (dkey *)((char *)fromd + fromd->dlen); ! 206: if(lev) { ! 207: *to.na-- = *from.na--; ! 208: mvd += sizeof(ndaddr); ! 209: } ! 210: else if(!treeonly(curbf)) { ! 211: *to.la-- = *from.la--; ! 212: mvd += sizeof(lfaddr); ! 213: } ! 214: } ! 215: if(lev) { /* another pointer for non-leaves */ ! 216: *to.na-- = *from.na--; ! 217: mvd += sizeof(ndaddr); ! 218: } ! 219: ha->kcnt = count; ! 220: nfree(ha) = NDSZ - sizeof(hdr) - sizeof(trailer) - mvd; ! 221: /* if lev == 0, we promote the last key, else the next key */ ! 222: key.mlen = lastkey(ha, prefix); ! 223: if(lev) { ! 224: mvgbt(prefix + fromd->dcom, fromd->dkey, fromd->dlen - DKEYSZ); ! 225: key.mlen = fromd->dcom + fromd->dlen - DKEYSZ; ! 226: count++; ! 227: fromd = (dkey *)((char *)fromd + fromd->dlen); ! 228: } ! 229: u.na = newnode(ha); ! 230: if(u.na == EOF) { /* error while splitting */ ! 231: curbf->fatal++; ! 232: return(EOF); ! 233: } ! 234: key.mdata = prefix; ! 235: /* other half */ ! 236: if(lev == 0) ! 237: to.la = lfadr(ha, 0); ! 238: else ! 239: to.na = ndadr(ha, 0); ! 240: tod = (dkey *)(ha + 1); ! 241: tod->dcom = 0; ! 242: tod->dlen = fromd->dlen + fromd->dcom; ! 243: mvgbt(tod->dkey, prefix, fromd->dcom); ! 244: mvgbt(tod->dkey + fromd->dcom, fromd->dkey, fromd->dlen - DKEYSZ); ! 245: mvd = tod->dlen; ! 246: fromd = (dkey *)((char *)fromd + fromd->dlen); ! 247: tod = (dkey *)((char *)tod + tod->dlen); ! 248: if(lev) { ! 249: *to.na-- = *from.na--; ! 250: mvd += sizeof(ndaddr); ! 251: } ! 252: else if(!treeonly(curbf)) { ! 253: *to.la-- = *from.la--; ! 254: mvd += sizeof(lfaddr); ! 255: } ! 256: count++; ! 257: for(i = 1; count < b->kcnt; i++, count++) { ! 258: mvgbt((char *)tod, (char *)fromd, fromd->dlen); ! 259: mvd += fromd->dlen; ! 260: tod = (dkey *)((char *)tod + tod->dlen); ! 261: fromd = (dkey *)((char *)fromd + fromd->dlen); ! 262: if(lev) { ! 263: *to.na-- = *from.na--; ! 264: mvd += sizeof(ndaddr); ! 265: } ! 266: else if(!treeonly(curbf)) { ! 267: *to.la-- = *from.la--; ! 268: mvd += sizeof(lfaddr); ! 269: } ! 270: ! 271: } ! 272: if(lev) { ! 273: *to.na-- = *from.na--; ! 274: mvd += sizeof(ndaddr); ! 275: } ! 276: ha->kcnt = i; ! 277: nfree(ha) = NDSZ - sizeof(hdr) - sizeof(trailer) - mvd; ! 278: mvgbt((char *)b, (char *)ha, NDSZ); ! 279: mustwrite(curbf, lev) = 1; ! 280: if(lev < curbf->height) { ! 281: if(xinsert(lev + 1, key, u) == EOF) { ! 282: curbf->fatal++; ! 283: return(EOF); ! 284: } ! 285: } ! 286: else ! 287: return(newroot(u, key, b)); ! 288: return(0); ! 289: } ! 290: ! 291: newroot(u, key, b) ! 292: addr u; ! 293: mbuf key; ! 294: hdr *b; ! 295: { hdr *x; ! 296: dkey *d; ! 297: if(curbf->height >= MXHT) { ! 298: errno = BTALL; ! 299: curbf->fatal++; ! 300: return(EOF); ! 301: } ! 302: if((x = curbf->path[b->hlev + 1] = (hdr *)malloc(NDSZ)) == NULL) { ! 303: errno = BNOMEM; ! 304: curbf->fatal++; ! 305: return(EOF); ! 306: } ! 307: *x = *b; ! 308: x->hlev++; ! 309: d = (dkey *)(x + 1); ! 310: d->dlen = DKEYSZ + key.mlen; ! 311: d->dcom = 0; ! 312: mvgbt(d->dkey, key.mdata, key.mlen); ! 313: *ndadr(x, 0) = u.na; ! 314: *ndadr(x, 1) = curbf->loc[b->hlev] = newnode(b); ! 315: x->kcnt = 1; ! 316: nfree(x) = NDSZ - sizeof(hdr) - sizeof(trailer) - DKEYSZ ! 317: - key.mlen - 2 * sizeof(ndaddr); ! 318: mustwrite(curbf, ++curbf->height) = 1; ! 319: return(0); ! 320: } ! 321: ! 322: lastkey(b, s) ! 323: hdr *b; ! 324: char *s; ! 325: { int i, n; ! 326: dkey *p; ! 327: p = (dkey *)(b + 1); ! 328: for(n = i = 0; i < b->kcnt; i++) { ! 329: mvgbt(s + p->dcom, p->dkey, p->dlen - DKEYSZ); ! 330: n = p->dlen + p->dcom - DKEYSZ; ! 331: p = (dkey *)((char *) p + p->dlen); ! 332: } ! 333: return(n); ! 334: } ! 335: ! 336: static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:bwrite.c\n"}; ! 337: /*0010010000010101*/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.