1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

radix_tree: api change

Instead of using 'key state & key end' uint8_t* switch to use
void* key, & size_t keylen.  This allows easier adaptation with
lvm code base with way too much casting with every use of function.

Also correctly mark const buffers to avoid compiled warnings and
casting.

Adapt the only bcache user ATM for API change.

Adapt unit test to match changed API.
This commit is contained in:
Zdenek Kabelac 2024-05-31 21:46:19 +02:00
parent 5731d06bc5
commit 88681f05f1
5 changed files with 156 additions and 133 deletions

View File

@ -178,9 +178,9 @@ unsigned radix_tree_size(struct radix_tree *rt)
return rt->nr_entries;
}
static bool _insert(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv);
static bool _insert(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv);
static bool _insert_unset(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
static bool _insert_unset(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
{
unsigned len = ke - kb;
@ -207,7 +207,7 @@ static bool _insert_unset(struct radix_tree *rt, struct value *v, uint8_t *kb, u
return true;
}
static bool _insert_value(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
static bool _insert_value(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
{
unsigned len = ke - kb;
@ -234,7 +234,7 @@ static bool _insert_value(struct radix_tree *rt, struct value *v, uint8_t *kb, u
return true;
}
static bool _insert_value_chain(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
static bool _insert_value_chain(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
{
struct value_chain *vc = v->value.ptr;
return _insert(rt, &vc->child, kb, ke, rv);
@ -248,7 +248,7 @@ static unsigned min(unsigned lhs, unsigned rhs)
return rhs;
}
static bool _insert_prefix_chain(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
static bool _insert_prefix_chain(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
{
struct prefix_chain *pc = v->value.ptr;
@ -313,7 +313,7 @@ static bool _insert_prefix_chain(struct radix_tree *rt, struct value *v, uint8_t
return true;
}
static bool _insert_node4(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
static bool _insert_node4(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
{
struct node4 *n4 = v->value.ptr;
if (n4->nr_entries == 4) {
@ -343,7 +343,7 @@ static bool _insert_node4(struct radix_tree *rt, struct value *v, uint8_t *kb, u
return true;
}
static bool _insert_node16(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
static bool _insert_node16(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
{
struct node16 *n16 = v->value.ptr;
@ -382,7 +382,7 @@ static bool _insert_node16(struct radix_tree *rt, struct value *v, uint8_t *kb,
return true;
}
static bool _insert_node48(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
static bool _insert_node48(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
{
struct node48 *n48 = v->value.ptr;
if (n48->nr_entries == 48) {
@ -417,7 +417,7 @@ static bool _insert_node48(struct radix_tree *rt, struct value *v, uint8_t *kb,
return true;
}
static bool _insert_node256(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
static bool _insert_node256(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
{
struct node256 *n256 = v->value.ptr;
bool r, was_unset = n256->values[*kb].type == UNSET;
@ -430,7 +430,7 @@ static bool _insert_node256(struct radix_tree *rt, struct value *v, uint8_t *kb,
}
// FIXME: the tree should not be touched if insert fails (eg, OOM)
static bool _insert(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t *ke, union radix_value rv)
static bool _insert(struct radix_tree *rt, struct value *v, const uint8_t *kb, const uint8_t *ke, union radix_value rv)
{
if (kb == ke) {
if (v->type == UNSET) {
@ -487,10 +487,10 @@ static bool _insert(struct radix_tree *rt, struct value *v, uint8_t *kb, uint8_t
struct lookup_result {
struct value *v;
uint8_t *kb;
const uint8_t *kb;
};
static struct lookup_result _lookup_prefix(struct value *v, uint8_t *kb, uint8_t *ke)
static struct lookup_result _lookup_prefix(struct value *v, const uint8_t *kb, const uint8_t *ke)
{
unsigned i;
struct value_chain *vc;
@ -555,8 +555,10 @@ static struct lookup_result _lookup_prefix(struct value *v, uint8_t *kb, uint8_t
return (struct lookup_result) {.v = v, .kb = kb};
}
bool radix_tree_insert(struct radix_tree *rt, uint8_t *kb, uint8_t *ke, union radix_value rv)
bool radix_tree_insert(struct radix_tree *rt, const void *key, size_t keylen, union radix_value rv)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
struct lookup_result lr = _lookup_prefix(&rt->root, kb, ke);
return _insert(rt, lr.v, lr.kb, ke, rv);
}
@ -639,7 +641,7 @@ static void _erase_elt(void *array, size_t obj_size, unsigned count, unsigned id
memset(((uint8_t *) array) + (count - 1) * obj_size, 0, obj_size);
}
static bool _remove(struct radix_tree *rt, struct value *root, uint8_t *kb, uint8_t *ke)
static bool _remove(struct radix_tree *rt, struct value *root, const uint8_t *kb, const uint8_t *ke)
{
bool r;
unsigned i, j;
@ -775,9 +777,12 @@ static bool _remove(struct radix_tree *rt, struct value *root, uint8_t *kb, uint
return false;
}
bool radix_tree_remove(struct radix_tree *rt, uint8_t *key_begin, uint8_t *key_end)
bool radix_tree_remove(struct radix_tree *rt, const void *key, size_t keylen)
{
if (_remove(rt, &rt->root, key_begin, key_end)) {
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
if (_remove(rt, &rt->root, kb, ke)) {
rt->nr_entries--;
return true;
}
@ -787,13 +792,13 @@ bool radix_tree_remove(struct radix_tree *rt, uint8_t *key_begin, uint8_t *key_e
//----------------------------------------------------------------
static bool _prefix_chain_matches(struct lookup_result *lr, uint8_t *ke)
static bool _prefix_chain_matches(const struct lookup_result *lr, const uint8_t *ke)
{
// It's possible the top node is a prefix chain, and
// the remaining key matches part of it.
if (lr->v->type == PREFIX_CHAIN) {
unsigned i, rlen = ke - lr->kb;
struct prefix_chain *pc = lr->v->value.ptr;
const struct prefix_chain *pc = lr->v->value.ptr;
if (rlen < pc->len) {
for (i = 0; i < rlen; i++)
if (pc->prefix[i] != lr->kb[i])
@ -805,7 +810,7 @@ static bool _prefix_chain_matches(struct lookup_result *lr, uint8_t *ke)
return false;
}
static bool _remove_subtree(struct radix_tree *rt, struct value *root, uint8_t *kb, uint8_t *ke, unsigned *count)
static bool _remove_subtree(struct radix_tree *rt, struct value *root, const uint8_t *kb, const uint8_t *ke, unsigned *count)
{
bool r;
unsigned i, j, len;
@ -931,8 +936,10 @@ static bool _remove_subtree(struct radix_tree *rt, struct value *root, uint8_t *
return false;
}
unsigned radix_tree_remove_prefix(struct radix_tree *rt, uint8_t *kb, uint8_t *ke)
unsigned radix_tree_remove_prefix(struct radix_tree *rt, const void *prefix, size_t prefix_len)
{
const uint8_t *kb = prefix;
const uint8_t *ke = kb + prefix_len;
unsigned count = 0;
if (_remove_subtree(rt, &rt->root, kb, ke, &count))
@ -943,9 +950,11 @@ unsigned radix_tree_remove_prefix(struct radix_tree *rt, uint8_t *kb, uint8_t *k
//----------------------------------------------------------------
bool radix_tree_lookup(struct radix_tree *rt,
uint8_t *kb, uint8_t *ke, union radix_value *result)
bool radix_tree_lookup(struct radix_tree *rt, const void *key, size_t keylen,
union radix_value *result)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
struct value_chain *vc;
struct lookup_result lr = _lookup_prefix(&rt->root, kb, ke);
if (lr.kb == ke) {
@ -984,11 +993,11 @@ static bool _iterate(struct value *v, struct radix_tree_iterator *it)
break;
case VALUE:
return it->visit(it, NULL, NULL, v->value);
return it->visit(it, NULL, 0, v->value);
case VALUE_CHAIN:
vc = v->value.ptr;
return it->visit(it, NULL, NULL, vc->value) && _iterate(&vc->child, it);
return it->visit(it, NULL, 0, vc->value) && _iterate(&vc->child, it);
case PREFIX_CHAIN:
pc = v->value.ptr;
@ -1027,9 +1036,11 @@ static bool _iterate(struct value *v, struct radix_tree_iterator *it)
return false;
}
void radix_tree_iterate(struct radix_tree *rt, uint8_t *kb, uint8_t *ke,
void radix_tree_iterate(struct radix_tree *rt, const void *key, size_t keylen,
struct radix_tree_iterator *it)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
struct lookup_result lr = _lookup_prefix(&rt->root, kb, ke);
if (lr.kb == ke || _prefix_chain_matches(&lr, ke))
(void) _iterate(lr.v, it);

View File

@ -104,7 +104,7 @@ unsigned radix_tree_size(struct radix_tree *rt)
return _count(rt->root);
}
static struct node **_lookup(struct node **pn, uint8_t *kb, uint8_t *ke)
static struct node **_lookup(struct node **pn, const uint8_t *kb, const uint8_t *ke)
{
struct node *n = *pn;
@ -121,7 +121,7 @@ static struct node **_lookup(struct node **pn, uint8_t *kb, uint8_t *ke)
return _lookup(&n->center, kb + 1, ke);
}
static bool _insert(struct node **pn, uint8_t *kb, uint8_t *ke, union radix_value v)
static bool _insert(struct node **pn, const uint8_t *kb, const uint8_t *ke, union radix_value v)
{
struct node *n = *pn;
@ -150,14 +150,19 @@ static bool _insert(struct node **pn, uint8_t *kb, uint8_t *ke, union radix_valu
return _insert(&n->center, kb + 1, ke, v);
}
bool radix_tree_insert(struct radix_tree *rt, uint8_t *kb, uint8_t *ke,
bool radix_tree_insert(struct radix_tree *rt, const void *key, size_t keylen,
union radix_value v)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
return _insert(&rt->root, kb, ke, v);
}
bool radix_tree_remove(struct radix_tree *rt, uint8_t *kb, uint8_t *ke)
bool radix_tree_remove(struct radix_tree *rt, const void *key, size_t keylen)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
struct node **pn = _lookup(&rt->root, kb, ke);
struct node *n = *pn;
@ -180,8 +185,10 @@ bool radix_tree_remove(struct radix_tree *rt, uint8_t *kb, uint8_t *ke)
return true;
}
unsigned radix_tree_remove_prefix(struct radix_tree *rt, uint8_t *kb, uint8_t *ke)
unsigned radix_tree_remove_prefix(struct radix_tree *rt, const void *key, size_t keylen)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
struct node **pn;
unsigned count;
@ -195,9 +202,11 @@ unsigned radix_tree_remove_prefix(struct radix_tree *rt, uint8_t *kb, uint8_t *k
return count;
}
bool radix_tree_lookup(struct radix_tree *rt, uint8_t *kb, uint8_t *ke,
bool radix_tree_lookup(struct radix_tree *rt, const void *key, size_t keylen,
union radix_value *result)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
struct node **pn = _lookup(&rt->root, kb, ke);
struct node *n = *pn;
@ -218,15 +227,18 @@ static void _iterate(struct node *n, struct radix_tree_iterator *it)
if (n->has_value)
// FIXME: fill out the key
it->visit(it, NULL, NULL, n->value);
it->visit(it, NULL, 0, n->value);
_iterate(n->center, it);
_iterate(n->right, it);
}
void radix_tree_iterate(struct radix_tree *rt, uint8_t *kb, uint8_t *ke,
void radix_tree_iterate(struct radix_tree *rt, const void *key, size_t keylen,
struct radix_tree_iterator *it)
{
const uint8_t *kb = key;
const uint8_t *ke = kb + keylen;
if (kb == ke)
_iterate(rt->root, it);
@ -236,7 +248,7 @@ void radix_tree_iterate(struct radix_tree *rt, uint8_t *kb, uint8_t *ke,
if (n) {
if (n->has_value)
it->visit(it, NULL, NULL, n->value);
it->visit(it, NULL, 0, n->value);
_iterate(n->center, it);
}
}

View File

@ -33,14 +33,14 @@ struct radix_tree *radix_tree_create(radix_value_dtr dtr, void *dtr_context);
void radix_tree_destroy(struct radix_tree *rt);
unsigned radix_tree_size(struct radix_tree *rt);
bool radix_tree_insert(struct radix_tree *rt, uint8_t *kb, uint8_t *ke, union radix_value v);
bool radix_tree_remove(struct radix_tree *rt, uint8_t *kb, uint8_t *ke);
bool radix_tree_insert(struct radix_tree *rt, const void *key, size_t keylen, union radix_value v);
bool radix_tree_remove(struct radix_tree *rt, const void *key, size_t keylen);
// Returns the number of values removed
unsigned radix_tree_remove_prefix(struct radix_tree *rt, uint8_t *prefix_b, uint8_t *prefix_e);
unsigned radix_tree_remove_prefix(struct radix_tree *rt, const void *prefix, size_t prefix_len);
bool radix_tree_lookup(struct radix_tree *rt,
uint8_t *kb, uint8_t *ke, union radix_value *result);
bool radix_tree_lookup(struct radix_tree *rt, const void *key, size_t keylen,
union radix_value *result);
// The radix tree stores entries in lexicographical order. Which means
// we can iterate entries, in order. Or iterate entries with a particular
@ -48,10 +48,10 @@ bool radix_tree_lookup(struct radix_tree *rt,
struct radix_tree_iterator {
// Returns false if the iteration should end.
bool (*visit)(struct radix_tree_iterator *it,
uint8_t *kb, uint8_t *ke, union radix_value v);
const void *key, size_t keylen, union radix_value v);
};
void radix_tree_iterate(struct radix_tree *rt, uint8_t *kb, uint8_t *ke,
void radix_tree_iterate(struct radix_tree *rt, const void *key, size_t keylen,
struct radix_tree_iterator *it);
// Checks that some constraints on the shape of the tree are

View File

@ -711,7 +711,7 @@ static struct block *_block_lookup(struct bcache *cache, int di, uint64_t i)
k.parts.di = di;
k.parts.b = i;
if (radix_tree_lookup(cache->rtree, k.bytes, k.bytes + sizeof(k.bytes), &v))
if (radix_tree_lookup(cache->rtree, k.bytes, sizeof(k.bytes), &v))
return v.ptr;
return NULL;
@ -726,7 +726,7 @@ static bool _block_insert(struct block *b)
k.parts.b = b->index;
v.ptr = b;
return radix_tree_insert(b->cache->rtree, k.bytes, k.bytes + sizeof(k.bytes), v);
return radix_tree_insert(b->cache->rtree, k.bytes, sizeof(k.bytes), v);
}
static void _block_remove(struct block *b)
@ -736,7 +736,7 @@ static void _block_remove(struct block *b)
k.parts.di = b->di;
k.parts.b = b->index;
(void) radix_tree_remove(b->cache->rtree, k.bytes, k.bytes + sizeof(k.bytes));
(void) radix_tree_remove(b->cache->rtree, k.bytes, sizeof(k.bytes));
}
//----------------------------------------------------------------
@ -1353,7 +1353,7 @@ struct invalidate_iterator {
};
static bool _writeback_v(struct radix_tree_iterator *it,
uint8_t *kb, uint8_t *ke, union radix_value v)
const void *kb, size_t keylen, union radix_value v)
{
struct block *b = v.ptr;
@ -1364,7 +1364,7 @@ static bool _writeback_v(struct radix_tree_iterator *it,
}
static bool _invalidate_v(struct radix_tree_iterator *it,
uint8_t *kb, uint8_t *ke, union radix_value v)
const void *kb, size_t keylen, union radix_value v)
{
struct block *b = v.ptr;
struct invalidate_iterator *iit = container_of(it, struct invalidate_iterator, it);
@ -1399,16 +1399,16 @@ bool bcache_invalidate_di(struct bcache *cache, int di)
k.parts.di = di;
it.it.visit = _writeback_v;
radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di), &it.it);
radix_tree_iterate(cache->rtree, k.bytes, sizeof(k.parts.di), &it.it);
_wait_all(cache);
it.success = true;
it.it.visit = _invalidate_v;
radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di), &it.it);
radix_tree_iterate(cache->rtree, k.bytes, sizeof(k.parts.di), &it.it);
if (it.success)
(void) radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di));
(void) radix_tree_remove_prefix(cache->rtree, k.bytes, sizeof(k.parts.di));
return it.success;
}
@ -1416,7 +1416,7 @@ bool bcache_invalidate_di(struct bcache *cache, int di)
//----------------------------------------------------------------
static bool _abort_v(struct radix_tree_iterator *it,
uint8_t *kb, uint8_t *ke, union radix_value v)
const void *kb, size_t keylen, union radix_value v)
{
struct block *b = v.ptr;
@ -1442,8 +1442,8 @@ void bcache_abort_di(struct bcache *cache, int di)
k.parts.di = di;
it.visit = _abort_v;
radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di), &it);
(void) radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di));
radix_tree_iterate(cache->rtree, k.bytes, sizeof(k.parts.di), &it);
(void) radix_tree_remove_prefix(cache->rtree, k.bytes, sizeof(k.parts.di));
}
//----------------------------------------------------------------

View File

@ -43,10 +43,10 @@ static void test_insert_one(void *fixture)
union radix_value v;
unsigned char k = 'a';
v.n = 65;
T_ASSERT(radix_tree_insert(rt, &k, &k + 1, v));
T_ASSERT(radix_tree_insert(rt, &k, 1, v));
T_ASSERT(radix_tree_is_well_formed(rt));
v.n = 0;
T_ASSERT(radix_tree_lookup(rt, &k, &k + 1, &v));
T_ASSERT(radix_tree_lookup(rt, &k, 1, &v));
T_ASSERT_EQUAL(v.n, 65);
}
@ -60,14 +60,14 @@ static void test_single_byte_keys(void *fixture)
for (i = 0; i < count; i++) {
k = i;
v.n = 100 + i;
T_ASSERT(radix_tree_insert(rt, &k, &k + 1, v));
T_ASSERT(radix_tree_insert(rt, &k, 1, v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
for (i = 0; i < count; i++) {
k = i;
T_ASSERT(radix_tree_lookup(rt, &k, &k + 1, &v));
T_ASSERT(radix_tree_lookup(rt, &k, 1, &v));
T_ASSERT_EQUAL(v.n, 100 + i);
}
}
@ -82,7 +82,7 @@ static void test_overwrite_single_byte_keys(void *fixture)
for (i = 0; i < count; i++) {
k = i;
v.n = 100 + i;
T_ASSERT(radix_tree_insert(rt, &k, &k + 1, v));
T_ASSERT(radix_tree_insert(rt, &k, 1, v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
@ -90,14 +90,14 @@ static void test_overwrite_single_byte_keys(void *fixture)
for (i = 0; i < count; i++) {
k = i;
v.n = 1000 + i;
T_ASSERT(radix_tree_insert(rt, &k, &k + 1, v));
T_ASSERT(radix_tree_insert(rt, &k, 1, v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
for (i = 0; i < count; i++) {
k = i;
T_ASSERT(radix_tree_lookup(rt, &k, &k + 1, &v));
T_ASSERT(radix_tree_lookup(rt, &k, 1, &v));
T_ASSERT_EQUAL(v.n, 1000 + i);
}
}
@ -113,7 +113,7 @@ static void test_16_bit_keys(void *fixture)
k[0] = i / 256;
k[1] = i % 256;
v.n = 100 + i;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
@ -121,7 +121,7 @@ static void test_16_bit_keys(void *fixture)
for (i = 0; i < count; i++) {
k[0] = i / 256;
k[1] = i % 256;
T_ASSERT(radix_tree_lookup(rt, k, k + sizeof(k), &v));
T_ASSERT(radix_tree_lookup(rt, k, sizeof(k), &v));
T_ASSERT_EQUAL(v.n, 100 + i);
}
}
@ -135,14 +135,14 @@ static void test_prefix_keys(void *fixture)
k[0] = 100;
k[1] = 200;
v.n = 1024;
T_ASSERT(radix_tree_insert(rt, k, k + 1, v));
T_ASSERT(radix_tree_insert(rt, k, 1, v));
T_ASSERT(radix_tree_is_well_formed(rt));
v.n = 2345;
T_ASSERT(radix_tree_insert(rt, k, k + 2, v));
T_ASSERT(radix_tree_insert(rt, k, 2, v));
T_ASSERT(radix_tree_is_well_formed(rt));
T_ASSERT(radix_tree_lookup(rt, k, k + 1, &v));
T_ASSERT(radix_tree_lookup(rt, k, 1, &v));
T_ASSERT_EQUAL(v.n, 1024);
T_ASSERT(radix_tree_lookup(rt, k, k + 2, &v));
T_ASSERT(radix_tree_lookup(rt, k, 2, &v));
T_ASSERT_EQUAL(v.n, 2345);
}
@ -155,14 +155,14 @@ static void test_prefix_keys_reversed(void *fixture)
k[0] = 100;
k[1] = 200;
v.n = 1024;
T_ASSERT(radix_tree_insert(rt, k, k + 2, v));
T_ASSERT(radix_tree_insert(rt, k, 2, v));
T_ASSERT(radix_tree_is_well_formed(rt));
v.n = 2345;
T_ASSERT(radix_tree_insert(rt, k, k + 1, v));
T_ASSERT(radix_tree_insert(rt, k, 1, v));
T_ASSERT(radix_tree_is_well_formed(rt));
T_ASSERT(radix_tree_lookup(rt, k, k + 2, &v));
T_ASSERT(radix_tree_lookup(rt, k, 2, &v));
T_ASSERT_EQUAL(v.n, 1024);
T_ASSERT(radix_tree_lookup(rt, k, k + 1, &v));
T_ASSERT(radix_tree_lookup(rt, k, 1, &v));
T_ASSERT_EQUAL(v.n, 2345);
}
@ -183,7 +183,7 @@ static void test_sparse_keys(void *fixture)
for (n = 0; n < 100000; n++) {
_gen_key(k, k + sizeof(k));
v.n = 1234;
T_ASSERT(radix_tree_insert(rt, k, k + 32, v));
T_ASSERT(radix_tree_insert(rt, k, 32, v));
// FIXME: remove
//T_ASSERT(radix_tree_is_well_formed(rt));
}
@ -198,11 +198,11 @@ static void test_remove_one(void *fixture)
_gen_key(k, k + sizeof(k));
v.n = 1234;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
T_ASSERT(radix_tree_is_well_formed(rt));
T_ASSERT(radix_tree_remove(rt, k, k + sizeof(k)));
T_ASSERT(radix_tree_remove(rt, k, sizeof(k)));
T_ASSERT(radix_tree_is_well_formed(rt));
T_ASSERT(!radix_tree_lookup(rt, k, k + sizeof(k), &v));
T_ASSERT(!radix_tree_lookup(rt, k, sizeof(k), &v));
}
static void test_remove_one_byte_keys(void *fixture)
@ -215,18 +215,18 @@ static void test_remove_one_byte_keys(void *fixture)
for (i = 0; i < 256; i++) {
k[0] = i;
v.n = i + 1000;
T_ASSERT(radix_tree_insert(rt, k, k + 1, v));
T_ASSERT(radix_tree_insert(rt, k, 1, v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
for (i = 0; i < 256; i++) {
k[0] = i;
T_ASSERT(radix_tree_remove(rt, k, k + 1));
T_ASSERT(radix_tree_remove(rt, k, 1));
T_ASSERT(radix_tree_is_well_formed(rt));
for (j = i + 1; j < 256; j++) {
k[0] = j;
T_ASSERT(radix_tree_lookup(rt, k, k + 1, &v));
T_ASSERT(radix_tree_lookup(rt, k, 1, &v));
if (v.n != j + 1000)
test_fail("v.n (%u) != j + 1000 (%u)\n",
(unsigned) v.n,
@ -236,7 +236,7 @@ static void test_remove_one_byte_keys(void *fixture)
for (i = 0; i < 256; i++) {
k[0] = i;
T_ASSERT(!radix_tree_lookup(rt, k, k + 1, &v));
T_ASSERT(!radix_tree_lookup(rt, k, 1, &v));
}
}
@ -250,18 +250,18 @@ static void test_remove_one_byte_keys_reversed(void *fixture)
for (i = 0; i < 256; i++) {
k[0] = i;
v.n = i + 1000;
T_ASSERT(radix_tree_insert(rt, k, k + 1, v));
T_ASSERT(radix_tree_insert(rt, k, 1, v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
for (i = 256; i; i--) {
k[0] = i - 1;
T_ASSERT(radix_tree_remove(rt, k, k + 1));
T_ASSERT(radix_tree_remove(rt, k, 1));
T_ASSERT(radix_tree_is_well_formed(rt));
for (j = 0; j < i - 1; j++) {
k[0] = j;
T_ASSERT(radix_tree_lookup(rt, k, k + 1, &v));
T_ASSERT(radix_tree_lookup(rt, k, 1, &v));
if (v.n != j + 1000)
test_fail("v.n (%u) != j + 1000 (%u)\n",
(unsigned) v.n,
@ -271,7 +271,7 @@ static void test_remove_one_byte_keys_reversed(void *fixture)
for (i = 0; i < 256; i++) {
k[0] = i;
T_ASSERT(!radix_tree_lookup(rt, k, k + 1, &v));
T_ASSERT(!radix_tree_lookup(rt, k, 1, &v));
}
}
static void test_remove_prefix_keys(void *fixture)
@ -285,21 +285,21 @@ static void test_remove_prefix_keys(void *fixture)
for (i = 0; i < 32; i++) {
v.n = i;
T_ASSERT(radix_tree_insert(rt, k, k + i, v));
T_ASSERT(radix_tree_insert(rt, k, i, v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
for (i = 0; i < 32; i++) {
T_ASSERT(radix_tree_remove(rt, k, k + i));
T_ASSERT(radix_tree_remove(rt, k, i));
T_ASSERT(radix_tree_is_well_formed(rt));
for (j = i + 1; j < 32; j++) {
T_ASSERT(radix_tree_lookup(rt, k, k + j, &v));
T_ASSERT(radix_tree_lookup(rt, k, j, &v));
T_ASSERT_EQUAL(v.n, j);
}
}
for (i = 0; i < 32; i++)
T_ASSERT(!radix_tree_lookup(rt, k, k + i, &v));
T_ASSERT(!radix_tree_lookup(rt, k, i, &v));
}
static void test_remove_prefix_keys_reversed(void *fixture)
@ -313,21 +313,21 @@ static void test_remove_prefix_keys_reversed(void *fixture)
for (i = 0; i < 32; i++) {
v.n = i;
T_ASSERT(radix_tree_insert(rt, k, k + i, v));
T_ASSERT(radix_tree_insert(rt, k, i, v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
for (i = 0; i < 32; i++) {
T_ASSERT(radix_tree_remove(rt, k, k + (31 - i)));
T_ASSERT(radix_tree_remove(rt, k, (31 - i)));
T_ASSERT(radix_tree_is_well_formed(rt));
for (j = 0; j < 31 - i; j++) {
T_ASSERT(radix_tree_lookup(rt, k, k + j, &v));
T_ASSERT(radix_tree_lookup(rt, k, j, &v));
T_ASSERT_EQUAL(v.n, j);
}
}
for (i = 0; i < 32; i++)
T_ASSERT(!radix_tree_lookup(rt, k, k + i, &v));
T_ASSERT(!radix_tree_lookup(rt, k, i, &v));
}
static void test_remove_prefix(void *fixture)
@ -343,14 +343,14 @@ static void test_remove_prefix(void *fixture)
if (k[0] == 21)
count++;
v.n = i;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
// remove keys in a sub range
k[0] = 21;
T_ASSERT_EQUAL(radix_tree_remove_prefix(rt, k, k + 1), count);
T_ASSERT_EQUAL(radix_tree_remove_prefix(rt, k, 1), count);
T_ASSERT(radix_tree_is_well_formed(rt));
}
@ -362,9 +362,9 @@ static void test_remove_prefix_single(void *fixture)
_gen_key(k, k + sizeof(k));
v.n = 1234;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
T_ASSERT(radix_tree_is_well_formed(rt));
T_ASSERT_EQUAL(radix_tree_remove_prefix(rt, k, k + 2), 1);
T_ASSERT_EQUAL(radix_tree_remove_prefix(rt, k, 2), 1);
T_ASSERT(radix_tree_is_well_formed(rt));
}
@ -378,10 +378,10 @@ static void test_size(void *fixture)
// populate some random 16bit keys
for (i = 0; i < 10000; i++) {
_gen_key(k, k + sizeof(k));
if (radix_tree_lookup(rt, k, k + sizeof(k), &v))
if (radix_tree_lookup(rt, k, sizeof(k), &v))
dup_count++;
v.n = i;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
}
T_ASSERT_EQUAL(radix_tree_size(rt), 10000 - dup_count);
@ -394,7 +394,7 @@ struct visitor {
};
static bool _visit(struct radix_tree_iterator *it,
uint8_t *kb, uint8_t *ke, union radix_value v)
const void *key, size_t keylen, union radix_value v)
{
struct visitor *vt = container_of(it, struct visitor, it);
vt->count++;
@ -413,13 +413,13 @@ static void test_iterate_all(void *fixture)
for (i = 0; i < 100000; i++) {
_gen_key(k, k + sizeof(k));
v.n = i;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
vt.count = 0;
vt.it.visit = _visit;
radix_tree_iterate(rt, NULL, NULL, &vt.it);
radix_tree_iterate(rt, NULL, 0, &vt.it);
T_ASSERT_EQUAL(vt.count, radix_tree_size(rt));
}
@ -437,7 +437,7 @@ static void test_iterate_subset(void *fixture)
if (k[0] == 21 && k[1] == 12)
subset_count++;
v.n = i;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
@ -445,7 +445,7 @@ static void test_iterate_subset(void *fixture)
vt.it.visit = _visit;
k[0] = 21;
k[1] = 12;
radix_tree_iterate(rt, k, k + 2, &vt.it);
radix_tree_iterate(rt, k, 2, &vt.it);
T_ASSERT_EQUAL(vt.count, subset_count);
}
@ -458,12 +458,12 @@ static void test_iterate_single(void *fixture)
_gen_key(k, k + sizeof(k));
v.n = 1234;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
T_ASSERT(radix_tree_is_well_formed(rt));
vt.count = 0;
vt.it.visit = _visit;
radix_tree_iterate(rt, k, k + 3, &vt.it);
radix_tree_iterate(rt, k, 3, &vt.it);
T_ASSERT_EQUAL(vt.count, 1);
}
@ -479,7 +479,7 @@ static void test_iterate_vary_middle(void *fixture)
for (i = 0; i < 16; i++) {
k[3] = i;
v.n = i;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
@ -487,7 +487,7 @@ static void test_iterate_vary_middle(void *fixture)
for (i = 0; i < 16; i++) {
vt.count = 0;
k[3] = i;
radix_tree_iterate(rt, k, k + 4, &vt.it);
radix_tree_iterate(rt, k, 4, &vt.it);
T_ASSERT_EQUAL(vt.count, 1);
}
}
@ -533,8 +533,8 @@ static void test_remove_calls_dtr(void *fixture)
v.n = i;
uint8_t *k = keys + (i * 3);
_gen_key(k, k + 3);
if (!radix_tree_lookup(rt, k, k + 3, &v)) {
T_ASSERT(radix_tree_insert(rt, k, k + 3, v));
if (!radix_tree_lookup(rt, k, 3, &v)) {
T_ASSERT(radix_tree_insert(rt, k, 3, v));
found = true;
}
@ -546,13 +546,13 @@ static void test_remove_calls_dtr(void *fixture)
// double check
for (i = 0; i < DTR_COUNT; i++) {
uint8_t *k = keys + (i * 3);
T_ASSERT(radix_tree_lookup(rt, k, k + 3, &v));
T_ASSERT(radix_tree_lookup(rt, k, 3, &v));
}
for (i = 0; i < DTR_COUNT; i++) {
uint8_t *k = keys + (i * 3);
// FIXME: check the values get passed to the dtr
T_ASSERT(radix_tree_remove(rt, k, k + 3));
T_ASSERT(radix_tree_remove(rt, k, 3));
}
T_ASSERT(c.c == DTR_COUNT);
@ -587,8 +587,8 @@ static void test_destroy_calls_dtr(void *fixture)
v.n = i;
uint8_t *k = keys + (i * 3);
_gen_key(k, k + 3);
if (!radix_tree_lookup(rt, k, k + 3, &v)) {
T_ASSERT(radix_tree_insert(rt, k, k + 3, v));
if (!radix_tree_lookup(rt, k, 3, &v)) {
T_ASSERT(radix_tree_insert(rt, k, 3, v));
found = true;
}
@ -621,17 +621,17 @@ static void test_bcache_scenario(void *fixture)
// trigger the bug.
k[4] = i;
v.n = i;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
k[4] = 0;
T_ASSERT(radix_tree_remove(rt, k, k + sizeof(k)));
T_ASSERT(radix_tree_remove(rt, k, sizeof(k)));
T_ASSERT(radix_tree_is_well_formed(rt));
k[4] = i;
v.n = i;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
T_ASSERT(radix_tree_is_well_formed(rt));
}
@ -647,7 +647,7 @@ static void _bcs2_step1(struct radix_tree *rt)
for (i = 0x6; i < 0x69; i++) {
k[0] = i;
v.n = i;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
}
@ -660,7 +660,7 @@ static void _bcs2_step2(struct radix_tree *rt)
memset(k, 0, sizeof(k));
for (i = 0x6; i < 0x69; i++) {
k[0] = i;
radix_tree_remove_prefix(rt, k, k + 4);
radix_tree_remove_prefix(rt, k, 4);
}
T_ASSERT(radix_tree_is_well_formed(rt));
}
@ -679,8 +679,8 @@ static void test_bcache_scenario2(void *fixture)
for (i = 0; i < 50; i++) {
k[0] = 0x6;
v.n = 0x6;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
radix_tree_remove_prefix(rt, k, k + 4);
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
radix_tree_remove_prefix(rt, k, 4);
}
T_ASSERT(radix_tree_is_well_formed(rt));
@ -694,10 +694,10 @@ static void test_bcache_scenario2(void *fixture)
k[0] = i;
k[4] = 0xf;
k[5] = 0x1;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
k[4] = 0;
k[5] = 0;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
@ -706,47 +706,47 @@ static void test_bcache_scenario2(void *fixture)
k[0] = i - 0x32;
k[4] = 0xf;
k[5] = 1;
T_ASSERT(radix_tree_remove(rt, k, k + sizeof(k)));
T_ASSERT(radix_tree_remove(rt, k, sizeof(k)));
k[0] = i;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
k[0] = i - 0x32;
k[4] = 0;
k[5] = 0;
T_ASSERT(radix_tree_remove(rt, k, k + sizeof(k)));
T_ASSERT(radix_tree_remove(rt, k, sizeof(k)));
k[0] = i;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
}
T_ASSERT(radix_tree_is_well_formed(rt));
memset(k, 0, sizeof(k));
k[0] = 0x6;
radix_tree_remove_prefix(rt, k, k + 4);
radix_tree_remove_prefix(rt, k, 4);
T_ASSERT(radix_tree_is_well_formed(rt));
k[0] = 0x38;
k[4] = 0xf;
k[5] = 0x1;
T_ASSERT(radix_tree_remove(rt, k, k + sizeof(k)));
T_ASSERT(radix_tree_remove(rt, k, sizeof(k)));
T_ASSERT(radix_tree_is_well_formed(rt));
memset(k, 0, sizeof(k));
k[0] = 0x6;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
T_ASSERT(radix_tree_is_well_formed(rt));
k[0] = 0x7;
radix_tree_remove_prefix(rt, k, k + 4);
radix_tree_remove_prefix(rt, k, 4);
T_ASSERT(radix_tree_is_well_formed(rt));
k[0] = 0x38;
T_ASSERT(radix_tree_remove(rt, k, k + sizeof(k)));
T_ASSERT(radix_tree_remove(rt, k, sizeof(k)));
T_ASSERT(radix_tree_is_well_formed(rt));
k[0] = 7;
T_ASSERT(radix_tree_insert(rt, k, k + sizeof(k), v));
T_ASSERT(radix_tree_insert(rt, k, sizeof(k), v));
T_ASSERT(radix_tree_is_well_formed(rt));
}
@ -769,7 +769,7 @@ static void __lookup_matches(struct radix_tree *rt, int fd, uint64_t b, uint64_t
k.parts.fd = fd;
k.parts.b = b;
T_ASSERT(radix_tree_lookup(rt, k.bytes, k.bytes + sizeof(k.bytes), &v));
T_ASSERT(radix_tree_lookup(rt, k.bytes, sizeof(k.bytes), &v));
T_ASSERT(v.n == expected);
}
@ -780,7 +780,7 @@ static void __lookup_fails(struct radix_tree *rt, int fd, uint64_t b)
k.parts.fd = fd;
k.parts.b = b;
T_ASSERT(!radix_tree_lookup(rt, k.bytes, k.bytes + sizeof(k.bytes), &v));
T_ASSERT(!radix_tree_lookup(rt, k.bytes, sizeof(k.bytes), &v));
}
static void __insert(struct radix_tree *rt, int fd, uint64_t b, uint64_t n)
@ -791,7 +791,7 @@ static void __insert(struct radix_tree *rt, int fd, uint64_t b, uint64_t n)
k.parts.fd = fd;
k.parts.b = b;
v.n = n;
T_ASSERT(radix_tree_insert(rt, k.bytes, k.bytes + sizeof(k.bytes), v));
T_ASSERT(radix_tree_insert(rt, k.bytes, sizeof(k.bytes), v));
}
static void __invalidate(struct radix_tree *rt, int fd)
@ -799,7 +799,7 @@ static void __invalidate(struct radix_tree *rt, int fd)
union key k;
k.parts.fd = fd;
radix_tree_remove_prefix(rt, k.bytes, k.bytes + sizeof(k.parts.fd));
radix_tree_remove_prefix(rt, k.bytes, sizeof(k.parts.fd));
T_ASSERT(radix_tree_is_well_formed(rt));
}