mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-23 02:01:55 +00:00
Trie index: Finding the node relative from other node; storing the path.
Will be useful for filter trie conversion
This commit is contained in:
parent
b7bf5c5b8d
commit
12377d33a5
20
lib/tindex.c
20
lib/tindex.c
@ -648,7 +648,7 @@ tindex_renumber(union tindex_data *idata, const struct tindex_info *tinfo, u64 o
|
|||||||
#define TINDEX_ALLOC_IDX ({ u64 out = idm_alloc(&(ti->idm)); if (!out) goto noidx; out; })
|
#define TINDEX_ALLOC_IDX ({ u64 out = idm_alloc(&(ti->idm)); if (!out) goto noidx; out; })
|
||||||
|
|
||||||
u64
|
u64
|
||||||
tindex_find(struct tindex *ti, const uTDB *bits_in, const uint blen, const u64 create)
|
tindex_find_rel_path(struct tindex *ti, const u64 sidx, const uTDB *bits_in, const uint blen, uint bpos, u64 *path, const u64 create)
|
||||||
{
|
{
|
||||||
if (blen > ti->bdepth)
|
if (blen > ti->bdepth)
|
||||||
if (create)
|
if (create)
|
||||||
@ -659,6 +659,8 @@ tindex_find(struct tindex *ti, const uTDB *bits_in, const uint blen, const u64 c
|
|||||||
union tindex_data *idata = ti->index_data;
|
union tindex_data *idata = ti->index_data;
|
||||||
const struct tindex_info stinfo = tindex_get_info(ti), *tinfo = &stinfo;
|
const struct tindex_info stinfo = tindex_get_info(ti), *tinfo = &stinfo;
|
||||||
|
|
||||||
|
ASSERT(sidx > 0);
|
||||||
|
ASSERT(sidx <= tinfo->addrmask);
|
||||||
|
|
||||||
/* Validate unit size */
|
/* Validate unit size */
|
||||||
switch (tinfo->usize) {
|
switch (tinfo->usize) {
|
||||||
@ -669,10 +671,16 @@ tindex_find(struct tindex *ti, const uTDB *bits_in, const uint blen, const u64 c
|
|||||||
default: bug("This shall never happen");
|
default: bug("This shall never happen");
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 idx = 1; /* The root node is always 1 */
|
/* Here we begin */
|
||||||
u64 uidx = 0; /* Parent node is 0 on beginning */
|
u64 idx = sidx;
|
||||||
|
u64 uidx = tindex_up(idata, tinfo, idx);
|
||||||
|
|
||||||
uint bpos = 0;
|
if (path)
|
||||||
|
memset(&(path[bpos]), 0, (blen - bpos) * sizeof(u64));
|
||||||
|
|
||||||
|
/* Shortcut for zero-length query */
|
||||||
|
if (blen == bpos)
|
||||||
|
return tindex_exists(ti->exists, idx) ? idx : 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Get data from trie */
|
/* Get data from trie */
|
||||||
@ -713,6 +721,10 @@ tindex_find(struct tindex *ti, const uTDB *bits_in, const uint blen, const u64 c
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is not final for sure, store the path node */
|
||||||
|
if (path && tindex_exists(ti->exists, idx))
|
||||||
|
path[bpos] = idx;
|
||||||
|
|
||||||
/* Just one bit, to be sure */
|
/* Just one bit, to be sure */
|
||||||
ASSERT(bits < 2);
|
ASSERT(bits < 2);
|
||||||
ASSERT(ilen == 1);
|
ASSERT(ilen == 1);
|
||||||
|
38
lib/tindex.h
38
lib/tindex.h
@ -20,6 +20,41 @@ struct tindex* tindex_new(pool *p);
|
|||||||
#define TINDEX_CREATE (~(0ULL))
|
#define TINDEX_CREATE (~(0ULL))
|
||||||
#define TINDEX_FIND 0
|
#define TINDEX_FIND 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the whole path to the indexed node at once
|
||||||
|
* @ti: the index to look into
|
||||||
|
* @sidx: index where to start
|
||||||
|
* @bits_in: data
|
||||||
|
* @blen: number of bits to extract from @bits_in.
|
||||||
|
* If @blen is not multiple of 64, the LSB's of the last u64 are ignored.
|
||||||
|
* @bpos: number of bits to ignore from @bits_in.
|
||||||
|
* @path: preallocated array of @blen of u64's to store the path.
|
||||||
|
* @create: TINDEX_FIND to find existing, TINDEX_CREATE to create new records,
|
||||||
|
* every other value is for internal use
|
||||||
|
*
|
||||||
|
* Return value: 0 for not found; nonzero = the index
|
||||||
|
*/
|
||||||
|
|
||||||
|
u64 tindex_find_rel_path(struct tindex *ti, const u64 sidx, const u32 *bits_in, const uint blen, const uint bpos, u64 *path, const u64 create);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find an index beginning somewhere else
|
||||||
|
* @ti: the index to look into
|
||||||
|
* @sidx: index where to start
|
||||||
|
* @bits_in: data
|
||||||
|
* @blen: number of bits to extract from @bits_in.
|
||||||
|
* If @blen is not multiple of 64, the LSB's of the last u64 are ignored.
|
||||||
|
* @bpos: number of bits to ignore from @bits_in.
|
||||||
|
* @create: TINDEX_FIND to find existing, TINDEX_CREATE to create new records,
|
||||||
|
* every other value is for internal use
|
||||||
|
*
|
||||||
|
* Return value: 0 for not found; nonzero = the index
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline u64 tindex_find_rel(struct tindex *ti, const u64 sidx, const u32 *bits_in, const uint blen, uint bpos, const u64 create)
|
||||||
|
{ return tindex_find_rel_path(ti, sidx, bits_in, blen, bpos, NULL, create); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find an index
|
* Find an index
|
||||||
* @ti: the tindex to look into
|
* @ti: the tindex to look into
|
||||||
@ -32,7 +67,8 @@ struct tindex* tindex_new(pool *p);
|
|||||||
* Return value: 0 for not found; nonzero = the index
|
* Return value: 0 for not found; nonzero = the index
|
||||||
*/
|
*/
|
||||||
|
|
||||||
u64 tindex_find(struct tindex *ti, const u32 *bits_in, const uint blen, const u64 create);
|
static inline u64 tindex_find(struct tindex *ti, const u32 *bits_in, const uint blen, const u64 create)
|
||||||
|
{ return tindex_find_rel(ti, 1, bits_in, blen, 0, create); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete an index.
|
* Delete an index.
|
||||||
|
@ -38,9 +38,12 @@ static inline void test_trie_add(struct test_trie *tt, u64 data) {
|
|||||||
static inline void test_trie_get(struct test_trie *tt, u64 data, u64 cnt) {
|
static inline void test_trie_get(struct test_trie *tt, u64 data, u64 cnt) {
|
||||||
u64 out = 0;
|
u64 out = 0;
|
||||||
u32 dtb[2] = { data >> 32, data };
|
u32 dtb[2] = { data >> 32, data };
|
||||||
u64 idx = tindex_find(tt->ti, dtb, 64, TINDEX_FIND);
|
u64 path[64] = {};
|
||||||
|
u64 idx = tindex_find_rel_path(tt->ti, 1, dtb, 64, 0, path, TINDEX_FIND);
|
||||||
if (idx) out = tt->data[idx];
|
if (idx) out = tt->data[idx];
|
||||||
bt_assert_msg(out == cnt, "Index %lu shall be in trie %lu times, is %lu times.", data, cnt, out);
|
bt_assert_msg(out == cnt, "Index %lu shall be in trie %lu times, is %lu times.", data, cnt, out);
|
||||||
|
for (int i=0; i<64; i++)
|
||||||
|
bt_assert(path[i] == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user