Files
palladum-lightning/ccan/ccan/htable/tools/density.c
Rusty Russell ae71a87c40 ccan: update to latest htable fixes, and update gossmap to meet new assertions.
Updating ccan to stricter htable revealed we were trying to put
(void *)1 in the htable, which is forbidden:

```
topology: ccan/ccan/htable/htable.c:382: htable_add_: Assertion `entry_is_valid((uintptr_t)p)' failed.
topology: FATAL SIGNAL 6 (version 1358d7f)
0x55f30c689c34 send_backtrace
	common/daemon.c:33
0x55f30c689ce0 crashdump
	common/daemon.c:46
0x7f5d150fe51f ???
	./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
0x7f5d15152828 __pthread_kill_implementation
	./nptl/pthread_kill.c:44
0x7f5d15152828 __pthread_kill_internal
	./nptl/pthread_kill.c:80
0x7f5d15152828 __GI___pthread_kill
	./nptl/pthread_kill.c:91
0x7f5d150fe475 __GI_raise
	../sysdeps/posix/raise.c:26
0x7f5d150e47b6 __GI_abort
	./stdlib/abort.c:79
0x7f5d150e46da __assert_fail_base
	./assert/assert.c:92
0x7f5d150f5e25 __GI___assert_fail
	./assert/assert.c:101
0x55f30c6adbe4 htable_add_
	ccan/ccan/htable/htable.c:382
0x55f30c65f303 chanidx_htable_add
	common/gossmap.c:35
0x55f30c6605ed new_channel
	common/gossmap.c:337
0x55f30c6609cf add_channel
	common/gossmap.c:425
0x55f30c661101 map_catchup
	common/gossmap.c:607
0x55f30c66221e gossmap_refresh
	common/gossmap.c:927
0x55f30c66e3e9 get_gossmap
	plugins/topology.c:27
0x55f30c66f939 listpeers_done
	plugins/topology.c:369
0x55f30c671f46 handle_rpc_reply
	plugins/libplugin.c:558
0x55f30c672a19 rpc_read_response_one
	plugins/libplugin.c:726
0x55f30c672b4f rpc_conn_read_response
	plugins/libplugin.c:746
0x55f30c6ae35e next_plan
	ccan/ccan/io/io.c:59
0x55f30c6aef93 do_plan
	ccan/ccan/io/io.c:407
0x55f30c6aefd5 io_ready
	ccan/ccan/io/io.c:417
0x55f30c6b1371 io_loop
	ccan/ccan/io/poll.c:453
0x55f30c67587c plugin_main
	plugins/libplugin.c:1559
0x55f30c6708eb main
	plugins/topology.c:701
0x7f5d150e5fcf __libc_start_call_main
	../sysdeps/nptl/libc_start_call_main.h:58
0x7f5d150e607c __libc_start_main_impl
	../csu/libc-start.c:409
0x55f30c65d894 ???
	???:0
0xffffffffffffffff ???
	???:0
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-07-10 20:48:53 -05:00

108 lines
2.5 KiB
C

/* Density measurements for hashtables. */
#include <ccan/err/err.h>
#include <ccan/htable/htable_type.h>
#include <ccan/htable/htable.c>
#include <ccan/hash/hash.h>
#include <ccan/ptrint/ptrint.h>
#include <ccan/time/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* We don't actually hash objects: we put values in as if they were ptrs */
static uintptr_t key(const ptrint_t *obj)
{
return ptr2int(obj);
}
static size_t hash_uintptr(uintptr_t key)
{
return hashl(&key, 1, 0);
}
static bool cmp(const ptrint_t *p, uintptr_t k)
{
return key(p) == k;
}
HTABLE_DEFINE_TYPE(ptrint_t, key, hash_uintptr, cmp, htable_ptrint);
/* Nanoseconds per operation */
static size_t normalize(const struct timeabs *start,
const struct timeabs *stop,
unsigned int num)
{
return time_to_nsec(time_divide(time_between(*stop, *start), num));
}
static size_t average_run(const struct htable_ptrint *ht, size_t count, size_t *longest)
{
size_t i, total = 0;
*longest = 0;
for (i = 0; i < count; i++) {
size_t h = hash_uintptr(i + 2);
size_t run = 1;
while (get_raw_ptr(&ht->raw, ht->raw.table[h % ((size_t)1 << ht->raw.bits)]) != int2ptr(i + 2)) {
h++;
run++;
}
total += run;
if (run > *longest)
*longest = run;
}
return total / count;
}
int main(int argc, char *argv[])
{
unsigned int i;
size_t num;
struct timeabs start, stop;
struct htable_ptrint ht;
if (argc != 2)
errx(1, "Usage: density <power-of-2-tablesize>");
num = atoi(argv[1]);
printf("Total buckets, buckets used, nanoseconds search time per element, avg run, longest run\n");
for (i = 1; i <= 99; i++) {
uintptr_t j;
struct htable_ptrint_iter it;
size_t count, avg_run, longest_run;
ptrint_t *p;
htable_ptrint_init_sized(&ht, num * 3 / 4);
assert((1 << ht.raw.bits) == num);
/* Can't put 0 or 1 in the hash table: multiply by a prime. */
for (j = 0; j < num * i / 100; j++) {
htable_ptrint_add(&ht, int2ptr(j + 2));
/* stop it from doubling! */
ht.raw.elems = num / 2;
}
/* Must not have changed! */
assert((1 << ht.raw.bits) == num);
/* Clean cache */
count = 0;
for (p = htable_ptrint_first(&ht, &it); p; p = htable_ptrint_next(&ht, &it))
count++;
assert(count == num * i / 100);
start = time_now();
for (j = 0; j < count; j++)
assert(htable_ptrint_get(&ht, j + 2));
stop = time_now();
avg_run = average_run(&ht, count, &longest_run);
printf("%zu,%zu,%zu,%zu,%zu\n",
num, count, normalize(&start, &stop, count), avg_run, longest_run);
fflush(stdout);
htable_ptrint_clear(&ht);
}
return 0;
}