diff options
author | David Lamparter <equinox@opensourcerouting.org> | 2017-07-06 16:33:10 +0200 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2017-07-11 13:47:31 +0200 |
commit | bc7a2c035aa2d8d2820503fb8b7c8328b28bdde4 (patch) | |
tree | 01b45f56f0989d7ecea277f28d424199945cbf04 /lib/table.c | |
parent | lib: add some abstraction guards for table code (diff) | |
download | frr-bc7a2c035aa2d8d2820503fb8b7c8328b28bdde4.tar.xz frr-bc7a2c035aa2d8d2820503fb8b7c8328b28bdde4.zip |
lib: table: maintain parallel hash for route_table
See next commit for description.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib/table.c')
-rw-r--r-- | lib/table.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/lib/table.c b/lib/table.c index d4dbeb79c..1f01a2997 100644 --- a/lib/table.c +++ b/lib/table.c @@ -27,6 +27,7 @@ #include "table.h" #include "memory.h" #include "sockunion.h" +#include "jhash.h" DEFINE_MTYPE( LIB, ROUTE_TABLE, "Route table") DEFINE_MTYPE( LIB, ROUTE_NODE, "Route node") @@ -34,6 +35,16 @@ DEFINE_MTYPE( LIB, ROUTE_NODE, "Route node") static void route_node_delete (struct route_node *); static void route_table_free (struct route_table *); +static unsigned route_table_hash_key(void *pp) +{ + struct prefix copy; + + /* make sure *all* unused bits are zero, particularly including alignment / + * padding and unused prefix bytes. */ + memset (©, 0, sizeof(copy)); + prefix_copy (©, (struct prefix *)pp); + return jhash (©, sizeof(copy), 0x55aa5a5a); +} /* * route_table_init_with_delegate @@ -45,6 +56,9 @@ route_table_init_with_delegate (route_table_delegate_t *delegate) rt = XCALLOC (MTYPE_ROUTE_TABLE, sizeof (struct route_table)); rt->delegate = delegate; + rt->hash = hash_create(route_table_hash_key, + (int (*)(const void *, const void *)) prefix_same, + "route table hash"); return rt; } @@ -65,13 +79,16 @@ route_node_new (struct route_table *table) static struct route_node * route_node_set (struct route_table *table, const struct prefix *prefix) { - struct route_node *node; + struct route_node *node, *inserted; node = route_node_new (table); prefix_copy (&node->p, prefix); node->table = table; + inserted = hash_get (node->table->hash, node, hash_alloc_intern); + assert (inserted == node); + return node; } @@ -94,6 +111,9 @@ route_table_free (struct route_table *rt) if (rt == NULL) return; + hash_clean (rt->hash, NULL); + hash_free (rt->hash); + node = rt->top; /* Bulk deletion of nodes remaining in this table. This function is not @@ -322,6 +342,7 @@ route_node_get (struct route_table *const table, union prefixconstptr pu) struct route_node *new; struct route_node *node; struct route_node *match; + struct route_node *inserted; u_char prefixlen = p->prefixlen; const u_char *prefix = &p->u.prefix; @@ -352,6 +373,8 @@ route_node_get (struct route_table *const table, union prefixconstptr pu) new->p.family = p->family; new->table = table; set_link (new, node); + inserted = hash_get (node->table->hash, new, hash_alloc_intern); + assert (inserted == new); if (match) set_link (match, new); @@ -407,6 +430,8 @@ route_node_delete (struct route_node *node) node->table->count--; + hash_release (node->table->hash, node); + /* WARNING: FRAGILE CODE! * route_node_free may have the side effect of free'ing the entire table. * this is permitted only if table->count got decremented to zero above, |