Annotation of 42BSD/usr.lib/libdbm/dbm.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.