From d922abeaba9e8700c6449efe836300a86d5614f7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 16 Jun 2022 17:02:39 +0930 Subject: [PATCH] connectd: optimize gossip_rcvd_filter. Instead of doing an allocation per entry, put the entry in directly. This means only 30 bit resolution on 32-bit machines, but if a bit of gossip gets accidently suppressed that's ok. Signed-off-by: Rusty Russell --- connectd/gossip_rcvd_filter.c | 40 ++++++++++++++--------------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/connectd/gossip_rcvd_filter.c b/connectd/gossip_rcvd_filter.c index 87e75890e..82111a39f 100644 --- a/connectd/gossip_rcvd_filter.c +++ b/connectd/gossip_rcvd_filter.c @@ -1,19 +1,24 @@ #include "config.h" #include #include +#include #include #include #include #include -static u64 msg_key(const u8 *msg) +/* We stash raw integers into ptrs, but leave two bits for htable code to use. */ +static size_t msg_key(const u8 *msg) { - return siphash24(siphash_seed(), msg, tal_bytelen(msg)); + size_t key = siphash24(siphash_seed(), msg, tal_bytelen(msg)); + + /* Avoid 0 and 1, which are invalid in the htable code. */ + return key | 0x3; } static size_t rehash(const void *key, void *unused) { - return *(u64 *)key; + return ptr2int(key); } static void destroy_msg_map(struct htable *ht) @@ -35,22 +40,12 @@ struct gossip_rcvd_filter { struct htable *cur, *old; }; -#if DEVELOPER -static void memleak_help_gossip_rcvd_filter(struct htable *memtable, - struct gossip_rcvd_filter *grf) -{ - memleak_remove_htable(memtable, grf->cur); - memleak_remove_htable(memtable, grf->old); -} -#endif - struct gossip_rcvd_filter *new_gossip_rcvd_filter(const tal_t *ctx) { struct gossip_rcvd_filter *f = tal(ctx, struct gossip_rcvd_filter); f->cur = new_msg_map(f); f->old = new_msg_map(f); - memleak_add_helper(f, memleak_help_gossip_rcvd_filter); return f; } @@ -108,7 +103,7 @@ static bool is_msg_gossip_broadcast(const u8 *cursor) return false; } -static bool extract_msg_key(const u8 *msg, u64 *key) +static bool extract_msg_key(const u8 *msg, size_t *key) { if (!is_msg_gossip_broadcast(msg)) return false; @@ -120,30 +115,27 @@ static bool extract_msg_key(const u8 *msg, u64 *key) /* Add a gossip msg to the received map */ void gossip_rcvd_filter_add(struct gossip_rcvd_filter *f, const u8 *msg) { - u64 key; + size_t key; - /* We don't attach destructor here directly to tag; would be neat, - * but it's also an extra allocation. */ if (extract_msg_key(msg, &key)) { - htable_add(f->cur, key, tal_dup(f->cur, u64, &key)); - /* Don't let it fill up forever though. */ + htable_add(f->cur, key, int2ptr(key)); + /* Don't let it fill up forever. */ if (htable_count(f->cur) > 10000) gossip_rcvd_filter_age(f); } } /* htable is fast, but it's also horribly manual. */ -static bool msg_map_remove(struct htable *ht, u64 key) +static bool msg_map_remove(struct htable *ht, size_t key) { struct htable_iter i; - u64 *c; + void *c; for (c = htable_firstval(ht, &i, key); c; c = htable_nextval(ht, &i, key)) { - if (*c == key) { + if (ptr2int(c) == key) { htable_del(ht, key, c); - tal_free(c); return true; } } @@ -153,7 +145,7 @@ static bool msg_map_remove(struct htable *ht, u64 key) /* Is a gossip msg in the received map? (Removes it) */ bool gossip_rcvd_filter_del(struct gossip_rcvd_filter *f, const u8 *msg) { - u64 key; + size_t key; if (!extract_msg_key(msg, &key)) return false;