|
|
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.