9728e59a0177e08289ed7e9442d1a4861e3d59e2
[kai/samba.git] / source / tdb / tdbtest.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include <fcntl.h>
7 #include <sys/mman.h>
8 #include <sys/stat.h>
9 #include <sys/time.h>
10 #include "tdb.h"
11 #include <gdbm.h>
12
13 /* a test program for tdb - the trivial database */
14
15
16
17 #define DELETE_PROB 7
18 #define STORE_PROB 5
19
20 static TDB_CONTEXT *db;
21 static GDBM_FILE gdbm;
22
23 struct timeval tp1,tp2;
24
25 static void start_timer()
26 {
27         gettimeofday(&tp1,NULL);
28 }
29
30 static double end_timer()
31 {
32         gettimeofday(&tp2,NULL);
33         return((tp2.tv_sec - tp1.tv_sec) + 
34                (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
35 }
36
37 static void fatal(char *why)
38 {
39         perror(why);
40         exit(1);
41 }
42
43
44 static void compare_db(void)
45 {
46         TDB_DATA d, key, nextkey;
47         datum gd, gkey, gnextkey;
48
49         key = tdb_firstkey(db);
50         while (key.dptr) {
51                 d = tdb_fetch(db, key);
52                 gkey.dptr = key.dptr;
53                 gkey.dsize = key.dsize;
54
55                 gd = gdbm_fetch(gdbm, gkey);
56
57                 if (!gd.dptr) fatal("key not in gdbm");
58                 if (gd.dsize != d.dsize) fatal("data sizes differ");
59                 if (memcmp(gd.dptr, d.dptr, d.dsize)) {
60                         fatal("data differs");
61                 }
62
63                 nextkey = tdb_nextkey(db, key);
64                 free(key.dptr);
65                 free(d.dptr);
66                 free(gd.dptr);
67                 key = nextkey;
68         }
69
70         gkey = gdbm_firstkey(gdbm);
71         while (gkey.dptr) {
72                 gd = gdbm_fetch(gdbm, gkey);
73                 key.dptr = gkey.dptr;
74                 key.dsize = gkey.dsize;
75
76                 d = tdb_fetch(db, key);
77
78                 if (!d.dptr) fatal("key not in db");
79                 if (d.dsize != gd.dsize) fatal("data sizes differ");
80                 if (memcmp(d.dptr, gd.dptr, gd.dsize)) {
81                         fatal("data differs");
82                 }
83
84                 gnextkey = gdbm_nextkey(gdbm, gkey);
85                 free(gkey.dptr);
86                 free(gd.dptr);
87                 free(d.dptr);
88                 gkey = gnextkey;
89         }
90 }
91
92 static char *randbuf(int len)
93 {
94         char *buf;
95         int i;
96         buf = (char *)malloc(len+1);
97
98         for (i=0;i<len;i++) {
99                 buf[i] = 'a' + (rand() % 26);
100         }
101         buf[i] = 0;
102         return buf;
103 }
104
105 static void addrec_db(void)
106 {
107         int klen, dlen;
108         char *k, *d;
109         TDB_DATA key, data;
110
111         klen = 1 + (rand() % 4);
112         dlen = 1 + (rand() % 100);
113
114         k = randbuf(klen);
115         d = randbuf(dlen);
116
117         key.dptr = k;
118         key.dsize = klen+1;
119
120         data.dptr = d;
121         data.dsize = dlen+1;
122
123         if (rand() % DELETE_PROB == 0) {
124                 tdb_delete(db, key);
125         } else if (rand() % STORE_PROB == 0) {
126                 if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
127                         fatal("tdb_store failed");
128                 }
129         } else {
130                 data = tdb_fetch(db, key);
131                 if (data.dptr) free(data.dptr);
132         }
133
134         free(k);
135         free(d);
136 }
137
138 static void addrec_gdbm(void)
139 {
140         int klen, dlen;
141         char *k, *d;
142         datum key, data;
143
144         klen = 1 + (rand() % 4);
145         dlen = 1 + (rand() % 100);
146
147         k = randbuf(klen);
148         d = randbuf(dlen);
149
150         key.dptr = k;
151         key.dsize = klen+1;
152
153         data.dptr = d;
154         data.dsize = dlen+1;
155
156         if (rand() % DELETE_PROB == 0) {
157                 gdbm_delete(gdbm, key);
158         } else if (rand() % STORE_PROB == 0) {
159                 if (gdbm_store(gdbm, key, data, GDBM_REPLACE) != 0) {
160                         fatal("gdbm_store failed");
161                 }
162         } else {
163                 data = gdbm_fetch(gdbm, key);
164                 if (data.dptr) free(data.dptr);
165         }
166
167         free(k);
168         free(d);
169 }
170
171 static int traverse_fn(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf, void *state)
172 {
173 #if 0
174         printf("[%s] [%s]\n", key.dptr, dbuf.dptr);
175 #endif
176         tdb_delete(db, key);
177         return 0;
178 }
179
180 int main(int argc, char *argv[])
181 {
182         int i, seed=0;
183         int loops = 10000;
184
185         unlink("test.gdbm");
186
187         db = tdb_open("test.db", 0, TDB_CLEAR_IF_FIRST, 
188                       O_RDWR | O_CREAT | O_TRUNC, 0600);
189         gdbm = gdbm_open("test.gdbm", 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST, 
190                          0600, NULL);
191
192         if (!db || !gdbm) {
193                 fatal("db open failed");
194         }
195
196         
197 #if 1
198         srand(seed);
199         start_timer();
200         for (i=0;i<loops;i++) addrec_gdbm();
201         printf("gdbm got %.2f ops/sec\n", i/end_timer());
202 #endif
203
204         srand(seed);
205         start_timer();
206         for (i=0;i<loops;i++) addrec_db();
207         printf("tdb got %.2f ops/sec\n", i/end_timer());
208
209         compare_db();
210
211         printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL));
212         printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL));
213
214         tdb_close(db);
215         gdbm_close(gdbm);
216
217         return 0;
218 }