mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-15 11:59:16 +01:00
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 <rusty@rustcorp.com.au>
This commit is contained in:
parent
87a471af98
commit
d922abeaba
1 changed files with 16 additions and 24 deletions
|
@ -1,19 +1,24 @@
|
|||
#include "config.h"
|
||||
#include <ccan/crypto/siphash24/siphash24.h>
|
||||
#include <ccan/htable/htable.h>
|
||||
#include <ccan/ptrint/ptrint.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/pseudorand.h>
|
||||
#include <connectd/gossip_rcvd_filter.h>
|
||||
#include <wire/peer_wire.h>
|
||||
|
||||
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;
|
||||
|
|
Loading…
Add table
Reference in a new issue