Merge bk://kernel.bkbits.net/gregkh/linux/i2c-2.6
[linux-2.6/history.git] / lib / radix-tree.c
blobcdfb8c6a97f1d540162559d4111ed1beaa4410fc
1 /*
2 * Copyright (C) 2001 Momchil Velikov
3 * Portions Copyright (C) 2001 Christoph Hellwig
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2, or (at
8 * your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <linux/errno.h>
21 #include <linux/init.h>
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/radix-tree.h>
25 #include <linux/percpu.h>
26 #include <linux/slab.h>
27 #include <linux/gfp.h>
28 #include <linux/string.h>
31 * Radix tree node definition.
33 #define RADIX_TREE_MAP_SHIFT 6
34 #define RADIX_TREE_MAP_SIZE (1UL << RADIX_TREE_MAP_SHIFT)
35 #define RADIX_TREE_MAP_MASK (RADIX_TREE_MAP_SIZE-1)
37 struct radix_tree_node {
38 unsigned int count;
39 void *slots[RADIX_TREE_MAP_SIZE];
42 struct radix_tree_path {
43 struct radix_tree_node *node, **slot;
46 #define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long))
47 #define RADIX_TREE_MAX_PATH (RADIX_TREE_INDEX_BITS/RADIX_TREE_MAP_SHIFT + 2)
49 static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH];
52 * Radix tree node cache.
54 static kmem_cache_t *radix_tree_node_cachep;
57 * Per-cpu pool of preloaded nodes
59 struct radix_tree_preload {
60 int nr;
61 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
63 DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
66 * This assumes that the caller has performed appropriate preallocation, and
67 * that the caller has pinned this thread of control to the current CPU.
69 static struct radix_tree_node *
70 radix_tree_node_alloc(struct radix_tree_root *root)
72 struct radix_tree_node *ret;
74 ret = kmem_cache_alloc(radix_tree_node_cachep, root->gfp_mask);
75 if (ret == NULL && !(root->gfp_mask & __GFP_WAIT)) {
76 struct radix_tree_preload *rtp;
78 rtp = &__get_cpu_var(radix_tree_preloads);
79 if (rtp->nr) {
80 ret = rtp->nodes[rtp->nr - 1];
81 rtp->nodes[rtp->nr - 1] = NULL;
82 rtp->nr--;
85 return ret;
88 static inline void
89 radix_tree_node_free(struct radix_tree_node *node)
91 kmem_cache_free(radix_tree_node_cachep, node);
95 * Load up this CPU's radix_tree_node buffer with sufficient objects to
96 * ensure that the addition of a single element in the tree cannot fail. On
97 * success, return zero, with preemption disabled. On error, return -ENOMEM
98 * with preemption not disabled.
100 int radix_tree_preload(int gfp_mask)
102 struct radix_tree_preload *rtp;
103 struct radix_tree_node *node;
104 int ret = -ENOMEM;
106 preempt_disable();
107 rtp = &__get_cpu_var(radix_tree_preloads);
108 while (rtp->nr < ARRAY_SIZE(rtp->nodes)) {
109 preempt_enable();
110 node = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
111 if (node == NULL)
112 goto out;
113 preempt_disable();
114 rtp = &__get_cpu_var(radix_tree_preloads);
115 if (rtp->nr < ARRAY_SIZE(rtp->nodes))
116 rtp->nodes[rtp->nr++] = node;
117 else
118 kmem_cache_free(radix_tree_node_cachep, node);
120 ret = 0;
121 out:
122 return ret;
126 * Return the maximum key which can be store into a
127 * radix tree with height HEIGHT.
129 static inline unsigned long radix_tree_maxindex(unsigned int height)
131 return height_to_maxindex[height];
135 * Extend a radix tree so it can store key @index.
137 static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)
139 struct radix_tree_node *node;
140 unsigned int height;
142 /* Figure out what the height should be. */
143 height = root->height + 1;
144 while (index > radix_tree_maxindex(height))
145 height++;
147 if (root->rnode) {
148 do {
149 if (!(node = radix_tree_node_alloc(root)))
150 return -ENOMEM;
152 /* Increase the height. */
153 node->slots[0] = root->rnode;
154 node->count = 1;
155 root->rnode = node;
156 root->height++;
157 } while (height > root->height);
158 } else
159 root->height = height;
161 return 0;
165 * radix_tree_insert - insert into a radix tree
166 * @root: radix tree root
167 * @index: index key
168 * @item: item to insert
170 * Insert an item into the radix tree at position @index.
172 int radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item)
174 struct radix_tree_node *node = NULL, *tmp, **slot;
175 unsigned int height, shift;
176 int error;
178 /* Make sure the tree is high enough. */
179 if (index > radix_tree_maxindex(root->height)) {
180 error = radix_tree_extend(root, index);
181 if (error)
182 return error;
185 slot = &root->rnode;
186 height = root->height;
187 shift = (height-1) * RADIX_TREE_MAP_SHIFT;
189 while (height > 0) {
190 if (*slot == NULL) {
191 /* Have to add a child node. */
192 if (!(tmp = radix_tree_node_alloc(root)))
193 return -ENOMEM;
194 *slot = tmp;
195 if (node)
196 node->count++;
199 /* Go a level down. */
200 node = *slot;
201 slot = (struct radix_tree_node **)
202 (node->slots + ((index >> shift) & RADIX_TREE_MAP_MASK));
203 shift -= RADIX_TREE_MAP_SHIFT;
204 height--;
207 if (*slot != NULL)
208 return -EEXIST;
209 if (node)
210 node->count++;
212 *slot = item;
213 return 0;
215 EXPORT_SYMBOL(radix_tree_insert);
218 * radix_tree_lookup - perform lookup operation on a radix tree
219 * @root: radix tree root
220 * @index: index key
222 * Lookup them item at the position @index in the radix tree @root.
224 void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
226 unsigned int height, shift;
227 struct radix_tree_node **slot;
229 height = root->height;
230 if (index > radix_tree_maxindex(height))
231 return NULL;
233 shift = (height-1) * RADIX_TREE_MAP_SHIFT;
234 slot = &root->rnode;
236 while (height > 0) {
237 if (*slot == NULL)
238 return NULL;
240 slot = (struct radix_tree_node **)
241 ((*slot)->slots + ((index >> shift) & RADIX_TREE_MAP_MASK));
242 shift -= RADIX_TREE_MAP_SHIFT;
243 height--;
246 return (void *) *slot;
248 EXPORT_SYMBOL(radix_tree_lookup);
250 static /* inline */ unsigned int
251 __lookup(struct radix_tree_root *root, void **results, unsigned long index,
252 unsigned int max_items, unsigned long *next_index)
254 unsigned int nr_found = 0;
255 unsigned int shift;
256 unsigned int height = root->height;
257 struct radix_tree_node *slot;
259 shift = (height-1) * RADIX_TREE_MAP_SHIFT;
260 slot = root->rnode;
262 while (height > 0) {
263 unsigned long i = (index >> shift) & RADIX_TREE_MAP_MASK;
265 for ( ; i < RADIX_TREE_MAP_SIZE; i++) {
266 if (slot->slots[i] != NULL)
267 break;
268 index &= ~((1 << shift) - 1);
269 index += 1 << shift;
270 if (index == 0)
271 goto out; /* 32-bit wraparound */
273 if (i == RADIX_TREE_MAP_SIZE)
274 goto out;
275 height--;
276 if (height == 0) { /* Bottom level: grab some items */
277 unsigned long j = index & RADIX_TREE_MAP_MASK;
279 for ( ; j < RADIX_TREE_MAP_SIZE; j++) {
280 index++;
281 if (slot->slots[j]) {
282 results[nr_found++] = slot->slots[j];
283 if (nr_found == max_items)
284 goto out;
288 shift -= RADIX_TREE_MAP_SHIFT;
289 slot = slot->slots[i];
291 out:
292 *next_index = index;
293 return nr_found;
297 * radix_tree_gang_lookup - perform multiple lookup on a radix tree
298 * @root: radix tree root
299 * @results: where the results of the lookup are placed
300 * @first_index: start the lookup from this key
301 * @max_items: place up to this many items at *results
303 * Performs an index-ascending scan of the tree for present items. Places
304 * them at *@results and returns the number of items which were placed at
305 * *@results.
307 * The implementation is naive.
309 unsigned int
310 radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
311 unsigned long first_index, unsigned int max_items)
313 const unsigned long max_index = radix_tree_maxindex(root->height);
314 unsigned long cur_index = first_index;
315 unsigned int ret = 0;
317 if (root->rnode == NULL)
318 goto out;
319 if (max_index == 0) { /* Bah. Special case */
320 if (first_index == 0) {
321 if (max_items > 0) {
322 *results = root->rnode;
323 ret = 1;
326 goto out;
328 while (ret < max_items) {
329 unsigned int nr_found;
330 unsigned long next_index; /* Index of next search */
332 if (cur_index > max_index)
333 break;
334 nr_found = __lookup(root, results + ret, cur_index,
335 max_items - ret, &next_index);
336 ret += nr_found;
337 if (next_index == 0)
338 break;
339 cur_index = next_index;
341 out:
342 return ret;
344 EXPORT_SYMBOL(radix_tree_gang_lookup);
347 * radix_tree_delete - delete an item from a radix tree
348 * @root: radix tree root
349 * @index: index key
351 * Remove the item at @index from the radix tree rooted at @root.
353 * Returns the address of the deleted item, or NULL if it was not present.
355 void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
357 struct radix_tree_path path[RADIX_TREE_MAX_PATH], *pathp = path;
358 unsigned int height, shift;
359 void *ret = NULL;
361 height = root->height;
362 if (index > radix_tree_maxindex(height))
363 goto out;
365 shift = (height-1) * RADIX_TREE_MAP_SHIFT;
366 pathp->node = NULL;
367 pathp->slot = &root->rnode;
369 while (height > 0) {
370 if (*pathp->slot == NULL)
371 goto out;
373 pathp[1].node = *pathp[0].slot;
374 pathp[1].slot = (struct radix_tree_node **)
375 (pathp[1].node->slots + ((index >> shift) & RADIX_TREE_MAP_MASK));
376 pathp++;
377 shift -= RADIX_TREE_MAP_SHIFT;
378 height--;
381 ret = *pathp[0].slot;
382 if (ret == NULL)
383 goto out;
385 *pathp[0].slot = NULL;
386 while (pathp[0].node && --pathp[0].node->count == 0) {
387 pathp--;
388 *pathp[0].slot = NULL;
389 radix_tree_node_free(pathp[1].node);
392 if (root->rnode == NULL)
393 root->height = 0; /* Empty tree, we can reset the height */
394 out:
395 return ret;
397 EXPORT_SYMBOL(radix_tree_delete);
399 static void
400 radix_tree_node_ctor(void *node, kmem_cache_t *cachep, unsigned long flags)
402 memset(node, 0, sizeof(struct radix_tree_node));
405 static __init unsigned long __maxindex(unsigned int height)
407 unsigned int tmp = height * RADIX_TREE_MAP_SHIFT;
408 unsigned long index = (~0UL >> (RADIX_TREE_INDEX_BITS - tmp - 1)) >> 1;
410 if (tmp >= RADIX_TREE_INDEX_BITS)
411 index = ~0UL;
412 return index;
415 static __init void radix_tree_init_maxindex(void)
417 unsigned int i;
419 for (i = 0; i < ARRAY_SIZE(height_to_maxindex); i++)
420 height_to_maxindex[i] = __maxindex(i);
423 void __init radix_tree_init(void)
425 radix_tree_node_cachep = kmem_cache_create("radix_tree_node",
426 sizeof(struct radix_tree_node), 0,
427 0, radix_tree_node_ctor, NULL);
428 if (!radix_tree_node_cachep)
429 panic ("Failed to create radix_tree_node cache\n");
430 radix_tree_init_maxindex();