Skip to content

Commit

Permalink
lib: do code optimization for radix_tree_lookup() and radix_tree_look…
Browse files Browse the repository at this point in the history
…up_slot()

radix_tree_lookup() and radix_tree_lookup_slot() have much the
same code except for the return value.

Introduce radix_tree_lookup_element() to do the real work.

/*
 * is_slot == 1 : search for the slot.
 * is_slot == 0 : search for the node.
 */
static void * radix_tree_lookup_element(struct radix_tree_root *root,
					unsigned long index, int is_slot);

Signed-off-by: Huang Shijie <[email protected]>
Cc: Nick Piggin <[email protected]>
Cc: Christoph Lameter <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
zyzii authored and torvalds committed Jun 17, 2009
1 parent 30639b6 commit b72b71c
Showing 1 changed file with 26 additions and 47 deletions.
73 changes: 26 additions & 47 deletions lib/radix-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,20 +351,12 @@ int radix_tree_insert(struct radix_tree_root *root,
}
EXPORT_SYMBOL(radix_tree_insert);

/**
* radix_tree_lookup_slot - lookup a slot in a radix tree
* @root: radix tree root
* @index: index key
*
* Returns: the slot corresponding to the position @index in the
* radix tree @root. This is useful for update-if-exists operations.
*
* This function can be called under rcu_read_lock iff the slot is not
* modified by radix_tree_replace_slot, otherwise it must be called
* exclusive from other writers. Any dereference of the slot must be done
* using radix_tree_deref_slot.
/*
* is_slot == 1 : search for the slot.
* is_slot == 0 : search for the node.
*/
void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
static void *radix_tree_lookup_element(struct radix_tree_root *root,
unsigned long index, int is_slot)
{
unsigned int height, shift;
struct radix_tree_node *node, **slot;
Expand All @@ -376,7 +368,7 @@ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
if (!radix_tree_is_indirect_ptr(node)) {
if (index > 0)
return NULL;
return (void **)&root->rnode;
return is_slot ? (void *)&root->rnode : node;
}
node = radix_tree_indirect_to_ptr(node);

Expand All @@ -397,7 +389,25 @@ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
height--;
} while (height > 0);

return (void **)slot;
return is_slot ? (void *)slot:node;
}

/**
* radix_tree_lookup_slot - lookup a slot in a radix tree
* @root: radix tree root
* @index: index key
*
* Returns: the slot corresponding to the position @index in the
* radix tree @root. This is useful for update-if-exists operations.
*
* This function can be called under rcu_read_lock iff the slot is not
* modified by radix_tree_replace_slot, otherwise it must be called
* exclusive from other writers. Any dereference of the slot must be done
* using radix_tree_deref_slot.
*/
void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
{
return (void **)radix_tree_lookup_element(root, index, 1);
}
EXPORT_SYMBOL(radix_tree_lookup_slot);

Expand All @@ -415,38 +425,7 @@ EXPORT_SYMBOL(radix_tree_lookup_slot);
*/
void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
{
unsigned int height, shift;
struct radix_tree_node *node, **slot;

node = rcu_dereference(root->rnode);
if (node == NULL)
return NULL;

if (!radix_tree_is_indirect_ptr(node)) {
if (index > 0)
return NULL;
return node;
}
node = radix_tree_indirect_to_ptr(node);

height = node->height;
if (index > radix_tree_maxindex(height))
return NULL;

shift = (height-1) * RADIX_TREE_MAP_SHIFT;

do {
slot = (struct radix_tree_node **)
(node->slots + ((index>>shift) & RADIX_TREE_MAP_MASK));
node = rcu_dereference(*slot);
if (node == NULL)
return NULL;

shift -= RADIX_TREE_MAP_SHIFT;
height--;
} while (height > 0);

return node;
return radix_tree_lookup_element(root, index, 0);
}
EXPORT_SYMBOL(radix_tree_lookup);

Expand Down

0 comments on commit b72b71c

Please sign in to comment.