diff options
author | Hans Reiser <reiser@namesys.com> | 2005-11-07 03:59:29 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 10:53:37 -0500 |
commit | a43313668f62a06e14c915b8c8994fc8a1257394 (patch) | |
tree | ae02e1ae145b3f277ead948c32b8b6d06a4e23d9 /lib | |
parent | 7361f4d8ca65d23a18ba009b4484612183332c2f (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')
-rw-r--r-- | lib/radix-tree.c | 51 |
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 | } |
282 | EXPORT_SYMBOL(radix_tree_insert); | 282 | EXPORT_SYMBOL(radix_tree_insert); |
283 | 283 | ||
284 | /** | 284 | static 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 | */ | ||
291 | void *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 | */ | ||
319 | void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) | ||
320 | { | ||
321 | return __lookup_slot(root, index); | ||
322 | } | ||
323 | EXPORT_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 | */ | ||
332 | void *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 | } |
314 | EXPORT_SYMBOL(radix_tree_lookup); | 339 | EXPORT_SYMBOL(radix_tree_lookup); |
315 | 340 | ||