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: {   61, 57, 53, 49, 45, 41, 37, 33,
 326:     29, 25, 21, 17, 13,  9,  5,  1,
 327: };
 328: long    hltab[64] =
 329: {
 330:     06100151277L,06106161736L,06452611562L,05001724107L,
 331:     02614772546L,04120731531L,04665262210L,07347467531L,
 332:     06735253126L,06042345173L,03072226605L,01464164730L,
 333:     03247435524L,07652510057L,01546775256L,05714532133L,
 334:     06173260402L,07517101630L,02431460343L,01743245566L,
 335:     00261675137L,02433103631L,03421772437L,04447707466L,
 336:     04435620103L,03757017115L,03641531772L,06767633246L,
 337:     02673230344L,00260612216L,04133454451L,00615531516L,
 338:     06137717526L,02574116560L,02304023373L,07061702261L,
 339:     05153031405L,05322056705L,07401116734L,06552375715L,
 340:     06165233473L,05311063631L,01212221723L,01052267235L,
 341:     06000615237L,01075222665L,06330216006L,04402355630L,
 342:     01451177262L,02000133436L,06025467062L,07121076461L,
 343:     03123433522L,01010635225L,01716177066L,05161746527L,
 344:     01736635071L,06243505026L,03637211610L,01756474365L,
 345:     04723077174L,03642763134L,05750130273L,03655541561L,
 346: };
 347: 
 348: long
 349: hashinc(hash)
 350: long hash;
 351: {
 352:     long bit;
 353: 
 354:     hash &= hmask;
 355:     bit = hmask+1;
 356:     for(;;) {
 357:         bit >>= 1;
 358:         if(bit == 0)
 359:             return(0L);
 360:         if((hash&bit) == 0)
 361:             return(hash|bit);
 362:         hash &= ~bit;
 363:     }
 364: }
 365: 
 366: long
 367: calchash(item)
 368: datum item;
 369: {
 370:     register i, j, f;
 371:     long hashl;
 372:     int hashi;
 373: 
 374:     hashl = 0;
 375:     hashi = 0;
 376:     for(i=0; i<item.dsize; i++) {
 377:         f = item.dptr[i];
 378:         for(j=0; j<BYTESIZ; j+=4) {
 379:             hashi += hitab[f&017];
 380:             hashl += hltab[hashi&077];
 381:             f >>= 4;
 382:         }
 383:     }
 384:     return(hashl);
 385: }
 386: 
 387: delitem(buf, n)
 388: char buf[PBLKSIZ];
 389: {
 390:     register short *sp;
 391:     register i1, i2, i3;
 392: 
 393:     sp = (short *)buf;
 394:     if(n < 0 || n >= sp[0])
 395:         goto bad;
 396:     i1 = sp[n+1];
 397:     i2 = PBLKSIZ;
 398:     if(n > 0)
 399:         i2 = sp[n+1-1];
 400:     i3 = sp[sp[0]+1-1];
 401:     if(i2 > i1)
 402:     while(i1 > i3) {
 403:         i1--;
 404:         i2--;
 405:         buf[i2] = buf[i1];
 406:         buf[i1] = 0;
 407:     }
 408:     i2 -= i1;
 409:     for(i1=n+1; i1<sp[0]; i1++)
 410:         sp[i1+1-1] = sp[i1+1] + i2;
 411:     sp[0]--;
 412:     sp[sp[0]+1] = 0;
 413:     return;
 414: 
 415: bad:
 416:     printf("bad delitem\n");
 417:     abort();
 418: }
 419: 
 420: additem(buf, item)
 421: char buf[PBLKSIZ];
 422: datum item;
 423: {
 424:     register short *sp;
 425:     register i1, i2;
 426: 
 427:     sp = (short *)buf;
 428:     i1 = PBLKSIZ;
 429:     if(sp[0] > 0)
 430:         i1 = sp[sp[0]+1-1];
 431:     i1 -= item.dsize;
 432:     i2 = (sp[0]+2) * sizeof(short);
 433:     if(i1 <= i2)
 434:         return(-1);
 435:     sp[sp[0]+1] = i1;
 436:     for(i2=0; i2<item.dsize; i2++) {
 437:         buf[i1] = item.dptr[i2];
 438:         i1++;
 439:     }
 440:     sp[0]++;
 441:     return(sp[0]-1);
 442: }
 443: 
 444: chkblk(buf)
 445: char buf[PBLKSIZ];
 446: {
 447:     register short *sp;
 448:     register t, i;
 449: 
 450:     sp = (short *)buf;
 451:     t = PBLKSIZ;
 452:     for(i=0; i<sp[0]; i++) {
 453:         if(sp[i+1] > t)
 454:             goto bad;
 455:         t = sp[i+1];
 456:     }
 457:     if(t < (sp[0]+1)*sizeof(short))
 458:         goto bad;
 459:     return;
 460: 
 461: bad:
 462:     printf("bad block\n");
 463:     abort();
 464:     clrbuf(buf, PBLKSIZ);
 465: }

Defined functions

additem defined in line 420; used 4 times
calchash defined in line 366; used 8 times
chkblk defined in line 444; used 1 times
clrbuf defined in line 270; used 4 times
cmpdatum defined in line 304; used 6 times
dbm_access defined in line 209; used 5 times
delete defined in line 63; never used
delitem defined in line 387; used 7 times
firsthash defined in line 184; used 4 times
firstkey defined in line 147; used 4 times
forder defined in line 26; never used
getbit defined in line 229; used 3 times
hashinc defined in line 348; used 4 times
makdatum defined in line 280; used 11 times
nextkey defined in line 153; used 4 times
setbit defined in line 252; used 1 times

Defined variables

hitab defined in line 324; used 1 times
hltab defined in line 328; used 1 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1511
Valid CSS Valid XHTML 1.0 Strict