Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <u.h>
#include <libc.h>
#include <db.h>
#include "msgdb.h"

struct Msgdb
{
        DB *db;
        int reset;
};

Msgdb*
mdopen(char *file, int create)
{
        Msgdb *mdb;
        DB *db;
        HASHINFO h;

        if((mdb = mallocz(sizeof(Msgdb), 1)) == nil)
                return nil;
        memset(&h, 0, sizeof h);
        h.cachesize = 2*1024*1024;
        if((db = dbopen(file, ORDWR|(create ? OCREATE:0), 0666, DB_HASH, &h)) == nil){
                free(mdb);
                return nil;
        }
        mdb->db = db;
        mdb->reset = 1;
        return mdb;
}

long
mdget(Msgdb *mdb, char *tok)
{
        DB *db = mdb->db;
        DBT key, val;
        uchar *p;

        key.data = tok;
        key.size = strlen(tok)+1;
        val.data = 0;
        val.size = 0;

        if(db->get(db, &key, &val, 0) < 0)
                return 0;
        if(val.data == 0)
                return 0;
        if(val.size != 4)
                return 0;
        p = val.data;
        return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
}

void
mdput(Msgdb *mdb, char *tok, long n)
{
        uchar p[4];
        DB *db = mdb->db;
        DBT key, val;

        key.data = tok;
        key.size = strlen(tok)+1;
        if(n <= 0){
                db->del(db, &key, 0);
                return;
        }

        p[0] = n>>24;
        p[1] = n>>16;
        p[2] = n>>8;
        p[3] = n;

        val.data = p;
        val.size = 4;
        db->put(db, &key, &val, 0);
}

void
mdenum(Msgdb *mdb)
{
        mdb->reset = 1;
}

int
mdnext(Msgdb *mdb, char **sp, long *vp)
{
        DBT key, val;
        uchar *p;
        DB *db = mdb->db;
        int i;

        i = db->seq(db, &key, &val, mdb->reset ? R_FIRST : R_NEXT);
        mdb->reset = 0;
        if(i)
                return -1;
        *sp = key.data;
        p = val.data;
        *vp = (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
        return 0;
}

void
mdclose(Msgdb *mdb)
{
        DB *db = mdb->db;

        db->close(db);
        mdb->db = nil;
}