print out the GUID in the CLDAP reply
[kai/samba.git] / source3 / 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 <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>
13
14 /* a test program for tdb - the trivial database */
15
16
17
18 #define DELETE_PROB 7
19 #define STORE_PROB 5
20
21 static TDB_CONTEXT *db;
22 static GDBM_FILE gdbm;
23
24 struct timeval tp1,tp2;
25
26 static void start_timer(void)
27 {
28         gettimeofday(&tp1,NULL);
29 }
30
31 static double end_timer(void)
32 {
33         gettimeofday(&tp2,NULL);
34         return((tp2.tv_sec - tp1.tv_sec) + 
35                (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
36 }
37
38 static void fatal(char *why)
39 {
40         perror(why);
41         exit(1);
42 }
43
44 static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
45 {
46         va_list ap;
47     
48         va_start(ap, format);
49         vfprintf(stdout, format, ap);
50         va_end(ap);
51         fflush(stdout);
52 }
53
54 static void compare_db(void)
55 {
56         TDB_DATA d, key, nextkey;
57         datum gd, gkey, gnextkey;
58
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;
64
65                 gd = gdbm_fetch(gdbm, gkey);
66
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");
71                 }
72
73                 nextkey = tdb_nextkey(db, key);
74                 free(key.dptr);
75                 free(d.dptr);
76                 free(gd.dptr);
77                 key = nextkey;
78         }
79
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;
85
86                 d = tdb_fetch(db, key);
87
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");
92                 }
93
94                 gnextkey = gdbm_nextkey(gdbm, gkey);
95                 free(gkey.dptr);
96                 free(gd.dptr);
97                 free(d.dptr);
98                 gkey = gnextkey;
99         }
100 }
101
102 static char *randbuf(int len)
103 {
104         char *buf;
105         int i;
106         buf = (char *)malloc(len+1);
107
108         for (i=0;i<len;i++) {
109                 buf[i] = 'a' + (rand() % 26);
110         }
111         buf[i] = 0;
112         return buf;
113 }
114
115 static void addrec_db(void)
116 {
117         int klen, dlen;
118         char *k, *d;
119         TDB_DATA key, data;
120
121         klen = 1 + (rand() % 4);
122         dlen = 1 + (rand() % 100);
123
124         k = randbuf(klen);
125         d = randbuf(dlen);
126
127         key.dptr = k;
128         key.dsize = klen+1;
129
130         data.dptr = d;
131         data.dsize = dlen+1;
132
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");
138                 }
139         } else {
140                 data = tdb_fetch(db, key);
141                 if (data.dptr) free(data.dptr);
142         }
143
144         free(k);
145         free(d);
146 }
147
148 static void addrec_gdbm(void)
149 {
150         int klen, dlen;
151         char *k, *d;
152         datum key, data;
153
154         klen = 1 + (rand() % 4);
155         dlen = 1 + (rand() % 100);
156
157         k = randbuf(klen);
158         d = randbuf(dlen);
159
160         key.dptr = k;
161         key.dsize = klen+1;
162
163         data.dptr = d;
164         data.dsize = dlen+1;
165
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");
171                 }
172         } else {
173                 data = gdbm_fetch(gdbm, key);
174                 if (data.dptr) free(data.dptr);
175         }
176
177         free(k);
178         free(d);
179 }
180
181 static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
182 {
183 #if 0
184         printf("[%s] [%s]\n", key.dptr, dbuf.dptr);
185 #endif
186         tdb_delete(tdb, key);
187         return 0;
188 }
189
190 static void merge_test(void)
191 {
192         int i;
193         char keys[5][2];
194         TDB_DATA key, data;
195         
196         for (i = 0; i < 5; i++) {
197                 sprintf(keys[i], "%d", i);
198                 key.dptr = keys[i];
199                 key.dsize = 2;
200                 
201                 data.dptr = "test";
202                 data.dsize = 4;
203                 
204                 if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
205                         fatal("tdb_store failed");
206                 }
207         }
208
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);
219 }
220         
221 int main(int argc, char *argv[])
222 {
223         int i, seed=0;
224         int loops = 10000;
225
226         unlink("test.gdbm");
227
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);
232
233         if (!db || !gdbm) {
234                 fatal("db open failed");
235         }
236
237         tdb_logging_function(db, tdb_log);
238         
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
245
246         merge_test();
247
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());
252
253         compare_db();
254
255         printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL));
256         printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL));
257
258         tdb_close(db);
259         gdbm_close(gdbm);
260
261         return 0;
262 }