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