lightningd: avoid keeping multiple copies of nodeid.
Simple refcount FTW. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
4fc498f901
commit
0c6d8996fc
|
@ -3,6 +3,7 @@
|
|||
#include <backtrace.h>
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/err/err.h>
|
||||
#include <ccan/htable/htable_type.h>
|
||||
#include <ccan/io/io.h>
|
||||
#include <ccan/opt/opt.h>
|
||||
#include <ccan/read_write_all/read_write_all.h>
|
||||
|
@ -58,6 +59,8 @@ struct log_book {
|
|||
* is more directly because the notification needs ld->plugins.
|
||||
*/
|
||||
struct lightningd *ld;
|
||||
/* Cache of all node_ids, to avoid multiple copies. */
|
||||
struct node_id_map *cache;
|
||||
};
|
||||
|
||||
struct log {
|
||||
|
@ -69,6 +72,32 @@ struct log {
|
|||
enum log_level *print_level;
|
||||
};
|
||||
|
||||
/* Avoids duplicate node_id entries. */
|
||||
struct node_id_cache {
|
||||
size_t count;
|
||||
struct node_id node_id;
|
||||
};
|
||||
|
||||
static const struct node_id *node_cache_id(const struct node_id_cache *nc)
|
||||
{
|
||||
return &nc->node_id;
|
||||
}
|
||||
|
||||
static size_t node_id_hash(const struct node_id *id)
|
||||
{
|
||||
return siphash24(siphash_seed(), id->k, sizeof(id->k));
|
||||
}
|
||||
|
||||
static bool node_id_cache_eq(const struct node_id_cache *nc,
|
||||
const struct node_id *node_id)
|
||||
{
|
||||
return node_id_eq(&nc->node_id, node_id);
|
||||
}
|
||||
|
||||
HTABLE_DEFINE_TYPE(struct node_id_cache,
|
||||
node_cache_id, node_id_hash, node_id_cache_eq,
|
||||
node_id_map);
|
||||
|
||||
static const char *level_prefix(enum log_level level)
|
||||
{
|
||||
switch (level) {
|
||||
|
@ -152,6 +181,8 @@ static size_t prune_log(struct log_book *log)
|
|||
|
||||
list_del_from(&log->log, &i->list);
|
||||
log->mem_used -= mem_used(i);
|
||||
if (i->nc && --i->nc->count == 0)
|
||||
tal_free(i->nc);
|
||||
tal_free(i);
|
||||
skipped++;
|
||||
deleted++;
|
||||
|
@ -174,6 +205,8 @@ struct log_book *new_log_book(struct lightningd *ld, size_t max_mem)
|
|||
list_head_init(&lr->print_filters);
|
||||
lr->init_time = time_now();
|
||||
lr->ld = ld;
|
||||
lr->cache = tal(lr, struct node_id_map);
|
||||
node_id_map_init(lr->cache);
|
||||
list_head_init(&lr->log);
|
||||
|
||||
return lr;
|
||||
|
@ -247,6 +280,11 @@ static void add_entry(struct log *log, struct log_entry *l)
|
|||
}
|
||||
}
|
||||
|
||||
static void destroy_node_id_cache(struct node_id_cache *nc, struct log_book *lr)
|
||||
{
|
||||
node_id_map_del(lr->cache, nc);
|
||||
}
|
||||
|
||||
static struct log_entry *new_log_entry(struct log *log, enum log_level level,
|
||||
const struct node_id *node_id)
|
||||
{
|
||||
|
@ -259,10 +297,19 @@ static struct log_entry *new_log_entry(struct log *log, enum log_level level,
|
|||
l->io = NULL;
|
||||
if (!node_id)
|
||||
node_id = log->default_node_id;
|
||||
if (node_id)
|
||||
l->node_id = tal_dup(l, struct node_id, node_id);
|
||||
else
|
||||
l->node_id = NULL;
|
||||
if (node_id) {
|
||||
l->nc = node_id_map_get(log->lr->cache, node_id);
|
||||
if (!l->nc) {
|
||||
l->nc = tal(log->lr->cache, struct node_id_cache);
|
||||
l->nc->count = 0;
|
||||
l->nc->node_id = *node_id;
|
||||
node_id_map_add(log->lr->cache, l->nc);
|
||||
tal_add_destructor2(l->nc, destroy_node_id_cache,
|
||||
log->lr);
|
||||
}
|
||||
l->nc->count++;
|
||||
} else
|
||||
l->nc = NULL;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
@ -271,7 +318,8 @@ static void maybe_print(struct log *log, const struct log_entry *l,
|
|||
size_t offset)
|
||||
{
|
||||
if (l->level >= log_print_level(log))
|
||||
log_to_file(log->prefix, l->level, l->node_id, offset != 0,
|
||||
log_to_file(log->prefix, l->level,
|
||||
l->nc ? &l->nc->node_id : NULL, offset != 0,
|
||||
&l->time, l->log + offset,
|
||||
l->io, tal_bytelen(l->io), log->lr->outf);
|
||||
}
|
||||
|
@ -315,7 +363,8 @@ void log_io(struct log *log, enum log_level dir,
|
|||
|
||||
/* Print first, in case we need to truncate. */
|
||||
if (l->level >= log_print_level(log))
|
||||
log_to_file(log->prefix, l->level, l->node_id, false,
|
||||
log_to_file(log->prefix, l->level,
|
||||
l->nc ? &l->nc->node_id : NULL, false,
|
||||
&l->time, str,
|
||||
data, len, log->lr->outf);
|
||||
|
||||
|
@ -400,7 +449,8 @@ static void log_each_line_(const struct log_book *lr,
|
|||
|
||||
list_for_each(&lr->log, i, list) {
|
||||
func(i->skipped, time_between(i->time, lr->init_time),
|
||||
i->level, i->node_id, i->prefix, i->log, i->io, arg);
|
||||
i->level, i->nc ? &i->nc->node_id : NULL,
|
||||
i->prefix, i->log, i->io, arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -644,7 +694,8 @@ void logging_options_parsed(struct log_book *lr)
|
|||
/* Catch up, since before we were only printing BROKEN msgs */
|
||||
list_for_each(&lr->log, l, list) {
|
||||
if (l->level >= filter_level(lr, l->prefix))
|
||||
log_to_file(l->prefix, l->level, l->node_id, false,
|
||||
log_to_file(l->prefix, l->level,
|
||||
l->nc ? &l->nc->node_id : NULL, false,
|
||||
&l->time, l->log,
|
||||
l->io, tal_bytelen(l->io), lr->outf);
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ struct log_entry {
|
|||
struct timeabs time;
|
||||
enum log_level level;
|
||||
unsigned int skipped;
|
||||
struct node_id *node_id;
|
||||
struct node_id_cache *nc;
|
||||
const char *prefix;
|
||||
char *log;
|
||||
/* Iff LOG_IO */
|
||||
|
|
Loading…
Reference in New Issue