4 #include "kerncompat.h"
5 #include "radix-tree.h"
8 #include "print-tree.h"
12 static int setup_key(struct radix_tree_root *root, struct key *key, int exists)
21 ret = radix_tree_gang_lookup(root, (void **)res, num, 2);
26 } else if (ret != 0 && num == res[0]) {
28 if (ret > 1 && num == res[1]) {
37 static int ins_one(struct ctree_root *root, struct radix_tree_root *radix)
39 struct ctree_path path;
45 ret = setup_key(radix, &key, 0);
46 sprintf(buf, "str-%Lu\n", key.objectid);
47 ret = insert_item(root, &key, buf, strlen(buf));
50 oid = (unsigned long)key.objectid;
51 radix_tree_preload(GFP_KERNEL);
52 ret = radix_tree_insert(radix, oid, (void *)oid);
53 radix_tree_preload_end();
58 printf("failed to insert %Lu\n", key.objectid);
62 static int insert_dup(struct ctree_root *root, struct radix_tree_root *radix)
64 struct ctree_path path;
69 ret = setup_key(radix, &key, 1);
72 sprintf(buf, "str-%Lu\n", key.objectid);
73 ret = insert_item(root, &key, buf, strlen(buf));
75 printf("insert on %Lu gave us %d\n", key.objectid, ret);
81 static int del_one(struct ctree_root *root, struct radix_tree_root *radix)
83 struct ctree_path path;
88 ret = setup_key(radix, &key, 1);
91 ret = search_slot(root, &key, &path, -1);
94 ret = del_item(root, &path);
95 release_path(root, &path);
98 ptr = radix_tree_delete(radix, key.objectid);
103 printf("failed to delete %Lu\n", key.objectid);
107 static int lookup_item(struct ctree_root *root, struct radix_tree_root *radix)
109 struct ctree_path path;
113 ret = setup_key(radix, &key, 1);
116 ret = search_slot(root, &key, &path, 0);
117 release_path(root, &path);
122 printf("unable to find key %Lu\n", key.objectid);
126 static int lookup_enoent(struct ctree_root *root, struct radix_tree_root *radix)
128 struct ctree_path path;
132 ret = setup_key(radix, &key, 0);
135 ret = search_slot(root, &key, &path, 0);
136 release_path(root, &path);
141 printf("able to find key that should not exist %Lu\n", key.objectid);
145 int (*ops[])(struct ctree_root *root, struct radix_tree_root *radix) =
146 { ins_one, insert_dup, del_one, lookup_item, lookup_enoent };
148 static int fill_radix(struct ctree_root *root, struct radix_tree_root *radix)
150 struct ctree_path path;
159 key.objectid = (unsigned long)-1;
162 ret = search_slot(root, &key, &path, 0);
164 release_path(root, &path);
167 slot = path.slots[0];
170 release_path(root, &path);
175 for (i = slot; i >= 0; i--) {
176 found = path.nodes[0]->leaf.items[i].key.objectid;
177 radix_tree_preload(GFP_KERNEL);
178 ret = radix_tree_insert(radix, found, (void *)found);
181 "failed to insert %lu into radix\n",
186 radix_tree_preload_end();
188 release_path(root, &path);
189 key.objectid = found - 1;
190 if (key.objectid > found)
196 void sigstopper(int ignored)
199 fprintf(stderr, "caught exit signal, stopping\n");
202 int print_usage(void)
204 printf("usage: tester [-ih] [-c count] [-f count]\n");
205 printf("\t -c count -- iteration count after filling\n");
206 printf("\t -f count -- run this many random inserts before starting\n");
207 printf("\t -i -- only do initial fill\n");
208 printf("\t -h -- this help text\n");
211 int main(int ac, char **av)
213 RADIX_TREE(radix, GFP_KERNEL);
214 struct ctree_super_block super;
215 struct ctree_root *root;
220 int iterations = 20000;
221 int init_fill_count = 800000;
223 int initial_only = 0;
225 root = open_ctree("dbfile", &super);
226 fill_radix(root, &radix);
228 signal(SIGTERM, sigstopper);
229 signal(SIGINT, sigstopper);
231 for (i = 1 ; i < ac ; i++) {
232 if (strcmp(av[i], "-i") == 0) {
234 } else if (strcmp(av[i], "-c") == 0) {
235 iterations = atoi(av[i+1]);
237 } else if (strcmp(av[i], "-f") == 0) {
238 init_fill_count = atoi(av[i+1]);
244 for (i = 0; i < init_fill_count; i++) {
245 ret = ins_one(root, &radix);
247 printf("initial fill failed\n");
251 if (i % 10000 == 0) {
252 printf("initial fill %d level %d count %d\n", i,
253 node_level(root->node->node.header.flags),
254 root->node->node.header.nritems);
256 if (keep_running == 0) {
261 if (initial_only == 1) {
264 for (i = 0; i < iterations; i++) {
265 op = rand() % ARRAY_SIZE(ops);
266 count = rand() % 128;
271 if (i && i % 5000 == 0) {
272 printf("open & close, root level %d nritems %d\n",
273 node_level(root->node->node.header.flags),
274 root->node->node.header.nritems);
275 write_ctree_super(root, &super);
277 root = open_ctree("dbfile", &super);
280 ret = ops[op](root, &radix);
282 fprintf(stderr, "op %d failed %d:%d\n",
284 print_tree(root, root->node);
285 fprintf(stderr, "op %d failed %d:%d\n",
290 if (keep_running == 0) {
297 write_ctree_super(root, &super);