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