source: vendor/current/lib/tdb/tools/tdbtest.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 5.2 KB
Line 
1/* a test program for tdb - the trivial database */
2
3#include "replace.h"
4#include "tdb.h"
5#include "system/filesys.h"
6#include "system/time.h"
7
8#include <gdbm.h>
9
10
11#define DELETE_PROB 7
12#define STORE_PROB 5
13
14static struct tdb_context *db;
15static GDBM_FILE gdbm;
16
17struct timeval tp1,tp2;
18
19static void _start_timer(void)
20{
21 gettimeofday(&tp1,NULL);
22}
23
24static double _end_timer(void)
25{
26 gettimeofday(&tp2,NULL);
27 return((tp2.tv_sec - tp1.tv_sec) +
28 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
29}
30
31static void fatal(const char *why)
32{
33 perror(why);
34 exit(1);
35}
36
37#ifdef PRINTF_ATTRIBUTE
38static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4);
39#endif
40static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...)
41{
42 va_list ap;
43
44 va_start(ap, format);
45 vfprintf(stdout, format, ap);
46 va_end(ap);
47 fflush(stdout);
48}
49
50static void compare_db(void)
51{
52 TDB_DATA d, key, nextkey;
53 datum gd, gkey, gnextkey;
54
55 key = tdb_firstkey(db);
56 while (key.dptr) {
57 d = tdb_fetch(db, key);
58 gkey.dptr = key.dptr;
59 gkey.dsize = key.dsize;
60
61 gd = gdbm_fetch(gdbm, gkey);
62
63 if (!gd.dptr) fatal("key not in gdbm");
64 if (gd.dsize != d.dsize) fatal("data sizes differ");
65 if (memcmp(gd.dptr, d.dptr, d.dsize)) {
66 fatal("data differs");
67 }
68
69 nextkey = tdb_nextkey(db, key);
70 free(key.dptr);
71 free(d.dptr);
72 free(gd.dptr);
73 key = nextkey;
74 }
75
76 gkey = gdbm_firstkey(gdbm);
77 while (gkey.dptr) {
78 gd = gdbm_fetch(gdbm, gkey);
79 key.dptr = gkey.dptr;
80 key.dsize = gkey.dsize;
81
82 d = tdb_fetch(db, key);
83
84 if (!d.dptr) fatal("key not in db");
85 if (d.dsize != gd.dsize) fatal("data sizes differ");
86 if (memcmp(d.dptr, gd.dptr, gd.dsize)) {
87 fatal("data differs");
88 }
89
90 gnextkey = gdbm_nextkey(gdbm, gkey);
91 free(gkey.dptr);
92 free(gd.dptr);
93 free(d.dptr);
94 gkey = gnextkey;
95 }
96}
97
98static char *randbuf(int len)
99{
100 char *buf;
101 int i;
102 buf = (char *)malloc(len+1);
103
104 for (i=0;i<len;i++) {
105 buf[i] = 'a' + (rand() % 26);
106 }
107 buf[i] = 0;
108 return buf;
109}
110
111static void addrec_db(void)
112{
113 int klen, dlen;
114 char *k, *d;
115 TDB_DATA key, data;
116
117 klen = 1 + (rand() % 4);
118 dlen = 1 + (rand() % 100);
119
120 k = randbuf(klen);
121 d = randbuf(dlen);
122
123 key.dptr = k;
124 key.dsize = klen+1;
125
126 data.dptr = d;
127 data.dsize = dlen+1;
128
129 if (rand() % DELETE_PROB == 0) {
130 tdb_delete(db, key);
131 } else if (rand() % STORE_PROB == 0) {
132 if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
133 fatal("tdb_store failed");
134 }
135 } else {
136 data = tdb_fetch(db, key);
137 if (data.dptr) free(data.dptr);
138 }
139
140 free(k);
141 free(d);
142}
143
144static void addrec_gdbm(void)
145{
146 int klen, dlen;
147 char *k, *d;
148 datum key, data;
149
150 klen = 1 + (rand() % 4);
151 dlen = 1 + (rand() % 100);
152
153 k = randbuf(klen);
154 d = randbuf(dlen);
155
156 key.dptr = k;
157 key.dsize = klen+1;
158
159 data.dptr = d;
160 data.dsize = dlen+1;
161
162 if (rand() % DELETE_PROB == 0) {
163 gdbm_delete(gdbm, key);
164 } else if (rand() % STORE_PROB == 0) {
165 if (gdbm_store(gdbm, key, data, GDBM_REPLACE) != 0) {
166 fatal("gdbm_store failed");
167 }
168 } else {
169 data = gdbm_fetch(gdbm, key);
170 if (data.dptr) free(data.dptr);
171 }
172
173 free(k);
174 free(d);
175}
176
177static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
178{
179#if 0
180 printf("[%s] [%s]\n", key.dptr, dbuf.dptr);
181#endif
182 tdb_delete(tdb, key);
183 return 0;
184}
185
186static void merge_test(void)
187{
188 int i;
189 char keys[5][2];
190 char tdata[] = "test";
191 TDB_DATA key, data;
192
193 for (i = 0; i < 5; i++) {
194 snprintf(keys[i],2, "%d", i);
195 key.dptr = keys[i];
196 key.dsize = 2;
197
198 data.dptr = tdata;
199 data.dsize = 4;
200
201 if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
202 fatal("tdb_store failed");
203 }
204 }
205
206 key.dptr = keys[0];
207 tdb_delete(db, key);
208 key.dptr = keys[4];
209 tdb_delete(db, key);
210 key.dptr = keys[2];
211 tdb_delete(db, key);
212 key.dptr = keys[1];
213 tdb_delete(db, key);
214 key.dptr = keys[3];
215 tdb_delete(db, key);
216}
217
218static char *test_path(const char *filename)
219{
220 const char *prefix = getenv("TEST_DATA_PREFIX");
221
222 if (prefix) {
223 char *path = NULL;
224 int ret;
225
226 ret = asprintf(&path, "%s/%s", prefix, filename);
227 if (ret == -1) {
228 return NULL;
229 }
230 return path;
231 }
232
233 return strdup(filename);
234}
235
236 int main(int argc, const char *argv[])
237{
238 int i, seed=0;
239 int loops = 10000;
240 int num_entries;
241 char test_gdbm[1] = "test.gdbm";
242 char *test_tdb;
243
244 test_gdbm[0] = test_path("test.gdbm");
245 test_tdb = test_path("test.tdb");
246
247 unlink(test_gdbm[0]);
248
249 db = tdb_open(test_tdb, 0, TDB_CLEAR_IF_FIRST,
250 O_RDWR | O_CREAT | O_TRUNC, 0600);
251 gdbm = gdbm_open(test_gdbm, 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST,
252 0600, NULL);
253
254 if (!db || !gdbm) {
255 fatal("db open failed");
256 }
257
258#if 1
259 srand(seed);
260 _start_timer();
261 for (i=0;i<loops;i++) addrec_gdbm();
262 printf("gdbm got %.2f ops/sec\n", i/_end_timer());
263#endif
264
265 merge_test();
266
267 srand(seed);
268 _start_timer();
269 for (i=0;i<loops;i++) addrec_db();
270 printf("tdb got %.2f ops/sec\n", i/_end_timer());
271
272 if (tdb_validate_freelist(db, &num_entries) == -1) {
273 printf("tdb freelist is corrupt\n");
274 } else {
275 printf("tdb freelist is good (%d entries)\n", num_entries);
276 }
277
278 compare_db();
279
280 printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL));
281 printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL));
282
283 tdb_close(db);
284 gdbm_close(gdbm);
285
286 free(test_gdbm[0]);
287 free(test_tdb);
288
289 return 0;
290}
Note: See TracBrowser for help on using the repository browser.