1 #include <u.h>
2 #include <libc.h>
3 #include <db.h>
4 #include "msgdb.h"
5 
6 struct Msgdb
7 {
8 	DB *db;
9 	int reset;
10 };
11 
12 Msgdb*
mdopen(char * file,int create)13 mdopen(char *file, int create)
14 {
15 	Msgdb *mdb;
16 	DB *db;
17 	HASHINFO h;
18 
19 	if((mdb = mallocz(sizeof(Msgdb), 1)) == nil)
20 		return nil;
21 	memset(&h, 0, sizeof h);
22 	h.cachesize = 2*1024*1024;
23 	if((db = dbopen(file, ORDWR|(create ? OCREATE:0), 0666, DB_HASH, &h)) == nil){
24 		free(mdb);
25 		return nil;
26 	}
27 	mdb->db = db;
28 	mdb->reset = 1;
29 	return mdb;
30 }
31 
32 long
mdget(Msgdb * mdb,char * tok)33 mdget(Msgdb *mdb, char *tok)
34 {
35 	DB *db = mdb->db;
36 	DBT key, val;
37 	uchar *p;
38 
39 	key.data = tok;
40 	key.size = strlen(tok)+1;
41 	val.data = 0;
42 	val.size = 0;
43 
44 	if(db->get(db, &key, &val, 0) < 0)
45 		return 0;
46 	if(val.data == 0)
47 		return 0;
48 	if(val.size != 4)
49 		return 0;
50 	p = val.data;
51 	return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
52 }
53 
54 void
mdput(Msgdb * mdb,char * tok,long n)55 mdput(Msgdb *mdb, char *tok, long n)
56 {
57 	uchar p[4];
58 	DB *db = mdb->db;
59 	DBT key, val;
60 
61 	key.data = tok;
62 	key.size = strlen(tok)+1;
63 	if(n <= 0){
64 		db->del(db, &key, 0);
65 		return;
66 	}
67 
68 	p[0] = n>>24;
69 	p[1] = n>>16;
70 	p[2] = n>>8;
71 	p[3] = n;
72 
73 	val.data = p;
74 	val.size = 4;
75 	db->put(db, &key, &val, 0);
76 }
77 
78 void
mdenum(Msgdb * mdb)79 mdenum(Msgdb *mdb)
80 {
81 	mdb->reset = 1;
82 }
83 
84 int
mdnext(Msgdb * mdb,char ** sp,long * vp)85 mdnext(Msgdb *mdb, char **sp, long *vp)
86 {
87 	DBT key, val;
88 	uchar *p;
89 	DB *db = mdb->db;
90 	int i;
91 
92 	i = db->seq(db, &key, &val, mdb->reset ? R_FIRST : R_NEXT);
93 	mdb->reset = 0;
94 	if(i)
95 		return -1;
96 	*sp = key.data;
97 	p = val.data;
98 	*vp = (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
99 	return 0;
100 }
101 
102 void
mdclose(Msgdb * mdb)103 mdclose(Msgdb *mdb)
104 {
105 	DB *db = mdb->db;
106 
107 	db->close(db);
108 	mdb->db = nil;
109 }
110