mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
tmp: tmp progress on trie API
This commit is contained in:
parent
7e68ba64a9
commit
3719d746bc
117
filter/trie.c
117
filter/trie.c
@ -817,12 +817,13 @@ trie_walk_init(struct f_trie_walk_state *s, const struct f_trie *t, const net_ad
|
||||
};
|
||||
|
||||
if (!net)
|
||||
return 1;
|
||||
{ log("return 0"); return 0; }
|
||||
|
||||
/* We want to find node of level at least plen */
|
||||
int plen = ROUND_DOWN_POW2(net->pxlen, TRIE_STEP);
|
||||
const struct f_trie_node *n = &t->root;
|
||||
const int v4 = t->ipv4;
|
||||
int step;
|
||||
|
||||
while (n)
|
||||
{
|
||||
@ -838,7 +839,7 @@ trie_walk_init(struct f_trie_walk_state *s, const struct f_trie *t, const net_ad
|
||||
if (nlen == plen)
|
||||
{
|
||||
/* Find proper local_pos, while accept_length is not used */
|
||||
int step = net->pxlen - plen;
|
||||
step = net->pxlen - plen;
|
||||
s->start_pos = s->local_pos = (1u << step) + GET_NET_BITS(net, v4, plen, step);
|
||||
s->accept_length = plen;
|
||||
}
|
||||
@ -859,6 +860,7 @@ trie_walk_init(struct f_trie_walk_state *s, const struct f_trie *t, const net_ad
|
||||
s->start_pos = 1;
|
||||
}
|
||||
|
||||
log("return 1");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -873,15 +875,114 @@ trie_walk_init(struct f_trie_walk_state *s, const struct f_trie *t, const net_ad
|
||||
/* We do not override the trie root in case of inclusive search */
|
||||
if (!include_successors)
|
||||
s->stack[0] = NULL;
|
||||
/* We are out of path, find nearest successor */
|
||||
else
|
||||
{
|
||||
int nlen;
|
||||
char buf[64];
|
||||
char buf2[64];
|
||||
net_format(net, buf, 64);
|
||||
net_addr curr;
|
||||
if (n == NULL)
|
||||
log("node is null");
|
||||
//bug("node is null");
|
||||
else {
|
||||
nlen = v4 ? n->v4.plen : n->v6.plen;
|
||||
if (v4)
|
||||
net_fill_ip4(&curr, ip4_and(n->v4.addr, ip4_mkmask(n->v4.plen)), n->v4.plen);
|
||||
//net_fill_ip4(&curr, n->v4.addr, n->v4.plen);
|
||||
else
|
||||
net_fill_ip6(&curr, ip6_and(n->v6.addr, ip6_mkmask(n->v6.plen)), n->v6.plen);
|
||||
//net_fill_ip6(&curr, n->v6.addr, n->v6.plen);
|
||||
net_format(&curr, buf2, 64);
|
||||
|
||||
/* Be careful about underflow */
|
||||
else if (s->stack_pos > 0)
|
||||
s->stack_pos--;
|
||||
log(" !SAME_PREFIX: %s vs. %s\n", buf, buf2);
|
||||
}
|
||||
|
||||
/* Search whole trie except skipped parts */
|
||||
if (include_successors)
|
||||
s->start_pos = 1;
|
||||
if (s->stack_pos > 0)
|
||||
n = s->stack[s->stack_pos - 1];
|
||||
else
|
||||
{
|
||||
log("root fallback");
|
||||
n = &t->root;
|
||||
}
|
||||
|
||||
nlen = v4 ? n->v4.plen : n->v6.plen;
|
||||
|
||||
log("phase 2 after back step");
|
||||
net_format(net, buf, 64);
|
||||
if (v4)
|
||||
net_fill_ip4(&curr, ip4_and(n->v4.addr, ip4_mkmask(n->v4.plen)), n->v4.plen);
|
||||
//net_fill_ip4(&curr, n->v4.addr, n->v4.plen);
|
||||
else
|
||||
net_fill_ip6(&curr, ip6_and(n->v6.addr, ip6_mkmask(n->v6.plen)), n->v6.plen);
|
||||
//net_fill_ip6(&curr, n->v6.addr, n->v6.plen);
|
||||
net_format(&curr, buf2, 64);
|
||||
log(" (%d) SAME_PREFIX: %s vs. %s\n", SAME_PREFIX(n, net, v4, MIN(net->pxlen, nlen)), buf, buf2);
|
||||
|
||||
step = net->pxlen - plen;
|
||||
/* Stack position point one element ahead */
|
||||
if (s->stack_pos == 1)
|
||||
{
|
||||
//bug("there");
|
||||
log("there");
|
||||
s->stack_pos--;
|
||||
s->start_pos = s->local_pos = 1;
|
||||
}
|
||||
else if (s->stack_pos > 1)
|
||||
{
|
||||
//bug("over");
|
||||
log("over");
|
||||
s->stack_pos--;
|
||||
|
||||
nlen = (v4) ? n->v4.plen : n->v6.plen;
|
||||
int next = (GET_NET_BITS(net, v4, nlen, step) + 1) % TRIE_STEP;
|
||||
while (s->stack_pos != 0 && next == 0)
|
||||
{
|
||||
n = s->stack[s->start_pos];
|
||||
step--;
|
||||
s->stack_pos--;
|
||||
next = (GET_NET_BITS(net, v4, nlen, step) + 1) % TRIE_STEP;
|
||||
}
|
||||
|
||||
/* Fix the stack_pos, one decrement one than needed */
|
||||
s->stack_pos++;
|
||||
|
||||
if ((n = GET_CHILD(n, v4, next)) != NULL)
|
||||
{
|
||||
log("settting the positions");
|
||||
s->stack[s->stack_pos] = n;
|
||||
//s->start_pos = (1u << step) + GET_NET_BITS(net, v4, plen, step);
|
||||
s->start_pos = 2 * (1u << step) + GET_NET_BITS(net, v4, plen, step);
|
||||
s->local_pos = 2 * (1u << step) + GET_NET_BITS(net, v4, plen, step);
|
||||
}
|
||||
//s->start_pos = s->local_pos = (1u << step) + GET_NET_BITS(net, v4, plen, step);
|
||||
//s->accept_length = plen;
|
||||
/* s->start_pos and s->local_pos is already initialized */
|
||||
}
|
||||
/* Be careful around underflow */
|
||||
else /* stack_pos == 0 */
|
||||
{
|
||||
bug("here");
|
||||
|
||||
//return 0;
|
||||
s->stack[0] = &t->root;
|
||||
s->start_pos = s->local_pos = (1u << step);
|
||||
s->accept_length = plen;
|
||||
}
|
||||
|
||||
struct net_addr net_copy;
|
||||
memcpy(&net_copy, net, sizeof(struct net_addr));
|
||||
/*
|
||||
if (v4)
|
||||
net_fill_ip4(net, ip4_and(), len);
|
||||
else
|
||||
net_fill_ip6(net, ip6_and(), len);
|
||||
*/
|
||||
//trie_walk_next(s, &net_copy);
|
||||
}
|
||||
|
||||
log("return 2");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -890,7 +890,8 @@ t_trie_walk_inclusive(void)
|
||||
{
|
||||
int level = round / TESTS_NUM;
|
||||
int v6 = level % 2;
|
||||
int num = PREFIXES_NUM * (int[]){1, 10, 100, 1000}[level / 2];
|
||||
//int num = PREFIXES_NUM * (int[]){0, 1, 10, 100, 1000}[level / 2];
|
||||
int num = PREFIXES_NUM * (int[]){32, 512}[level / 2];
|
||||
int pos = 0, end = 0;
|
||||
list *prefixes = make_random_prefix_list(num, v6, 1);
|
||||
struct f_trie *trie = make_trie_from_prefix_list(prefixes);
|
||||
@ -903,7 +904,7 @@ t_trie_walk_inclusive(void)
|
||||
|
||||
qsort(pxset, num, sizeof(struct f_prefix), compare_prefixes);
|
||||
|
||||
/* // print sorted prefixes
|
||||
// print sorted prefixes
|
||||
bt_debug("sorted prefixes\n");
|
||||
for (struct f_prefix *px = pxset; px < pxset + num; px++)
|
||||
{
|
||||
@ -937,12 +938,20 @@ t_trie_walk_inclusive(void)
|
||||
bt_debug("Full walk inclusive done\n");
|
||||
|
||||
|
||||
/* Prepare net for subnet walk - start with random prefix */
|
||||
pos = bt_random() % num;
|
||||
/* Prepare net for subnet walk - start with random prefix from trie */
|
||||
if (num)
|
||||
pos = bt_random() % num;
|
||||
else
|
||||
pos = 0;
|
||||
end = pos + (int[]){2, 2, 3, 4}[level / 2];
|
||||
end = MIN(end, num);
|
||||
|
||||
struct f_prefix from = pxset[pos];
|
||||
struct f_prefix from;
|
||||
|
||||
if (num)
|
||||
from = pxset[pos];
|
||||
else
|
||||
get_random_prefix(&from, v6, 1);
|
||||
|
||||
/* Find a common superprefix to several subsequent prefixes */
|
||||
for (; pos < end; pos++)
|
||||
@ -977,11 +986,6 @@ t_trie_walk_inclusive(void)
|
||||
if (compare_prefixes(&pxset[pos], &from) >= 0)
|
||||
break;
|
||||
|
||||
/* Account for subnets before searched net from */
|
||||
//for (; pos < num; pos++)
|
||||
//if (net_compare(&pxset[pos].net, &from.net) >= 0)
|
||||
//break;
|
||||
|
||||
int p0 = pos;
|
||||
char buf0[64];
|
||||
bt_format_net(buf0, 64, &from.net);
|
||||
@ -991,7 +995,8 @@ t_trie_walk_inclusive(void)
|
||||
TRIE_WALK2(trie, net, &from.net, 1)
|
||||
{
|
||||
log_networks(&net, &pxset[pos].net);
|
||||
bt_assert(net_compare(&net, &pxset[pos].net) >= 0);
|
||||
//bt_assert(net_compare(&net, &pxset[pos].net) >= 0);
|
||||
bt_assert(net_compare(&net, &from.net) >= 0);
|
||||
|
||||
/* Skip possible duplicates */
|
||||
while (net_equal(&pxset[pos].net, &pxset[pos + 1].net))
|
||||
@ -1004,11 +1009,76 @@ t_trie_walk_inclusive(void)
|
||||
bt_assert(pos == num);
|
||||
bt_debug("Subnet walk done inclusive for %s (found %d nets)\n", buf0, pos - p0);
|
||||
|
||||
/* Prepare net for subnet walk - start with random prefix (likely not from trie) */
|
||||
get_random_prefix(&from, v6, 1);
|
||||
|
||||
for (pos = 0; pos < num; pos++)
|
||||
{
|
||||
bt_format_net(buf0, 64, &pxset[pos].net);
|
||||
bt_debug(" -> %s ", buf0);
|
||||
if (net_compare(&pxset[pos].net, &from.net) >= 0)
|
||||
{
|
||||
bt_debug("true, breaking\n");
|
||||
break;
|
||||
}
|
||||
else
|
||||
bt_debug("false\n");
|
||||
}
|
||||
|
||||
p0 = pos;
|
||||
bt_format_net(buf0, 64, &from.net);
|
||||
bt_debug("Subnet walk inclusive for random %s (round %d, %d nets)\n", buf0, round, num);
|
||||
|
||||
/* Subnet walk */
|
||||
TRIE_WALK2(trie, net, &from.net, 1)
|
||||
{
|
||||
/* Make sure that net is from inserted prefixes */
|
||||
bt_format_net(buf0, 64, &net);
|
||||
bt_debug("got: %s", buf0);
|
||||
bt_format_net(buf0, 64, &pxset[pos].net);
|
||||
bt_debug(" expected %s", buf0);
|
||||
if (pos + 1 < num)
|
||||
{
|
||||
bt_format_net(buf0, 64, &pxset[pos + 1].net);
|
||||
bt_debug(" (next: %s)\n", buf0);
|
||||
}
|
||||
else
|
||||
bt_debug("\n");
|
||||
|
||||
bt_assert(net_equal(&net, &pxset[pos].net));
|
||||
bt_assert(net_compare(&net, &from.net) >= 0);
|
||||
|
||||
while (net_equal(&pxset[pos].net, &pxset[pos + 1].net))
|
||||
pos++;
|
||||
|
||||
pos++;
|
||||
}
|
||||
TRIE_WALK2_END;
|
||||
|
||||
bt_debug("Subnet walk inclusive for random %s (found %d nets from %d)\n", buf0, pos - p0, num - p0);
|
||||
bt_assert(pos == num);
|
||||
|
||||
tmp_flush();
|
||||
}
|
||||
|
||||
bt_bird_cleanup();
|
||||
return 1;
|
||||
|
||||
|
||||
/*
|
||||
* empty trie
|
||||
* inclusive after last element
|
||||
* inclusive before first element
|
||||
* not found root (empty trie)
|
||||
* not found root (after last)
|
||||
* not found root (before first)
|
||||
* not found root (single element)
|
||||
* not found root inbetween
|
||||
* not found first level
|
||||
* not found first level (after)
|
||||
* not found first level (before)
|
||||
* general case (found / not found on higher level)
|
||||
*/
|
||||
}
|
||||
|
||||
int
|
||||
|
3
lib/ip.h
3
lib/ip.h
@ -145,9 +145,6 @@ static inline ip4_addr ip4_xor(ip4_addr a, ip4_addr b)
|
||||
static inline ip4_addr ip4_not(ip4_addr a)
|
||||
{ return _MI4(~_I(a)); }
|
||||
|
||||
static inline int ip4_less(ip4_addr a, ip4_addr b)
|
||||
{ return _I(a) < _I(b); }
|
||||
|
||||
|
||||
static inline int ip6_equal(ip6_addr a, ip6_addr b)
|
||||
{ return _I0(a) == _I0(b) && _I1(a) == _I1(b) && _I2(a) == _I2(b) && _I3(a) == _I3(b); }
|
||||
|
Loading…
Reference in New Issue
Block a user