|
|
1.1 root 1: #include "dbm.h"
2: #include <sys/types.h>
3: #include <sys/stat.h>
4:
5: dbminit(file)
6: char *file;
7: {
8: struct stat statb;
9:
10: strcpy(pagbuf, file);
11: strcat(pagbuf, ".pag");
12: pagf = open(pagbuf, 2);
13:
14: strcpy(pagbuf, file);
15: strcat(pagbuf, ".dir");
16: dirf = open(pagbuf, 2);
17: if(pagf < 0 || dirf < 0) {
18: printf("cannot open database %s\n", file);
19: return(-1);
20: }
21: fstat(dirf, &statb);
22: maxbno = statb.st_size*BYTESIZ-1;
23: return(0);
24: }
25:
26: long
27: forder(key)
28: datum key;
29: {
30: long hash;
31:
32: hash = calchash(key);
33: for(hmask=0;; hmask=(hmask<<1)+1) {
34: blkno = hash & hmask;
35: bitno = blkno + hmask;
36: if(getbit() == 0)
37: break;
38: }
39: return(blkno);
40: }
41:
42: datum
43: fetch(key)
44: datum key;
45: {
46: register i;
47: datum item;
48:
49: dbm_access(calchash(key));
50: for(i=0;; i+=2) {
51: item = makdatum(pagbuf, i);
52: if(item.dptr == NULL)
53: return(item);
54: if(cmpdatum(key, item) == 0) {
55: item = makdatum(pagbuf, i+1);
56: if(item.dptr == NULL)
57: printf("items not in pairs\n");
58: return(item);
59: }
60: }
61: }
62:
63: delete(key)
64: datum key;
65: {
66: register i;
67: datum item;
68:
69: dbm_access(calchash(key));
70: for(i=0;; i+=2) {
71: item = makdatum(pagbuf, i);
72: if(item.dptr == NULL)
73: return(-1);
74: if(cmpdatum(key, item) == 0) {
75: delitem(pagbuf, i);
76: delitem(pagbuf, i);
77: break;
78: }
79: }
80: lseek(pagf, blkno*PBLKSIZ, 0);
81: write(pagf, pagbuf, PBLKSIZ);
82: return(0);
83: }
84:
85: store(key, dat)
86: datum key, dat;
87: {
88: register i;
89: datum item;
90: char ovfbuf[PBLKSIZ];
91:
92: loop:
93: dbm_access(calchash(key));
94: for(i=0;; i+=2) {
95: item = makdatum(pagbuf, i);
96: if(item.dptr == NULL)
97: break;
98: if(cmpdatum(key, item) == 0) {
99: delitem(pagbuf, i);
100: delitem(pagbuf, i);
101: break;
102: }
103: }
104: i = additem(pagbuf, key);
105: if(i < 0)
106: goto split;
107: if(additem(pagbuf, dat) < 0) {
108: delitem(pagbuf, i);
109: goto split;
110: }
111: lseek(pagf, blkno*PBLKSIZ, 0);
112: write(pagf, pagbuf, PBLKSIZ);
113: return;
114:
115: split:
116: if(key.dsize+dat.dsize+2*sizeof(short) >= PBLKSIZ) {
117: printf("entry too big\n");
118: return;
119: }
120: clrbuf(ovfbuf, PBLKSIZ);
121: for(i=0;;) {
122: item = makdatum(pagbuf, i);
123: if(item.dptr == NULL)
124: break;
125: if(calchash(item) & (hmask+1)) {
126: additem(ovfbuf, item);
127: delitem(pagbuf, i);
128: item = makdatum(pagbuf, i);
129: if(item.dptr == NULL) {
130: printf("split not paired\n");
131: break;
132: }
133: additem(ovfbuf, item);
134: delitem(pagbuf, i);
135: continue;
136: }
137: i += 2;
138: }
139: lseek(pagf, blkno*PBLKSIZ, 0);
140: write(pagf, pagbuf, PBLKSIZ);
141: lseek(pagf, (blkno+hmask+1)*PBLKSIZ, 0);
142: write(pagf, ovfbuf, PBLKSIZ);
143: setbit();
144: goto loop;
145: }
146:
147: datum
148: firstkey()
149: {
150: return(firsthash(0L));
151: }
152:
153: datum
154: nextkey(key)
155: datum key;
156: {
157: register i;
158: datum item, bitem;
159: long hash;
160: int f;
161:
162: hash = calchash(key);
163: dbm_access(hash);
164: f = 1;
165: for(i=0;; i+=2) {
166: item = makdatum(pagbuf, i);
167: if(item.dptr == NULL)
168: break;
169: if(cmpdatum(key, item) <= 0)
170: continue;
171: if(f || cmpdatum(bitem, item) < 0) {
172: bitem = item;
173: f = 0;
174: }
175: }
176: if(f == 0)
177: return(bitem);
178: hash = hashinc(hash);
179: if(hash == 0)
180: return(item);
181: return(firsthash(hash));
182: }
183:
184: datum
185: firsthash(hash)
186: long hash;
187: {
188: register i;
189: datum item, bitem;
190:
191: loop:
192: dbm_access(hash);
193: bitem = makdatum(pagbuf, 0);
194: for(i=2;; i+=2) {
195: item = makdatum(pagbuf, i);
196: if(item.dptr == NULL)
197: break;
198: if(cmpdatum(bitem, item) < 0)
199: bitem = item;
200: }
201: if(bitem.dptr != NULL)
202: return(bitem);
203: hash = hashinc(hash);
204: if(hash == 0)
205: return(item);
206: goto loop;
207: }
208:
209: dbm_access(hash)
210: long hash;
211: {
212: static long oldb = -1;
213:
214: for(hmask=0;; hmask=(hmask<<1)+1) {
215: blkno = hash & hmask;
216: bitno = blkno + hmask;
217: if(getbit() == 0)
218: break;
219: }
220: if(blkno != oldb) {
221: clrbuf(pagbuf, PBLKSIZ);
222: lseek(pagf, blkno*PBLKSIZ, 0);
223: read(pagf, pagbuf, PBLKSIZ);
224: chkblk(pagbuf);
225: oldb = blkno;
226: }
227: }
228:
229: getbit()
230: {
231: long bn;
232: register b, i, n;
233: static oldb = -1;
234:
235: if(bitno > maxbno)
236: return(0);
237: n = bitno % BYTESIZ;
238: bn = bitno / BYTESIZ;
239: i = bn % DBLKSIZ;
240: b = bn / DBLKSIZ;
241: if(b != oldb) {
242: clrbuf(dirbuf, DBLKSIZ);
243: lseek(dirf, (long)b*DBLKSIZ, 0);
244: read(dirf, dirbuf, DBLKSIZ);
245: oldb = b;
246: }
247: if(dirbuf[i] & (1<<n))
248: return(1);
249: return(0);
250: }
251:
252: setbit()
253: {
254: long bn;
255: register i, n, b;
256:
257: if(bitno > maxbno) {
258: maxbno = bitno;
259: getbit();
260: }
261: n = bitno % BYTESIZ;
262: bn = bitno / BYTESIZ;
263: i = bn % DBLKSIZ;
264: b = bn / DBLKSIZ;
265: dirbuf[i] |= 1<<n;
266: lseek(dirf, (long)b*DBLKSIZ, 0);
267: write(dirf, dirbuf, DBLKSIZ);
268: }
269:
270: clrbuf(cp, n)
271: register char *cp;
272: register n;
273: {
274:
275: do
276: *cp++ = 0;
277: while(--n);
278: }
279:
280: datum
281: makdatum(buf, n)
282: char buf[PBLKSIZ];
283: {
284: register short *sp;
285: register t;
286: datum item;
287:
288: sp = (short *)buf;
289: if(n < 0 || n >= sp[0])
290: goto null;
291: t = PBLKSIZ;
292: if(n > 0)
293: t = sp[n+1-1];
294: item.dptr = buf+sp[n+1];
295: item.dsize = t - sp[n+1];
296: return(item);
297:
298: null:
299: item.dptr = NULL;
300: item.dsize = 0;
301: return(item);
302: }
303:
304: cmpdatum(d1, d2)
305: datum d1, d2;
306: {
307: register n;
308: register char *p1, *p2;
309:
310: n = d1.dsize;
311: if(n != d2.dsize)
312: return(n - d2.dsize);
313: if(n == 0)
314: return(0);
315: p1 = d1.dptr;
316: p2 = d2.dptr;
317: do
318: if(*p1++ != *p2++)
319: return(*--p1 - *--p2);
320: while(--n);
321: return(0);
322: }
323:
324: int hitab[16]
325: /* ken's
326: {
327: 055,043,036,054,063,014,004,005,
328: 010,064,077,000,035,027,025,071,
329: };
330: */
331: = { 61, 57, 53, 49, 45, 41, 37, 33,
332: 29, 25, 21, 17, 13, 9, 5, 1,
333: };
334: long hltab[64]
335: = {
336: 06100151277L,06106161736L,06452611562L,05001724107L,
337: 02614772546L,04120731531L,04665262210L,07347467531L,
338: 06735253126L,06042345173L,03072226605L,01464164730L,
339: 03247435524L,07652510057L,01546775256L,05714532133L,
340: 06173260402L,07517101630L,02431460343L,01743245566L,
341: 00261675137L,02433103631L,03421772437L,04447707466L,
342: 04435620103L,03757017115L,03641531772L,06767633246L,
343: 02673230344L,00260612216L,04133454451L,00615531516L,
344: 06137717526L,02574116560L,02304023373L,07061702261L,
345: 05153031405L,05322056705L,07401116734L,06552375715L,
346: 06165233473L,05311063631L,01212221723L,01052267235L,
347: 06000615237L,01075222665L,06330216006L,04402355630L,
348: 01451177262L,02000133436L,06025467062L,07121076461L,
349: 03123433522L,01010635225L,01716177066L,05161746527L,
350: 01736635071L,06243505026L,03637211610L,01756474365L,
351: 04723077174L,03642763134L,05750130273L,03655541561L,
352: };
353:
354: long
355: hashinc(hash)
356: long hash;
357: {
358: long bit;
359:
360: hash &= hmask;
361: bit = hmask+1;
362: for(;;) {
363: bit >>= 1;
364: if(bit == 0)
365: return(0L);
366: if((hash&bit) == 0)
367: return(hash|bit);
368: hash &= ~bit;
369: }
370: }
371:
372: long
373: calchash(item)
374: datum item;
375: {
376: register i, j, f;
377: long hashl;
378: int hashi;
379:
380: hashl = 0;
381: hashi = 0;
382: for(i=0; i<item.dsize; i++) {
383: f = item.dptr[i];
384: for(j=0; j<BYTESIZ; j+=4) {
385: hashi += hitab[f&017];
386: hashl += hltab[hashi&63];
387: f >>= 4;
388: }
389: }
390: return(hashl);
391: }
392:
393: delitem(buf, n)
394: char buf[PBLKSIZ];
395: {
396: register short *sp;
397: register i1, i2, i3;
398:
399: sp = (short *)buf;
400: if(n < 0 || n >= sp[0])
401: goto bad;
402: i1 = sp[n+1];
403: i2 = PBLKSIZ;
404: if(n > 0)
405: i2 = sp[n+1-1];
406: i3 = sp[sp[0]+1-1];
407: if(i2 > i1)
408: while(i1 > i3) {
409: i1--;
410: i2--;
411: buf[i2] = buf[i1];
412: buf[i1] = 0;
413: }
414: i2 -= i1;
415: for(i1=n+1; i1<sp[0]; i1++)
416: sp[i1+1-1] = sp[i1+1] + i2;
417: sp[0]--;
418: sp[sp[0]+1] = 0;
419: return;
420:
421: bad:
422: printf("bad delitem\n");
423: abort();
424: }
425:
426: additem(buf, item)
427: char buf[PBLKSIZ];
428: datum item;
429: {
430: register short *sp;
431: register i1, i2;
432:
433: sp = (short *)buf;
434: i1 = PBLKSIZ;
435: if(sp[0] > 0)
436: i1 = sp[sp[0]+1-1];
437: i1 -= item.dsize;
438: i2 = (sp[0]+2) * sizeof(short);
439: if(i1 <= i2)
440: return(-1);
441: sp[sp[0]+1] = i1;
442: for(i2=0; i2<item.dsize; i2++) {
443: buf[i1] = item.dptr[i2];
444: i1++;
445: }
446: sp[0]++;
447: return(sp[0]-1);
448: }
449:
450: chkblk(buf)
451: char buf[PBLKSIZ];
452: {
453: register short *sp;
454: register t, i;
455:
456: sp = (short *)buf;
457: t = PBLKSIZ;
458: for(i=0; i<sp[0]; i++) {
459: if(sp[i+1] > t)
460: goto bad;
461: t = sp[i+1];
462: }
463: if(t < (sp[0]+1)*sizeof(short))
464: goto bad;
465: return;
466:
467: bad:
468: printf("bad block\n");
469: abort();
470: clrbuf(buf, PBLKSIZ);
471: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.