preparing for release of 2.2.3a
[Samba.git] / source / tdb / tdbtest.c
blob80e9c8d07e696e20f35245af72b78a3f43976937
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 <stdarg.h>
8 #include <sys/mman.h>
9 #include <sys/stat.h>
10 #include <sys/time.h>
11 #include "tdb.h"
12 #include <gdbm.h>
14 /* a test program for tdb - the trivial database */
18 #define DELETE_PROB 7
19 #define STORE_PROB 5
21 static TDB_CONTEXT *db;
22 static GDBM_FILE gdbm;
24 struct timeval tp1,tp2;
26 static void start_timer(void)
28 gettimeofday(&tp1,NULL);
31 static double end_timer(void)
33 gettimeofday(&tp2,NULL);
34 return((tp2.tv_sec - tp1.tv_sec) +
35 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
38 static void fatal(char *why)
40 perror(why);
41 exit(1);
44 static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
46 va_list ap;
48 va_start(ap, format);
49 vfprintf(stdout, format, ap);
50 va_end(ap);
51 fflush(stdout);
54 static void compare_db(void)
56 TDB_DATA d, key, nextkey;
57 datum gd, gkey, gnextkey;
59 key = tdb_firstkey(db);
60 while (key.dptr) {
61 d = tdb_fetch(db, key);
62 gkey.dptr = key.dptr;
63 gkey.dsize = key.dsize;
65 gd = gdbm_fetch(gdbm, gkey);
67 if (!gd.dptr) fatal("key not in gdbm");
68 if (gd.dsize != d.dsize) fatal("data sizes differ");
69 if (memcmp(gd.dptr, d.dptr, d.dsize)) {
70 fatal("data differs");
73 nextkey = tdb_nextkey(db, key);
74 SAFE_FREE(key.dptr);
75 SAFE_FREE(d.dptr);
76 SAFE_FREE(gd.dptr);
77 key = nextkey;
80 gkey = gdbm_firstkey(gdbm);
81 while (gkey.dptr) {
82 gd = gdbm_fetch(gdbm, gkey);
83 key.dptr = gkey.dptr;
84 key.dsize = gkey.dsize;
86 d = tdb_fetch(db, key);
88 if (!d.dptr) fatal("key not in db");
89 if (d.dsize != gd.dsize) fatal("data sizes differ");
90 if (memcmp(d.dptr, gd.dptr, gd.dsize)) {
91 fatal("data differs");
94 gnextkey = gdbm_nextkey(gdbm, gkey);
95 SAFE_FREE(gkey.dptr);
96 SAFE_FREE(gd.dptr);
97 SAFE_FREE(d.dptr);
98 gkey = gnextkey;
102 static char *randbuf(int len)
104 char *buf;
105 int i;
106 buf = (char *)malloc(len+1);
108 for (i=0;i<len;i++) {
109 buf[i] = 'a' + (rand() % 26);
111 buf[i] = 0;
112 return buf;
115 static void addrec_db(void)
117 int klen, dlen;
118 char *k, *d;
119 TDB_DATA key, data;
121 klen = 1 + (rand() % 4);
122 dlen = 1 + (rand() % 100);
124 k = randbuf(klen);
125 d = randbuf(dlen);
127 key.dptr = k;
128 key.dsize = klen+1;
130 data.dptr = d;
131 data.dsize = dlen+1;
133 if (rand() % DELETE_PROB == 0) {
134 tdb_delete(db, key);
135 } else if (rand() % STORE_PROB == 0) {
136 if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
137 fatal("tdb_store failed");
139 } else {
140 data = tdb_fetch(db, key);
141 SAFE_FREE(data.dptr);
144 SAFE_FREE(k);
145 SAFE_FREE(d);
148 static void addrec_gdbm(void)
150 int klen, dlen;
151 char *k, *d;
152 datum key, data;
154 klen = 1 + (rand() % 4);
155 dlen = 1 + (rand() % 100);
157 k = randbuf(klen);
158 d = randbuf(dlen);
160 key.dptr = k;
161 key.dsize = klen+1;
163 data.dptr = d;
164 data.dsize = dlen+1;
166 if (rand() % DELETE_PROB == 0) {
167 gdbm_delete(gdbm, key);
168 } else if (rand() % STORE_PROB == 0) {
169 if (gdbm_store(gdbm, key, data, GDBM_REPLACE) != 0) {
170 fatal("gdbm_store failed");
172 } else {
173 data = gdbm_fetch(gdbm, key);
174 SAFE_FREE(data.dptr);
177 SAFE_FREE(k);
178 SAFE_FREE(d);
181 static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
183 #if 0
184 printf("[%s] [%s]\n", key.dptr, dbuf.dptr);
185 #endif
186 tdb_delete(tdb, key);
187 return 0;
190 static void merge_test(void)
192 int i;
193 char keys[5][2];
194 TDB_DATA key, data;
196 for (i = 0; i < 5; i++) {
197 sprintf(keys[i], "%d", i);
198 key.dptr = keys[i];
199 key.dsize = 2;
201 data.dptr = "test";
202 data.dsize = 4;
204 if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
205 fatal("tdb_store failed");
209 key.dptr = keys[0];
210 tdb_delete(db, key);
211 key.dptr = keys[4];
212 tdb_delete(db, key);
213 key.dptr = keys[2];
214 tdb_delete(db, key);
215 key.dptr = keys[1];
216 tdb_delete(db, key);
217 key.dptr = keys[3];
218 tdb_delete(db, key);
221 int main(int argc, char *argv[])
223 int i, seed=0;
224 int loops = 10000;
226 unlink("test.gdbm");
228 db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST,
229 O_RDWR | O_CREAT | O_TRUNC, 0600);
230 gdbm = gdbm_open("test.gdbm", 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST,
231 0600, NULL);
233 if (!db || !gdbm) {
234 fatal("db open failed");
237 tdb_logging_function(db, tdb_log);
239 #if 1
240 srand(seed);
241 start_timer();
242 for (i=0;i<loops;i++) addrec_gdbm();
243 printf("gdbm got %.2f ops/sec\n", i/end_timer());
244 #endif
246 merge_test();
248 srand(seed);
249 start_timer();
250 for (i=0;i<loops;i++) addrec_db();
251 printf("tdb got %.2f ops/sec\n", i/end_timer());
253 compare_db();
255 printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL));
256 printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL));
258 tdb_close(db);
259 gdbm_close(gdbm);
261 return 0;