1 /* a test program for tdb - the trivial database */
5 #include "system/filesys.h"
6 #include "system/time.h"
14 static struct tdb_context
*db
;
15 static GDBM_FILE gdbm
;
17 struct timeval tp1
,tp2
;
19 static void _start_timer(void)
21 gettimeofday(&tp1
,NULL
);
24 static double _end_timer(void)
26 gettimeofday(&tp2
,NULL
);
27 return((tp2
.tv_sec
- tp1
.tv_sec
) +
28 (tp2
.tv_usec
- tp1
.tv_usec
)*1.0e-6);
31 static void fatal(const char *why
)
37 #ifdef PRINTF_ATTRIBUTE
38 static void tdb_log(struct tdb_context
*tdb
, int level
, const char *format
, ...) PRINTF_ATTRIBUTE(3,4);
40 static void tdb_log(struct tdb_context
*tdb
, int level
, const char *format
, ...)
45 vfprintf(stdout
, format
, ap
);
50 static void compare_db(void)
52 TDB_DATA d
, key
, nextkey
;
53 datum gd
, gkey
, gnextkey
;
55 key
= tdb_firstkey(db
);
57 d
= tdb_fetch(db
, key
);
59 gkey
.dsize
= key
.dsize
;
61 gd
= gdbm_fetch(gdbm
, gkey
);
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");
69 nextkey
= tdb_nextkey(db
, key
);
76 gkey
= gdbm_firstkey(gdbm
);
78 gd
= gdbm_fetch(gdbm
, gkey
);
80 key
.dsize
= gkey
.dsize
;
82 d
= tdb_fetch(db
, key
);
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");
90 gnextkey
= gdbm_nextkey(gdbm
, gkey
);
98 static char *randbuf(int len
)
102 buf
= (char *)malloc(len
+1);
104 for (i
=0;i
<len
;i
++) {
105 buf
[i
] = 'a' + (rand() % 26);
111 static void addrec_db(void)
117 klen
= 1 + (rand() % 4);
118 dlen
= 1 + (rand() % 100);
129 if (rand() % DELETE_PROB
== 0) {
131 } else if (rand() % STORE_PROB
== 0) {
132 if (tdb_store(db
, key
, data
, TDB_REPLACE
) != 0) {
133 fatal("tdb_store failed");
136 data
= tdb_fetch(db
, key
);
137 if (data
.dptr
) free(data
.dptr
);
144 static void addrec_gdbm(void)
150 klen
= 1 + (rand() % 4);
151 dlen
= 1 + (rand() % 100);
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");
169 data
= gdbm_fetch(gdbm
, key
);
170 if (data
.dptr
) free(data
.dptr
);
177 static int traverse_fn(struct tdb_context
*tdb
, TDB_DATA key
, TDB_DATA dbuf
, void *state
)
180 printf("[%s] [%s]\n", key
.dptr
, dbuf
.dptr
);
182 tdb_delete(tdb
, key
);
186 static void merge_test(void)
190 char tdata
[] = "test";
193 for (i
= 0; i
< 5; i
++) {
194 snprintf(keys
[i
],2, "%d", i
);
201 if (tdb_store(db
, key
, data
, TDB_REPLACE
) != 0) {
202 fatal("tdb_store failed");
218 static char *test_path(const char *filename
)
220 const char *prefix
= getenv("TEST_DATA_PREFIX");
226 ret
= asprintf(&path
, "%s/%s", prefix
, filename
);
233 return strdup(filename
);
236 int main(int argc
, const char *argv
[])
241 char test_gdbm
[1] = "test.gdbm";
244 test_gdbm
[0] = test_path("test.gdbm");
245 test_tdb
= test_path("test.tdb");
247 unlink(test_gdbm
[0]);
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
,
255 fatal("db open failed");
261 for (i
=0;i
<loops
;i
++) addrec_gdbm();
262 printf("gdbm got %.2f ops/sec\n", i
/_end_timer());
269 for (i
=0;i
<loops
;i
++) addrec_db();
270 printf("tdb got %.2f ops/sec\n", i
/_end_timer());
272 if (tdb_validate_freelist(db
, &num_entries
) == -1) {
273 printf("tdb freelist is corrupt\n");
275 printf("tdb freelist is good (%d entries)\n", num_entries
);
280 printf("traversed %d records\n", tdb_traverse(db
, traverse_fn
, NULL
));
281 printf("traversed %d records\n", tdb_traverse(db
, traverse_fn
, NULL
));