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
;
158 key
.objectid
= (unsigned long)-1;
161 ret
= search_slot(root
, &key
, &path
, 0);
162 slot
= path
.slots
[0];
165 release_path(root
, &path
);
170 for (i
= slot
; i
>= 0; i
--) {
171 found
= path
.nodes
[0]->leaf
.items
[i
].key
.objectid
;
172 radix_tree_preload(GFP_KERNEL
);
173 ret
= radix_tree_insert(radix
, found
, (void *)found
);
176 "failed to insert %lu into radix\n",
181 radix_tree_preload_end();
183 release_path(root
, &path
);
184 key
.objectid
= found
- 1;
185 if (key
.objectid
> found
)
191 void sigstopper(int ignored
)
194 fprintf(stderr
, "caught exit signal, stopping\n");
197 int print_usage(void)
199 printf("usage: tester [-ih] [-c count] [-f count]\n");
200 printf("\t -c count -- iteration count after filling\n");
201 printf("\t -f count -- run this many random inserts before starting\n");
202 printf("\t -i -- only do initial fill\n");
203 printf("\t -h -- this help text\n");
206 int main(int ac
, char **av
)
208 RADIX_TREE(radix
, GFP_KERNEL
);
209 struct ctree_super_block super
;
210 struct ctree_root
*root
;
215 int iterations
= 20000;
216 int init_fill_count
= 800000;
218 int initial_only
= 0;
220 root
= open_ctree("dbfile", &super
);
221 fill_radix(root
, &radix
);
223 signal(SIGTERM
, sigstopper
);
224 signal(SIGINT
, sigstopper
);
226 for (i
= 1 ; i
< ac
; i
++) {
227 if (strcmp(av
[i
], "-i") == 0) {
229 } else if (strcmp(av
[i
], "-c") == 0) {
230 iterations
= atoi(av
[i
+1]);
232 } else if (strcmp(av
[i
], "-f") == 0) {
233 init_fill_count
= atoi(av
[i
+1]);
239 for (i
= 0; i
< init_fill_count
; i
++) {
240 ret
= ins_one(root
, &radix
);
242 printf("initial fill failed\n");
246 if (i
% 10000 == 0) {
247 printf("initial fill %d level %d count %d\n", i
,
248 node_level(root
->node
->node
.header
.flags
),
249 root
->node
->node
.header
.nritems
);
251 if (keep_running
== 0) {
256 if (initial_only
== 1) {
259 for (i
= 0; i
< iterations
; i
++) {
260 op
= rand() % ARRAY_SIZE(ops
);
261 count
= rand() % 128;
266 if (i
&& i
% 5000 == 0) {
267 printf("open & close, root level %d nritems %d\n",
268 node_level(root
->node
->node
.header
.flags
),
269 root
->node
->node
.header
.nritems
);
270 write_ctree_super(root
, &super
);
272 root
= open_ctree("dbfile", &super
);
275 ret
= ops
[op
](root
, &radix
);
277 fprintf(stderr
, "op %d failed %d:%d\n",
279 print_tree(root
, root
->node
);
280 fprintf(stderr
, "op %d failed %d:%d\n",
285 if (keep_running
== 0) {
292 write_ctree_super(root
, &super
);