Annotation of 43BSDReno/old/libdbm/dbm.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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