aboutsummaryrefslogtreecommitdiffstats
path: root/lib/radix-tree.c
diff options
context:
space:
mode:
authorHans Reiser <reiser@namesys.com>2005-11-07 03:59:29 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 10:53:37 -0500
commita43313668f62a06e14c915b8c8994fc8a1257394 (patch)
treeae02e1ae145b3f277ead948c32b8b6d06a4e23d9 /lib/radix-tree.c
parent7361f4d8ca65d23a18ba009b4484612183332c2f (diff)
[PATCH] reiser4: add radix_tree_lookup_slot()
Reiser4 uses radix trees to solve a trouble reiser4_readdir has serving nfs requests. Unfortunately, radix tree api lacks an operation suitable for modifying existing entry. This patch adds radix_tree_lookup_slot which returns pointer to found item within the tree. That location can be then updated. Both Nick and Christoph Lameter have patches which need this as well. Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'lib/radix-tree.c')
-rw-r--r--lib/radix-tree.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index d1c057e71b68..88511c3805ad 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -281,35 +281,60 @@ int radix_tree_insert(struct radix_tree_root *root,
281} 281}
282EXPORT_SYMBOL(radix_tree_insert); 282EXPORT_SYMBOL(radix_tree_insert);
283 283
284/** 284static inline void **__lookup_slot(struct radix_tree_root *root,
285 * radix_tree_lookup - perform lookup operation on a radix tree 285 unsigned long index)
286 * @root: radix tree root
287 * @index: index key
288 *
289 * Lookup the item at the position @index in the radix tree @root.
290 */
291void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
292{ 286{
293 unsigned int height, shift; 287 unsigned int height, shift;
294 struct radix_tree_node *slot; 288 struct radix_tree_node **slot;
295 289
296 height = root->height; 290 height = root->height;
297 if (index > radix_tree_maxindex(height)) 291 if (index > radix_tree_maxindex(height))
298 return NULL; 292 return NULL;
299 293
300 shift = (height-1) * RADIX_TREE_MAP_SHIFT; 294 shift = (height-1) * RADIX_TREE_MAP_SHIFT;
301 slot = root->rnode; 295 slot = &root->rnode;
302 296
303 while (height > 0) { 297 while (height > 0) {
304 if (slot == NULL) 298 if (*slot == NULL)
305 return NULL; 299 return NULL;
306 300
307 slot = slot->slots[(index >> shift) & RADIX_TREE_MAP_MASK]; 301 slot = (struct radix_tree_node **)
302 ((*slot)->slots +
303 ((index >> shift) & RADIX_TREE_MAP_MASK));
308 shift -= RADIX_TREE_MAP_SHIFT; 304 shift -= RADIX_TREE_MAP_SHIFT;
309 height--; 305 height--;
310 } 306 }
311 307
312 return slot; 308 return (void **)slot;
309}
310
311/**
312 * radix_tree_lookup_slot - lookup a slot in a radix tree
313 * @root: radix tree root
314 * @index: index key
315 *
316 * Lookup the slot corresponding to the position @index in the radix tree
317 * @root. This is useful for update-if-exists operations.
318 */
319void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
320{
321 return __lookup_slot(root, index);
322}
323EXPORT_SYMBOL(radix_tree_lookup_slot);
324
325/**
326 * radix_tree_lookup - perform lookup operation on a radix tree
327 * @root: radix tree root
328 * @index: index key
329 *
330 * Lookup the item at the position @index in the radix tree @root.
331 */
332void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
333{
334 void **slot;
335
336 slot = __lookup_slot(root, index);
337 return slot != NULL ? *slot : NULL;
313} 338}
314EXPORT_SYMBOL(radix_tree_lookup); 339EXPORT_SYMBOL(radix_tree_lookup);
315 340