| #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; |
| } |