dm btree: add dm_btree_find_lowest_key
dm_btree_find_lowest_key is the reciprocal of dm_btree_find_highest_key. Factor out common code for dm_btree_find_{highest,lowest}_key. dm_btree_find_lowest_key is needed for an upcoming DM target, as such it is best to get this interface in place. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
This commit is contained in:
Родитель
7e664b3dec
Коммит
f164e6900f
|
@ -770,8 +770,8 @@ EXPORT_SYMBOL_GPL(dm_btree_insert_notify);
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
static int find_highest_key(struct ro_spine *s, dm_block_t block,
|
static int find_key(struct ro_spine *s, dm_block_t block, bool find_highest,
|
||||||
uint64_t *result_key, dm_block_t *next_block)
|
uint64_t *result_key, dm_block_t *next_block)
|
||||||
{
|
{
|
||||||
int i, r;
|
int i, r;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
@ -788,7 +788,11 @@ static int find_highest_key(struct ro_spine *s, dm_block_t block,
|
||||||
else
|
else
|
||||||
i--;
|
i--;
|
||||||
|
|
||||||
*result_key = le64_to_cpu(ro_node(s)->keys[i]);
|
if (find_highest)
|
||||||
|
*result_key = le64_to_cpu(ro_node(s)->keys[i]);
|
||||||
|
else
|
||||||
|
*result_key = le64_to_cpu(ro_node(s)->keys[0]);
|
||||||
|
|
||||||
if (next_block || flags & INTERNAL_NODE)
|
if (next_block || flags & INTERNAL_NODE)
|
||||||
block = value64(ro_node(s), i);
|
block = value64(ro_node(s), i);
|
||||||
|
|
||||||
|
@ -799,16 +803,16 @@ static int find_highest_key(struct ro_spine *s, dm_block_t block,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dm_btree_find_highest_key(struct dm_btree_info *info, dm_block_t root,
|
static int dm_btree_find_key(struct dm_btree_info *info, dm_block_t root,
|
||||||
uint64_t *result_keys)
|
bool find_highest, uint64_t *result_keys)
|
||||||
{
|
{
|
||||||
int r = 0, count = 0, level;
|
int r = 0, count = 0, level;
|
||||||
struct ro_spine spine;
|
struct ro_spine spine;
|
||||||
|
|
||||||
init_ro_spine(&spine, info);
|
init_ro_spine(&spine, info);
|
||||||
for (level = 0; level < info->levels; level++) {
|
for (level = 0; level < info->levels; level++) {
|
||||||
r = find_highest_key(&spine, root, result_keys + level,
|
r = find_key(&spine, root, find_highest, result_keys + level,
|
||||||
level == info->levels - 1 ? NULL : &root);
|
level == info->levels - 1 ? NULL : &root);
|
||||||
if (r == -ENODATA) {
|
if (r == -ENODATA) {
|
||||||
r = 0;
|
r = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -822,8 +826,23 @@ int dm_btree_find_highest_key(struct dm_btree_info *info, dm_block_t root,
|
||||||
|
|
||||||
return r ? r : count;
|
return r ? r : count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dm_btree_find_highest_key(struct dm_btree_info *info, dm_block_t root,
|
||||||
|
uint64_t *result_keys)
|
||||||
|
{
|
||||||
|
return dm_btree_find_key(info, root, true, result_keys);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL_GPL(dm_btree_find_highest_key);
|
EXPORT_SYMBOL_GPL(dm_btree_find_highest_key);
|
||||||
|
|
||||||
|
int dm_btree_find_lowest_key(struct dm_btree_info *info, dm_block_t root,
|
||||||
|
uint64_t *result_keys)
|
||||||
|
{
|
||||||
|
return dm_btree_find_key(info, root, false, result_keys);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(dm_btree_find_lowest_key);
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: We shouldn't use a recursive algorithm when we have limited stack
|
* FIXME: We shouldn't use a recursive algorithm when we have limited stack
|
||||||
* space. Also this only works for single level trees.
|
* space. Also this only works for single level trees.
|
||||||
|
|
|
@ -134,6 +134,14 @@ int dm_btree_insert_notify(struct dm_btree_info *info, dm_block_t root,
|
||||||
int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
|
int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
|
||||||
uint64_t *keys, dm_block_t *new_root);
|
uint64_t *keys, dm_block_t *new_root);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns < 0 on failure. Otherwise the number of key entries that have
|
||||||
|
* been filled out. Remember trees can have zero entries, and as such have
|
||||||
|
* no lowest key.
|
||||||
|
*/
|
||||||
|
int dm_btree_find_lowest_key(struct dm_btree_info *info, dm_block_t root,
|
||||||
|
uint64_t *result_keys);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns < 0 on failure. Otherwise the number of key entries that have
|
* Returns < 0 on failure. Otherwise the number of key entries that have
|
||||||
* been filled out. Remember trees can have zero entries, and as such have
|
* been filled out. Remember trees can have zero entries, and as such have
|
||||||
|
|
Загрузка…
Ссылка в новой задаче