Commit 04be35ec authored by Maria Matejka's avatar Maria Matejka
Browse files

Trie index: storing existence of indices

parent 0972274d
Loading
Loading
Loading
Loading
+34 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ union tindex_data {

struct tindex {
  union tindex_data *index_data;
  u64 *exists;
  pool *p;
  struct idm idm;
  u8 unit_size;
@@ -40,6 +41,7 @@ tindex_new(pool *p)
  ti->unit_size = TI_MIN_UNIT_SIZE;
  ti->address_size = TI_MIN_ADDRESS_SIZE;
  ti->index_data = mb_allocz(p, ti->unit_size * (1 << ti->address_size));
  ti->exists = mb_allocz(p, (1 << (ti->address_size - 3)));
  idm_init(&(ti->idm), p, (1 << (ti->address_size - 5)), (1 << ti->address_size));
  u32 rootnode = idm_alloc(&(ti->idm));
  ASSERT(rootnode == 1);
@@ -234,6 +236,24 @@ static inline uint tindex_input_bits(const u64 *bits_in, const uint blen, uint *
  return ilen;
}

static inline void
tindex_exists_set(const struct tindex *ti, const u64 idx)
{
  ti->exists[idx / 64] |= (1ULL << (idx % 64));
}

static inline u64
tindex_exists(const struct tindex *ti, const u64 idx)
{
  return (ti->exists[idx / 64] & (1ULL << (idx % 64)));
}

static inline void
tindex_exists_clear(const struct tindex *ti, const u64 idx)
{
  ti->exists[idx / 64] &= ~(1ULL << (idx % 64));
}

const char dump_indent[] = "                                                                ";
#define INDENT (dump_indent + sizeof(dump_indent) - depth - 1)

@@ -263,7 +283,7 @@ _tindex_dump(const struct tindex *ti, u64 idx, uint depth, uint bit)
  if (depth)
    dlen++;

  debug("%s0x%x/%u (%lu)\n", INDENT, data, dlen, idx);
  debug("%s0x%x/%u (%lu %c)\n", INDENT, data, dlen, idx, tindex_exists(ti, idx) ? '*' : ' ');
  u64 left = tindex_left(ti, idx, usize, asize, addrmask);
  if (left)
    _tindex_dump(ti, left, depth+1, 0);
@@ -325,11 +345,19 @@ tindex_find(struct tindex *ti, const u64 *bits_in, const uint blen, const int cr
      ilen = tindex_input_bits(bits_in, blen, &bpos, 1, &bits);

      /* No more bits, we're done */
      if (!ilen)
      if (!ilen) {
	/* Existence bits fiddling */
	if (create)
	  tindex_exists_set(ti, idx);
	else if (!tindex_exists(ti, idx))
	  return 0;

	return idx;
      }

      /* Just one bit, to be sure */
      ASSERT(bits < 2);
      ASSERT(ilen == 1);

      /* Go left or right? */
      u64 nidx = bits ? tindex_right(ti, idx, usize, asize, addrmask) : tindex_left(ti, idx, usize, asize, addrmask);
@@ -410,9 +438,11 @@ tindex_find(struct tindex *ti, const u64 *bits_in, const uint blen, const int cr
    /* Grow there a branch if it has to be grown, otherwise return */
    if (split)
      break;
    else
    else {
      tindex_exists_set(ti, midx);
      return midx;
    }
  }

  /* Growing a new branch */
  while (1) {
@@ -426,6 +456,7 @@ tindex_find(struct tindex *ti, const u64 *bits_in, const uint blen, const int cr
    /* End of input data */
    if ((ilen < dsize - 1) || !tindex_input_bits(bits_in, blen, &bpos, 1, &dataright)) {
      tindex_put(ti, idx, usize, asize, dsize, dshift, data, ilen, 0, 0, uidx);
      tindex_exists_set(ti, idx);
      return idx;
    }

+1 −15
Original line number Diff line number Diff line
@@ -10,21 +10,7 @@
#include "nest/bird.h"

/**
 * tindex_bitcheck() callback is called by tindex_find() repeatedly
 * to get input bits as needed. Maximal number of bits is
 * given in @len; it shall be replaced the actual number of bits
 * returned. The bits shall be returned in LSB of the return value.
 * If (and only if) no bits are remaining, @len shall be changed,
 * otherwise the callee must always return full bit string.
 *
 * This is intended to be implemented as a nested function in
 * a library call using this tree index.
 **/

typedef u64 (*tindex_bitcheck)(u8 *len);

/**
 * Allocate a new tr[ei]e index from the given pool
 * Allocate a new trie index from the given pool
 * @p: pool to allocate from
 *
 * Returns the allocated tindex structure.
+2 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ struct test_trie {

static inline void test_trie_add(struct test_trie *tt, u64 data) {
  u64 idx = tindex_find(tt->ti, &data, 64, 1);
  bt_assert(idx > 0);

  u64 nlen = tt->len;
  while (idx > nlen)
@@ -57,7 +58,7 @@ t_simple(void)
  }

  for (u64 i = 0; i < 20; i++)
    bt_assert(test_trie_get(&tt, i) == 1);
    bt_assert_msg(test_trie_get(&tt, i) == 1, "Index %lu shall be in trie", i);

  return 1;
}