|
|
1.1 ! root 1: # To unbundle, sh this file ! 2: echo be.h 1>&2 ! 3: sed 's/.//' >be.h <<'//GO.SYSIN DD be.h' ! 4: -#define BERROR 100 /* first btree value of errno */ ! 5: -#define BUTRAN BERROR + 0 /* user caused tran abort */ ! 6: -#define BNOWRITE BERROR + 1 /* not opened for writing */ ! 7: -#define BIOWRT BERROR + 2 /* wrote short record */ ! 8: -#define BNOMEM BERROR + 3 /* no mem from malloc */ ! 9: -#define BFATAL BERROR + 4 /* last chance for user */ ! 10: -#define BTALL BERROR + 5 /* tree becoming taller than MXHT */ ! 11: -#define BLASTE BERROR + 6 /* one past last btree value of errno */ ! 12: -extern int errno; ! 13: -/*0101010011100100*/ ! 14: //GO.SYSIN DD be.h ! 15: echo cbt.h 1>&2 ! 16: sed 's/.//' >cbt.h <<'//GO.SYSIN DD cbt.h' ! 17: -#ifdef TEST ! 18: -#define NDSZ 64 ! 19: -#else ! 20: -#define NDSZ 1024/* for real systems (larger may be slower) */ ! 21: -#endif ! 22: -#define MAXKLEN (NDSZ/4)-8 ! 23: -#if MAXKLEN > 255 ! 24: -#undef MAXKLEN ! 25: -#define MAXKLEN 255 ! 26: -#endif ! 27: -#define MXHT 5 ! 28: -typedef long ndaddr; ! 29: -/* for communication with users */ ! 30: -typedef struct { ! 31: - char *mdata; ! 32: - unsigned short mlen; ! 33: -} mbuf; ! 34: -typedef struct bfile { ! 35: - struct bfile *next; ! 36: - struct hdr *path[MXHT + 1]; ! 37: - char height, advnc, rdwrt, flag[MXHT + 1]; ! 38: - ndaddr loc[MXHT + 1]; ! 39: - int tfd, dfd; ! 40: - char *fname, *altname; ! 41: - struct rdptr { ! 42: - struct dkey *rptr; /* current dkey */ ! 43: - short rnum; /* its ordinal */ ! 44: - char rpref[MAXKLEN]; /* first dcom bytes of its key */ ! 45: - } rdptr; ! 46: - char fatal; /* this bfile can't be used */ ! 47: -} bfile; ! 48: -extern bfile *bopen(); ! 49: -extern mbuf bkey(); ! 50: - ! 51: -#define BERROR 100 /* first btree value of errno */ ! 52: -#define BUTRAN BERROR + 0 /* user caused tran abort */ ! 53: -#define BNOWRITE BERROR + 1 /* not opened for writing */ ! 54: -#define BIOWRT BERROR + 2 /* wrote short record */ ! 55: -#define BNOMEM BERROR + 3 /* no mem from malloc */ ! 56: -#define BFATAL BERROR + 4 /* last chance for user */ ! 57: -#define BTALL BERROR + 5 /* tree becoming taller than MXHT */ ! 58: -#define BRDERR BERROR + 6 /* read short record or read error */ ! 59: -#define BLASTE BERROR + 7 /* one past last btree value of errno */ ! 60: -extern int errno; ! 61: - ! 62: -/* users can ignore the rest of this stuff */ ! 63: -/* keys in nodes */ ! 64: -typedef struct dkey { ! 65: - unsigned char dlen; /* total size of structure */ ! 66: - char dcom; /* bytes in common with preceding */ ! 67: - char dkey[MAXKLEN]; /* rest of key */ ! 68: -} dkey; ! 69: -#define DKEYSZ 2 /* overhead in dkey */ ! 70: -/* node header */ ! 71: -typedef struct hdr { ! 72: - long hstamp; /* for owning process */ ! 73: - short kcnt; /* keys in node */ ! 74: - char htype; ! 75: - char hlev; ! 76: -} hdr; ! 77: -typedef struct { ! 78: - short tfree; /* free bytes in node, at end for triv checking */ ! 79: -} trailer; ! 80: -#define nfree(p) ((trailer *)((char *)(p) + NDSZ - sizeof(trailer)))->tfree ! 81: -#define SHARED 1 ! 82: -#define INDEX 2 ! 83: -#define READONLY 4 ! 84: -#define bf_type(b, t) ((b)->path[0]->htype & (t)) ! 85: -#define treeonly(b) bf_type(b, INDEX) ! 86: -#define shared(b) bf_type(b, SHARED) ! 87: -#define readonly(b) bf_type(b, READONLY) ! 88: -/* disk addresses */ ! 89: -typedef struct { ! 90: - long lloc; ! 91: - unsigned short llen; ! 92: -} lfaddr; ! 93: -#define ndadr(b, j) ((ndaddr *)((char *)(b) + NDSZ - sizeof(trailer)) - (j) - 1) ! 94: -#define lfadr(b, j) ((lfaddr *)((char *)(b) + NDSZ - sizeof(trailer)) - (j) - 1) ! 95: -#define mustwrite(bf, n) bf->flag[n] /* for getincore */ ! 96: -/* node format: ! 97: - * hdr, dkey, dkey, dkey, ..., space, adr, adrn, ..., adr0, trailer ! 98: - */ ! 99: -extern int bdump; /* dump on first fatal error */ ! 100: -extern long tranid, getlpid(); /* unique transaction id */ ! 101: -#ifndef EOF ! 102: -#ifndef NULL ! 103: -#define NULL 0 ! 104: -#endif ! 105: -#define EOF -1 ! 106: -#endif ! 107: -#define NOTFOUND 0 ! 108: -#define FOUND 1 ! 109: - ! 110: -#define alloc(x) (x *)malloc(sizeof(x)) ! 111: -#define stamped(b) b->hstamp == tranid ! 112: -/*1000001111101111*/ ! 113: //GO.SYSIN DD cbt.h ! 114: echo pr.h 1>&2 ! 115: sed 's/.//' >pr.h <<'//GO.SYSIN DD pr.h' ! 116: -typedef struct { ! 117: - short match; /* FOUND, NOTFOUND, or EOF */ ! 118: - unsigned char ncom, /* len of prefix in common with d */ ! 119: - ocom; /* len for predecessor of d */ ! 120: - dkey *d; /* first key >= requested */ ! 121: - /* or, if match==EOF, last in node */ ! 122: -} private; ! 123: -/*0111110111010100*/ ! 124: //GO.SYSIN DD pr.h ! 125: echo bdelete.c 1>&2 ! 126: sed 's/.//' >bdelete.c <<'//GO.SYSIN DD bdelete.c' ! 127: -#include "cbt.h" ! 128: -#include "pr.h" ! 129: - ! 130: -extern bfile *curbf; ! 131: -bdelete(bf, key) bfile *bf; mbuf key; ! 132: -{ dkey *dold, *dnew; ! 133: - hdr *b; ! 134: - int svlen, dellen; ! 135: - char *ffree; ! 136: - ! 137: - if(bf == NULL) ! 138: - return(EOF); ! 139: - if(notran(bf)) ! 140: - return(EOF); ! 141: - if(!bf->rdwrt) { ! 142: - errno = BNOWRITE; ! 143: - return(EOF); ! 144: - } ! 145: - if(bseek(bf, key) != FOUND) ! 146: - return(NOTFOUND); ! 147: - b = bf->path[0]; ! 148: - dold = bf->rdptr.rptr; ! 149: - if(bf->rdptr.rnum + 1 >= b->kcnt) { ! 150: - nfree(b) += dold->dlen + (treeonly(bf)? 0: sizeof(lfaddr)); ! 151: - --b->kcnt; ! 152: - mustwrite(bf, 0) = 1; ! 153: - if(b->hlev == 0 && b->kcnt <= 0 || b->hlev > 0 && b->kcnt < 0) { ! 154: - mustwrite(bf, 0) = 0; ! 155: - ndelete(1, key); ! 156: - } ! 157: - if(b->kcnt < 0) ! 158: - b->kcnt = 0; ! 159: - (void) bseek(bf, key); ! 160: - return(FOUND); ! 161: - } ! 162: - ! 163: - if(treeonly(bf)) ! 164: - ffree = (char *)&nfree(b) - nfree(b); ! 165: - else ! 166: - ffree = (char *)lfadr(b, b->kcnt - 1) - nfree(b); ! 167: - svlen = dold->dlen; ! 168: - dnew = (dkey *)((char *)dold + dold->dlen); ! 169: - if(dnew->dcom <= dold->dcom) { ! 170: - mvgbt((char *)dold, (char *)dnew, ffree - (char *)dnew); ! 171: - if(!treeonly(bf)) ! 172: - rmlfadr(b, bf->rdptr.rnum); ! 173: - b->kcnt--; ! 174: - mustwrite(bf, 0) = 1; ! 175: - nfree(b) += svlen + (treeonly(bf)? 0: sizeof(lfaddr)); ! 176: - (void) bseek(bf, key); ! 177: - return(FOUND); ! 178: - } ! 179: - dellen = dnew->dcom - dold->dcom; ! 180: - /* writing over dold */ ! 181: - dold->dlen = dnew->dlen + dellen; ! 182: - mvgbt(dold->dkey + dellen, dnew->dkey, ffree - dnew->dkey); ! 183: - if(!treeonly(bf)) ! 184: - rmlfadr(b, bf->rdptr.rnum); ! 185: - b->kcnt--; ! 186: - mustwrite(bf, 0) = 1; ! 187: - nfree(b) += svlen - dellen + (treeonly(bf)? 0: sizeof(lfaddr)); ! 188: - (void) bseek(bf, key); ! 189: - return(FOUND); ! 190: -} ! 191: -rmlfadr(b, n) hdr *b; unsigned int n; ! 192: -{ ! 193: - mvgbt((char *)lfadr(b, b->kcnt - 2), (char *)lfadr(b, b->kcnt - 1), ! 194: - (int)sizeof(lfaddr) * (b->kcnt - 1 - n)); ! 195: -} ! 196: -rmndadr(b, n) hdr *b; unsigned short n; ! 197: -{ ! 198: - mvgbt((char *)ndadr(b, b->kcnt - 1), (char *)ndadr(b, b->kcnt), ! 199: - (int)sizeof(ndaddr) * (b->kcnt - n)); ! 200: -} ! 201: -ndelete(lev, key) mbuf key; ! 202: -{ hdr *b; ! 203: - int svlen, dellen; ! 204: - unsigned short n; ! 205: - private x; ! 206: - char *ffree; ! 207: - dkey *dold, *dnew; ! 208: - if(lev > curbf->height) { ! 209: - b = curbf->path[curbf->height]; ! 210: - b->hlev = 0; ! 211: - curbf->height = 0; ! 212: - mustwrite(curbf, 0) = 1; ! 213: - curbf->loc[0] = 0; ! 214: - nfree(b) = NDSZ - sizeof(hdr) - sizeof(trailer); ! 215: - b->kcnt = 0; ! 216: - mvgbt((char *)curbf->path[0], (char *)b, NDSZ); ! 217: - return; ! 218: - } ! 219: - b = curbf->path[lev]; ! 220: - n = xscan(b, key, &x); ! 221: - if(x.match == EOF) { ! 222: - if(b->kcnt <= 0) { ! 223: - mustwrite(curbf, lev) = 0; ! 224: - ndelete(lev+1, key); ! 225: - return; ! 226: - } ! 227: - b->kcnt--; ! 228: - nfree(b) += sizeof(ndaddr) + x.d->dlen; ! 229: - mustwrite(curbf, lev) = 1; ! 230: - return; ! 231: - } ! 232: - dold = x.d; ! 233: - dnew = (dkey *)((char *)dold + dold->dlen); ! 234: - ffree = (char *)ndadr(b, b->kcnt) - nfree(b); ! 235: - svlen = dold->dlen; ! 236: - if(n + 1 >= b->kcnt || dnew->dcom <= dold->dcom) { ! 237: - mvgbt((char *)dold, (char *)dnew, ffree - (char *)dnew); ! 238: - rmndadr(b, n); ! 239: - b->kcnt--; ! 240: - mustwrite(curbf, lev) = 1; ! 241: - nfree(b) += sizeof(ndaddr) + svlen; ! 242: - return; ! 243: - } ! 244: - dellen = dnew->dcom - dold->dcom; ! 245: - /* writing over dold */ ! 246: - dold->dlen = dnew->dlen + dellen; ! 247: - mvgbt(dold->dkey + dellen, dnew->dkey, ffree - dnew->dkey); ! 248: - rmndadr(b, n); ! 249: - b->kcnt--; ! 250: - mustwrite(curbf, lev) = 1; ! 251: - nfree(b) += sizeof(ndaddr) + svlen - dellen; ! 252: -} ! 253: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:bdelete.c\n"}; ! 254: -/*1101110100011001*/ ! 255: //GO.SYSIN DD bdelete.c ! 256: echo bt.c 1>&2 ! 257: sed 's/.//' >bt.c <<'//GO.SYSIN DD bt.c' ! 258: -#include "cbt.h" ! 259: -#include "pr.h" ! 260: - ! 261: -bfile *curbf; ! 262: -extern bfile *newtran(); ! 263: -extern char *malloc(), *strcpy(); ! 264: -extern long lseek(); ! 265: - ! 266: -bfile *bopen(s, typ) char *s; /* typ is 0 or 2 */ ! 267: -{ bfile *p; ! 268: - int n, i; ! 269: - ! 270: - p = alloc(bfile); ! 271: - if(p == NULL) ! 272: - goto nomem; ! 273: - n = strlen(s); ! 274: - p->fname = malloc((unsigned)n + 3); ! 275: - if(p->fname == NULL) ! 276: - goto nomem; ! 277: - (void) strcpy(p->fname, s); ! 278: - strcpy(p->fname + n, ".T"); ! 279: - if((p->tfd = open(p->fname, typ)) == -1) { ! 280: - free(p->fname); ! 281: - free((char *)p); ! 282: - return(NULL); ! 283: - } ! 284: - p->rdwrt = typ; ! 285: - p->fatal = p->advnc = 0; ! 286: - p->altname = NULL; ! 287: - for(i = 0; i <= MXHT; i++) { ! 288: - p->path[i] = NULL; ! 289: - p->flag[i] = 0; ! 290: - p->loc[i] = 0; ! 291: - } ! 292: - p->path[0] = (hdr *)malloc(NDSZ); ! 293: - if(p->path[0] == NULL) ! 294: - goto nomem; ! 295: - curbf = p; ! 296: - if(ndrd(0, (ndaddr)0) == EOF) ! 297: - return(NULL); ! 298: - strcpy(p->fname + n, ".F"); ! 299: - if(!treeonly(p) && (p->dfd = open(p->fname, typ)) == -1) { ! 300: - (void) close(p->tfd); ! 301: - free(p->fname); ! 302: - free((char *) p->path[0]); ! 303: - free((char *)p); ! 304: - return(NULL); ! 305: - } ! 306: - else if(treeonly(p)) ! 307: - p->dfd = -1; ! 308: - p->fname[n] = 0; ! 309: - if(shared(p)) ! 310: - return(newtran(p)); ! 311: - else if(tranid == 0) ! 312: - tranid = getlpid(); ! 313: - p->height = p->path[0]->hlev; ! 314: - for(n = 1; n <= p->height; n++) ! 315: - if((p->path[n] = (hdr *)malloc(NDSZ)) == NULL) ! 316: - goto nomem; ! 317: - if(p->height > 0) ! 318: - mvgbt((char *)p->path[p->height], (char *)p->path[0], NDSZ); ! 319: - (void) bfirst(p); ! 320: - return(p); ! 321: -nomem: ! 322: - errno = BNOMEM; ! 323: - return(NULL); ! 324: -} ! 325: - ! 326: -bseek(bf, key) bfile *bf; mbuf key; ! 327: -{ private m; ! 328: - int i; ! 329: - if(bf == NULL) ! 330: - return(EOF); ! 331: - if(notran(bf)) ! 332: - return(EOF); ! 333: - if(!readonly(bf)) ! 334: - for(i = 0; i < bf->height; i++) ! 335: - if(mustwrite(bf, i)) ! 336: - if(fixpath(bf) == EOF) ! 337: - return(EOF); ! 338: - bf->rdptr.rnum = desce(bf, key, &m); ! 339: - if(bf->rdptr.rnum == EOF) ! 340: - return(EOF); ! 341: - bf->advnc = 0; ! 342: - bf->rdptr.rptr = m.d; ! 343: - if(m.match == EOF) { ! 344: - if(advance() == EOF) ! 345: - return(EOF); ! 346: - if(bf->rdptr.rptr != NULL) ! 347: - m.match = NOTFOUND; ! 348: - } ! 349: - if(m.match != EOF) ! 350: - mvgbt(bf->rdptr.rpref, key.mdata, bf->rdptr.rptr->dcom); ! 351: - /* maybe use rptr instead of m.d */ ! 352: - return(m.match); ! 353: -} ! 354: - ! 355: -bfirst(bf) bfile *bf; ! 356: -{ mbuf key; ! 357: - key.mlen = 0; ! 358: - return(bseek(bf, key)); ! 359: -} ! 360: - ! 361: -bclose(bf) bfile *bf; ! 362: -{ int i; ! 363: - if(bf == NULL) ! 364: - return; ! 365: - if(shared(bf)) { ! 366: - if(intran()) ! 367: - trabort(); ! 368: - rmtran(bf); ! 369: - } ! 370: - else ! 371: - bflush(bf); ! 372: - free(bf->fname); ! 373: - for(i = 0; i <= MXHT; i++) ! 374: - if(bf->path[i] != NULL) ! 375: - free((char *)bf->path[i]); ! 376: - if(bf->tfd != -1) ! 377: - (void) close(bf->tfd); ! 378: - if(bf->dfd != -1) ! 379: - (void) close(bf->dfd); ! 380: - free((char *)bf); ! 381: -} ! 382: - ! 383: -bflush(bf) bfile *bf; ! 384: -{ int i; ! 385: - if(bf == NULL) ! 386: - return(0); ! 387: - if(!bf->rdwrt) { ! 388: - errno = BNOWRITE; ! 389: - return(EOF); ! 390: - } ! 391: - curbf = bf; ! 392: - if(shared(bf)) ! 393: - if(intran()) { ! 394: - trabort(); ! 395: - return(EOF); ! 396: - } ! 397: - else return(0); ! 398: - for(i = 0; i <= bf->height; i++) { ! 399: - if(!mustwrite(bf, i)) ! 400: - continue; ! 401: - if(readonly(bf) || i == bf->height) ! 402: - if(ndwrt(bf->path[i], bf->loc[i]) == EOF) ! 403: - return(EOF); ! 404: - else ! 405: - if(fixpath(bf) == EOF) ! 406: - return(EOF); ! 407: - bf->flag[i] = 0; ! 408: - } ! 409: - return(0); ! 410: -} ! 411: - ! 412: -breclen(bf) bfile *bf; ! 413: -{ ! 414: - if(bf == NULL) ! 415: - return(EOF); ! 416: - if(notran(bf)) ! 417: - return(EOF); ! 418: - if(bf->advnc) ! 419: - if(advance() == EOF) ! 420: - return(EOF); ! 421: - if(bf->rdptr.rnum >= bf->path[0]->kcnt) ! 422: - return(EOF); ! 423: - if(treeonly(bf)) ! 424: - return(0); ! 425: - return(lfadr(bf->path[0], bf->rdptr.rnum)->llen); ! 426: -} ! 427: - ! 428: -mbuf bkey(bf) bfile *bf; ! 429: -{ mbuf x; ! 430: - dkey *d; ! 431: - if(bf == NULL) ! 432: - goto eof; ! 433: - if(notran(bf)) ! 434: - goto eof; ! 435: - if(bf->advnc) ! 436: - if(advance() == EOF) ! 437: - goto eof; ! 438: - if(bf->rdptr.rnum >= bf->path[0]->kcnt) ! 439: - goto eof; ! 440: - d = bf->rdptr.rptr; ! 441: - x.mlen = d->dlen - DKEYSZ + d->dcom; ! 442: - mvgbt(bf->rdptr.rpref + d->dcom, d->dkey, d->dlen-DKEYSZ); ! 443: - x.mdata = bf->rdptr.rpref; ! 444: - return(x); ! 445: -eof: ! 446: - x.mlen = 0; ! 447: - x.mdata = NULL; ! 448: - return(x); ! 449: -} ! 450: - ! 451: -bread(bf, key, rec) bfile *bf; mbuf *key, *rec; ! 452: -{ ! 453: - dkey *d; ! 454: - lfaddr *x; ! 455: - int n; ! 456: - if(bf == NULL) ! 457: - return(NULL); ! 458: - if(notran(bf)) ! 459: - return(EOF); ! 460: - if(bf->advnc) ! 461: - if(advance() == EOF) ! 462: - return(EOF); ! 463: - if(bf->rdptr.rnum >= bf->path[0]->kcnt) ! 464: - return(EOF); ! 465: - if(key != NULL) { ! 466: - d = bf->rdptr.rptr; ! 467: - key->mlen = d->dlen - DKEYSZ + d->dcom; ! 468: - mvgbt(key->mdata, bf->rdptr.rpref, d->dcom); ! 469: - mvgbt(key->mdata + d->dcom, d->dkey, d->dlen - DKEYSZ); ! 470: - } ! 471: - if(rec != NULL && !treeonly(bf)) { ! 472: - x = lfadr(bf->path[0], bf->rdptr.rnum); ! 473: - rec->mlen = x->llen; ! 474: - if(rec->mlen != 0) { ! 475: - (void) lseek(bf->dfd, x->lloc, 0); ! 476: - if((n = read(bf->dfd, rec->mdata, (int)rec->mlen)) ! 477: - != rec->mlen) { ! 478: - if(n >= 0) ! 479: - errno = BRDERR; ! 480: - return(EOF); ! 481: - } ! 482: - } ! 483: - } ! 484: - bf->advnc = 1; ! 485: - return(0); ! 486: -} ! 487: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:bt.c\n"}; ! 488: -/*0001011110110101*/ ! 489: //GO.SYSIN DD bt.c ! 490: echo btadd.c 1>&2 ! 491: sed 's/.//' >btadd.c <<'//GO.SYSIN DD btadd.c' ! 492: -#include "stdio.h" ! 493: -#include "cbt.h" ! 494: - ! 495: -/* like btbuild, but random access */ ! 496: -char keybuf[NDSZ]; ! 497: -char recbuf[32767]; ! 498: -mbuf key = { keybuf, 0}; ! 499: -mbuf rec = { recbuf, 0}; ! 500: -bfile *bf; ! 501: -int cflag; ! 502: - ! 503: -main(argc, argv) ! 504: -char **argv; ! 505: -{ int n; ! 506: - if(argv[1][0] == '-') { ! 507: - cflag++; ! 508: - argc--; ! 509: - argv++; ! 510: - } ! 511: - if(argc != 2) { ! 512: - fprintf(stderr, "usage: btadd bfile < recs\n"); ! 513: - exit(1); ! 514: - } ! 515: - if((bf = bopen(argv[1], 2)) == NULL) { ! 516: - perror(argv[1]); ! 517: - exit(1); ! 518: - } ! 519: - for(;;) { ! 520: - get(2, (char *)&key.mlen); ! 521: - if(key.mlen > MAXKLEN) { ! 522: - fprintf(stderr, "key too long\n"); ! 523: - exit(1); ! 524: - } ! 525: - get(key.mlen, key.mdata); ! 526: - get(2, (char *)&rec.mlen); ! 527: - if(rec.mlen > sizeof(recbuf)) { ! 528: - fprintf(stderr, "rec len %ud: recompile btadd\n", ! 529: - rec.mlen); ! 530: - abort(); ! 531: - } ! 532: - get(rec.mlen, rec.mdata); ! 533: - (void)bwrite(bf, key, rec); ! 534: - bfirst(bf); ! 535: - if(bseek(bf, key) != FOUND) { ! 536: - key.mdata[key.mlen] = 0; ! 537: - fprintf(stderr, "vanished:%s:\n", key.mdata); ! 538: - abort(); ! 539: - } ! 540: - if(cflag) ! 541: - bcheck(bf); ! 542: - } ! 543: -} ! 544: -get(n, s) ! 545: -char *s; ! 546: -{ int m; ! 547: - for(m = 0; n > 0; n -= m) { ! 548: - m = read(0, s, n); ! 549: - if(m == 0) { ! 550: - bclose(bf); ! 551: - exit(0); ! 552: - } ! 553: - if(m < 0) { ! 554: - fprintf(stderr, "io error in btadd\n"); ! 555: - abort(); ! 556: - } ! 557: - s += m; ! 558: - } ! 559: -} ! 560: - ! 561: -mbuf new, old; ! 562: -char newbuf[NDSZ], oldbuf[NDSZ]; ! 563: -bcheck(bf) ! 564: -bfile *bf; ! 565: -{ long i; ! 566: - int j, k; ! 567: - char *p; ! 568: - bfirst(bf); ! 569: - new.mdata = newbuf; ! 570: - old.mdata = oldbuf; ! 571: - for(i = 0;; i++) { ! 572: - if(bread(bf, &new, (mbuf *)NULL) == EOF) ! 573: - break; ! 574: - if(i > 0) { ! 575: - k = new.mlen; ! 576: - if(old.mlen < new.mlen) ! 577: - k = old.mlen; ! 578: - for(j = 0; j < k; j++) ! 579: - if(new.mdata[j] != old.mdata[j]) ! 580: - break; ! 581: - if(j != k) { ! 582: - if(new.mdata[j] > old.mdata[j]) ! 583: - continue; ! 584: -bad: ! 585: - fprintf(stderr, "disorder at key %ld\n", i); ! 586: - key.mdata[key.mlen] = 0; ! 587: - fprintf(stderr, "key is:%s:\n", key.mdata); ! 588: - abort(); ! 589: - } ! 590: - if(old.mlen >= new.mlen) ! 591: - goto bad; ! 592: - } ! 593: - p = old.mdata; ! 594: - old = new; ! 595: - new.mdata = p; ! 596: - } ! 597: -} ! 598: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/25:btadd.c\n"}; ! 599: -/*1100001100101101*/ ! 600: //GO.SYSIN DD btadd.c ! 601: echo btbuild.c 1>&2 ! 602: sed 's/.//' >btbuild.c <<'//GO.SYSIN DD btbuild.c' ! 603: -#include "stdio.h" ! 604: -#include "cbt.h" ! 605: -#define SZ MXHT+1 ! 606: - ! 607: -typedef struct { ! 608: - unsigned short mlen; ! 609: - char mdata[NDSZ]; /* max size of values */ ! 610: -} xbuf; ! 611: -int address[SZ]; /* where the next address goes in the node */ ! 612: -xbuf curkey[SZ]; /* last key put in the node */ ! 613: -xbuf shortone; /* for compression */ ! 614: -int freecnt[SZ]; /* number of bytes left in node */ ! 615: -dkey *kp[SZ]; /* where to put next dkey in node */ ! 616: -char node[SZ][NDSZ]; /* the nodes */ ! 617: -char used[SZ+1]; /* which nodes have been used */ ! 618: -xbuf nkey; /* as read by getrec */ ! 619: -struct { ! 620: - unsigned short mlen; ! 621: - char mdata[32767]; ! 622: -} val; ! 623: -lfaddr currec; /* where getrec put val */ ! 624: -FILE *tfd, *dfd; ! 625: -char name[16]; ! 626: -int type; ! 627: -long reccnt; ! 628: -extern char *malloc(); ! 629: - ! 630: -char * ! 631: -prkey(a) ! 632: -xbuf *a; ! 633: -{ int i; ! 634: - unsigned char c; ! 635: - static char buf[4*NDSZ], *p; ! 636: - for(i = 0, p = buf; i < a->mlen; i++) { ! 637: - c = a->mdata[i]; ! 638: - if(c < ' ') { ! 639: - *p++ = '^'; ! 640: - c += ' '; ! 641: - } ! 642: - if(c < 127) ! 643: - *p++ = (char)c; ! 644: - else { ! 645: - *p++ = '\\'; ! 646: - *p++ = (c >> 6) + '0'; ! 647: - *p++ = ((c&63)>>3) + '0'; ! 648: - *p++ = c&7 + '0'; ! 649: - } ! 650: - } ! 651: - *p++ = 0; ! 652: - return(buf); ! 653: -} ! 654: -pref(a, b, lev) xbuf *a, *b; ! 655: -{ register int n; ! 656: - register char *p, *q; ! 657: - for(n = 0, p = a->mdata, q = b->mdata; n < a->mlen && n < b->mlen; n++) ! 658: - if(*p++ != *q++) ! 659: - break; ! 660: - p--, q--; ! 661: - if(lev == 0 && ((n == b->mlen && n >= a->mlen) || *p > *q)) { ! 662: - fprintf(stderr, "key %ld out of order:\n", reccnt); ! 663: - fprintf(stderr, "key %ld is %s\n", reccnt - 1, prkey(a)); ! 664: - fprintf(stderr, "key %ld is %s\n", reccnt, prkey(b)); ! 665: - } ! 666: - return(n); ! 667: -} ! 668: - ! 669: -getrec() ! 670: -{ ! 671: - reccnt++; ! 672: - if(mget(&nkey)) ! 673: - return(-1); ! 674: - if(mget((xbuf *)&val)) ! 675: - fail("half a record read"); ! 676: - if((currec.llen = val.mlen) != 0) { ! 677: - currec.lloc = ftell(dfd); ! 678: - (void) fwrite(val.mdata, 1, val.mlen, dfd); ! 679: - if(ferror(dfd)) ! 680: - fail("value write"); ! 681: - } ! 682: - else currec.lloc = 0; ! 683: - return(1); ! 684: -} ! 685: - ! 686: -mget(a) xbuf *a; ! 687: -{ ! 688: - (void) fread((char *)&(a->mlen), 1, sizeof(a->mlen), stdin); ! 689: - if(feof(stdin) || ferror(stdin)) ! 690: - return(1); ! 691: - if(fread(a->mdata, 1, a->mlen, stdin) != a->mlen) ! 692: - return(1); ! 693: - return(0); ! 694: -} ! 695: - ! 696: -ndaddr ndwrt(level) ! 697: -{ ndaddr loc; ! 698: - int i; ! 699: - hdr *x; ! 700: - trailer *t; ! 701: - loc = ftell(tfd)/NDSZ; ! 702: - x = (hdr *)(node[level]); ! 703: - x->hlev = level; ! 704: - t = (trailer *)(node[level] + NDSZ - sizeof(trailer)); ! 705: - t->tfree = freecnt[level]; ! 706: - x->kcnt = address[level] - (level == 0? 0: 1); ! 707: - x->htype = type; ! 708: - (void) fwrite(node[level], 1, NDSZ, tfd); ! 709: - if(ferror(tfd)) ! 710: - fail("node write"); ! 711: - for(i = 0; i < NDSZ; i++) ! 712: - node[level][i] = 0; ! 713: - address[level] = 0; ! 714: - curkey[level].mlen = 0; ! 715: - freecnt[level] = NDSZ - sizeof(hdr) - sizeof(trailer); ! 716: - if(level) ! 717: - freecnt[level] -= sizeof(ndaddr); ! 718: - kp[level] = (dkey *)(node[level] + sizeof(hdr)); ! 719: - return(loc); ! 720: -} ! 721: - ! 722: -finish(level, ptr) ndaddr ptr; ! 723: -{ ndaddr loc; ! 724: - if(!used[level]) ! 725: - return; ! 726: - *ndadr(node[level], address[level]++) = ptr; ! 727: - if(!used[level + 1]) ! 728: - fseek(tfd, 0L, 0); ! 729: - loc = ndwrt(level); ! 730: - finish(level + 1, loc); ! 731: -} ! 732: - ! 733: -insert(level, key, ptr) xbuf *key; ndaddr ptr; ! 734: -{ int n, len; ! 735: - char *p; ! 736: - ndaddr loc; ! 737: - used[level] = 1; ! 738: - n = pref(&curkey[level], key, level); ! 739: - len = DKEYSZ + key->mlen - n + sizeof(ptr); ! 740: - if(len < freecnt[level]) { ! 741: - *ndadr(node[level], address[level]++) = ptr; ! 742: - kp[level]->dlen = len - sizeof(ptr); ! 743: - kp[level]->dcom = n; ! 744: - mvgbt(kp[level]->dkey, key->mdata + n, key->mlen - n); ! 745: - p = (char *)(kp[level]) + kp[level]->dlen; ! 746: - kp[level] = (dkey *)p; ! 747: - freecnt[level] -= len; ! 748: - curkey[level] = *key; ! 749: - } ! 750: - else { ! 751: - *ndadr(node[level],address[level]++) = ptr; ! 752: - loc = ndwrt(level); ! 753: - insert(level+1, key, loc); ! 754: - curkey[level].mlen = 0; ! 755: - } ! 756: -} ! 757: - ! 758: -doit() ! 759: -{ int n, len; ! 760: - ndaddr loc; ! 761: - char *p; ! 762: - for(;;) { ! 763: - if(getrec() == -1) ! 764: - break; ! 765: - used[0] = 1; ! 766: - n = pref(&curkey[0], &nkey, 0); ! 767: - len = DKEYSZ + nkey.mlen - n + sizeof(currec); ! 768: - if(type & INDEX) ! 769: - len -= sizeof(currec); ! 770: - if(len < freecnt[0]) { ! 771: - freecnt[0] -= len; ! 772: - if(!(type & INDEX)) ! 773: - *lfadr(node[0], address[0]++) = currec; ! 774: - else ! 775: - address[0]++; ! 776: - kp[0]->dlen = DKEYSZ + nkey.mlen - n; ! 777: - kp[0]->dcom = n; ! 778: - mvgbt(kp[0]->dkey, nkey.mdata + n, nkey.mlen - n); ! 779: - p = (char *)(kp[0]) + kp[0]->dlen; ! 780: - kp[0] = (dkey *)p; ! 781: - curkey[0] = nkey; ! 782: - } ! 783: - else { ! 784: - shortest(&curkey[0], &nkey); ! 785: - loc = ndwrt(0); ! 786: - freecnt[0] -= DKEYSZ + nkey.mlen + sizeof(currec); ! 787: - if(type & INDEX) ! 788: - freecnt[0] += sizeof(currec); ! 789: - insert(1, &shortone, loc); ! 790: - if(!(type & INDEX)) ! 791: - *lfadr(node[0], address[0]++) = currec; ! 792: - else ! 793: - address[0]++; ! 794: - kp[0]->dlen = DKEYSZ + nkey.mlen; ! 795: - kp[0]->dcom = 0; ! 796: - mvgbt(kp[0]->dkey, nkey.mdata, nkey.mlen); ! 797: - p = (char *)(kp[0]) + kp[0]->dlen; ! 798: - kp[0] = (dkey *)p; ! 799: - curkey[0] = nkey; ! 800: - } ! 801: - } ! 802: - if(!used[1]) ! 803: - (void) fseek(tfd, 0L, 0); ! 804: - loc = ndwrt(0); ! 805: - finish(1, loc); ! 806: -} ! 807: - ! 808: -init(s) ! 809: -char *s; ! 810: -{ int i; ! 811: - hdr *b; ! 812: - char xx[NDSZ]; ! 813: - (void) sprintf(name, "%s.T", s); ! 814: - tfd = fopen(name, "r"); ! 815: - if(tfd == NULL) { ! 816: - perror(s); ! 817: - exit(1); ! 818: - } ! 819: - fread(xx, 1, NDSZ, tfd); ! 820: - fclose(tfd); ! 821: - tfd = fopen(name, "w"); ! 822: - (void) fseek(tfd, (long)NDSZ, 0); ! 823: - b = (hdr *)xx; ! 824: - type = b->htype; ! 825: - (void) sprintf(name, "%s.F", s); ! 826: - if((type & INDEX) != INDEX) ! 827: - dfd = fopen(name, "w"); ! 828: - for(i = 0; i < SZ; i++) { ! 829: - freecnt[i] = NDSZ - sizeof(hdr) - sizeof(trailer); ! 830: - if(i) ! 831: - freecnt[i] -= sizeof(ndaddr); ! 832: - kp[i] = (dkey *)(node[i] + sizeof(hdr)); ! 833: - } ! 834: -} ! 835: - ! 836: -main(argc, argv) ! 837: -char **argv; ! 838: -{ ! 839: - if(argc != 2) { ! 840: - fprintf(stderr, "%s: too many arguments\n", argv[1]); ! 841: - exit(1); ! 842: - } ! 843: - init(argv[1]); ! 844: - doit(); ! 845: - exit(0); ! 846: -} ! 847: - ! 848: -shortest(a, b) xbuf *a, *b; ! 849: -{ int n; ! 850: - char *p, *q, *s; ! 851: - p = a->mdata; ! 852: - q = b->mdata; ! 853: - s = shortone.mdata; ! 854: - for(n = 0; n < a->mlen && n < b->mlen; n++, p++, q++) ! 855: - if(*p == *q) ! 856: - *s++ = *p; ! 857: - else break; ! 858: - if(n < a->mlen) { ! 859: - again: ! 860: - if(n + 1 == a->mlen) ! 861: - *s++ = *p; ! 862: - else if(*p + 1 < *q) ! 863: - *s++ = *p + 1; ! 864: - else { ! 865: - *s++ = *p++; ! 866: - n++; ! 867: - if(*p + 1 > *p) ! 868: - *s++ = *p + 1; ! 869: - else goto again; ! 870: - } ! 871: - } ! 872: - shortone.mlen = s - shortone.mdata; ! 873: -} ! 874: -prbuf(x) xbuf *x; ! 875: -{ int i; ! 876: - for(i = 0; i < x->mlen; i++) ! 877: - printf("%3.3o ", x->mdata[i]); ! 878: - putchar('\n'); ! 879: -} ! 880: -fail(s) ! 881: -char *s; ! 882: -{ ! 883: - perror(s); ! 884: - exit(2); ! 885: -} ! 886: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:btbuild.c\n"}; ! 887: -/*1101000110100100*/ ! 888: //GO.SYSIN DD btbuild.c ! 889: echo btcat.c 1>&2 ! 890: sed 's/.//' >btcat.c <<'//GO.SYSIN DD btcat.c' ! 891: -#include "stdio.h" ! 892: -#include "cbt.h" ! 893: -extern char *malloc(), *realloc(); ! 894: -extern mbuf bkey(); ! 895: -extern bfile *bopen(); ! 896: -int rflag; ! 897: -int rsize = 64; ! 898: -mbuf key, rec; ! 899: -char tabchar = '\t'; ! 900: -main(argc, argv) char **argv; ! 901: -{ ! 902: - rec.mdata = malloc(rsize); ! 903: - key.mdata = malloc(NDSZ); ! 904: - for(argc--, argv++; argc > 0; argc--, argv++) { ! 905: - switch(*argv[0]) { ! 906: - case '-': ! 907: - if(argv[0][1] == 'R') ! 908: - rflag = 1; ! 909: - else fprintf(stderr, "unknown option %s\n", argv[0]); ! 910: - break; ! 911: - default: ! 912: - copy(argv[0]); ! 913: - break; ! 914: - } ! 915: - } ! 916: - exit(0); ! 917: -} ! 918: -copy(s) char *s; ! 919: -{ bfile *bt; ! 920: - int n; ! 921: - bt = bopen(s, 0); ! 922: - if(bt == NULL) { ! 923: - perror(s); ! 924: - exit(1); ! 925: - } ! 926: - if(bfirst(bt) == EOF) { ! 927: - fprintf(stderr, "%s empty\n", s); ! 928: - return; ! 929: - } ! 930: - while((n = breclen(bt)) != EOF) { ! 931: - if(n > rsize) { ! 932: - rsize = n; ! 933: - rec.mdata = realloc(rec.mdata, rsize); ! 934: - } ! 935: - (void) bread(bt, &key, &rec); ! 936: - if(!rflag) { ! 937: - out(key); ! 938: - putchar(tabchar); ! 939: - out(rec); ! 940: - putchar('\n'); ! 941: - } ! 942: - else { ! 943: - fwrite((char *)&key.mlen, 1, sizeof(short), stdout); ! 944: - fwrite(key.mdata, key.mlen, 1, stdout); ! 945: - fwrite((char *)&rec.mlen, 1, sizeof(short), stdout); ! 946: - fwrite(rec.mdata, rec.mlen, 1, stdout); ! 947: - } ! 948: - ! 949: - } ! 950: - bclose(bt); ! 951: -} ! 952: -out(a) mbuf a; ! 953: -{ int i; ! 954: - for(i = 0; i < a.mlen; i++) putchar(*(a.mdata + i)); ! 955: -} ! 956: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/4/8:btcat.c\n"}; ! 957: -/*1110000011011001*/ ! 958: //GO.SYSIN DD btcat.c ! 959: echo btcreat.c 1>&2 ! 960: sed 's/.//' >btcreat.c <<'//GO.SYSIN DD btcreat.c' ! 961: -#include "stdio.h" ! 962: -#include "cbt.h" ! 963: -#define error(x, y) {fprintf(stderr, x, y); exit(1); } ! 964: - ! 965: -int iflag, rflag; ! 966: -char node[NDSZ]; ! 967: -char buf[512]; ! 968: -extern char *malloc(); ! 969: - ! 970: -main(argc, argv) ! 971: -char **argv; ! 972: -{ int i, fd; ! 973: - hdr *b; ! 974: - char *p; ! 975: - for(i = 1; i < argc; i++) { ! 976: - if(argv[i][0] == '-') { ! 977: - for(p = argv[i] + 1; *p; p++) ! 978: - if(*p == 'i') ! 979: - iflag = 1; ! 980: - else if(*p == 'r') ! 981: - rflag = 1; ! 982: - else ! 983: - error("unknown flag %c\n", *p); ! 984: - if(i >= argc - 1) ! 985: - error("file name?", 0); ! 986: - continue; ! 987: - } ! 988: - if(!iflag) { ! 989: - sprintf(buf, "%s.F", argv[i]); ! 990: - if((fd = creat(buf, 0666)) < 0) { ! 991: - perror(buf); ! 992: - exit(1); ! 993: - } ! 994: - close(fd); ! 995: - } ! 996: - sprintf(buf, "%s.T", argv[i]); ! 997: - if((fd = creat(buf, 0666)) < 0) { ! 998: - perror(buf); ! 999: - if(!iflag) { ! 1000: - sprintf(buf, "%s.F", argv[i]); ! 1001: - unlink(buf); ! 1002: - } ! 1003: - exit(1); ! 1004: - } ! 1005: - b = (hdr *)node; ! 1006: - b->kcnt = 0; ! 1007: - if(iflag) ! 1008: - b->htype |= INDEX; ! 1009: - if(rflag) ! 1010: - b->htype |= READONLY; ! 1011: - nfree(b) = NDSZ - sizeof(hdr) - sizeof(trailer); ! 1012: - if(write(fd, node, NDSZ) != NDSZ) ! 1013: - perror("failed"); ! 1014: - close(fd); ! 1015: - } ! 1016: - exit(0); ! 1017: -} ! 1018: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:btcreat.c\n"}; ! 1019: -/*0011011101111110*/ ! 1020: //GO.SYSIN DD btcreat.c ! 1021: echo btdelete.c 1>&2 ! 1022: sed 's/.//' >btdelete.c <<'//GO.SYSIN DD btdelete.c' ! 1023: -/* read keys from stdin, and delete the records from argv[1] */ ! 1024: -#include "stdio.h" ! 1025: -#include "cbt.h" ! 1026: - ! 1027: -char buf[NDSZ]; ! 1028: -bfile *bf; ! 1029: -mbuf key; ! 1030: - ! 1031: -main(argc, argv) ! 1032: -char **argv; ! 1033: -{ char *p; ! 1034: - int c = 0; ! 1035: - if(argc != 2) { ! 1036: - fprintf(stderr, "usage: delete b-tree < keys\n"); ! 1037: - exit(1); ! 1038: - } ! 1039: - if((bf = bopen(argv[1], 2)) == NULL) { ! 1040: - perror(argv[1]); ! 1041: - exit(1); ! 1042: - } ! 1043: - key.mdata = buf; ! 1044: -loop: ! 1045: - if(c == EOF) { ! 1046: - bclose(bf); ! 1047: - exit(0); ! 1048: - } ! 1049: - for(p = buf; (c = getchar()) != '\n' && c != EOF; *p++ = c) ! 1050: - ; ! 1051: - *p = 0; ! 1052: - key.mlen = p - buf; ! 1053: - if(key.mlen == 0) ! 1054: - goto loop; ! 1055: - if(!bdelete(bf, key)) ! 1056: - fprintf(stderr, "not in file:%s\n", buf); ! 1057: - goto loop; ! 1058: -} ! 1059: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:btdelete.c\n"}; ! 1060: -/*0010110100010101*/ ! 1061: //GO.SYSIN DD btdelete.c ! 1062: echo btdiag.c 1>&2 ! 1063: sed 's/.//' >btdiag.c <<'//GO.SYSIN DD btdiag.c' ! 1064: -#include "stdio.h" ! 1065: -#include "cbt.h" ! 1066: -#include "sys/types.h" ! 1067: -#include "sys/stat.h" ! 1068: - ! 1069: -extern bfile *bopen(); ! 1070: -extern char *malloc(); ! 1071: -extern int errno; ! 1072: -int errcnt; ! 1073: -char nodes[MXHT + 1][NDSZ]; ! 1074: -int loc[MXHT + 1]; ! 1075: -char *seen; ! 1076: -dkey *curd[MXHT + 1]; ! 1077: -char curkey[MXHT + 1][MAXKLEN]; ! 1078: -int keynum[MXHT + 1]; ! 1079: -mbuf tinykey = { "", 0}; ! 1080: -mbuf giantkey = {"\177\177\177\177", 4}; ! 1081: - ! 1082: -main(argc, argv) ! 1083: -char **argv; ! 1084: -{ bfile *bt; ! 1085: - int n; ! 1086: - if(argc < 2) ! 1087: - error("file name?"); ! 1088: - bt = bopen(argv[1], 0); ! 1089: - if(bt == 0) ! 1090: - error("couldn't open tree"); ! 1091: - n = diagnose(bt); ! 1092: - printf("return value is %d\n", n); ! 1093: - exit(n); ! 1094: -} ! 1095: - ! 1096: -diagnose(b) ! 1097: -bfile *b; ! 1098: -{ int i; ! 1099: - struct stat statb; ! 1100: - if(fstat(b->tfd, &statb) < 0) ! 1101: - error("can't stat tree"); ! 1102: - if(statb.st_size % NDSZ || statb.st_size <= 0) { ! 1103: - printf("tree size %d mod ndsz %d != 0\n", statb.st_size, NDSZ); ! 1104: - errcnt++; ! 1105: - } ! 1106: - if(b->height > MXHT || b->height < 0) { ! 1107: - printf("tree height %d weird max %d\n", b->height, MXHT); ! 1108: - return(-1); ! 1109: - } ! 1110: - seen = malloc(statb.st_size / NDSZ); ! 1111: - for(i = 0; i < statb.st_size/NDSZ; i++) ! 1112: - seen[i] = -1; ! 1113: - lseek(b->tfd, 0, 0); ! 1114: - if((i = read(b->tfd, nodes[b->height], NDSZ)) != NDSZ) { ! 1115: - printf("read of root returned %d (%d)\n", i, errno); ! 1116: - error("can't proceed"); ! 1117: - } ! 1118: - return(dolevel(b->tfd, b->height, tinykey, giantkey) || errcnt); ! 1119: -} ! 1120: - ! 1121: -mbuf ! 1122: -firstkey(n) ! 1123: -{ hdr *b; ! 1124: - mbuf z; ! 1125: - int i; ! 1126: - b = (hdr *)nodes[n]; ! 1127: - keynum[n] = 0; ! 1128: - if(keynum[n] >= b->kcnt) { ! 1129: - z.mlen = -1; ! 1130: - return(z); ! 1131: - } ! 1132: - curd[n] = (dkey *)(b+1); ! 1133: - for(i = 0; i < curd[n]->dlen - DKEYSZ; i++) ! 1134: - curkey[n][i] = curd[n]->dkey[i]; ! 1135: - z.mlen = i; ! 1136: - z.mdata = curkey[n]; ! 1137: - return(z); ! 1138: -} ! 1139: - ! 1140: -mbuf ! 1141: -nextkey(n) ! 1142: -{ mbuf z; ! 1143: - char *p = (char *)curd[n]; ! 1144: - dkey *d; ! 1145: - int i; ! 1146: - hdr *b = (hdr *)nodes[n]; ! 1147: - if(++keynum[n] >= b->kcnt) { ! 1148: - z.mlen = -1; ! 1149: - return(z); ! 1150: - } ! 1151: - p += curd[n]->dlen; ! 1152: - d = curd[n] = (dkey *)p; ! 1153: - z.mdata = curkey[n]; ! 1154: - for(i = 0; i < d->dlen - DKEYSZ; i++) ! 1155: - z.mdata[d->dcom + i] = d->dkey[i]; ! 1156: - z.mlen = i + d->dcom; ! 1157: - return(z); ! 1158: -} ! 1159: - ! 1160: -dolevel(fd, lev, lokey, hikey) ! 1161: -mbuf lokey, hikey; ! 1162: -{ int i, j; ! 1163: - mbuf left, right; ! 1164: - char leftx[MAXKLEN]; ! 1165: - hdr *b = (hdr *)nodes[lev]; ! 1166: - if(lseek(fd, loc[lev] * NDSZ, 0) < 0 || read(fd, nodes[lev], NDSZ) != NDSZ) { ! 1167: - printf("couldn't read node %d, level %d\n", loc[lev], lev); ! 1168: - return(-1); ! 1169: - } ! 1170: - if(seen[loc[lev]] != -1) { ! 1171: - printf("node %d visited twice, at lev %d and %d\n", lev, seen[loc[lev]], lev); ! 1172: - if(lev != seen[loc[lev]]) ! 1173: - return(-1); ! 1174: - } ! 1175: - else ! 1176: - seen[loc[lev]] = lev; ! 1177: - if(check(loc[lev], nodes[lev], lokey, hikey)) ! 1178: - return(-1); ! 1179: - if(lev == 0) ! 1180: - return(0); ! 1181: - right = firstkey(lev); ! 1182: - left.mlen = lokey.mlen; ! 1183: - left.mdata = leftx; ! 1184: - for(j = 0; j < left.mlen; j++) ! 1185: - left.mdata[j] = lokey.mdata[j]; ! 1186: - for(i = 0; i < b->kcnt; i++) { ! 1187: - loc[lev - 1] = *ndadr(b, i); ! 1188: - if(dolevel(fd, lev - 1, left, right)) ! 1189: - return(-1); ! 1190: - left.mlen = right.mlen; ! 1191: - for(j = 0; j < left.mlen; j++) ! 1192: - left.mdata[j] = right.mdata[j]; ! 1193: - right = nextkey(lev); ! 1194: - if(right.mlen < 0) ! 1195: - printf("unexpected end of keys, node %d\n", loc[lev]); ! 1196: - } ! 1197: - loc[lev - 1] = *ndadr(b, i); ! 1198: - return(dolevel(fd, lev - 1, left, hikey)); ! 1199: -} ! 1200: - ! 1201: -check(noden, b, lokey, hikey) ! 1202: -hdr *b; ! 1203: -mbuf lokey, hikey; ! 1204: -{ int i, plen, sz, j; ! 1205: - char *p, prefix[MAXKLEN]; ! 1206: - dkey *d; ! 1207: - ! 1208: - /* check space allocation */ ! 1209: - sz = sizeof(hdr) + sizeof(trailer) + nfree(b); ! 1210: - if(nfree(b) < 0) { ! 1211: - printf("nfree: %d < 0, node %d\n", nfree(b), noden); ! 1212: - errcnt++; ! 1213: - } ! 1214: - if(sz > NDSZ) { ! 1215: - printf("nfree: %d impossibly large, node %d\n", nfree(b), noden); ! 1216: - errcnt++; ! 1217: - } ! 1218: - if(b->kcnt < 0) { ! 1219: - printf("kcnt %d < 0, node %d\n", b->kcnt, noden); ! 1220: - return(-1); ! 1221: - } ! 1222: - p = (char *)(b+1); ! 1223: - for(i = 0; i < b->kcnt; i++) { ! 1224: - d = (dkey *)p; ! 1225: - if(d->dlen < DKEYSZ) { ! 1226: - printf("node %d, key %d, dlen %d too small\n", noden, i, d->dlen); ! 1227: - return(-1); ! 1228: - } ! 1229: - if(b->hlev) ! 1230: - sz += sizeof(ndaddr); ! 1231: - else if(!(b->htype & INDEX)) ! 1232: - sz += sizeof(lfaddr); ! 1233: - if((sz += d->dlen) > NDSZ) { ! 1234: - printf("node %d, contents too large\n", noden); ! 1235: - return(-1); ! 1236: - } ! 1237: - p += d->dlen; ! 1238: - } ! 1239: - if(b->hlev) ! 1240: - sz += sizeof(ndaddr); ! 1241: - if(sz != NDSZ) { ! 1242: - printf("node %d, size %d ndsz %d\n", noden, sz, NDSZ); ! 1243: - return(-1); ! 1244: - } ! 1245: - /* check key ordering */ ! 1246: - p = (char *)(b + 1); ! 1247: - d = (dkey *)p; ! 1248: - if(d->dcom != 0) { ! 1249: - printf("node %d first key has dcom %d > 0\n", noden, d->dcom); ! 1250: - return(-1); ! 1251: - } ! 1252: - plen = lokey.mlen; ! 1253: - for(i = 0; i < plen; i++) ! 1254: - prefix[i] = lokey.mdata[i]; ! 1255: - for(i = 0; i < b->kcnt; i++) { ! 1256: - if(d->dcom > plen) { ! 1257: - printf("node %d key %d, dcom %d bigger than len %d of prev key\n", ! 1258: - noden, i, d->dcom, plen); ! 1259: - return(-1); ! 1260: - } ! 1261: - for(j = 0; j < d->dlen - DKEYSZ; j++) { ! 1262: - if(j + d->dcom > plen) ! 1263: - break; ! 1264: - if(d->dkey[j] < prefix[d->dcom + j]) { ! 1265: - printf("node %d, key %d out of order\n", ! 1266: - noden, i); ! 1267: - errcnt++; ! 1268: - break; ! 1269: - } ! 1270: - else if(d->dkey[j] == prefix[d->dcom + j]) ! 1271: - continue; ! 1272: - else ! 1273: - break; ! 1274: - } ! 1275: - for(j = 0; j < d->dlen - DKEYSZ; j++) ! 1276: - prefix[j + d->dcom] = d->dkey[j]; ! 1277: - plen = j + d->dcom; ! 1278: - } ! 1279: - for(i = 0; i < plen && i < hikey.mlen; i++) { ! 1280: - if(prefix[i] < hikey.mdata[i]) ! 1281: - return(0); ! 1282: - else if(prefix[i] == hikey.mdata[i]) ! 1283: - continue; ! 1284: - printf("node %d last key too large pref %s, hi %s\n", noden, prefix, hikey.mdata); ! 1285: - return(-1); ! 1286: - } ! 1287: - if(plen > hikey.mlen) { ! 1288: - printf("node %d last key too large plen %d, hikey.len %d\n", noden, plen, hikey.mlen); ! 1289: - return(-1); ! 1290: - } ! 1291: - return(0); ! 1292: -} ! 1293: - ! 1294: -error(s) ! 1295: -char *s; ! 1296: -{ ! 1297: - printf("%s\n", s); ! 1298: - exit(1); ! 1299: -} ! 1300: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:btdiag.c\n"}; ! 1301: -/*1100001011001101*/ ! 1302: //GO.SYSIN DD btdiag.c ! 1303: echo btexer.c 1>&2 ! 1304: sed 's/.//' >btexer.c <<'//GO.SYSIN DD btexer.c' ! 1305: -#include "cbt.h" ! 1306: -extern char *malloc(); ! 1307: - ! 1308: -bfile *bt; ! 1309: -mbuf *key; ! 1310: -char *state; ! 1311: -#define IN 1 ! 1312: -#define OUT 2 ! 1313: -int cnt, keysz; ! 1314: -char *buf; ! 1315: -char cmdbuf[128]; ! 1316: -mbuf rec = {"", 0}; ! 1317: -extern char *outkey(); ! 1318: -char *filename; ! 1319: - ! 1320: -main(argc, argv) ! 1321: -char **argv; ! 1322: -{ int i; ! 1323: - if(argc != 3) ! 1324: - error("usage: file key-cnt"); ! 1325: - bt = bopen(filename = argv[1], 2); ! 1326: - if(bt == 0) ! 1327: - error("bopen"); ! 1328: - sprintf(cmdbuf, "btdiag %s", argv[1]); ! 1329: - cnt = atoi(argv[2]); ! 1330: - printf("cnt = %d\n", cnt); ! 1331: - key = (mbuf *)malloc(cnt * sizeof(mbuf)); ! 1332: - keysz = NDSZ/5; ! 1333: - if(keysz > MAXKLEN) ! 1334: - keysz = MAXKLEN; ! 1335: - printf("keysz %d\n", keysz); ! 1336: - buf = malloc((keysz + 1) * cnt); ! 1337: - state = malloc(cnt); ! 1338: - if(buf == 0 || state == 0) ! 1339: - error("key malloc"); ! 1340: - for(i = 0; i < cnt; i++) ! 1341: - state[i] = OUT; ! 1342: - for(i = 0; i < cnt; i++) ! 1343: - key[i].mlen = keysz; ! 1344: - for(i = 0; i < cnt; i++) ! 1345: - key[i].mdata = buf + i * (keysz + 1); ! 1346: - srand(0); ! 1347: - for(i = 0; i < cnt * (keysz + 1); i++) ! 1348: - buf[i] = rand() % 94 + ' ' + 1; ! 1349: - for(i = 0; i < cnt; i++) ! 1350: - buf[i * (keysz + 1) + keysz] = 0; ! 1351: - doit(); ! 1352: - printf("sbrk %d\n", sbrk(0)); ! 1353: - exit(0); ! 1354: -} ! 1355: - ! 1356: -doit() ! 1357: -{ ! 1358: - allin(); ! 1359: - test("allin ok\n"); ! 1360: - checkseek(); ! 1361: - out(500); ! 1362: - test("out 500 ok\n"); ! 1363: - checkseek(); ! 1364: - in(500); ! 1365: - test("in 500 ok\n"); ! 1366: - checkseek(); ! 1367: - out(700); ! 1368: - test("out 700 ok\n"); ! 1369: - checkseek(); ! 1370: - in(700); ! 1371: - test("in 700 ok\n"); ! 1372: - checkseek(); ! 1373: - out(1000); ! 1374: - test("out 1000 ok\n"); ! 1375: - checkseek(); ! 1376: - in(100); ! 1377: - test("in 100 ok\n"); ! 1378: - checkseek(); ! 1379: - in(200); ! 1380: - test("in 200 ok\n"); ! 1381: - checkseek(); ! 1382: - in(300); ! 1383: - test("in 300 ok\n"); ! 1384: - checkseek(); ! 1385: -} ! 1386: - ! 1387: -test(s) ! 1388: -char *s; ! 1389: -{ int n; ! 1390: - bclose(bt); ! 1391: - n = system(cmdbuf); ! 1392: - if(n) { ! 1393: - printf("%s returned %d\n", cmdbuf, n); ! 1394: - exit(1); ! 1395: - } ! 1396: - else ! 1397: - printf(s); ! 1398: - bt = bopen(filename, 2); ! 1399: - if(bt == NULL) ! 1400: - error(filename); ! 1401: -} ! 1402: - ! 1403: -error(s) ! 1404: -char *s; ! 1405: -{ ! 1406: - perror(s); ! 1407: - exit(1); ! 1408: -} ! 1409: - ! 1410: -allin() ! 1411: -{ int i; ! 1412: - for(i = 0; i < cnt; i++) { ! 1413: - if(state[i] == IN) ! 1414: - continue; ! 1415: - if(bwrite(bt, key[i], rec) == EOF) ! 1416: - printf("write error %d on key %d\n", errno, i); ! 1417: - else ! 1418: - state[i] = IN; ! 1419: - } ! 1420: -} ! 1421: - ! 1422: -in(n) ! 1423: -{ int i; ! 1424: - for(i = 0; i < cnt; i++) { ! 1425: - if(state[i] == IN || (rand() % 1007) >= n) ! 1426: - continue; ! 1427: - else if(bwrite(bt, key[i], rec) == EOF) ! 1428: - printf("write error %d on key %d\n", errno, i); ! 1429: - else ! 1430: - state[i] = IN; ! 1431: - } ! 1432: -} ! 1433: - ! 1434: -out(n) ! 1435: -{ int i, count = 0; ! 1436: - for(i = 0; i < cnt; i++) { ! 1437: - if(state[i] == OUT || (rand() % 1007) >= n) ! 1438: - continue; ! 1439: - if(bdelete(bt, key[i], rec) != 1) { ! 1440: - printf("bdelete error %d on key %s\n", errno, outkey(i)); ! 1441: - printf("out(%d) deleted %d\n", n, count); ! 1442: - bflush(bt); ! 1443: - exit(1); ! 1444: - } ! 1445: - else if(bt->fatal) ! 1446: - printf("set fatal flag, bdelete key %d %s err %d\n", i, outkey(i), errno); ! 1447: - else { ! 1448: - count++; ! 1449: - state[i] = OUT; ! 1450: - } ! 1451: - } ! 1452: -} ! 1453: - ! 1454: -checkseek() ! 1455: -{ int i, j, count = 0; ! 1456: - mbuf x; ! 1457: - printf("\tcheckseek"); ! 1458: - for(i = 0; i < cnt; i++) { ! 1459: - if(state[i] == OUT) ! 1460: - continue; ! 1461: - if(bseek(bt, key[i]) != FOUND) { ! 1462: - printf("sought key %s, not found\n", key[i].mdata); ! 1463: - continue; ! 1464: - } ! 1465: - x = bkey(bt); ! 1466: - for(j = 0; j < keysz; j++) ! 1467: - if(key[i].mdata[j] != x.mdata[j]) { ! 1468: - printf("bkey mismatch at key %d\n", i); ! 1469: - break; ! 1470: - } ! 1471: - count++; ! 1472: - } ! 1473: - printf(" saw %d\n", count); ! 1474: -} ! 1475: - ! 1476: -char * ! 1477: -outkey(n) ! 1478: -{ static char kb[MAXKLEN + 1]; ! 1479: - int i; ! 1480: - strncpy(kb, key[n].mdata, keysz); ! 1481: - return(kb); ! 1482: -} ! 1483: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:btexer.c\n"}; ! 1484: -/*1101101100011000*/ ! 1485: //GO.SYSIN DD btexer.c ! 1486: echo btran.c 1>&2 ! 1487: sed 's/.//' >btran.c <<'//GO.SYSIN DD btran.c' ! 1488: -#include "stdio.h" ! 1489: -#define MAX 8192 ! 1490: -char tab = '\t'; ! 1491: -char *line, *oline; ! 1492: -char abuf[MAX], bbuf[MAX]; ! 1493: -int cnt, ocnt; ! 1494: -main() ! 1495: -{ long lcnt = 0; ! 1496: - line = abuf; ! 1497: - oline = bbuf; ! 1498: - for(; !feof(stdin); ) { ! 1499: - lcnt++; ! 1500: - (void) fgets(line, MAX, stdin); ! 1501: - if(feof(stdin)) cnt = 0; ! 1502: - else cnt = strlen(line); ! 1503: - if(cnt >= MAX-1) { ! 1504: - fprintf(stderr, "line %ld too long\n", lcnt); ! 1505: - cnt = 0; ! 1506: - } ! 1507: - output(); ! 1508: - } ! 1509: - exit(0); ! 1510: -} ! 1511: -output() ! 1512: -{ unsigned short u; ! 1513: - char *p; ! 1514: - if(ocnt <= 1) { /* oline was used to give ooline a newline */ ! 1515: - swtch(); ! 1516: - return; ! 1517: - } ! 1518: - if(cnt != 1) /* line isnt a newline to be added to oline */ ! 1519: - oline[--ocnt] = 0; ! 1520: - else oline[ocnt] = 0; ! 1521: - for(p = oline; *p && *p != tab; p++); ! 1522: - u = p - oline; ! 1523: - (void) fwrite((char *)&u, 1, sizeof(u), stdout); ! 1524: - (void) fwrite(oline, (int)u, 1, stdout); ! 1525: - if(*p == tab) ! 1526: - p++; ! 1527: - if(oline + ocnt - p < 0) ! 1528: - u = 0; ! 1529: - else u = oline + ocnt - p; ! 1530: - (void) fwrite((char *)&u, 1, sizeof(u), stdout); ! 1531: - (void) fwrite(p, (int)u, 1, stdout); ! 1532: - swtch(); ! 1533: -} ! 1534: -swtch() ! 1535: -{ char *x; ! 1536: - x = line; ! 1537: - line = oline; ! 1538: - oline = x; ! 1539: - ocnt = cnt; ! 1540: -} ! 1541: -static char VER[] = "\n80/2/13:btran.c\n"; ! 1542: -/*1111100011110011*/ ! 1543: //GO.SYSIN DD btran.c ! 1544: echo btreport.c 1>&2 ! 1545: sed 's/.//' >btreport.c <<'//GO.SYSIN DD btreport.c' ! 1546: -#include "stdio.h" ! 1547: -#include "cbt.h" ! 1548: -#include "sys/types.h" ! 1549: -#include "sys/stat.h" ! 1550: -extern bfile *bopen(); ! 1551: - ! 1552: -long ndcnt[MXHT + 1]; ! 1553: -long frcnt, reccnt, reclen; ! 1554: -bfile *bt; ! 1555: - ! 1556: -main(argc, argv) ! 1557: -char **argv; ! 1558: -{ int i, j; ! 1559: - for(i = 1; i < argc; i++) { ! 1560: - doarg(argv[i]); ! 1561: - for(j = 0; j <= MXHT; j++) ! 1562: - ndcnt[j] = 0; ! 1563: - frcnt = reccnt = reclen = 0; ! 1564: - if(i+1 < argc) ! 1565: - putchar('\n'); ! 1566: - } ! 1567: - exit(0); ! 1568: -} ! 1569: - ! 1570: -doarg(s) ! 1571: -char *s; ! 1572: -{ struct stat statbuf; ! 1573: - long x; ! 1574: - int i; ! 1575: - bt = bopen(s, 0); ! 1576: - if(bt == NULL) { ! 1577: - i = strlen(s); ! 1578: - if(s[i-2] == '.') { ! 1579: - s[i-2] = 0; ! 1580: - if(s[i-1] == 'F') ! 1581: - return; ! 1582: - if(s[i-1] == 'T') ! 1583: - bt = bopen(s, 0); ! 1584: - } ! 1585: - if(bt == NULL) { ! 1586: - perror(s); ! 1587: - return; ! 1588: - } ! 1589: - } ! 1590: - fstat(bt->tfd, &statbuf); ! 1591: - printf("%s.T %ld bytes", s, statbuf.st_size); ! 1592: - if(bt->dfd > 0 && fstat(bt->dfd, &statbuf) == 0) ! 1593: - printf(", %s.F %ld bytes", s, statbuf.st_size); ! 1594: - putchar('\n'); ! 1595: - donode((ndaddr)0); ! 1596: - for(x = i = 0; i <= MXHT; i++) ! 1597: - x += ndcnt[i] * NDSZ; ! 1598: - printf("%ld bytes used in tree\n", x); ! 1599: - for(i = 0; i <= bt->height; i++) ! 1600: - printf(" %ld nodes at level %d", ndcnt[i], i); ! 1601: - printf("\n%ld bytes free\n", frcnt); ! 1602: - printf("%ld records totalling %ld bytes\n", reccnt, reclen); ! 1603: - bclose(bt); ! 1604: -} ! 1605: - ! 1606: -/* this routine believes the tree is well-formed */ ! 1607: -donode(n) ! 1608: -ndaddr n; ! 1609: -{ char buf[NDSZ]; ! 1610: - hdr *b = (hdr *)buf; ! 1611: - int i; ! 1612: - (void) lseek(bt->tfd, (long)NDSZ * n, 0); ! 1613: - i = read(bt->tfd, buf, NDSZ); ! 1614: - if(i != NDSZ) { ! 1615: - printf("btreport: attempt to read node %d failed\n", n); ! 1616: - perror("breport"); ! 1617: - exit(1); ! 1618: - } ! 1619: - ndcnt[b->hlev]++; ! 1620: - frcnt += nfree(b); ! 1621: - if(b->hlev) ! 1622: - for(i = 0; i <= b->kcnt; i++) ! 1623: - donode(*ndadr(b, i)); ! 1624: - else ! 1625: - for(i = 0; i < b->kcnt; i++) { ! 1626: - reccnt++; ! 1627: - if(!(b->htype & INDEX)) ! 1628: - reclen += lfadr(b, i)->llen; ! 1629: - } ! 1630: -} ! 1631: -static struct D { struct D *a; char *b;} VER = {&VER,"\n86/8/12:btreport.c\n"}; ! 1632: //GO.SYSIN DD btreport.c ! 1633: echo btsquash.c 1>&2 ! 1634: sed 's/.//' >btsquash.c <<'//GO.SYSIN DD btsquash.c' ! 1635: -#include "stdio.h" ! 1636: -#include "cbt.h" ! 1637: - ! 1638: -extern int errno; ! 1639: -mbuf key, value; ! 1640: -char kbuf[NDSZ], vbuf[32767]; ! 1641: -bfile *bfd; ! 1642: -FILE *pfd; ! 1643: -extern FILE *popen(); ! 1644: -char iflag, rflag; ! 1645: - ! 1646: -main(argc, argv) ! 1647: -char **argv; ! 1648: -{ ! 1649: - if(argc != 2) { ! 1650: - fprintf(stderr, "usage; %s file-name\n", argv[0]); ! 1651: - exit(1); ! 1652: - } ! 1653: - bfd = bopen(argv[1], 0); ! 1654: - if(bfd == NULL) ! 1655: - fail(argv[1]); ! 1656: - strcpy(vbuf, "cbt creat "); ! 1657: - if(bfd->path[0]->htype & INDEX) { ! 1658: - iflag = 1; ! 1659: - strcat(vbuf, "-i "); ! 1660: - } ! 1661: - if(bfd->path[0]->htype & READONLY) { ! 1662: - rflag = 1; ! 1663: - strcat(vbuf, "-r"); ! 1664: - } ! 1665: - sprintf(kbuf, "%s TS%d", vbuf, getpid()); ! 1666: - if(system(kbuf) != 0) { ! 1667: - fprintf(stderr, "%s failed\n", kbuf); ! 1668: - exit(1); ! 1669: - } ! 1670: - /* this refers to the installed version? */ ! 1671: - sprintf(kbuf, "cbt build -r TS%d", getpid()); ! 1672: - pfd = popen(kbuf, "w"); ! 1673: - if(pfd == NULL) ! 1674: - fail(kbuf); ! 1675: - key.mdata = kbuf; ! 1676: - value.mdata = vbuf; ! 1677: - errno = 0; ! 1678: - while(bread(bfd, &key, &value) != EOF) { ! 1679: - (void) fwrite((char *)&key.mlen, 1, sizeof(key.mlen), pfd); ! 1680: - (void) fwrite(key.mdata, 1, key.mlen, pfd); ! 1681: - (void) fwrite((char *)&value.mlen, 1, sizeof(value.mlen), pfd); ! 1682: - (void) fwrite(value.mdata, 1, value.mlen, pfd); ! 1683: - if(ferror(pfd)) ! 1684: - fail("write to build"); ! 1685: - } ! 1686: - if(errno) ! 1687: - fail("extracting"); ! 1688: - if(pclose(pfd) != 0) ! 1689: - fail("pipe close"); ! 1690: - sprintf(kbuf, "%s.T", argv[1]); ! 1691: - sprintf(vbuf, "TS%d.T", getpid()); ! 1692: - unlink(kbuf); ! 1693: - link(vbuf, kbuf); ! 1694: - if(iflag) ! 1695: - exit(0); ! 1696: - sprintf(kbuf, "%s.F", argv[1]); ! 1697: - sprintf(vbuf, "TS%d.F", getpid()); ! 1698: - unlink(kbuf); ! 1699: - link(vbuf, kbuf); ! 1700: - if(errno) ! 1701: - perror("linking"); ! 1702: - exit(0); ! 1703: -} ! 1704: - ! 1705: -fail(s) ! 1706: -char *s; ! 1707: -{ ! 1708: - perror(s); ! 1709: - exit(2); ! 1710: -} ! 1711: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/4/26:btsquash.c\n"}; ! 1712: -/*0100011001101001*/ ! 1713: //GO.SYSIN DD btsquash.c ! 1714: echo bttest.c 1>&2 ! 1715: sed 's/.//' >bttest.c <<'//GO.SYSIN DD bttest.c' ! 1716: -#include "stdio.h" ! 1717: -#include "cbt.h" ! 1718: -extern char *malloc(); ! 1719: -extern bfile *bopen(); ! 1720: -extern mbuf bkey(); ! 1721: -extern long lseek(); ! 1722: - ! 1723: -char *onearg(); ! 1724: -mbuf key, value; ! 1725: -bfile *it; ! 1726: -#define OPEN 1 ! 1727: -#define CLOSE 2 ! 1728: -#define SEEK 3 ! 1729: -#define FIRST 4 ! 1730: -#define NEXT 5 ! 1731: -#define WRITE 6 ! 1732: -#define BT 7 ! 1733: -#define LEV 8 ! 1734: -#define NODE 9 ! 1735: -#define KEY 10 ! 1736: -#define FLUSH 11 ! 1737: -#define COMMIT 12 ! 1738: -#define SHELL 13 ! 1739: -#define DELETE 14 ! 1740: -#define START 15 ! 1741: -#define CHECK 16 ! 1742: -struct cmd ! 1743: -{ int cmt, cln; ! 1744: - char *ccm; ! 1745: -} cmnd[] = ! 1746: -{ {OPEN, 4, "open"}, ! 1747: - {CLOSE, 5, "close"}, ! 1748: - {SHELL, 1, "!"}, ! 1749: - {DELETE, 6, "delete"}, ! 1750: - {SEEK, 4, "seek"}, ! 1751: - {FIRST, 5, "first"}, ! 1752: - {NEXT, 4, "next"}, ! 1753: - {NEXT, 4, "read"}, ! 1754: - {WRITE, 5, "write"}, ! 1755: - {CHECK, 5, "check"}, ! 1756: - {BT, 2, "bt"}, ! 1757: - {LEV, 3, "lev"}, ! 1758: - {NODE, 4, "node"}, ! 1759: - {KEY, 3, "key"}, ! 1760: - {FLUSH, 5, "flush"}, ! 1761: - {COMMIT, 6, "commit"}, ! 1762: - {START, 5, "start"}, ! 1763: - {START, 7, "trstart"}, ! 1764: - {0, 0, 0} ! 1765: -}; ! 1766: -char line[128]; ! 1767: -char ndbuf[512]; ! 1768: -main() ! 1769: -{ ! 1770: - int n; ! 1771: - char *s, *p; ! 1772: - key.mdata = malloc(200); ! 1773: - value.mdata = malloc(200); ! 1774: - for(;;) { ! 1775: - for(n = 0; n < sizeof(line); n++) ! 1776: - line[n] = 0; ! 1777: - (void) fgets(line, sizeof(line), stdin); ! 1778: - if(feof(stdin)) break; ! 1779: - switch(cmtp(line)) { ! 1780: - default: ! 1781: - printf("?\n"); ! 1782: - break; ! 1783: - case CLOSE: ! 1784: - bclose(it); ! 1785: - break; ! 1786: - case SHELL: ! 1787: - (void) system(line); ! 1788: - printf("!\n"); ! 1789: - break; ! 1790: - case START: ! 1791: - /* printf("%d\n", trstart()); */ ! 1792: - break; ! 1793: - case COMMIT: ! 1794: - /* btcommit(); */ ! 1795: - break; ! 1796: - case FLUSH: ! 1797: - bflush(it); ! 1798: - break; ! 1799: - case OPEN: ! 1800: - s = onearg(line); ! 1801: - it = bopen(s, 2); ! 1802: - if(it == NULL || errno) ! 1803: - { perror(s); ! 1804: - } ! 1805: - break; ! 1806: - case DELETE: ! 1807: - s = onearg(line); ! 1808: - if(s[strlen(s)-1] == '\n') ! 1809: - s[strlen(s)-1] = 0; ! 1810: - todatum(s, &key); ! 1811: - printf("%d\n", bdelete(it, key)); ! 1812: - break; ! 1813: - case SEEK: ! 1814: - s = onearg(line); ! 1815: - if(s[strlen(s)-1] == '\n') ! 1816: - s[strlen(s)-1] = 0; ! 1817: - todatum(s, &key); ! 1818: - printf("%d\n", bseek(it, key)); ! 1819: - break; ! 1820: - case FIRST: ! 1821: - printf("%d\n", bfirst(it)); ! 1822: - break; ! 1823: - case NEXT: ! 1824: - printf("%d - ", bread(it, &key, &value)); ! 1825: - prbuf(value); ! 1826: - printf(" | "); ! 1827: - prbuf(key); ! 1828: - putchar('\n'); ! 1829: - break; ! 1830: - case WRITE: ! 1831: - twoarg(line, &s, &p); ! 1832: - todatum(s, &key); ! 1833: - todatum(p, &value); ! 1834: - printf("%d\n", bwrite(it, key, value)); ! 1835: - break; ! 1836: - case BT: ! 1837: - prbt(it); ! 1838: - break; ! 1839: - case LEV: ! 1840: - (void) sscanf(line, "%d", &n); ! 1841: - if(n < 0 || n > it->height) ! 1842: - { printf("out of range\n"); ! 1843: - break; ! 1844: - } ! 1845: - tprnode(it->path[n]); ! 1846: - break; ! 1847: - case NODE: ! 1848: - (void) sscanf(line, "%d", &n); ! 1849: - (void) lseek(it->tfd, (long)n*NDSZ, 0); ! 1850: - (void) read(it->tfd, ndbuf, NDSZ); ! 1851: - tprnode((hdr *)ndbuf); ! 1852: - break; ! 1853: - case CHECK: ! 1854: - (void) sscanf(line, "%d", &n); ! 1855: - (void) lseek(it->tfd, (long)n * NDSZ, 0); ! 1856: - (void) read(it->tfd, ndbuf, NDSZ); ! 1857: - checknode((hdr *)ndbuf); ! 1858: - break; ! 1859: - case KEY: ! 1860: - printf("%d ", breclen(it)); ! 1861: - prbuf(bkey(it)); ! 1862: - putchar('\n'); ! 1863: - break; ! 1864: - } ! 1865: - } ! 1866: - exit(0); ! 1867: -} ! 1868: -cmtp(s) char *s; ! 1869: -{ struct cmd *p; ! 1870: - int i; ! 1871: - for(p=cmnd; p->cln != 0; p++) ! 1872: - if(strncmp(s, p->ccm, p->cln) == 0) ! 1873: - { for(i=0; i<p->cln; i++) ! 1874: - line[i] =' '; ! 1875: - return(p->cmt); ! 1876: - } ! 1877: - return(-1); ! 1878: -} ! 1879: -char *onearg(s) char *s; ! 1880: -{ char *p, *q; ! 1881: - for(p=s; *p == ' '; p++); ! 1882: - for(q=p; *q && *q!='\n'; q++); ! 1883: - *q = 0; ! 1884: - return(p); ! 1885: -} ! 1886: -todatum(s, k) char *s; mbuf *k; ! 1887: -{ int i; ! 1888: - k->mlen = strlen(s); ! 1889: - if(s[k->mlen - 1] == '\n') ! 1890: - k->mlen--; ! 1891: - for(i=0; i<k->mlen; i++) ! 1892: - k->mdata[i] = s[i]; ! 1893: -} ! 1894: -twoarg(a, b, c) char *a, **b, **c; ! 1895: -{ char *p, *q; ! 1896: - for(; *a==' '; a++); ! 1897: - for(p=a; *p && *p!='\t'; p++); ! 1898: - *p++ = 0; ! 1899: - for(q=p; *q && *q!='\n'; q++); ! 1900: - *q = 0; ! 1901: - *b = a; ! 1902: - *c = p; ! 1903: -} ! 1904: -prbuf(a) mbuf a; ! 1905: -{ int i; ! 1906: - printf("%d:", a.mlen); ! 1907: - for(i=0; i<a.mlen; i++) ! 1908: - putchar(a.mdata[i]); ! 1909: -} ! 1910: -prbt(a) bfile *a; ! 1911: -{ int i; ! 1912: - printf("ht %d adv %d rdw %d flags ", a->height, a->advnc, ! 1913: - a->rdwrt); ! 1914: - for(i = 0; i <= MXHT; i++) ! 1915: - printf(" %d", a->flag[i]); ! 1916: - putchar('\n'); ! 1917: - printf("nodes "); ! 1918: - for(i = 0; i <= MXHT; i++) ! 1919: - printf(" %d", a->loc[i]); ! 1920: - putchar('\n'); ! 1921: - printf("rdkey #%d:", a->rdptr.rnum); ! 1922: - printf(":\n"); ! 1923: -} ! 1924: -tprnode(a) hdr *a; ! 1925: -{ int i; ! 1926: - dkey *q; ! 1927: - prhdr(a); ! 1928: - q = (dkey *)(a+1); ! 1929: - for(i = 0; i < a->kcnt; i++) { ! 1930: - if(a->hlev == 0) ! 1931: - prlfa(lfadr(a, i)); ! 1932: - else prnda(ndadr(a, i)); ! 1933: - prkey(q); ! 1934: - q = (dkey *)((char *)q + q->dlen); ! 1935: - } ! 1936: - if(a->hlev) ! 1937: - prnda(ndadr(a, i)); ! 1938: - putchar('\n'); ! 1939: -} ! 1940: -checknode(a) ! 1941: -hdr *a; ! 1942: -{ int i; ! 1943: - char *p; ! 1944: - for(i = 0, p = (char *)(a + 1); i < a->kcnt; i++) ! 1945: - p += *p; ! 1946: - i = p - (char *)a + nfree(a) + sizeof(trailer); ! 1947: - if(a->hlev) ! 1948: - i += (a->kcnt + 1) * sizeof(ndaddr); ! 1949: - else if(!treeonly(it)) ! 1950: - i += a->kcnt * sizeof(lfaddr); ! 1951: - if(i == NDSZ) { ! 1952: - printf("ok\n"); ! 1953: - return; ! 1954: - } ! 1955: - printf("nfree should be %d not %d\n", NDSZ - i + nfree(a), ! 1956: - nfree(a)); ! 1957: -} ! 1958: -prhdr(a) hdr *a; ! 1959: -{ ! 1960: - printf("stamp %ld kcnt %d type %d lev %d free %d\n", ! 1961: - a->hstamp, a->kcnt, a->htype, a->hlev, nfree(a)); ! 1962: -} ! 1963: -prlfa(a) lfaddr *a; ! 1964: -{ ! 1965: - if(treeonly(it)) ! 1966: - printf("\t"); ! 1967: - else ! 1968: - printf("%ld %u\t", a->lloc, a->llen); ! 1969: -} ! 1970: -prnda(a) ndaddr *a; ! 1971: -{ ! 1972: - printf("%u\t", *a); ! 1973: -} ! 1974: -prkey(b) dkey *b; ! 1975: -{ int i; ! 1976: - for(i = 0; i < b->dcom; i++) ! 1977: - putchar(' '); ! 1978: - for(i = 0; i < b->dlen - DKEYSZ; i++) ! 1979: - putchar(b->dkey[i]); ! 1980: - putchar('\n'); ! 1981: -} ! 1982: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:bttest.c\n"}; ! 1983: -/*0111000111010001*/ ! 1984: //GO.SYSIN DD bttest.c ! 1985: echo bwrite.c 1>&2 ! 1986: sed 's/.//' >bwrite.c <<'//GO.SYSIN DD bwrite.c' ! 1987: -#include "cbt.h" ! 1988: -#include "pr.h" ! 1989: - ! 1990: -typedef union { ! 1991: - ndaddr na; ! 1992: - lfaddr la; ! 1993: -} addr; ! 1994: -static char splitting[MXHT+1]; ! 1995: -extern bfile *curbf; ! 1996: -extern ndaddr oldnode(), newnode(); ! 1997: -extern char *malloc(); ! 1998: - ! 1999: -extern long brecwrite(); ! 2000: - ! 2001: -bwrite(bf, key, rec) mbuf key, rec; bfile *bf; ! 2002: -{ addr u; ! 2003: - int n; ! 2004: - if(bf == NULL) ! 2005: - return(EOF); ! 2006: - if(!bf->rdwrt) { ! 2007: - errno = BNOWRITE; ! 2008: - return(EOF); ! 2009: - } ! 2010: - if(notran(bf)) ! 2011: - return(EOF); ! 2012: - if(key.mlen > MAXKLEN) ! 2013: - return(EOF); ! 2014: - if(!treeonly(bf)) { ! 2015: - u.la.llen = rec.mlen; ! 2016: - u.la.lloc = brecwrite(rec); ! 2017: - if(u.la.lloc == EOF) ! 2018: - return(EOF); ! 2019: - } ! 2020: - if(desce(bf, key, (private *)NULL) == EOF) ! 2021: - return(EOF); ! 2022: - n = xinsert(0, key, u); ! 2023: - (void) bseek(bf, key); ! 2024: - return(n); ! 2025: -} ! 2026: - ! 2027: -fixpath(bf) ! 2028: -bfile *bf; ! 2029: -{ addr u; ! 2030: - hdr *b; ! 2031: - int i, n, j; ! 2032: - for(i = 0; i < bf->height; i++) { ! 2033: - if(!mustwrite(bf, i)) ! 2034: - continue; ! 2035: - n = bf->loc[i]; ! 2036: - if((u.na = oldnode(i)) == EOF) ! 2037: - return(EOF); ! 2038: - b = bf->path[i+1]; ! 2039: - for(j = 0; j <= b->kcnt; j++) ! 2040: - if(*ndadr(b, j) == n) ! 2041: - break; ! 2042: - if(j > b->kcnt){ /* curtains, the parent doesn't point to us */ ! 2043: - errno = BFATAL; ! 2044: - return(EOF); ! 2045: - } ! 2046: - *ndadr(b, j) = u.na; ! 2047: - mustwrite(bf, i + 1) = 1; ! 2048: - } ! 2049: - return(0); ! 2050: -} ! 2051: - ! 2052: -xinsert(lev, key, u) mbuf key; addr u; ! 2053: -{ private x; ! 2054: - int n, dellen; ! 2055: - hdr *b = curbf->path[lev]; ! 2056: - char ba[NDSZ], bb[NDSZ]; ! 2057: - dkey *dx, *dy; ! 2058: - if(splitting[lev]) ! 2059: - if(desce(curbf, key, (private *)NULL) == EOF) ! 2060: - return(EOF); ! 2061: - n = xscan(b, key, &x); ! 2062: - if(x.match == FOUND) { ! 2063: - if(treeonly(curbf)) ! 2064: - return(FOUND); ! 2065: - else if(lev) ! 2066: - *ndadr(b, n) = u.na; ! 2067: - else ! 2068: - *lfadr(b, n) = u.la; ! 2069: - mustwrite(curbf, lev) = 1; ! 2070: - return(FOUND); ! 2071: - } ! 2072: - dx = (dkey *)ba; ! 2073: - dy = (dkey *)bb; ! 2074: - dellen = newx(&x, key, dx, dy); ! 2075: - if(lev) ! 2076: - dellen += sizeof(ndaddr); ! 2077: - else if(!treeonly(curbf)) ! 2078: - dellen += sizeof(lfaddr); ! 2079: - if(dellen > nfree(b)) { ! 2080: - if(nsplit(lev) == EOF) ! 2081: - return(EOF); ! 2082: - splitting[lev] = 1; ! 2083: - n = xinsert(lev, key, u); ! 2084: - splitting[lev] = 0; ! 2085: - return(n); ! 2086: - } ! 2087: - b = curbf->path[lev]; /* with thanks to brian meekings */ ! 2088: - addaddr(b, n, u); ! 2089: - newkeys(b, &x, dx, dy); ! 2090: - b->kcnt++; ! 2091: - nfree(b) -= dellen; ! 2092: - mustwrite(curbf, lev) = 1; ! 2093: - return(NOTFOUND); ! 2094: -} ! 2095: - ! 2096: -newx(x, key, c, d) private *x; mbuf key; dkey *c, *d; ! 2097: -{ int i, j; ! 2098: - if(x->match != EOF) ! 2099: - c->dcom = x->ocom; ! 2100: - else c->dcom = x->ncom; ! 2101: - i = key.mlen - c->dcom; ! 2102: - c->dlen = DKEYSZ + i; ! 2103: - mvgbt(c->dkey, key.mdata + c->dcom, i); ! 2104: - if(x->match == EOF) ! 2105: - return(c->dlen); ! 2106: - j = x->ncom - x->d->dcom; ! 2107: - d->dcom = x->ncom; ! 2108: - d->dlen = x->d->dlen - j; ! 2109: - mvgbt(d->dkey, x->d->dkey + j, d->dlen - DKEYSZ); ! 2110: - return(c->dlen - j); ! 2111: -} ! 2112: - ! 2113: -addaddr(b, n, u) ! 2114: -hdr *b; ! 2115: -addr u; ! 2116: -{ ! 2117: - if(b->hlev) { ! 2118: - mvgbt((char *)ndadr(b, b->kcnt + 1), ! 2119: - (char *)ndadr(b, b->kcnt), ! 2120: - sizeof(ndaddr) * (b->kcnt + 1 - n) ); ! 2121: - *ndadr(b, n) = u.na; ! 2122: - return; ! 2123: - } ! 2124: - if(treeonly(curbf)) ! 2125: - return; ! 2126: - mvgbt((char *)lfadr(b, b->kcnt), (char *)lfadr(b, b->kcnt - 1), ! 2127: - sizeof(lfaddr) * (b->kcnt - n)); ! 2128: - *lfadr(b, n) = u.la; ! 2129: -} ! 2130: - ! 2131: -newkeys(b, x, c, d) ! 2132: -hdr *b; ! 2133: -private *x; ! 2134: -dkey *c, *d; ! 2135: -{ int n; ! 2136: - char *ffree; ! 2137: - if(b->hlev) ! 2138: - ffree = (char *)ndadr(b, b->kcnt) - nfree(b); ! 2139: - else if(treeonly(curbf)) ! 2140: - ffree = (char *)&nfree(b) - nfree(b); ! 2141: - else ! 2142: - ffree = (char *)lfadr(b, b->kcnt - 1) - nfree(b); ! 2143: - if(x->match != EOF) { ! 2144: - n = c->dlen + d->dlen; ! 2145: - n -= x->d->dlen; ! 2146: - mvgbt((char *)x->d + n, (char *)x->d, ffree - (char *)x->d); ! 2147: - mvgbt((char *)x->d, (char *)c, c->dlen); ! 2148: - mvgbt((char *)x->d + c->dlen, (char *)d, d->dlen); ! 2149: - } ! 2150: - else if(b->kcnt > 0) ! 2151: - mvgbt((char *)x->d + x->d->dlen, (char *)c, c->dlen); ! 2152: - else ! 2153: - mvgbt((char *)x->d, (char *)c, c->dlen); ! 2154: -} ! 2155: - ! 2156: -nsplit(lev) ! 2157: -{ dkey *tod, *fromd; ! 2158: - char prefix[MAXKLEN + 10]; ! 2159: - hdr *b = curbf->path[lev]; ! 2160: - mbuf key; ! 2161: - addr u; ! 2162: - union { ! 2163: - lfaddr *la; ! 2164: - ndaddr *na; ! 2165: - } from, to; ! 2166: - int mvd, x, i, count, n; ! 2167: - hdr *ha; ! 2168: - char a[NDSZ]; ! 2169: - ! 2170: - x = (NDSZ - sizeof(hdr) - sizeof(trailer)) / 2; ! 2171: - ha = (hdr *) a; ! 2172: - mvd = count = 0; ! 2173: - tod = (dkey *)(ha + 1); ! 2174: - fromd = (dkey *)(b + 1); ! 2175: - if(lev == 0) { ! 2176: - to.la = lfadr(ha, 0); ! 2177: - from.la = lfadr(b, 0); ! 2178: - } ! 2179: - else { ! 2180: - to.na = ndadr(ha, 0); ! 2181: - from.na = ndadr(b, 0); ! 2182: - } ! 2183: - *ha = *b; ! 2184: - n = (b->kcnt + 1)/2; ! 2185: - if(lev && b->kcnt - n <= 1) ! 2186: - n--; ! 2187: - for(; count < n && mvd <= x; count++) { ! 2188: - mvgbt((char *)tod, (char *)fromd, fromd->dlen); ! 2189: - mvd += fromd->dlen; ! 2190: - tod = (dkey *)((char *)tod + fromd->dlen); ! 2191: - fromd = (dkey *)((char *)fromd + fromd->dlen); ! 2192: - if(lev) { ! 2193: - *to.na-- = *from.na--; ! 2194: - mvd += sizeof(ndaddr); ! 2195: - } ! 2196: - else if(!treeonly(curbf)) { ! 2197: - *to.la-- = *from.la--; ! 2198: - mvd += sizeof(lfaddr); ! 2199: - } ! 2200: - } ! 2201: - if(lev) { /* another pointer for non-leaves */ ! 2202: - *to.na-- = *from.na--; ! 2203: - mvd += sizeof(ndaddr); ! 2204: - } ! 2205: - ha->kcnt = count; ! 2206: - nfree(ha) = NDSZ - sizeof(hdr) - sizeof(trailer) - mvd; ! 2207: - /* if lev == 0, we promote the last key, else the next key */ ! 2208: - key.mlen = lastkey(ha, prefix); ! 2209: - if(lev) { ! 2210: - mvgbt(prefix + fromd->dcom, fromd->dkey, fromd->dlen - DKEYSZ); ! 2211: - key.mlen = fromd->dcom + fromd->dlen - DKEYSZ; ! 2212: - count++; ! 2213: - fromd = (dkey *)((char *)fromd + fromd->dlen); ! 2214: - } ! 2215: - u.na = newnode(ha); ! 2216: - if(u.na == EOF) { /* error while splitting */ ! 2217: - curbf->fatal++; ! 2218: - return(EOF); ! 2219: - } ! 2220: - key.mdata = prefix; ! 2221: - /* other half */ ! 2222: - if(lev == 0) ! 2223: - to.la = lfadr(ha, 0); ! 2224: - else ! 2225: - to.na = ndadr(ha, 0); ! 2226: - tod = (dkey *)(ha + 1); ! 2227: - tod->dcom = 0; ! 2228: - tod->dlen = fromd->dlen + fromd->dcom; ! 2229: - mvgbt(tod->dkey, prefix, fromd->dcom); ! 2230: - mvgbt(tod->dkey + fromd->dcom, fromd->dkey, fromd->dlen - DKEYSZ); ! 2231: - mvd = tod->dlen; ! 2232: - fromd = (dkey *)((char *)fromd + fromd->dlen); ! 2233: - tod = (dkey *)((char *)tod + tod->dlen); ! 2234: - if(lev) { ! 2235: - *to.na-- = *from.na--; ! 2236: - mvd += sizeof(ndaddr); ! 2237: - } ! 2238: - else if(!treeonly(curbf)) { ! 2239: - *to.la-- = *from.la--; ! 2240: - mvd += sizeof(lfaddr); ! 2241: - } ! 2242: - count++; ! 2243: - for(i = 1; count < b->kcnt; i++, count++) { ! 2244: - mvgbt((char *)tod, (char *)fromd, fromd->dlen); ! 2245: - mvd += fromd->dlen; ! 2246: - tod = (dkey *)((char *)tod + tod->dlen); ! 2247: - fromd = (dkey *)((char *)fromd + fromd->dlen); ! 2248: - if(lev) { ! 2249: - *to.na-- = *from.na--; ! 2250: - mvd += sizeof(ndaddr); ! 2251: - } ! 2252: - else if(!treeonly(curbf)) { ! 2253: - *to.la-- = *from.la--; ! 2254: - mvd += sizeof(lfaddr); ! 2255: - } ! 2256: - ! 2257: - } ! 2258: - if(lev) { ! 2259: - *to.na-- = *from.na--; ! 2260: - mvd += sizeof(ndaddr); ! 2261: - } ! 2262: - ha->kcnt = i; ! 2263: - nfree(ha) = NDSZ - sizeof(hdr) - sizeof(trailer) - mvd; ! 2264: - mvgbt((char *)b, (char *)ha, NDSZ); ! 2265: - mustwrite(curbf, lev) = 1; ! 2266: - if(lev < curbf->height) { ! 2267: - if(xinsert(lev + 1, key, u) == EOF) { ! 2268: - curbf->fatal++; ! 2269: - return(EOF); ! 2270: - } ! 2271: - } ! 2272: - else ! 2273: - return(newroot(u, key, b)); ! 2274: - return(0); ! 2275: -} ! 2276: - ! 2277: -newroot(u, key, b) ! 2278: -addr u; ! 2279: -mbuf key; ! 2280: -hdr *b; ! 2281: -{ hdr *x; ! 2282: - dkey *d; ! 2283: - if(curbf->height >= MXHT) { ! 2284: - errno = BTALL; ! 2285: - curbf->fatal++; ! 2286: - return(EOF); ! 2287: - } ! 2288: - if((x = curbf->path[b->hlev + 1] = (hdr *)malloc(NDSZ)) == NULL) { ! 2289: - errno = BNOMEM; ! 2290: - curbf->fatal++; ! 2291: - return(EOF); ! 2292: - } ! 2293: - *x = *b; ! 2294: - x->hlev++; ! 2295: - d = (dkey *)(x + 1); ! 2296: - d->dlen = DKEYSZ + key.mlen; ! 2297: - d->dcom = 0; ! 2298: - mvgbt(d->dkey, key.mdata, key.mlen); ! 2299: - *ndadr(x, 0) = u.na; ! 2300: - *ndadr(x, 1) = curbf->loc[b->hlev] = newnode(b); ! 2301: - x->kcnt = 1; ! 2302: - nfree(x) = NDSZ - sizeof(hdr) - sizeof(trailer) - DKEYSZ ! 2303: - - key.mlen - 2 * sizeof(ndaddr); ! 2304: - mustwrite(curbf, ++curbf->height) = 1; ! 2305: - return(0); ! 2306: -} ! 2307: - ! 2308: -lastkey(b, s) ! 2309: -hdr *b; ! 2310: -char *s; ! 2311: -{ int i, n; ! 2312: - dkey *p; ! 2313: - p = (dkey *)(b + 1); ! 2314: - for(n = i = 0; i < b->kcnt; i++) { ! 2315: - mvgbt(s + p->dcom, p->dkey, p->dlen - DKEYSZ); ! 2316: - n = p->dlen + p->dcom - DKEYSZ; ! 2317: - p = (dkey *)((char *) p + p->dlen); ! 2318: - } ! 2319: - return(n); ! 2320: -} ! 2321: - ! 2322: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:bwrite.c\n"}; ! 2323: -/*0010010000010101*/ ! 2324: //GO.SYSIN DD bwrite.c ! 2325: echo diskrd.c 1>&2 ! 2326: sed 's/.//' >diskrd.c <<'//GO.SYSIN DD diskrd.c' ! 2327: -#include "cbt.h" ! 2328: - ! 2329: -extern bfile *curbf; ! 2330: -extern long lseek(); ! 2331: - ! 2332: -ndrd(lev, where) ndaddr where; ! 2333: -{ ! 2334: - register n; ! 2335: - if(mustwrite(curbf, lev)) { ! 2336: - /* do we ever get here? (yes, while splitting) */ ! 2337: - if(ndwrt(curbf->path[lev], curbf->loc[lev]) == EOF) ! 2338: - return(EOF); ! 2339: - mustwrite(curbf, lev) = 0; ! 2340: - } ! 2341: - if(lseek(curbf->tfd, where * (long)NDSZ, 0) == -1) ! 2342: - return(EOF); ! 2343: - if((n = read(curbf->tfd, (char *)curbf->path[lev], NDSZ)) != NDSZ) { ! 2344: - if(n >= 0) ! 2345: - errno = BRDERR; ! 2346: - return(EOF); ! 2347: - } ! 2348: - curbf->loc[lev] = where; ! 2349: - return(0); ! 2350: -} ! 2351: - ! 2352: -getincore(lev, where) ndaddr where; ! 2353: -{ ! 2354: - if(ndrd(lev, where) == EOF) ! 2355: - return(EOF); ! 2356: - if(curbf->path[lev]->hlev != lev) { ! 2357: - errno = BRDERR; ! 2358: - curbf->fatal++; ! 2359: - return(EOF); ! 2360: - } ! 2361: - return(0); ! 2362: -} ! 2363: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:diskrd.c\n"}; ! 2364: -/*1010100001000111*/ ! 2365: //GO.SYSIN DD diskrd.c ! 2366: echo diskwrt.c 1>&2 ! 2367: sed 's/.//' >diskwrt.c <<'//GO.SYSIN DD diskwrt.c' ! 2368: -#include "cbt.h" ! 2369: - ! 2370: -extern bfile *curbf; ! 2371: -extern long lseek(); ! 2372: - ! 2373: -ndwrt(b, where) hdr *b; ndaddr where; ! 2374: -{ ! 2375: - register n; ! 2376: - if(lseek(curbf->tfd, where * (long)NDSZ, 0) == -1) ! 2377: - return(EOF); ! 2378: - if((n = write(curbf->tfd, (char *)b, NDSZ)) != NDSZ) { /*unacceptable*/ ! 2379: - if(n >= 0) ! 2380: - errno = BIOWRT; ! 2381: - curbf->fatal++; ! 2382: - return(EOF); ! 2383: - } ! 2384: - return(0); ! 2385: -} ! 2386: - ! 2387: -long brecwrite(rec) mbuf rec; ! 2388: -{ long loc; ! 2389: - int n; ! 2390: - errno = 0; ! 2391: - loc = lseek(curbf->dfd, 0L, 2); ! 2392: - if((n = write(curbf->dfd, rec.mdata, rec.mlen)) == rec.mlen) ! 2393: - return(loc); ! 2394: - else if(n == -1 || errno) ! 2395: - return(EOF); ! 2396: - errno = BIOWRT; ! 2397: - return(EOF); ! 2398: -} ! 2399: - ! 2400: -ndaddr newnode(b) hdr *b; ! 2401: -{ long loc; ! 2402: - int n; ! 2403: - b->hstamp = tranid; ! 2404: - loc = lseek(curbf->tfd, 0L, 2); ! 2405: - if(loc == -1) ! 2406: - return(EOF); ! 2407: - if((n = write(curbf->tfd, (char *)b, NDSZ)) != NDSZ) ! 2408: - if(n < 0) ! 2409: - return(EOF); ! 2410: - else { ! 2411: - errno = BIOWRT; ! 2412: - return(EOF); ! 2413: - } ! 2414: - return(loc/NDSZ); ! 2415: -} ! 2416: - ! 2417: -ndaddr oldnode(lev) ! 2418: -{ int n; ! 2419: - ndaddr a; ! 2420: - if(curbf->path[lev]->hstamp != tranid) { ! 2421: - a = newnode(curbf->path[lev]); ! 2422: - if(a == EOF) ! 2423: - curbf->fatal++; ! 2424: - curbf->loc[lev] = a; ! 2425: - return(a); ! 2426: - } ! 2427: - if(lseek(curbf->tfd, (long)curbf->loc[lev]*NDSZ, 0) == EOF) ! 2428: - return(EOF); ! 2429: - if((n = write(curbf->tfd, (char *)curbf->path[lev], NDSZ)) != NDSZ) { ! 2430: - if(n >= 0) ! 2431: - errno = BIOWRT; ! 2432: - return(EOF); ! 2433: - } ! 2434: - mustwrite(curbf, lev) = 0; ! 2435: - return(curbf->loc[lev]); ! 2436: -} ! 2437: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:diskwrt.c\n"}; ! 2438: -/*0100101010000110*/ ! 2439: //GO.SYSIN DD diskwrt.c ! 2440: echo get.c 1>&2 ! 2441: sed 's/.//' >get.c <<'//GO.SYSIN DD get.c' ! 2442: -#include "stdio.h" ! 2443: -#include "cbt.h" ! 2444: -extern bfile *bopen(); ! 2445: -extern mbuf bkey(); ! 2446: - ! 2447: -char *index; ! 2448: -char *dfile; ! 2449: -char sep = '!'; ! 2450: -char preflg; ! 2451: -char nl; ! 2452: - ! 2453: -/* get key from index, print all records from dfile. ! 2454: - * default file names and separator in the index are as given ! 2455: - * preflg => prefix searching ! 2456: - */ ! 2457: -char line[256]; ! 2458: -char buf1[256], buf2[2048]; ! 2459: -bfile *bi, *bd; ! 2460: - ! 2461: -main(argc, argv) ! 2462: -char **argv; ! 2463: -{ int i; ! 2464: - char *p; ! 2465: - for(i = 1; i < argc && *argv[i] == '-'; i++) ! 2466: - for(p = argv[i] + 1; *(p-1) && *p; p++) ! 2467: - switch(*p) { ! 2468: - default: ! 2469: - fprintf(stderr, "unk flag %c\n", *p); ! 2470: - exit(1); ! 2471: - case 'p': ! 2472: - preflg = 1; ! 2473: - break; ! 2474: - case 'n': ! 2475: - nl = *++p; ! 2476: - break; ! 2477: - case 's': ! 2478: - sep = *++p; ! 2479: - break; ! 2480: - } ! 2481: - if(i < argc) { ! 2482: - dfile = argv[i++]; ! 2483: - bd = bopen(dfile, 0); ! 2484: - if(bd == NULL) { ! 2485: - perror(dfile); ! 2486: - exit(1); ! 2487: - } ! 2488: - } ! 2489: - if(i < argc) { ! 2490: - index = argv[i++]; ! 2491: - bi = bopen(index, 0); ! 2492: - if(bi == NULL) { ! 2493: - perror(index); ! 2494: - exit(1); ! 2495: - } ! 2496: - } ! 2497: - for(;;) { ! 2498: - (void) fgets(line, sizeof(line), stdin); ! 2499: - if(feof(stdin)) ! 2500: - exit(1); ! 2501: - for(p = line; *p && *p != '\n'; p++) ! 2502: - ; ! 2503: - if(*p == '\n') ! 2504: - *p = 0; ! 2505: - if(index) ! 2506: - doindex(); ! 2507: - dodata(); ! 2508: - } ! 2509: -} ! 2510: - ! 2511: -doindex() ! 2512: -{ mbuf key, found, newkey, rec; ! 2513: - int cnt; ! 2514: - char *q; ! 2515: - key.mlen = strlen(line); ! 2516: - key.mdata = line; ! 2517: - if(bseek(bi, key) == EOF) { ! 2518: - printf("not found\n"); ! 2519: - return; ! 2520: - } ! 2521: - for(cnt = 0; ; cnt++) { ! 2522: - if(bread(bi, &found, (mbuf *)NULL) == EOF) ! 2523: - break; ! 2524: - if(found.mlen < key.mlen || strncmp(found.mdata, line, key.mlen) ! 2525: - break; ! 2526: - if(!preflg && found.mdata[key.mlen] != sep) ! 2527: - break; ! 2528: - for(q = found.mdata; q < found.mdata + found.mlen; q++) ! 2529: - if(*q == sep) ! 2530: - break; ! 2531: - if(*q != sep) { ! 2532: - fprintf(stderr, "retrieved bad index:%s\n", ! 2533: - found.mdata); ! 2534: - continue; ! 2535: - } ! 2536: - newkey.mdata = ++q; ! 2537: - newkey.mlen = found.mlen - (q - found.mdata); ! 2538: - if(bseek(bd, newkey) != FOUND) { ! 2539: - fprintf(stderr, "erro, didn't find %s\n", ! 2540: - newkey.mdata); ! 2541: - continue; ! 2542: - } ! 2543: - bread(bd, (mbuf *)NULL &rec); ! 2544: - for(i = 0; i < rec.mlen; i++) ! 2545: - if(rec.mdata[i] != nl) ! 2546: - putchar(rec.mdata[i]); ! 2547: - else ! 2548: - putchar('\n'); ! 2549: - putchar('\n'); ! 2550: - } ! 2551: - if(cnt == 0) ! 2552: - printf("not found\n"); ! 2553: -} ! 2554: -/*1010001100101110*/ ! 2555: //GO.SYSIN DD get.c ! 2556: echo lib.c 1>&2 ! 2557: sed 's/.//' >lib.c <<'//GO.SYSIN DD lib.c' ! 2558: -#include "cbt.h" ! 2559: -mvgbt(to, from, ln) register char *from, *to; ! 2560: -{ ! 2561: - if(from > to) ! 2562: - while(ln-- > 0) *to++ = *from++; ! 2563: - else if(from < to) ! 2564: - { from += ln-1; ! 2565: - to += ln-1; ! 2566: - while(ln-- > 0) *to-- = *from--; ! 2567: - } ! 2568: -} ! 2569: - ! 2570: -prnode(b) ! 2571: -hdr *b; ! 2572: -{ int i; ! 2573: - char *p; ! 2574: - dkey *d; ! 2575: - ! 2576: - printf("kcnt %d htype %d hlev %d nfree %d ndsz %d\n", b->kcnt, b->htype, ! 2577: - b->hlev, nfree(b), NDSZ); ! 2578: - for(i = 0, p = (char *)(b+1); i < b->kcnt; i++) { ! 2579: - d = (dkey *)p; ! 2580: - prdkey(d); ! 2581: - p += d->dlen; ! 2582: - } ! 2583: - putchar('\n'); ! 2584: -} ! 2585: - ! 2586: -prdkey(d) ! 2587: -dkey *d; ! 2588: -{ int i; ! 2589: - printf("(%d,%d,", d->dlen, d->dcom); ! 2590: - for(i = 0; i < MAXKLEN &&i < d->dlen - DKEYSZ; i++) /* dlen unsigned */ ! 2591: - putchar(d->dkey[i]); ! 2592: - printf("),"); ! 2593: -} ! 2594: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:lib.c\n"}; ! 2595: -/*1001101011001110*/ ! 2596: //GO.SYSIN DD lib.c ! 2597: echo nodesz.c 1>&2 ! 2598: sed 's/.//' >nodesz.c <<'//GO.SYSIN DD nodesz.c' ! 2599: -#include "cbt.h" ! 2600: -your nodesize is NDSZ bytes. Except for checking, ! 2601: -nodesize should be the file system block size (cbt.h). ! 2602: -/*0100111000000100*/ ! 2603: //GO.SYSIN DD nodesz.c ! 2604: echo prelim.c 1>&2 ! 2605: sed 's/.//' >prelim.c <<'//GO.SYSIN DD prelim.c' ! 2606: -#include "stdio.h" ! 2607: -char line[129]; ! 2608: -main() ! 2609: -{ unsigned short n; ! 2610: - for(;;) { ! 2611: - fgets(line, sizeof(line), stdin); ! 2612: - if(feof(stdin)) ! 2613: - break; ! 2614: - n = strlen(line); ! 2615: - n--; ! 2616: - fwrite(&n, 1, sizeof(n), stdout); ! 2617: - fwrite(line, 1, n, stdout); ! 2618: - n = 0; ! 2619: - fwrite(&n, 1, sizeof(n), stdout); ! 2620: - } ! 2621: -} ! 2622: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/4/8:prelim.c\n"}; ! 2623: -/*1011011100100111*/ ! 2624: //GO.SYSIN DD prelim.c ! 2625: echo salvage.c 1>&2 ! 2626: sed 's/.//' >salvage.c <<'//GO.SYSIN DD salvage.c' ! 2627: -/* write out all records pointed to by level 0 blocks, ! 2628: - * whether or not the level 0 blocks are accessible. ! 2629: - * the output is like that of bcat -R, except that many keys ! 2630: - * will be duplicated ! 2631: - * In general, the later keys are more up to date ! 2632: - * btsalvage xxx | slvg | sort | slvg2 | cbt build -R newxxx ! 2633: - * is the optimistic way of slavaging a b-tree in which the non-leaves ! 2634: - * have been clobbered ! 2635: - */ ! 2636: -#include "cbt.h" ! 2637: -#include "pr.h" ! 2638: -#include "stdio.h" ! 2639: - ! 2640: -bfile *curbf; ! 2641: -extern bfile *newtran(), *xopen(); ! 2642: -extern char *malloc(), *strcpy(), *realloc(); ! 2643: -extern long lseek(); ! 2644: -char keybuf[NDSZ]; ! 2645: -char *recbuf; ! 2646: -int buflen; ! 2647: - ! 2648: -main(argc, argv) ! 2649: -char **argv; ! 2650: -{ bfile *bf; ! 2651: - mbuf key, rec; ! 2652: - int n; ! 2653: - if(argc != 2) { ! 2654: - fprintf(stderr, "usage: salvage file\n"); ! 2655: - exit(1); ! 2656: - } ! 2657: - bf = xopen(argv[1], 0); ! 2658: - key.mdata = keybuf; ! 2659: - if(bf == NULL) { ! 2660: - fprintf(stderr, "couldn't open %s\n", argv[1]); ! 2661: - exit(1); ! 2662: - } ! 2663: - while((n = breclen(bf)) > buflen) { ! 2664: - if(buflen == 0) ! 2665: - recbuf = malloc(buflen = 1024); ! 2666: - else ! 2667: - recbuf = realloc(recbuf, buflen += 1024); ! 2668: - if(recbuf == NULL) { ! 2669: - fprintf(stderr, "recbuf[%d] failed\n", buflen); ! 2670: - exit(1); ! 2671: - } ! 2672: - rec.mdata = recbuf; ! 2673: - } ! 2674: - for(;;) { ! 2675: - xread(bf, &key, &rec); ! 2676: - write(1, (char *)&key.mlen, 2); ! 2677: - write(1, key.mdata, key.mlen); ! 2678: - write(1, (char *)&rec.mlen, 2); ! 2679: - write(1, rec.mdata, rec.mlen); ! 2680: - } ! 2681: -} ! 2682: -bfile *xopen(s, typ) char *s; /* typ is 0 or 2 */ ! 2683: -{ bfile *p; ! 2684: - int n, i; ! 2685: - ! 2686: - p = alloc(bfile); ! 2687: - if(p == NULL) ! 2688: - goto nomem; ! 2689: - n = strlen(s); ! 2690: - p->fname = malloc((unsigned)n + 3); ! 2691: - if(p->fname == NULL) ! 2692: - goto nomem; ! 2693: - (void) strcpy(p->fname, s); ! 2694: - strcpy(p->fname + n, ".T"); ! 2695: - if((p->tfd = open(p->fname, typ)) == -1) { ! 2696: - free(p->fname); ! 2697: - free((char *)p); ! 2698: - return(NULL); ! 2699: - } ! 2700: - p->rdwrt = typ; ! 2701: - p->fatal = p->advnc = 0; ! 2702: - p->altname = NULL; ! 2703: - for(i = 0; i <= MXHT; i++) { ! 2704: - p->path[i] = NULL; ! 2705: - p->flag[i] = 0; ! 2706: - p->loc[i] = 0; ! 2707: - } ! 2708: - p->path[0] = (hdr *)malloc(NDSZ); ! 2709: - if(p->path[0] == NULL) ! 2710: - goto nomem; ! 2711: - curbf = p; ! 2712: - if(read(p->tfd, (char *)p->path[0], NDSZ) != NDSZ) { ! 2713: - perror(" first read"); ! 2714: - exit(1); ! 2715: - } ! 2716: - strcpy(p->fname + n, ".F"); ! 2717: - if(!treeonly(p) && (p->dfd = open(p->fname, typ)) == -1) { ! 2718: - (void) close(p->tfd); ! 2719: - free(p->fname); ! 2720: - free(p->path[0]); ! 2721: - free((char *)p); ! 2722: - return(NULL); ! 2723: - } ! 2724: - else if(treeonly(p)) ! 2725: - p->dfd = -1; ! 2726: - p->fname[n] = 0; ! 2727: - p->height = p->path[0]->hlev; ! 2728: - xfirst(p); ! 2729: - return(p); ! 2730: -nomem: ! 2731: - errno = BNOMEM; ! 2732: - return(NULL); ! 2733: -} ! 2734: - ! 2735: -breclen(bf) bfile *bf; ! 2736: -{ ! 2737: - if(bf == NULL) ! 2738: - return(EOF); ! 2739: - if(notran(bf)) ! 2740: - return(EOF); ! 2741: - if(bf->advnc) ! 2742: - xadvance(); ! 2743: - if(bf->rdptr.rnum >= bf->path[0]->kcnt) ! 2744: - return(EOF); ! 2745: - if(treeonly(bf)) ! 2746: - return(0); ! 2747: - return(lfadr(bf->path[0], bf->rdptr.rnum)->llen); ! 2748: -} ! 2749: - ! 2750: -xread(bf, key, rec) bfile *bf; mbuf *key, *rec; ! 2751: -{ ! 2752: - dkey *d; ! 2753: - lfaddr *x; ! 2754: - if(bf == NULL) ! 2755: - return(NULL); ! 2756: - if(notran(bf)) ! 2757: - return(EOF); ! 2758: - if(bf->advnc) ! 2759: - xadvance(); ! 2760: - if(bf->rdptr.rnum >= bf->path[0]->kcnt) ! 2761: - return(EOF); ! 2762: - if(key != NULL) { ! 2763: - d = bf->rdptr.rptr; ! 2764: - key->mlen = d->dlen - DKEYSZ + d->dcom; ! 2765: - mvgbt(key->mdata, bf->rdptr.rpref, d->dcom); ! 2766: - mvgbt(key->mdata + d->dcom, d->dkey, d->dlen - DKEYSZ); ! 2767: - } ! 2768: - if(rec != NULL && !treeonly(bf)) { ! 2769: - x = lfadr(bf->path[0], bf->rdptr.rnum); ! 2770: - rec->mlen = x->llen; ! 2771: - if(rec->mlen != 0) { ! 2772: - (void) lseek(bf->dfd, x->lloc, 0); ! 2773: - (void) read(bf->dfd, rec->mdata, (int)rec->mlen); ! 2774: - } ! 2775: - /* errors on read ? */ ! 2776: - } ! 2777: - bf->advnc = 1; ! 2778: - return(0); ! 2779: -} ! 2780: - ! 2781: -xstep(level) ! 2782: -/* ran off the end of node at lev-1 */ ! 2783: -{ hdr *b; ! 2784: - int n, i; ! 2785: - ndaddr u; ! 2786: - do { ! 2787: - n = read(curbf->tfd, (char *)curbf->path[0], NDSZ); ! 2788: - if(n == 0) ! 2789: - exit(0); ! 2790: - if(n != NDSZ) { ! 2791: - perror("xstep"); ! 2792: - exit(1); ! 2793: - } ! 2794: - } while(curbf->path[0]->hlev != 0); ! 2795: -} ! 2796: - ! 2797: -xadvance() ! 2798: -{ mbuf x; ! 2799: - dkey *dold, *dnew; ! 2800: - struct rdptr *y = &curbf->rdptr; ! 2801: - curbf->advnc = 0; ! 2802: - dold = y->rptr; ! 2803: - if(++y->rnum < curbf->path[0]->kcnt) { ! 2804: - dnew = (dkey *)((char *)dold + dold->dlen); ! 2805: - if(dold->dcom < dnew->dcom) ! 2806: - mvgbt(y->rpref + dold->dcom, dold->dkey, dnew->dcom - dold->dcom); ! 2807: - y->rptr = dnew; ! 2808: - return; ! 2809: - } ! 2810: - if(xstep(1) == EOF) { ! 2811: - y->rnum = curbf->path[0]->kcnt + 1; ! 2812: - y->rptr = NULL; ! 2813: - } ! 2814: - else { ! 2815: - y->rnum = 0; ! 2816: - y->rptr = (dkey *)(curbf->path[0] + 1); ! 2817: - } ! 2818: -} ! 2819: - ! 2820: -xfirst(p) ! 2821: -bfile *p; ! 2822: -{ int n; ! 2823: - while(p->path[0]->hlev != 0) { ! 2824: - n = read(p->tfd, (char *)p->path[0], NDSZ); ! 2825: - if(n == 0) { ! 2826: - fprintf(stderr, "empty?\n"); ! 2827: - exit(0); ! 2828: - } ! 2829: - if(n != NDSZ) { ! 2830: - perror("xfirst"); ! 2831: - exit(1); ! 2832: - } ! 2833: - } ! 2834: - curbf->rdptr.rnum = 0; ! 2835: - curbf->rdptr.rptr = (dkey *)(curbf->path[0] + 1); ! 2836: -} ! 2837: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:salvage.c\n"}; ! 2838: -/*0000110110110000*/ ! 2839: //GO.SYSIN DD salvage.c ! 2840: echo seek.c 1>&2 ! 2841: sed 's/.//' >seek.c <<'//GO.SYSIN DD seek.c' ! 2842: -#include "cbt.h" ! 2843: -#include "pr.h" ! 2844: - ! 2845: -extern bfile *curbf; ! 2846: - ! 2847: -xscan(b, key, x) hdr *b; mbuf key; private *x; ! 2848: -{ int ncom, i, n, val; ! 2849: - char a, *p; ! 2850: - dkey *d; ! 2851: - ! 2852: - n = i = ncom = 0; ! 2853: - val = NOTFOUND; ! 2854: - p = (char *)(b+1); ! 2855: - d = (dkey *)p; ! 2856: - for(; i < b->kcnt; i++, p += d->dlen) { ! 2857: - d = (dkey *)p; ! 2858: - if(ncom < d->dcom) ! 2859: - goto onward; ! 2860: - if(ncom > d->dcom) { ! 2861: - if(x != NULL) { ! 2862: - x->match = val; ! 2863: - x->ncom = d->dcom; ! 2864: - x->ocom = ncom; ! 2865: - x->d = d; ! 2866: - } ! 2867: - return(i); ! 2868: - } ! 2869: - for(n = ncom; ncom < key.mlen && ncom - n < d->dlen - DKEYSZ; ncom++) { ! 2870: - if((a = d->dkey[ncom - n]) == key.mdata[ncom]) ! 2871: - continue; ! 2872: - if(a < key.mdata[ncom]) ! 2873: - goto onward; ! 2874: - goto done; ! 2875: - } ! 2876: - if(ncom == key.mlen) { ! 2877: - if(ncom == d->dlen - DKEYSZ + d->dcom) ! 2878: - val = FOUND; ! 2879: - goto done; ! 2880: - } ! 2881: - onward: ; ! 2882: - } ! 2883: -/* infinity: */ ! 2884: - if(x != NULL) { ! 2885: - x->match = EOF; ! 2886: - x->ncom = ncom; ! 2887: - x->ocom = n; ! 2888: - x->d = d; ! 2889: - } ! 2890: - return(i); ! 2891: -done: ! 2892: - if(x != NULL) { ! 2893: - x->match = val; ! 2894: - x->ncom = ncom; ! 2895: - x->ocom = n; ! 2896: - x->d = d; ! 2897: - } ! 2898: - return(i); ! 2899: -} ! 2900: - ! 2901: -desce(bf, key, x) bfile *bf; mbuf key; private *x; ! 2902: -{ int i, j; ! 2903: - ndaddr u; ! 2904: - for(i = bf->height; i > 0; i--) { ! 2905: - j = xscan(bf->path[i], key, (private *)NULL); ! 2906: - u = *ndadr(bf->path[i], j); ! 2907: - if(bf->loc[i-1] != u) ! 2908: - if(getincore(i - 1, u) == EOF) ! 2909: - return(EOF); ! 2910: - } ! 2911: - i = xscan(bf->path[0], key, x); ! 2912: - return(i); ! 2913: -} ! 2914: - ! 2915: -step(level) ! 2916: -/* ran off the end of node at lev-1 */ ! 2917: -{ hdr *b; ! 2918: - int n, i; ! 2919: - ndaddr u; ! 2920: - if(level > curbf->height) ! 2921: - return(EOF); ! 2922: - n = curbf->loc[level - 1]; ! 2923: - b = curbf->path[level]; ! 2924: - for(i = 0; i <= b->kcnt; i++) ! 2925: - if(*ndadr(b, i) == n) ! 2926: - break; ! 2927: - if(i >= b->kcnt) ! 2928: - return(step(level + 1)); ! 2929: - n = level; ! 2930: - i++; ! 2931: - do { ! 2932: - u = *ndadr(curbf->path[n], i); ! 2933: - if(curbf->loc[n-1] != u) ! 2934: - if(getincore(n - 1, u) == EOF) ! 2935: - return(EOF); ! 2936: - i = 0; ! 2937: - } while(--n > 0); ! 2938: - return(0); ! 2939: -} ! 2940: - ! 2941: -advance() ! 2942: -{ dkey *dold, *dnew; ! 2943: - struct rdptr *y = &curbf->rdptr; ! 2944: - curbf->advnc = 0; ! 2945: - dold = y->rptr; ! 2946: - if(++y->rnum < curbf->path[0]->kcnt) { ! 2947: - dnew = (dkey *)((char *)dold + dold->dlen); ! 2948: - if(dold->dcom < dnew->dcom) ! 2949: - mvgbt(y->rpref + dold->dcom, dold->dkey, dnew->dcom - dold->dcom); ! 2950: - y->rptr = dnew; ! 2951: - return(0); ! 2952: - } ! 2953: - errno = 0; ! 2954: - if(step(1) == EOF) { ! 2955: - if(errno) ! 2956: - return(EOF); ! 2957: - y->rnum = curbf->path[0]->kcnt + 1; ! 2958: - y->rptr = NULL; ! 2959: - } ! 2960: - else { ! 2961: - y->rnum = 0; ! 2962: - y->rptr = (dkey *)(curbf->path[0] + 1); ! 2963: - } ! 2964: - return(0); ! 2965: -} ! 2966: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:seek.c\n"}; ! 2967: -/*1100011110101111*/ ! 2968: -/*1101111110111111*/ ! 2969: //GO.SYSIN DD seek.c ! 2970: echo slvg.c 1>&2 ! 2971: sed 's/.//' >slvg.c <<'//GO.SYSIN DD slvg.c' ! 2972: -#include "stdio.h" ! 2973: -/* change the output of btsalvage or btcat -R to sortable */ ! 2974: -/* an 8 byte sortable sequence number is appended to each key ! 2975: - * that slvg2 can keep only the last record with a given key */ ! 2976: - ! 2977: -char *buf; ! 2978: -int buflen; ! 2979: -long reccnt; ! 2980: -extern char *malloc(), *realloc(); ! 2981: - ! 2982: -main() ! 2983: -{ int n, i, j; ! 2984: - for(;;) { ! 2985: - if(read(0, &n, 2) == 0) ! 2986: - exit(0); ! 2987: - if(n > buflen) ! 2988: - space(n); ! 2989: - read(0, buf, n); ! 2990: - reccnt++; ! 2991: - out(buf, n, '\t'); ! 2992: - countout(); ! 2993: - read(0, &n, 2); ! 2994: - if(n > buflen) ! 2995: - space(n); ! 2996: - read(0, buf, n); ! 2997: - j = n; ! 2998: - for(i = 0; i < 4; i++) { ! 2999: - putchar('a' + (j & 0xf)); ! 3000: - j >>= 4; ! 3001: - } ! 3002: - out(buf, n, '\n'); ! 3003: - } ! 3004: -} ! 3005: - ! 3006: -space(n) ! 3007: -{ ! 3008: - while(n > buflen) { ! 3009: - if(buflen == 0) ! 3010: - buf = malloc(buflen = 1024); ! 3011: - else ! 3012: - buf = realloc(buf, buflen += 1024); ! 3013: - if(buf == 0) { ! 3014: - fprintf(stderr, "buf[%d]failed\n", buflen); ! 3015: - exit(1); ! 3016: - } ! 3017: - ! 3018: - } ! 3019: -} ! 3020: - ! 3021: -out(s, n, c) ! 3022: -char *s; ! 3023: -{ ! 3024: - while(n-- > 0) { ! 3025: - putchar('3' + ((*s >> 6) & 3)); ! 3026: - putchar((*s & 077) + ' '); ! 3027: - s++; ! 3028: - } ! 3029: - putchar(c); ! 3030: -} ! 3031: - ! 3032: -countout() ! 3033: -{ int i, n; ! 3034: - n = reccnt; ! 3035: - for(i = 7; i >= 0; i--) ! 3036: - putchar('0' + ((n >> (4*i)) & 077)); ! 3037: -} ! 3038: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/7:slvg.c\n"}; ! 3039: -/*1100100010001010*/ ! 3040: //GO.SYSIN DD slvg.c ! 3041: echo slvg2.c 1>&2 ! 3042: sed 's/.//' >slvg2.c <<'//GO.SYSIN DD slvg2.c' ! 3043: -/* takes the output fromt slvg | sort and puts it back into ! 3044: - * form suitable for btbuild -R ! 3045: - * it reduces the two byte codes, and it only keeps the ! 3046: - * last version of each record. ! 3047: - * the input format is ! 3048: - * key tab 8-bytes-of-sequence 4-byete-of-value-len value newline ! 3049: - */ ! 3050: -#include "stdio.h" ! 3051: -#define BUF 20000 ! 3052: -char bufa[BUF], bufb[BUF]; ! 3053: -char *old = bufa; ! 3054: -char *new = bufb; ! 3055: -int len; ! 3056: - ! 3057: -main() ! 3058: -{ char *p, *q; ! 3059: - int c, i; ! 3060: -loop: ! 3061: - for(p = new; (c = getchar()) != '\t' && c != EOF; *p++ = c) ! 3062: - if(p - new >= BUF) { ! 3063: - fprintf(stderr, "recompile slvg2 with more BUF\n"); ! 3064: - exit(1); ! 3065: - } ! 3066: - if(c == EOF) ! 3067: - exit(0); ! 3068: - *p++ = 0; ! 3069: - for(i = 0; i < 8; i++) ! 3070: - getchar(); ! 3071: - if((p - new != len || strcmp(old, new) != 0) && len > 0) { ! 3072: - out(old); ! 3073: - dorest(); ! 3074: - } ! 3075: - len = p - new; ! 3076: - q = old; ! 3077: - old = new; ! 3078: - new = q; ! 3079: - ignore(); ! 3080: - goto loop; ! 3081: -} ! 3082: - ! 3083: -out(s) ! 3084: -char *s; ! 3085: -{ short n; ! 3086: - char c; ! 3087: - n = (len - 1)/2; ! 3088: - fwrite((char *)&n, 1, 2, stdout); ! 3089: - for(; *s; s++) { ! 3090: - c = (*s - '3') << 6; ! 3091: - c |= *++s- ' '; ! 3092: - putchar(c); ! 3093: - } ! 3094: -} ! 3095: - ! 3096: -ignore() ! 3097: -{ int c; ! 3098: - while((c = getchar()) != '\n' && c != EOF) ! 3099: - ; ! 3100: - if(c == EOF) ! 3101: - exit(0); ! 3102: -} ! 3103: - ! 3104: -dorest() ! 3105: -{ unsigned short n; ! 3106: - int i; ! 3107: - /* 4 bytes of length */ ! 3108: - for(i = n = 0; i < 4; i++) ! 3109: - n |= (getchar() - 'a') << (4*i); ! 3110: - fwrite((char *)&n, 1, 2, stdout); ! 3111: - while((i = getchar()) != '\n' && i != EOF) { ! 3112: - n = (i - '3') << 6; ! 3113: - n |= getchar() - ' '; ! 3114: - putchar(n); ! 3115: - } ! 3116: -} ! 3117: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:slvg2.c\n"}; ! 3118: -/*0010100001111110*/ ! 3119: -/*1110001101011101*/ ! 3120: //GO.SYSIN DD slvg2.c ! 3121: echo tran.c 1>&2 ! 3122: sed 's/.//' >tran.c <<'//GO.SYSIN DD tran.c' ! 3123: -/* place holders */ ! 3124: -#include "cbt.h" ! 3125: -extern long time(); ! 3126: -long tranid; ! 3127: - ! 3128: -long getlpid() ! 3129: -{ ! 3130: - return(time((long *)0) ^ 077777 + getpid()); ! 3131: -} ! 3132: -extern bfile *curbf; ! 3133: -bfile *newtran(bf) bfile *bf; ! 3134: -{ ! 3135: - tranid = getlpid(); ! 3136: - return(bf); ! 3137: -} ! 3138: - ! 3139: -notran(bf) bfile *bf; ! 3140: -{ ! 3141: - curbf = bf; ! 3142: - if(bf->fatal) { ! 3143: - if(bf->fatal++ < 2) { ! 3144: - errno = BFATAL; ! 3145: - return(EOF); ! 3146: - } ! 3147: - perror("btree repeatedly accessed after fatal error"); ! 3148: - abort(); ! 3149: - } ! 3150: - return(0); ! 3151: -} ! 3152: - ! 3153: -trabort() ! 3154: -{ ! 3155: - errno = BUTRAN; ! 3156: - tranid = 0; ! 3157: -} ! 3158: - ! 3159: -intran() ! 3160: -{ ! 3161: - return(0); ! 3162: -} ! 3163: - ! 3164: -rmtran(bf) bfile *bf; ! 3165: -{ ! 3166: -} ! 3167: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:tran.c\n"}; ! 3168: -/*0001010110001011*/ ! 3169: //GO.SYSIN DD tran.c ! 3170: echo makefile 1>&2 ! 3171: sed 's/.//' >makefile <<'//GO.SYSIN DD makefile' ! 3172: -.SUFFIXES: .x .o .c ! 3173: -.c.o: ! 3174: - $(CC) $(CFLAGS) -c $< ! 3175: - -ld -r -X $@ ! 3176: - mv a.out $@ ! 3177: -.c.x: ! 3178: - $(CC) $(CFLAGS) -c $< ! 3179: - -ld -r -X $*.o ! 3180: - mv a.out $*.o ! 3181: - ar u btlib $*.o ! 3182: - rm $*.o ! 3183: - touch $*.x ! 3184: -CFLAGS=-g ! 3185: -debug: bttest ! 3186: -all: nodesize ! 3187: -all: btlib btcat btbuild bttest btcreat btreport btsquash btran btdelete ! 3188: -all: btadd btdiag btexer ! 3189: -bwrite.x bdelete.x diskrd.x diskwrt.x bt.x seek.x tran.x: cbt.h ! 3190: -btsquash.o btcreat.o btreport.o bttest.o btcat.o btbuild.o: cbt.h ! 3191: -btlib: bt.x seek.x tran.x diskrd.x diskwrt.x bwrite.x bdelete.x lib.x ! 3192: - ranlib btlib ! 3193: -cyntax: ! 3194: - cyntax bttest.c bt.c seek.c tran.c diskrd.c diskwrt.c bwrite.c bdelete.c lib.c ! 3195: -bttest: bttest.o btlib ! 3196: - $(CC) $(CFLAGS) -o bttest bttest.o btlib ! 3197: -btran: btran.o ! 3198: - $(CC) $(CFLAGS) -o btran btran.o ! 3199: -btsquash: btsquash.o btlib ! 3200: - $(CC) $(CFLAGS) -o btsquash btsquash.o btlib ! 3201: -btadd: btadd.o btlib ! 3202: - $(CC) $(CFLAGS) -o btadd btadd.o btlib ! 3203: -btreport: btreport.o btlib ! 3204: - $(CC) $(CFLAGS) -o btreport btreport.o btlib ! 3205: -btdelete: btdelete.o btlib ! 3206: - $(CC) $(CFLAGS) -o btdelete btdelete.o btlib ! 3207: -btcreat: btcreat.o cbt.h ! 3208: - $(CC) $(CFLAGS) -o btcreat btcreat.o btlib ! 3209: -btdiag: btdiag.o btlib ! 3210: - $(CC) $(CFLAGS) -o btdiag btdiag.o btlib ! 3211: -btexer: btexer.o btlib ! 3212: - $(CC) $(CFLAGS) -o btexer btexer.o btlib ! 3213: -btcat: btcat.o btlib ! 3214: - cc -o btcat btcat.o btlib ! 3215: -btbuild: btbuild.o lib.x ! 3216: - $(CC) $(CFLAGS) -o btbuild btbuild.o btlib ! 3217: -nodesize: ! 3218: - @cc -E $(CFLAGS) nodesz.c | grep nodesize ! 3219: -install: ! 3220: - -cp cbt /usr/bin ! 3221: - -cp cbt.h /usr/include ! 3222: - -cp btlib /usr/lib/libcbt.a ! 3223: - -ranlib /usr/lib/libcbt.a ! 3224: -clean: ! 3225: - rm *.o *.x btlib ! 3226: //GO.SYSIN DD makefile ! 3227: echo cbt 1>&2 ! 3228: sed 's/.//' >cbt <<'//GO.SYSIN DD cbt' ! 3229: -LIB=/usr/lib/btree ! 3230: -if test $# = 0 ! 3231: -then ! 3232: - echo 'cbt add|build|cat|creat|delete|report|squash ...' ! 3233: - exit 1 ! 3234: -fi ! 3235: -x=$1 ! 3236: -shift ! 3237: -case $x in ! 3238: -add) case $1 in ! 3239: - -*) shift ! 3240: - $LIB/btadd $* ;; ! 3241: - *) $LIB/btran | $LIB/btadd $* ;; ! 3242: - esac ;; ! 3243: -build) case $1 in ! 3244: - -*) shift ! 3245: - $LIB/btbuild $* ;; ! 3246: - *) $LIB/btran | $LIB/btbuild $* ;; ! 3247: - esac ;; ! 3248: -cat) $LIB/btcat $* ;; ! 3249: -creat) $LIB/btcreat $* ;; ! 3250: -delete) case $1 in ! 3251: - -*) shift ! 3252: - $LIB/btdelete $* ;; ! 3253: - *) $LIB/btran | $LIB/btdelete $* ;; ! 3254: - esac ;; ! 3255: -grep) $LIB/btgrep $* ;; ! 3256: -report) $LIB/btreport $* ;; ! 3257: -squash) if test $# != 1 ! 3258: - then ! 3259: - echo usage cbt squash file-name ! 3260: - exit 1 ! 3261: - fi ! 3262: - $LIB/btsquash $1 ;; ! 3263: -*) echo 1>&2 unknown command $x ! 3264: -esac ! 3265: //GO.SYSIN DD cbt ! 3266: echo verify 1>&2 ! 3267: sed 's/.//' >verify <<'//GO.SYSIN DD verify' ! 3268: -PATH=:$PATH ! 3269: -export PATH ! 3270: -x=$1 ! 3271: -if test $# = 0 ! 3272: -then ! 3273: - echo verify rec-cnt ! 3274: - exit 1 ! 3275: -fi ! 3276: -echo 1. loading a btree with $x records ! 3277: -btcreat junk ! 3278: -awk '{for(i = 0; i < $1; i++) printf "%8.8d\n", i}' <<! | btran | btbuild junk ! 3279: -$x ! 3280: -! ! 3281: -echo 1. does btreport think there are $x records ! 3282: -btreport junk ! 3283: -echo 2. if btcat doesn\'t agree, it will say so ! 3284: -btcat junk | awk 'length != 9 || $0+0 != NR-1 {print length, $0+0, NR, "bad"}' ! 3285: -echo 2. end of load test ! 3286: -echo ! 3287: -echo 3. delete all the records ! 3288: -awk '{for(i = 0; i < $1; i++) printf "%8.8d\n", i}' <<! | btdelete junk ! 3289: -$x ! 3290: -! ! 3291: -echo 3. btreport should think they are all gone ! 3292: -btreport junk ! 3293: -echo 4. btcat should too ! 3294: -btcat junk | awk '{next}; END {print NR " records"}' ! 3295: -echo 4. there should be no records left ! 3296: -echo ! 3297: -echo 5. now load them back one at a time ! 3298: -echo $x | awk '{for(i = 0; i < $1; i++) printf "%8.8d\n", i}' | ! 3299: - btran | tee foo | btadd junk ! 3300: -echo 5. btreport should think there are $x records ! 3301: -btreport junk ! 3302: -echo 6. btcat should think so too ! 3303: -btcat junk | awk 'length != 9 || $0+0 != NR-1 {print length, $0+0, NR, "bad"} ! 3304: - END {print NR " records"}' ! 3305: -echo 6. there should have been no bad records ! 3306: -echo ! 3307: -echo 7. now throw every other one away ! 3308: -awk '{for(i = 0; i < $1; i+=2) printf "%8.8d\n", i}' <<! | btdelete junk ! 3309: -$x ! 3310: -! ! 3311: -echo 7. btreport should think they are gone ! 3312: -btreport junk ! 3313: -echo 8. btcat should too ! 3314: -btcat junk | awk '{next}; END {print NR " records"}' ! 3315: -echo 8. there should be half the records left ! 3316: -echo ! 3317: -echo 9. now squash the file ! 3318: -btsquash junk ! 3319: -echo 9. btreport says ! 3320: -btreport junk ! 3321: -echo 10. and can btcat find them all: ! 3322: -btcat junk | awk 'length != 9 || $0+0 != 2*NR-1 {print length, $0+0, NR, "bad"} ! 3323: - END {print NR " records"}' ! 3324: -echo 10. there should be half the records left ! 3325: -echo ! 3326: -echo 11. now put the other half back ! 3327: -echo $x | awk '{for(i = 0; i < $1; i+=2) printf "%8.8d\n", i}' | ! 3328: - btran | btadd junk ! 3329: -echo 11. btreport should see $x records ! 3330: -btreport junk ! 3331: -echo 12. so should btcat ! 3332: -btcat junk | awk 'length != 9 || $0+0 != NR-1 {print length, $0+0, NR, "bad"} ! 3333: - END {print NR " records"}' ! 3334: -echo 13. and they should all be there after squashing ! 3335: -btsquash junk ! 3336: -echo 13. btreport should see $x records ! 3337: -btreport junk ! 3338: -echo 14. so should btcat ! 3339: -btcat junk | awk 'length != 9 || $0+0 != NR-1 {print length, $0+0, NR, "bad"} ! 3340: - END {print NR " records"}' ! 3341: -echo and that is all I could think of doing ! 3342: //GO.SYSIN DD verify ! 3343: echo README 1>&2 ! 3344: sed 's/.//' >README <<'//GO.SYSIN DD README' ! 3345: -INSTALLING THE BTREE STUFF ! 3346: -Acceptance testing - ! 3347: -1. Put the distributed software in a testing directory. ! 3348: - Put the name of the directory in the LIB= line in cbt. ! 3349: - make all. (If you are not on a vax, remove the -g CFLAG in makefile.) ! 3350: - (If your machine does not have ranlib, remove all references ! 3351: - to it from the makefile.) ! 3352: -2. Run the verify shell script with various arguments. I use ! 3353: - verify 10, verify 100, and verify 1000. The last needs 3 minutes ! 3354: - of cpu time. ! 3355: -3. Copy everything to its final directory. Fix the CFLAGS line in ! 3356: - the makefile by removing -DTEST. Change the LIB= line in cbt ! 3357: - to point to this directory. Change the NDSZ definition after ! 3358: - #else in cbt.h to the size of a file system block on your system ! 3359: - (512 or 1024 or whatever). ! 3360: -4. make clean ! 3361: - make all ! 3362: - Run the verify shell script to check that everything is still ok. ! 3363: -5. make install ! 3364: //GO.SYSIN DD README
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.