#define TINDEX_ALLOC_IDX ({ u64 out = idm_alloc(&(ti->idm)); if (!out) goto noidx; out; })
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 (create)
union tindex_data *idata = ti->index_data;
const struct tindex_info stinfo = tindex_get_info(ti), *tinfo = &stinfo;
+ ASSERT(sidx > 0);
+ ASSERT(sidx <= tinfo->addrmask);
/* Validate unit size */
switch (tinfo->usize) {
default: bug("This shall never happen");
}
- u64 idx = 1; /* The root node is always 1 */
- u64 uidx = 0; /* Parent node is 0 on beginning */
+ /* Here we begin */
+ 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) {
/* Get data from trie */
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 */
ASSERT(bits < 2);
ASSERT(ilen == 1);
#define TINDEX_CREATE (~(0ULL))
#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
* @ti: the tindex to look into
* 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.
static inline void test_trie_get(struct test_trie *tt, u64 data, u64 cnt) {
u64 out = 0;
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];
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);
}
/*