|
|
1.1 root 1: #include "stdio.h"
2: #include "cbt.h"
3: #define SZ MXHT+1
4:
5: typedef struct {
6: unsigned short mlen;
7: char mdata[NDSZ]; /* max size of values */
8: } xbuf;
9: int address[SZ]; /* where the next address goes in the node */
10: xbuf curkey[SZ]; /* last key put in the node */
11: xbuf shortone; /* for compression */
12: int freecnt[SZ]; /* number of bytes left in node */
13: dkey *kp[SZ]; /* where to put next dkey in node */
14: char node[SZ][NDSZ]; /* the nodes */
15: char used[SZ+1]; /* which nodes have been used */
16: xbuf nkey; /* as read by getrec */
17: struct {
18: unsigned short mlen;
19: char mdata[32767];
20: } val;
21: lfaddr currec; /* where getrec put val */
22: FILE *tfd, *dfd;
23: char name[16];
24: int type;
25: long reccnt;
26: extern char *malloc();
27:
28: char *
29: prkey(a)
30: xbuf *a;
31: { int i;
32: unsigned char c;
33: static char buf[4*NDSZ], *p;
34: for(i = 0, p = buf; i < a->mlen; i++) {
35: c = a->mdata[i];
36: if(c < ' ') {
37: *p++ = '^';
38: c += ' ';
39: }
40: if(c < 127)
41: *p++ = (char)c;
42: else {
43: *p++ = '\\';
44: *p++ = (c >> 6) + '0';
45: *p++ = ((c&63)>>3) + '0';
46: *p++ = c&7 + '0';
47: }
48: }
49: *p++ = 0;
50: return(buf);
51: }
52: pref(a, b, lev) xbuf *a, *b;
53: { register int n;
54: register char *p, *q;
55: for(n = 0, p = a->mdata, q = b->mdata; n < a->mlen && n < b->mlen; n++)
56: if(*p++ != *q++)
57: break;
58: p--, q--;
59: if(lev == 0 && ((n == b->mlen && n >= a->mlen) || *p > *q)) {
60: fprintf(stderr, "key %ld out of order:\n", reccnt);
61: fprintf(stderr, "key %ld is %s\n", reccnt - 1, prkey(a));
62: fprintf(stderr, "key %ld is %s\n", reccnt, prkey(b));
63: }
64: return(n);
65: }
66:
67: getrec()
68: {
69: reccnt++;
70: if(mget(&nkey))
71: return(-1);
72: if(mget((xbuf *)&val))
73: fail("half a record read");
74: if((currec.llen = val.mlen) != 0) {
75: currec.lloc = ftell(dfd);
76: (void) fwrite(val.mdata, 1, val.mlen, dfd);
77: if(ferror(dfd))
78: fail("value write");
79: }
80: else currec.lloc = 0;
81: return(1);
82: }
83:
84: mget(a) xbuf *a;
85: {
86: (void) fread((char *)&(a->mlen), 1, sizeof(a->mlen), stdin);
87: if(feof(stdin) || ferror(stdin))
88: return(1);
89: if(fread(a->mdata, 1, a->mlen, stdin) != a->mlen)
90: return(1);
91: return(0);
92: }
93:
94: ndaddr ndwrt(level)
95: { ndaddr loc;
96: int i;
97: hdr *x;
98: trailer *t;
99: loc = ftell(tfd)/NDSZ;
100: x = (hdr *)(node[level]);
101: x->hlev = level;
102: t = (trailer *)(node[level] + NDSZ - sizeof(trailer));
103: t->tfree = freecnt[level];
104: x->kcnt = address[level] - (level == 0? 0: 1);
105: x->htype = type;
106: (void) fwrite(node[level], 1, NDSZ, tfd);
107: if(ferror(tfd))
108: fail("node write");
109: for(i = 0; i < NDSZ; i++)
110: node[level][i] = 0;
111: address[level] = 0;
112: curkey[level].mlen = 0;
113: freecnt[level] = NDSZ - sizeof(hdr) - sizeof(trailer);
114: if(level)
115: freecnt[level] -= sizeof(ndaddr);
116: kp[level] = (dkey *)(node[level] + sizeof(hdr));
117: return(loc);
118: }
119:
120: finish(level, ptr) ndaddr ptr;
121: { ndaddr loc;
122: if(!used[level])
123: return;
124: *ndadr(node[level], address[level]++) = ptr;
125: if(!used[level + 1])
126: fseek(tfd, 0L, 0);
127: loc = ndwrt(level);
128: finish(level + 1, loc);
129: }
130:
131: insert(level, key, ptr) xbuf *key; ndaddr ptr;
132: { int n, len;
133: char *p;
134: ndaddr loc;
135: used[level] = 1;
136: n = pref(&curkey[level], key, level);
137: len = DKEYSZ + key->mlen - n + sizeof(ptr);
138: if(len < freecnt[level]) {
139: *ndadr(node[level], address[level]++) = ptr;
140: kp[level]->dlen = len - sizeof(ptr);
141: kp[level]->dcom = n;
142: mvgbt(kp[level]->dkey, key->mdata + n, key->mlen - n);
143: p = (char *)(kp[level]) + kp[level]->dlen;
144: kp[level] = (dkey *)p;
145: freecnt[level] -= len;
146: curkey[level] = *key;
147: }
148: else {
149: *ndadr(node[level],address[level]++) = ptr;
150: loc = ndwrt(level);
151: insert(level+1, key, loc);
152: curkey[level].mlen = 0;
153: }
154: }
155:
156: doit()
157: { int n, len;
158: ndaddr loc;
159: char *p;
160: for(;;) {
161: if(getrec() == -1)
162: break;
163: used[0] = 1;
164: n = pref(&curkey[0], &nkey, 0);
165: len = DKEYSZ + nkey.mlen - n + sizeof(currec);
166: if(type & INDEX)
167: len -= sizeof(currec);
168: if(len < freecnt[0]) {
169: freecnt[0] -= len;
170: if(!(type & INDEX))
171: *lfadr(node[0], address[0]++) = currec;
172: else
173: address[0]++;
174: kp[0]->dlen = DKEYSZ + nkey.mlen - n;
175: kp[0]->dcom = n;
176: mvgbt(kp[0]->dkey, nkey.mdata + n, nkey.mlen - n);
177: p = (char *)(kp[0]) + kp[0]->dlen;
178: kp[0] = (dkey *)p;
179: curkey[0] = nkey;
180: }
181: else {
182: shortest(&curkey[0], &nkey);
183: loc = ndwrt(0);
184: freecnt[0] -= DKEYSZ + nkey.mlen + sizeof(currec);
185: if(type & INDEX)
186: freecnt[0] += sizeof(currec);
187: insert(1, &shortone, loc);
188: if(!(type & INDEX))
189: *lfadr(node[0], address[0]++) = currec;
190: else
191: address[0]++;
192: kp[0]->dlen = DKEYSZ + nkey.mlen;
193: kp[0]->dcom = 0;
194: mvgbt(kp[0]->dkey, nkey.mdata, nkey.mlen);
195: p = (char *)(kp[0]) + kp[0]->dlen;
196: kp[0] = (dkey *)p;
197: curkey[0] = nkey;
198: }
199: }
200: if(!used[1])
201: (void) fseek(tfd, 0L, 0);
202: loc = ndwrt(0);
203: finish(1, loc);
204: }
205:
206: init(s)
207: char *s;
208: { int i;
209: hdr *b;
210: char xx[NDSZ];
211: (void) sprintf(name, "%s.T", s);
212: tfd = fopen(name, "r");
213: if(tfd == NULL) {
214: perror(s);
215: exit(1);
216: }
217: fread(xx, 1, NDSZ, tfd);
218: fclose(tfd);
219: tfd = fopen(name, "w");
220: (void) fseek(tfd, (long)NDSZ, 0);
221: b = (hdr *)xx;
222: type = b->htype;
223: (void) sprintf(name, "%s.F", s);
224: if((type & INDEX) != INDEX)
225: dfd = fopen(name, "w");
226: for(i = 0; i < SZ; i++) {
227: freecnt[i] = NDSZ - sizeof(hdr) - sizeof(trailer);
228: if(i)
229: freecnt[i] -= sizeof(ndaddr);
230: kp[i] = (dkey *)(node[i] + sizeof(hdr));
231: }
232: }
233:
234: main(argc, argv)
235: char **argv;
236: {
237: if(argc != 2) {
238: fprintf(stderr, "%s: too many arguments\n", argv[1]);
239: exit(1);
240: }
241: init(argv[1]);
242: doit();
243: exit(0);
244: }
245:
246: shortest(a, b) xbuf *a, *b;
247: { int n;
248: char *p, *q, *s;
249: p = a->mdata;
250: q = b->mdata;
251: s = shortone.mdata;
252: for(n = 0; n < a->mlen && n < b->mlen; n++, p++, q++)
253: if(*p == *q)
254: *s++ = *p;
255: else break;
256: if(n < a->mlen) {
257: again:
258: if(n + 1 == a->mlen)
259: *s++ = *p;
260: else if(*p + 1 < *q)
261: *s++ = *p + 1;
262: else {
263: *s++ = *p++;
264: n++;
265: if(*p + 1 > *p)
266: *s++ = *p + 1;
267: else goto again;
268: }
269: }
270: shortone.mlen = s - shortone.mdata;
271: }
272: prbuf(x) xbuf *x;
273: { int i;
274: for(i = 0; i < x->mlen; i++)
275: printf("%3.3o ", x->mdata[i]);
276: putchar('\n');
277: }
278: fail(s)
279: char *s;
280: {
281: perror(s);
282: exit(2);
283: }
284: static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:btbuild.c\n"};
285: /*1101000110100100*/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.