4 Copyright (C) Ronnie Sahlberg 2007
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "lib/util/dlinklist.h"
22 #include "system/filesys.h"
28 #include "common/rb_tree.h"
30 static struct timeval tp1
,tp2
;
32 static void start_timer(void)
34 gettimeofday(&tp1
,NULL
);
37 static double end_timer(void)
39 gettimeofday(&tp2
,NULL
);
40 return (tp2
.tv_sec
+ (tp2
.tv_usec
*1.0e-6)) -
41 (tp1
.tv_sec
+ (tp1
.tv_usec
*1.0e-6));
46 static void *callback(void *p
, void *d
)
48 uint32_t *data
= (uint32_t *)d
;
59 static void *random_add(void *p
, void *d
)
64 static int traverse(void *p
, void *d
)
66 uint32_t *data
= (uint32_t *)d
;
68 printf("traverse data:%d\n",*data
);
72 static int random_traverse(void *p
, void *d
)
74 printf("%s ",(char *)d
);
78 static uint32_t calc_checksum
= 0;
79 static int traverse_checksum(void *p
, void *d
)
83 sscanf(d
, "%d.%d.%d", &i
, &j
, &k
);
84 calc_checksum
+= i
*100+j
*10+k
;
88 static int count_traverse(void *p
, void *d
)
95 static int count_traverse_abort(void *p
, void *d
)
105 int main(int argc
, const char *argv
[])
107 struct poptOption popt_options
[] = {
110 { "num-records", 'r', POPT_ARG_INT
, &num_records
, 0, "num_records", "integer" },
113 int opt
, traverse_count
;
114 const char **extra_argv
;
121 uint32_t key1
[3] = {0,10,20};
122 uint32_t key2
[3] = {0,10,21};
123 uint32_t key3
[3] = {0,11,20};
124 uint32_t key4
[3] = {2,10,20};
129 pc
= poptGetContext(argv
[0], argc
, argv
, popt_options
, POPT_CONTEXT_KEEP_FIRST
);
131 while ((opt
= poptGetNextOpt(pc
)) != -1) {
134 fprintf(stderr
, "Invalid option %s: %s\n",
135 poptBadOption(pc
, 0), poptStrerror(opt
));
140 /* setup the remaining options for the main program to use */
141 extra_argv
= poptGetArgs(pc
);
144 while (extra_argv
[extra_argc
]) extra_argc
++;
147 printf("testing trbt_insert32_callback for %d records\n", num_records
);
148 memctx
= talloc_new(NULL
);
149 u32array
= talloc_array(memctx
, uint32_t *, num_records
);
150 tree
= trbt_create(memctx
, 0);
151 for (i
=0; i
<num_records
; i
++) {
152 u32array
[i
] = talloc(u32array
, uint32_t);
154 trbt_insert32_callback(tree
, i
, callback
, u32array
[i
]);
156 for (i
=3; i
<num_records
; i
++) {
157 trbt_insert32_callback(tree
, i
, callback
, NULL
);
160 printf("first 3 keys should have data==1\n");
161 printf("the rest of the keys should have data==2\n");
162 for (i
=0; i
<num_records
; i
++) {
163 data
= trbt_lookup32(tree
, i
);
164 printf("key:%d data:%d\n", i
, *data
);
166 // talloc_report_full(tree, stdout);
167 // talloc_report_full(memctx, stdout);
170 printf("deleting key 2\n");
171 talloc_free(u32array
[2]);
172 // talloc_report_full(tree, stdout);
173 // talloc_report_full(memctx, stdout);
176 printf("deleting key 1\n");
177 talloc_free(u32array
[1]);
178 // talloc_report_full(tree, stdout);
179 // talloc_report_full(memctx, stdout);
182 printf("freeing tree\n");
183 talloc_report_full(memctx
, stdout
);
187 printf("testing trbt_insertarray32_callback\n");
188 memctx
= talloc_new(NULL
);
189 tree
= trbt_create(memctx
, 0);
190 u32array
= talloc_array(memctx
, uint32_t *, 4);
192 u32array
[i
] = talloc(u32array
, uint32_t);
195 trbt_insertarray32_callback(tree
, 3, key1
, callback
, u32array
[0]);
196 trbt_insertarray32_callback(tree
, 3, key1
, callback
, u32array
[0]);
197 trbt_insertarray32_callback(tree
, 3, key2
, callback
, u32array
[1]);
198 trbt_insertarray32_callback(tree
, 3, key3
, callback
, u32array
[2]);
199 trbt_insertarray32_callback(tree
, 3, key2
, callback
, u32array
[1]);
200 trbt_insertarray32_callback(tree
, 3, key1
, callback
, u32array
[0]);
202 data
= trbt_lookuparray32(tree
, 3, key1
);
203 printf("key1 dataptr:%p == %d\n",data
,data
?*data
:-1);
204 data
= trbt_lookuparray32(tree
, 3, key2
);
205 printf("key2 dataptr:%p == %d\n",data
,data
?*data
:-1);
206 data
= trbt_lookuparray32(tree
, 3, key3
);
207 printf("key3 dataptr:%p == %d\n",data
,data
?*data
:-1);
208 data
= trbt_lookuparray32(tree
, 3, key4
);
209 printf("key4 dataptr:%p == %d\n",data
,data
?*data
:-1);
210 trbt_traversearray32(tree
, 3, traverse
, NULL
);
212 printf("\ndeleting key4\n");
213 talloc_free(trbt_lookuparray32(tree
, 3, key4
));
214 data
= trbt_lookuparray32(tree
, 3, key1
);
215 printf("key1 dataptr:%p == %d\n",data
,data
?*data
:-1);
216 data
= trbt_lookuparray32(tree
, 3, key2
);
217 printf("key2 dataptr:%p == %d\n",data
,data
?*data
:-1);
218 data
= trbt_lookuparray32(tree
, 3, key3
);
219 printf("key3 dataptr:%p == %d\n",data
,data
?*data
:-1);
220 data
= trbt_lookuparray32(tree
, 3, key4
);
221 printf("key4 dataptr:%p == %d\n",data
,data
?*data
:-1);
222 trbt_traversearray32(tree
, 3, traverse
, NULL
);
224 printf("\ndeleting key2\n");
225 talloc_free(trbt_lookuparray32(tree
, 3, key2
));
226 data
= trbt_lookuparray32(tree
, 3, key1
);
227 printf("key1 dataptr:%p == %d\n",data
,data
?*data
:-1);
228 data
= trbt_lookuparray32(tree
, 3, key2
);
229 printf("key2 dataptr:%p == %d\n",data
,data
?*data
:-1);
230 data
= trbt_lookuparray32(tree
, 3, key3
);
231 printf("key3 dataptr:%p == %d\n",data
,data
?*data
:-1);
232 data
= trbt_lookuparray32(tree
, 3, key4
);
233 printf("key4 dataptr:%p == %d\n",data
,data
?*data
:-1);
234 trbt_traversearray32(tree
, 3, traverse
, NULL
);
236 printf("\ndeleting key3\n");
237 talloc_free(trbt_lookuparray32(tree
, 3, key3
));
238 data
= trbt_lookuparray32(tree
, 3, key1
);
239 printf("key1 dataptr:%p == %d\n",data
,data
?*data
:-1);
240 data
= trbt_lookuparray32(tree
, 3, key2
);
241 printf("key2 dataptr:%p == %d\n",data
,data
?*data
:-1);
242 data
= trbt_lookuparray32(tree
, 3, key3
);
243 printf("key3 dataptr:%p == %d\n",data
,data
?*data
:-1);
244 data
= trbt_lookuparray32(tree
, 3, key4
);
245 printf("key4 dataptr:%p == %d\n",data
,data
?*data
:-1);
246 trbt_traversearray32(tree
, 3, traverse
, NULL
);
248 printf("\ndeleting key1\n");
249 talloc_free(trbt_lookuparray32(tree
, 3, key1
));
250 data
= trbt_lookuparray32(tree
, 3, key1
);
251 printf("key1 dataptr:%p == %d\n",data
,data
?*data
:-1);
252 data
= trbt_lookuparray32(tree
, 3, key2
);
253 printf("key2 dataptr:%p == %d\n",data
,data
?*data
:-1);
254 data
= trbt_lookuparray32(tree
, 3, key3
);
255 printf("key3 dataptr:%p == %d\n",data
,data
?*data
:-1);
256 data
= trbt_lookuparray32(tree
, 3, key4
);
257 printf("key4 dataptr:%p == %d\n",data
,data
?*data
:-1);
258 trbt_traversearray32(tree
, 3, traverse
, NULL
);
264 printf("\nrun random insert and delete for 60 seconds\n");
265 memctx
= talloc_new(NULL
);
266 tree
= trbt_create(memctx
, 0);
270 /* add and delete nodes from a 3 level tree fro 60 seconds.
271 each time a node is added or deleted, traverse the tree and
272 compute a checksum over the data stored in the tree and compare this
273 with a checksum we keep which contains what the checksum should be
275 while(end_timer() < 60.0){
283 if (trbt_lookuparray32(tree
, 3, key
) == NULL
) {
284 /* this node does not yet exist, add it to the
285 tree and update the checksum
287 str
=talloc_asprintf(memctx
, "%d.%d.%d", key
[0],key
[1],key
[2]);
288 trbt_insertarray32_callback(tree
, 3, key
, random_add
, str
);
289 checksum
+= key
[0]*100+key
[1]*10+key
[2];
292 if ((str
=trbt_lookuparray32(tree
, 3, key
)) != NULL
) {
293 /* this node does exist in the tree, delete
294 it and update the checksum accordingly
297 checksum
-= key
[0]*100+key
[1]*10+key
[2];
300 /* traverse all nodes in the tree and calculate the checksum
301 it better match the one we keep track of in
305 trbt_traversearray32(tree
, 3, traverse_checksum
, NULL
);
306 if(checksum
!= calc_checksum
) {
307 printf("Wrong checksum %d!=%d\n",checksum
, calc_checksum
);
311 if(i
%1000==999)printf(".");fflush(stdout
);
313 printf("\niterations passed:%d\n", i
);
314 trbt_traversearray32(tree
, 3, random_traverse
, NULL
);
316 printf("first node: %s\n", (char *)trbt_findfirstarray32(tree
, 3));
319 trbt_traversearray32(tree
, 3, count_traverse
, &traverse_count
);
321 printf("number of entries in traverse %d\n", traverse_count
);
324 trbt_traversearray32(tree
, 3, count_traverse_abort
, &traverse_count
);
326 printf("number of entries in aborted traverse %d\n", traverse_count
);
327 if (traverse_count
!= 1) {
328 printf("Failed to abort the traverse. Should have been aborted after 1 element but did iterate over %d elements\n", traverse_count
);
331 printf("\ndeleting all entries\n");
338 talloc_free(trbt_lookuparray32(tree
, 3, key
));
342 trbt_traversearray32(tree
, 3, random_traverse
, NULL
);
344 talloc_report_full(tree
, stdout
);