diff --git a/ccan/README b/ccan/README index 06863e6bdb87..eaf436160fc8 100644 --- a/ccan/README +++ b/ccan/README @@ -1,3 +1,3 @@ CCAN imported from http://ccodearchive.net. -CCAN version: init-2589-g161fe383 +CCAN version: init-2590-gaf04734d diff --git a/ccan/ccan/htable/htable_type.h b/ccan/ccan/htable/htable_type.h index 0aacb7f33492..103d2ff17cb1 100644 --- a/ccan/ccan/htable/htable_type.h +++ b/ccan/ccan/htable/htable_type.h @@ -1,19 +1,23 @@ /* Licensed under LGPLv2+ - see LICENSE file for details */ #ifndef CCAN_HTABLE_TYPE_H #define CCAN_HTABLE_TYPE_H +#include "config.h" +#include #include #include -#include "config.h" /** - * HTABLE_DEFINE_TYPE - create a set of htable ops for a type + * HTABLE_DEFINE_NODUPS_TYPE/HTABLE_DEFINE_DUPS_TYPE - create a set of htable ops for a type * @type: a type whose pointers will be values in the hash. * @keyof: a function/macro to extract a key: @keyof(const type *elem) * @hashfn: a hash function for a @key: size_t @hashfn(const *) * @eqfn: an equality function keys: bool @eqfn(const type *, const *) * @prefix: a prefix for all the functions to define (of form _*) * - * NULL values may not be placed into the hash table. + * There are two variants, one of which allows duplicate keys, and one which + * does not. The defined functions differ in some cases, as shown below. + * + * NULL values may not be placed into the hash table (nor (void *)1). * * This defines the type hashtable type and an iterator type: * struct ; @@ -33,15 +37,18 @@ * * Delete and delete-by key return true if it was in the set: * bool _del(struct *ht, const *e); - * bool _delkey(struct *ht, const *k); + * bool _delkey(struct *ht, const *k) (NODUPS only); * * Delete by iterator: * bool _delval(struct *ht, struct _iter *i); * - * Find and return the (first) matching element, or NULL: - * type *_get(const struct @name *ht, const *k); + * Find and return the matching element, or NULL: + * type *_get(const struct @name *ht, const *k) (NODUPS only); * - * Find and return all matching elements, or NULL: + * Test for an element: + * bool _exists(const struct @name *ht, const *k); + * + * Find and return all matching elements, or NULL (DUPS only): * type *_getfirst(const struct @name *ht, const *k, * struct _iter *i); * type *_getnext(const struct @name *ht, const *k, @@ -59,7 +66,7 @@ * You can use HTABLE_INITIALIZER like so: * struct ht = { HTABLE_INITIALIZER(ht.raw, _hash, NULL) }; */ -#define HTABLE_DEFINE_TYPE(type, keyof, hashfn, eqfn, name) \ +#define HTABLE_DEFINE_TYPE_CORE(type, keyof, hashfn, eqfn, name) \ struct name { struct htable raw; }; \ struct name##_iter { struct htable_iter i; }; \ static inline size_t name##_hash(const void *elem, void *priv) \ @@ -89,66 +96,33 @@ { \ return htable_copy(&dst->raw, &src->raw); \ } \ - static inline bool name##_add(struct name *ht, const type *elem) \ - { \ - return htable_add(&ht->raw, hashfn(keyof(elem)), elem); \ - } \ static inline UNNEEDED bool name##_del(struct name *ht, \ const type *elem) \ { \ return htable_del(&ht->raw, hashfn(keyof(elem)), elem); \ } \ - static inline UNNEEDED type *name##_get(const struct name *ht, \ - const HTABLE_KTYPE(keyof, type) k) \ - { \ - struct htable_iter i; \ - size_t h = hashfn(k); \ - void *c; \ - \ - for (c = htable_firstval(&ht->raw,&i,h); \ - c; \ - c = htable_nextval(&ht->raw,&i,h)) { \ - if (eqfn(c, k)) \ - return c; \ - } \ - return NULL; \ - } \ static inline UNNEEDED type *name##_getmatch_(const struct name *ht, \ const HTABLE_KTYPE(keyof, type) k, \ size_t h, \ type *v, \ - struct name##_iter *iter) \ + struct htable_iter *iter) \ { \ while (v) { \ if (eqfn(v, k)) \ break; \ - v = htable_nextval(&ht->raw, &iter->i, h); \ + v = htable_nextval(&ht->raw, iter, h); \ } \ return v; \ } \ - static inline UNNEEDED type *name##_getfirst(const struct name *ht, \ - const HTABLE_KTYPE(keyof, type) k, \ - struct name##_iter *iter) \ - { \ - size_t h = hashfn(k); \ - type *v = htable_firstval(&ht->raw, &iter->i, h); \ - return name##_getmatch_(ht, k, h, v, iter); \ - } \ - static inline UNNEEDED type *name##_getnext(const struct name *ht, \ - const HTABLE_KTYPE(keyof, type) k, \ - struct name##_iter *iter) \ + static inline UNNEEDED bool name##_exists(const struct name *ht, \ + const HTABLE_KTYPE(keyof, type) k) \ { \ + struct htable_iter i; \ size_t h = hashfn(k); \ - type *v = htable_nextval(&ht->raw, &iter->i, h); \ - return name##_getmatch_(ht, k, h, v, iter); \ - } \ - static inline UNNEEDED bool name##_delkey(struct name *ht, \ - const HTABLE_KTYPE(keyof, type) k) \ - { \ - type *elem = name##_get(ht, k); \ - if (elem) \ - return name##_del(ht, elem); \ - return false; \ + void *v; \ + \ + v = htable_firstval(&ht->raw, &i, h); \ + return name##_getmatch_(ht, k, h, v, &i) != NULL; \ } \ static inline UNNEEDED void name##_delval(struct name *ht, \ struct name##_iter *iter) \ @@ -177,6 +151,64 @@ return htable_prev(&ht->raw, &iter->i); \ } +#define HTABLE_DEFINE_NODUPS_TYPE(type, keyof, hashfn, eqfn, name) \ + HTABLE_DEFINE_TYPE_CORE(type, keyof, hashfn, eqfn, name) \ + static inline UNNEEDED type *name##_get(const struct name *ht, \ + const HTABLE_KTYPE(keyof, type) k) \ + { \ + struct htable_iter i; \ + size_t h = hashfn(k); \ + void *v; \ + \ + v = htable_firstval(&ht->raw, &i, h); \ + return name##_getmatch_(ht, k, h, v, &i); \ + } \ + static inline bool name##_add(struct name *ht, const type *elem) \ + { \ + /* Open-coded for slightly more efficiency */ \ + const HTABLE_KTYPE(keyof, type) k = keyof(elem); \ + struct htable_iter i; \ + size_t h = hashfn(k); \ + void *v; \ + \ + v = htable_firstval(&ht->raw, &i, h); \ + assert(!name##_getmatch_(ht, k, h, v, &i)); \ + return htable_add(&ht->raw, h, elem); \ + } \ + static inline UNNEEDED bool name##_delkey(struct name *ht, \ + const HTABLE_KTYPE(keyof, type) k) \ + { \ + type *elem = name##_get(ht, k); \ + if (elem) \ + return name##_del(ht, elem); \ + return false; \ + } + +#define HTABLE_DEFINE_DUPS_TYPE(type, keyof, hashfn, eqfn, name) \ + HTABLE_DEFINE_TYPE_CORE(type, keyof, hashfn, eqfn, name) \ + static inline bool name##_add(struct name *ht, const type *elem) \ + { \ + const HTABLE_KTYPE(keyof, type) k = keyof(elem); \ + return htable_add(&ht->raw, hashfn(k), elem); \ + } \ + static inline UNNEEDED type *name##_getfirst(const struct name *ht, \ + const HTABLE_KTYPE(keyof, type) k, \ + struct name##_iter *iter) \ + { \ + size_t h = hashfn(k); \ + type *v = htable_firstval(&ht->raw, &iter->i, h); \ + return name##_getmatch_(ht, k, h, v, &iter->i); \ + } \ + static inline UNNEEDED type *name##_getnext(const struct name *ht, \ + const HTABLE_KTYPE(keyof, type) k, \ + struct name##_iter *iter) \ + { \ + size_t h = hashfn(k); \ + type *v = htable_nextval(&ht->raw, &iter->i, h); \ + return name##_getmatch_(ht, k, h, v, &iter->i); \ + } + + #if HAVE_TYPEOF #define HTABLE_KTYPE(keyof, type) typeof(keyof((const type *)NULL)) #else diff --git a/ccan/ccan/htable/test/run-type-int.c b/ccan/ccan/htable/test/run-type-int.c index 16c4f56ed40a..69142c7add58 100644 --- a/ccan/ccan/htable/test/run-type-int.c +++ b/ccan/ccan/htable/test/run-type-int.c @@ -38,7 +38,7 @@ static bool cmp(const struct obj *obj, const unsigned int key) return obj->key == key; } -HTABLE_DEFINE_TYPE(struct obj, objkey, objhash, cmp, htable_obj); +HTABLE_DEFINE_NODUPS_TYPE(struct obj, objkey, objhash, cmp, htable_obj); static void add_vals(struct htable_obj *ht, struct obj val[], unsigned int num) @@ -112,14 +112,19 @@ static bool check_mask(struct htable *ht, const struct obj val[], unsigned num) return true; } +/* This variant allows duplicates! */ +HTABLE_DEFINE_DUPS_TYPE(struct obj, objkey, objhash, cmp, htable_obj_dups); + int main(void) { unsigned int i; struct htable_obj ht, ht2; + struct htable_obj_dups ht_dups; struct obj val[NUM_VALS], *result; unsigned int dne; void *p; struct htable_obj_iter iter; + struct htable_obj_dups_iter dups_iter; plan_tests(29); for (i = 0; i < NUM_VALS; i++) @@ -183,32 +188,35 @@ int main(void) del_vals_bykey(&ht, val, NUM_VALS); del_vals_bykey(&ht2, val, NUM_VALS); + /* Duplicates-allowed tests */ + htable_obj_dups_init(&ht_dups); /* Write two of the same value. */ val[1] = val[0]; - htable_obj_add(&ht, &val[0]); - htable_obj_add(&ht, &val[1]); + htable_obj_dups_add(&ht_dups, &val[0]); + htable_obj_dups_add(&ht_dups, &val[1]); i = 0; - result = htable_obj_getfirst(&ht, i, &iter); + result = htable_obj_dups_getfirst(&ht_dups, i, &dups_iter); ok1(result == &val[0] || result == &val[1]); if (result == &val[0]) { - ok1(htable_obj_getnext(&ht, i, &iter) == &val[1]); - ok1(htable_obj_getnext(&ht, i, &iter) == NULL); + ok1(htable_obj_dups_getnext(&ht_dups, i, &dups_iter) == &val[1]); + ok1(htable_obj_dups_getnext(&ht_dups, i, &dups_iter) == NULL); /* Deleting first should make us iterate over the other. */ - ok1(htable_obj_del(&ht, &val[0])); - ok1(htable_obj_getfirst(&ht, i, &iter) == &val[1]); - ok1(htable_obj_getnext(&ht, i, &iter) == NULL); + ok1(htable_obj_dups_del(&ht_dups, &val[0])); + ok1(htable_obj_dups_getfirst(&ht_dups, i, &dups_iter) == &val[1]); + ok1(htable_obj_dups_getnext(&ht_dups, i, &dups_iter) == NULL); } else { - ok1(htable_obj_getnext(&ht, i, &iter) == &val[0]); - ok1(htable_obj_getnext(&ht, i, &iter) == NULL); + ok1(htable_obj_dups_getnext(&ht_dups, i, &dups_iter) == &val[0]); + ok1(htable_obj_dups_getnext(&ht_dups, i, &dups_iter) == NULL); /* Deleting first should make us iterate over the other. */ - ok1(htable_obj_del(&ht, &val[1])); - ok1(htable_obj_getfirst(&ht, i, &iter) == &val[0]); - ok1(htable_obj_getnext(&ht, i, &iter) == NULL); + ok1(htable_obj_dups_del(&ht_dups, &val[1])); + ok1(htable_obj_dups_getfirst(&ht_dups, i, &dups_iter) == &val[0]); + ok1(htable_obj_dups_getnext(&ht_dups, i, &dups_iter) == NULL); } + htable_obj_dups_clear(&ht_dups); htable_obj_clear(&ht); htable_obj_clear(&ht2); return exit_status(); diff --git a/ccan/ccan/htable/test/run-type.c b/ccan/ccan/htable/test/run-type.c index c4201ed0cc5f..857bbbfbef45 100644 --- a/ccan/ccan/htable/test/run-type.c +++ b/ccan/ccan/htable/test/run-type.c @@ -33,7 +33,10 @@ static bool cmp(const struct obj *obj, const unsigned int *key) return obj->key == *key; } -HTABLE_DEFINE_TYPE(struct obj, objkey, objhash, cmp, htable_obj); +HTABLE_DEFINE_NODUPS_TYPE(struct obj, objkey, objhash, cmp, + htable_obj); +HTABLE_DEFINE_DUPS_TYPE(struct obj, objkey, objhash, cmp, + htable_obj_dups); static void add_vals(struct htable_obj *ht, struct obj val[], unsigned int num) @@ -111,12 +114,14 @@ int main(void) { unsigned int i; struct htable_obj ht, ht2; + struct htable_obj_dups ht_dups; struct obj val[NUM_VALS], *result; unsigned int dne; void *p; struct htable_obj_iter iter; + struct htable_obj_dups_iter dups_iter; - plan_tests(35); + plan_tests(36); for (i = 0; i < NUM_VALS; i++) val[i].key = i; dne = i; @@ -182,32 +187,37 @@ int main(void) del_vals_bykey(&ht, val, NUM_VALS); del_vals_bykey(&ht2, val, NUM_VALS); + /* Duplicates-allowed tests */ + htable_obj_dups_init(&ht_dups); + /* Write two of the same value. */ val[1] = val[0]; - htable_obj_add(&ht, &val[0]); - htable_obj_add(&ht, &val[1]); + htable_obj_dups_add(&ht_dups, &val[0]); + htable_obj_dups_add(&ht_dups, &val[1]); i = 0; - result = htable_obj_getfirst(&ht, &i, &iter); + result = htable_obj_dups_getfirst(&ht_dups, &i, &dups_iter); ok1(result == &val[0] || result == &val[1]); if (result == &val[0]) { - ok1(htable_obj_getnext(&ht, &i, &iter) == &val[1]); - ok1(htable_obj_getnext(&ht, &i, &iter) == NULL); + ok1(htable_obj_dups_getnext(&ht_dups, &i, &dups_iter) == &val[1]); + ok1(htable_obj_dups_getnext(&ht_dups, &i, &dups_iter) == NULL); /* Deleting first should make us iterate over the other. */ - ok1(htable_obj_del(&ht, &val[0])); - ok1(htable_obj_getfirst(&ht, &i, &iter) == &val[1]); - ok1(htable_obj_getnext(&ht, &i, &iter) == NULL); + ok1(htable_obj_dups_del(&ht_dups, &val[0])); + ok1(htable_obj_dups_getfirst(&ht_dups, &i, &dups_iter) == &val[1]); + ok1(htable_obj_dups_getnext(&ht_dups, &i, &dups_iter) == NULL); } else { - ok1(htable_obj_getnext(&ht, &i, &iter) == &val[0]); - ok1(htable_obj_getnext(&ht, &i, &iter) == NULL); + ok1(htable_obj_dups_getnext(&ht_dups, &i, &dups_iter) == &val[0]); + ok1(htable_obj_dups_getnext(&ht_dups, &i, &dups_iter) == NULL); /* Deleting first should make us iterate over the other. */ - ok1(htable_obj_del(&ht, &val[1])); - ok1(htable_obj_getfirst(&ht, &i, &iter) == &val[0]); - ok1(htable_obj_getnext(&ht, &i, &iter) == NULL); + ok1(htable_obj_dups_del(&ht_dups, &val[1])); + ok1(htable_obj_dups_getfirst(&ht_dups, &i, &dups_iter) == &val[0]); + ok1(htable_obj_dups_getnext(&ht_dups, &i, &dups_iter) == NULL); } + htable_obj_dups_clear(&ht_dups); + ok1(htable_obj_dups_count(&ht_dups) == 0); htable_obj_clear(&ht); ok1(htable_obj_count(&ht) == 0); htable_obj_clear(&ht2); diff --git a/ccan/ccan/htable/tools/density.c b/ccan/ccan/htable/tools/density.c index 5f7400b9ece6..df5afc51f50c 100644 --- a/ccan/ccan/htable/tools/density.c +++ b/ccan/ccan/htable/tools/density.c @@ -26,7 +26,7 @@ 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); +HTABLE_DEFINE_NODUPS_TYPE(ptrint_t, key, hash_uintptr, cmp, htable_ptrint); /* Nanoseconds per operation */ static size_t normalize(const struct timeabs *start, diff --git a/ccan/ccan/htable/tools/speed.c b/ccan/ccan/htable/tools/speed.c index e185b6f69eb7..a6198528d241 100644 --- a/ccan/ccan/htable/tools/speed.c +++ b/ccan/ccan/htable/tools/speed.c @@ -33,7 +33,7 @@ static bool cmp(const struct object *object, const unsigned int *key) return object->key == *key; } -HTABLE_DEFINE_TYPE(struct object, objkey, hash_obj, cmp, htable_obj); +HTABLE_DEFINE_NODUPS_TYPE(struct object, objkey, hash_obj, cmp, htable_obj); static unsigned int popcount(unsigned long val) { diff --git a/ccan/ccan/htable/tools/stringspeed.c b/ccan/ccan/htable/tools/stringspeed.c index c6ca10f523ae..5f30359a585e 100644 --- a/ccan/ccan/htable/tools/stringspeed.c +++ b/ccan/ccan/htable/tools/stringspeed.c @@ -31,7 +31,7 @@ static bool cmp(const char *obj, const char *key) return strcmp(obj, key) == 0; } -HTABLE_DEFINE_TYPE(char, strkey, hash_str, cmp, htable_str); +HTABLE_DEFINE_NODUPS_TYPE(char, strkey, hash_str, cmp, htable_str); /* Nanoseconds per operation */ static size_t normalize(const struct timeabs *start, diff --git a/ccan/ccan/intmap/benchmark/speed.c b/ccan/ccan/intmap/benchmark/speed.c index 16eb40f355ae..cf2dae7eed36 100644 --- a/ccan/ccan/intmap/benchmark/speed.c +++ b/ccan/ccan/intmap/benchmark/speed.c @@ -59,7 +59,7 @@ static bool eqfn(const struct htable_elem *elem, const uint64_t index) { return elem->index == index; } -HTABLE_DEFINE_TYPE(struct htable_elem, keyof, hashfn, eqfn, hash); +HTABLE_DEFINE_NODUPS_TYPE(struct htable_elem, keyof, hashfn, eqfn, hash); static bool check_val(intmap_index_t i, uint64_t *v, uint64_t *expected) { diff --git a/ccan/ccan/likely/likely.c b/ccan/ccan/likely/likely.c index 83e8d6fbe10b..6b6e4aea0319 100644 --- a/ccan/ccan/likely/likely.c +++ b/ccan/ccan/likely/likely.c @@ -29,8 +29,8 @@ static bool trace_eq(const struct trace *t1, const struct trace *t2) } /* struct thash */ -HTABLE_DEFINE_TYPE(struct trace, (const struct trace *), hash_trace, trace_eq, - thash); +HTABLE_DEFINE_NODUPS_TYPE(struct trace, (const struct trace *), hash_trace, trace_eq, + thash); static struct thash htable = { HTABLE_INITIALIZER(htable.raw, thash_hash, NULL) }; diff --git a/ccan/ccan/mem/mem.c b/ccan/ccan/mem/mem.c index fcd4dda9fe7f..13027a2a7b0f 100644 --- a/ccan/ccan/mem/mem.c +++ b/ccan/ccan/mem/mem.c @@ -123,6 +123,6 @@ void memtaint(void *data, size_t len) memcpy(p, tainter, len); #if HAVE_VALGRIND_MEMCHECK_H - (void)VALGRIND_MAKE_MEM_UNDEFINED(data, len); + VALGRIND_MAKE_MEM_UNDEFINED(data, len); #endif } diff --git a/ccan/ccan/mem/mem.h b/ccan/ccan/mem/mem.h index 61792575702e..20286dcbefd4 100644 --- a/ccan/ccan/mem/mem.h +++ b/ccan/ccan/mem/mem.h @@ -244,7 +244,7 @@ void memswap(void *a, void *b, size_t n); #include static inline void *memcheck_(const void *data, size_t len) { - (void)VALGRIND_CHECK_MEM_IS_DEFINED(data, len); + VALGRIND_CHECK_MEM_IS_DEFINED(data, len); return (void *)data; } #else diff --git a/channeld/channeld_htlc.h b/channeld/channeld_htlc.h index 93dd00f21c24..61258b0af9d3 100644 --- a/channeld/channeld_htlc.h +++ b/channeld/channeld_htlc.h @@ -56,7 +56,8 @@ static inline size_t htlc_hash(u64 id) { return siphash24(siphash_seed(), &id, sizeof(id)); } -HTABLE_DEFINE_TYPE(struct htlc, htlc_key, htlc_hash, htlc_cmp, htlc_map); +HTABLE_DEFINE_DUPS_TYPE(struct htlc, htlc_key, htlc_hash, htlc_cmp, + htlc_map); static inline struct htlc *htlc_get(struct htlc_map *htlcs, u64 id, enum side owner) { diff --git a/common/gossmap.c b/common/gossmap.c index a33d2a6b13b9..8e35d5bcd1c4 100644 --- a/common/gossmap.c +++ b/common/gossmap.c @@ -33,8 +33,8 @@ static size_t scid_hash(const struct short_channel_id scid) { return siphash24(siphash_seed(), &scid, sizeof(scid)); } -HTABLE_DEFINE_TYPE(ptrint_t, chanidx_id, scid_hash, chanidx_eq_id, - chanidx_htable); +HTABLE_DEFINE_NODUPS_TYPE(ptrint_t, chanidx_id, scid_hash, chanidx_eq_id, + chanidx_htable); static struct node_id nodeidx_id(const ptrint_t *pidx); static bool nodeidx_eq_id(const ptrint_t *pidx, const struct node_id id) @@ -46,8 +46,8 @@ static size_t nodeid_hash(const struct node_id id) { return siphash24(siphash_seed(), &id, PUBKEY_CMPR_LEN); } -HTABLE_DEFINE_TYPE(ptrint_t, nodeidx_id, nodeid_hash, nodeidx_eq_id, - nodeidx_htable); +HTABLE_DEFINE_NODUPS_TYPE(ptrint_t, nodeidx_id, nodeid_hash, nodeidx_eq_id, + nodeidx_htable); struct gossmap { /* We updated this every time we reopen, so we know to update iterators! */ diff --git a/common/test/run-htable.c b/common/test/run-htable.c index e3f0d847611b..64ac0b568555 100644 --- a/common/test/run-htable.c +++ b/common/test/run-htable.c @@ -127,8 +127,8 @@ static size_t example_key_hash(u64 key) { return siphash24(&seed, &key, sizeof(key)); } -HTABLE_DEFINE_TYPE(struct example, example_key, example_key_hash, example_eq_key, - example_htable); +HTABLE_DEFINE_NODUPS_TYPE(struct example, example_key, example_key_hash, example_eq_key, + example_htable); static struct example *new_example(const tal_t *ctx, size_t i) { diff --git a/connectd/connectd.h b/connectd/connectd.h index 0d5354282da8..a62f4475b7bf 100644 --- a/connectd/connectd.h +++ b/connectd/connectd.h @@ -137,11 +137,11 @@ static bool peer_eq_node_id(const struct peer *peer, } /*~ This defines 'struct peer_htable' which contains 'struct peer' pointers. */ -HTABLE_DEFINE_TYPE(struct peer, - peer_keyof, - node_id_hash, - peer_eq_node_id, - peer_htable); +HTABLE_DEFINE_NODUPS_TYPE(struct peer, + peer_keyof, + node_id_hash, + peer_eq_node_id, + peer_htable); /* Node id, with any addresses we were explicitly given for it */ struct important_id { @@ -164,11 +164,11 @@ static bool important_id_eq_node_id(const struct important_id *imp, } /*~ This defines 'struct important_id_htable' */ -HTABLE_DEFINE_TYPE(struct important_id, - important_id_keyof, - node_id_hash, - important_id_eq_node_id, - important_id_htable); +HTABLE_DEFINE_NODUPS_TYPE(struct important_id, + important_id_keyof, + node_id_hash, + important_id_eq_node_id, + important_id_htable); /*~ Peers we're trying to reach: we iterate through addrs until we succeed * or fail. */ @@ -207,11 +207,11 @@ static bool connecting_eq_node_id(const struct connecting *connecting, /*~ This defines 'struct connecting_htable' which contains 'struct connecting' * pointers. */ -HTABLE_DEFINE_TYPE(struct connecting, - connecting_keyof, - node_id_hash, - connecting_eq_node_id, - connecting_htable); +HTABLE_DEFINE_NODUPS_TYPE(struct connecting, + connecting_keyof, + node_id_hash, + connecting_eq_node_id, + connecting_htable); struct scid_to_node_id { struct short_channel_id scid; @@ -231,11 +231,11 @@ static bool scid_to_node_id_eq_scid(const struct scid_to_node_id *scid_to_node_i /*~ This defines 'struct scid_htable' which maps short_channel_ids to peers: * we use this to forward onion messages which specify the next hop by scid/dir. */ -HTABLE_DEFINE_TYPE(struct scid_to_node_id, - scid_to_node_id_keyof, - short_channel_id_hash, - scid_to_node_id_eq_scid, - scid_htable); +HTABLE_DEFINE_NODUPS_TYPE(struct scid_to_node_id, + scid_to_node_id_keyof, + short_channel_id_hash, + scid_to_node_id_eq_scid, + scid_htable); /*~ This is the global state, like `struct lightningd *ld` in lightningd. */ struct daemon { diff --git a/gossipd/gossipd.h b/gossipd/gossipd.h index e00ea173292f..052df348f6e5 100644 --- a/gossipd/gossipd.h +++ b/gossipd/gossipd.h @@ -26,9 +26,9 @@ const struct node_id *peer_node_id(const struct peer *peer); bool peer_node_id_eq(const struct peer *peer, const struct node_id *node_id); /* Defines struct peer_node_id_map */ -HTABLE_DEFINE_TYPE(struct peer, - peer_node_id, node_id_hash, peer_node_id_eq, - peer_node_id_map); +HTABLE_DEFINE_NODUPS_TYPE(struct peer, + peer_node_id, node_id_hash, peer_node_id_eq, + peer_node_id_map); /*~ The core daemon structure: */ struct daemon { diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 77637065005b..41b9e0e68a8c 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -43,7 +43,7 @@ static void next_topology_timer(struct chain_topology *topo) static bool we_broadcast(const struct chain_topology *topo, const struct bitcoin_txid *txid) { - return outgoing_tx_map_get(topo->outgoing_txs, txid) != NULL; + return outgoing_tx_map_exists(topo->outgoing_txs, txid); } static void filter_block_txs(struct chain_topology *topo, struct block *b) diff --git a/lightningd/chaintopology.h b/lightningd/chaintopology.h index 948876e1ff08..4f80d21622a8 100644 --- a/lightningd/chaintopology.h +++ b/lightningd/chaintopology.h @@ -68,7 +68,8 @@ static inline bool block_eq(const struct block *b, const struct bitcoin_blkid *k { return bitcoin_blkid_eq(&b->blkid, key); } -HTABLE_DEFINE_TYPE(struct block, keyof_block_map, hash_sha, block_eq, block_map); +HTABLE_DEFINE_NODUPS_TYPE(struct block, keyof_block_map, hash_sha, block_eq, + block_map); /* Hash blocks by sha */ static inline const struct bitcoin_txid *keyof_outgoing_tx_map(const struct outgoing_tx *t) @@ -87,8 +88,9 @@ static inline bool outgoing_tx_eq(const struct outgoing_tx *b, const struct bitc { return bitcoin_txid_eq(&b->txid, key); } -HTABLE_DEFINE_TYPE(struct outgoing_tx, keyof_outgoing_tx_map, - outgoing_tx_hash_sha, outgoing_tx_eq, outgoing_tx_map); +HTABLE_DEFINE_DUPS_TYPE(struct outgoing_tx, keyof_outgoing_tx_map, + outgoing_tx_hash_sha, outgoing_tx_eq, + outgoing_tx_map); /* Our plugins give us a series of blockcount, feerate pairs. */ struct feerate_est { diff --git a/lightningd/htlc_end.h b/lightningd/htlc_end.h index 42f2a0384ae4..6b106caca9bf 100644 --- a/lightningd/htlc_end.h +++ b/lightningd/htlc_end.h @@ -132,11 +132,11 @@ static inline bool htlc_out_eq(const struct htlc_out *out, } -HTABLE_DEFINE_TYPE(struct htlc_in, keyof_htlc_in, hash_htlc_key, htlc_in_eq, - htlc_in_map); +HTABLE_DEFINE_NODUPS_TYPE(struct htlc_in, keyof_htlc_in, hash_htlc_key, htlc_in_eq, + htlc_in_map); -HTABLE_DEFINE_TYPE(struct htlc_out, keyof_htlc_out, hash_htlc_key, htlc_out_eq, - htlc_out_map); +HTABLE_DEFINE_NODUPS_TYPE(struct htlc_out, keyof_htlc_out, hash_htlc_key, htlc_out_eq, + htlc_out_map); struct htlc_in *find_htlc_in(const struct htlc_in_map *map, const struct channel *channel, diff --git a/lightningd/htlc_set.h b/lightningd/htlc_set.h index 4bc44bad5ee3..c93ca1536151 100644 --- a/lightningd/htlc_set.h +++ b/lightningd/htlc_set.h @@ -50,11 +50,11 @@ static inline bool htlc_set_eq(const struct htlc_set *set, return sha256_eq(payment_hash, &set->payment_hash); } -HTABLE_DEFINE_TYPE(struct htlc_set, - keyof_htlc_set, - hash_payment_hash, - htlc_set_eq, - htlc_set_map); +HTABLE_DEFINE_NODUPS_TYPE(struct htlc_set, + keyof_htlc_set, + hash_payment_hash, + htlc_set_eq, + htlc_set_map); /* Handles arg: if it completes a set, calls invoice_try_pay */ void htlc_set_add_(struct lightningd *ld, diff --git a/lightningd/log.c b/lightningd/log.c index eb03450f7047..09a510e19246 100644 --- a/lightningd/log.c +++ b/lightningd/log.c @@ -118,9 +118,9 @@ static bool node_id_cache_eq(const struct node_id_cache *nc, 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); +HTABLE_DEFINE_NODUPS_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) { diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index e96a96229612..65148dbee861 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -45,8 +45,8 @@ static bool replay_tx_eq_txid(const struct replay_tx *rtx, return bitcoin_txid_eq(&rtx->txid, txid); } -HTABLE_DEFINE_TYPE(struct replay_tx, replay_tx_keyof, txid_hash, replay_tx_eq_txid, - replay_tx_hash); +HTABLE_DEFINE_NODUPS_TYPE(struct replay_tx, replay_tx_keyof, txid_hash, replay_tx_eq_txid, + replay_tx_hash); /* Helper for memleak detection */ static void memleak_replay_tx_hash(struct htable *memtable, diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index 77739a3d7c75..9ed655eb07a3 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -174,9 +174,9 @@ static bool peer_node_id_eq(const struct peer *peer, } /* Defines struct peer_node_id_map */ -HTABLE_DEFINE_TYPE(struct peer, - peer_node_id, node_id_hash, peer_node_id_eq, - peer_node_id_map); +HTABLE_DEFINE_NODUPS_TYPE(struct peer, + peer_node_id, node_id_hash, peer_node_id_eq, + peer_node_id_map); static inline size_t dbid_hash(u64 dbid) { @@ -194,8 +194,8 @@ static bool peer_dbid_eq(const struct peer *peer, u64 dbid) return peer->dbid == dbid; } /* Defines struct peer_dbid_map */ -HTABLE_DEFINE_TYPE(struct peer, - peer_dbid, dbid_hash, peer_dbid_eq, - peer_dbid_map); +HTABLE_DEFINE_NODUPS_TYPE(struct peer, + peer_dbid, dbid_hash, peer_dbid_eq, + peer_dbid_map); #endif /* LIGHTNING_LIGHTNINGD_PEER_CONTROL_H */ diff --git a/lightningd/watch.c b/lightningd/watch.c index faba763ece24..67b2bb083a04 100644 --- a/lightningd/watch.c +++ b/lightningd/watch.c @@ -171,7 +171,7 @@ struct txwatch *find_txwatch_(struct chain_topology *topo, bool watching_txid(const struct chain_topology *topo, const struct bitcoin_txid *txid) { - return txwatch_hash_get(topo->txwatches, txid) != NULL; + return txwatch_hash_exists(topo->txwatches, txid); } struct txowatch *watch_txo(const tal_t *ctx, diff --git a/lightningd/watch.h b/lightningd/watch.h index f5d73460de78..596da3a31497 100644 --- a/lightningd/watch.h +++ b/lightningd/watch.h @@ -20,14 +20,14 @@ const struct bitcoin_outpoint *txowatch_keyof(const struct txowatch *w); size_t txo_hash(const struct bitcoin_outpoint *out); bool txowatch_eq(const struct txowatch *w, const struct bitcoin_outpoint *out); -HTABLE_DEFINE_TYPE(struct txowatch, txowatch_keyof, txo_hash, txowatch_eq, - txowatch_hash); +HTABLE_DEFINE_DUPS_TYPE(struct txowatch, txowatch_keyof, txo_hash, txowatch_eq, + txowatch_hash); const struct bitcoin_txid *txwatch_keyof(const struct txwatch *w); size_t txid_hash(const struct bitcoin_txid *txid); bool txwatch_eq(const struct txwatch *w, const struct bitcoin_txid *txid); -HTABLE_DEFINE_TYPE(struct txwatch, txwatch_keyof, txid_hash, txwatch_eq, - txwatch_hash); +HTABLE_DEFINE_DUPS_TYPE(struct txwatch, txwatch_keyof, txid_hash, txwatch_eq, + txwatch_hash); struct txwatch *watch_txid_(const tal_t *ctx, diff --git a/plugins/askrene/askrene.c b/plugins/askrene/askrene.c index 413eedddb8c1..411da3f2afdc 100644 --- a/plugins/askrene/askrene.c +++ b/plugins/askrene/askrene.c @@ -44,11 +44,11 @@ static inline bool per_htlc_cost_eq_key(const struct per_htlc_cost *phc, return short_channel_id_dir_eq(scidd, &phc->scidd); } -HTABLE_DEFINE_TYPE(struct per_htlc_cost, - per_htlc_cost_key, - hash_scidd, - per_htlc_cost_eq_key, - additional_cost_htable); +HTABLE_DEFINE_NODUPS_TYPE(struct per_htlc_cost, + per_htlc_cost_key, + hash_scidd, + per_htlc_cost_eq_key, + additional_cost_htable); static bool have_layer(const char **layers, const char *name) { diff --git a/plugins/askrene/layer.c b/plugins/askrene/layer.c index 2a5680469978..6237f605d26d 100644 --- a/plugins/askrene/layer.c +++ b/plugins/askrene/layer.c @@ -69,8 +69,8 @@ static inline bool constraint_eq_scidd(const struct constraint *c, return short_channel_id_dir_eq(scidd, &c->scidd); } -HTABLE_DEFINE_TYPE(struct constraint, constraint_scidd, hash_scidd, - constraint_eq_scidd, constraint_hash); +HTABLE_DEFINE_DUPS_TYPE(struct constraint, constraint_scidd, hash_scidd, + constraint_eq_scidd, constraint_hash); static struct short_channel_id local_channel_scid(const struct local_channel *lc) @@ -90,8 +90,8 @@ static inline bool local_channel_eq_scid(const struct local_channel *lc, return short_channel_id_eq(scid, lc->scid); } -HTABLE_DEFINE_TYPE(struct local_channel, local_channel_scid, hash_scid, - local_channel_eq_scid, local_channel_hash); +HTABLE_DEFINE_NODUPS_TYPE(struct local_channel, local_channel_scid, hash_scid, + local_channel_eq_scid, local_channel_hash); static const struct short_channel_id_dir * local_update_scidd(const struct local_update *lu) @@ -105,8 +105,8 @@ static inline bool local_update_eq_scidd(const struct local_update *lu, return short_channel_id_dir_eq(scidd, &lu->scidd); } -HTABLE_DEFINE_TYPE(struct local_update, local_update_scidd, hash_scidd, - local_update_eq_scidd, local_update_hash); +HTABLE_DEFINE_NODUPS_TYPE(struct local_update, local_update_scidd, hash_scidd, + local_update_eq_scidd, local_update_hash); static const struct short_channel_id_dir * bias_scidd(const struct bias *bias) @@ -120,8 +120,8 @@ static bool bias_eq_scidd(const struct bias *bias, return short_channel_id_dir_eq(scidd, &bias->scidd); } -HTABLE_DEFINE_TYPE(struct bias, bias_scidd, hash_scidd, - bias_eq_scidd, bias_hash); +HTABLE_DEFINE_NODUPS_TYPE(struct bias, bias_scidd, hash_scidd, + bias_eq_scidd, bias_hash); struct layer { /* Inside global list of layers */ @@ -207,7 +207,6 @@ static struct local_channel *add_local_channel(struct layer *layer, lc->scid = scid; lc->capacity = capacity; - assert(!local_channel_hash_get(layer->local_channels, scid)); local_channel_hash_add(layer->local_channels, lc); return lc; } diff --git a/plugins/askrene/reserve.c b/plugins/askrene/reserve.c index 82c9096d3c27..abec9372dfc7 100644 --- a/plugins/askrene/reserve.c +++ b/plugins/askrene/reserve.c @@ -31,8 +31,8 @@ static bool reserve_eq_scidd(const struct reserve *r, return short_channel_id_dir_eq(scidd, &r->rhop.scidd); } -HTABLE_DEFINE_TYPE(struct reserve, reserve_scidd, hash_scidd, - reserve_eq_scidd, reserve_htable); +HTABLE_DEFINE_DUPS_TYPE(struct reserve, reserve_scidd, hash_scidd, + reserve_eq_scidd, reserve_htable); struct reserve_htable *new_reserve_htable(const tal_t *ctx) { diff --git a/plugins/channel_hint.h b/plugins/channel_hint.h index 081ad32a8b57..200458f82213 100644 --- a/plugins/channel_hint.h +++ b/plugins/channel_hint.h @@ -52,8 +52,8 @@ const struct short_channel_id_dir *channel_hint_keyof(const struct channel_hint bool channel_hint_eq(const struct channel_hint *a, const struct short_channel_id_dir *b); -HTABLE_DEFINE_TYPE(struct channel_hint, channel_hint_keyof, - channel_hint_hash, channel_hint_eq, channel_hint_map) +HTABLE_DEFINE_NODUPS_TYPE(struct channel_hint, channel_hint_keyof, + channel_hint_hash, channel_hint_eq, channel_hint_map) /* A collection of channel_hint instances, allowing us to handle and * update them more easily. */ diff --git a/plugins/pay.c b/plugins/pay.c index 22d51f304296..b4d119c36ec4 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -327,8 +327,8 @@ static bool pay_mpp_eq(const struct pay_mpp *pm, const struct pay_sort_key *key) && pm->sortkey.groupid == key->groupid; } -HTABLE_DEFINE_TYPE(struct pay_mpp, pay_mpp_key, pay_mpp_hash, pay_mpp_eq, - pay_map); +HTABLE_DEFINE_NODUPS_TYPE(struct pay_mpp, pay_mpp_key, pay_mpp_hash, pay_mpp_eq, + pay_map); static void add_amount_sent(struct plugin *p, const char *invstring, diff --git a/plugins/renepay/chan_extra.h b/plugins/renepay/chan_extra.h index cf06d166a8fd..d7213ad52cad 100644 --- a/plugins/renepay/chan_extra.h +++ b/plugins/renepay/chan_extra.h @@ -50,8 +50,9 @@ static inline bool chan_extra_eq_scid(const struct chan_extra *cd, return short_channel_id_eq(scid, cd->scid); } -HTABLE_DEFINE_TYPE(struct chan_extra, chan_extra_scid, short_channel_id_hash, - chan_extra_eq_scid, chan_extra_map); +HTABLE_DEFINE_NODUPS_TYPE(struct chan_extra, chan_extra_scid, short_channel_id_hash, + chan_extra_eq_scid, + chan_extra_map); /* Helpers for chan_extra_map */ /* Channel knowledge invariants: diff --git a/plugins/renepay/disabledmap.h b/plugins/renepay/disabledmap.h index 2dea547b076f..7bd0487bd23d 100644 --- a/plugins/renepay/disabledmap.h +++ b/plugins/renepay/disabledmap.h @@ -31,8 +31,8 @@ my_short_channel_id_dir_eq(const struct short_channel_id_dir *scidd_a, /* A htable for short_channel_id_dir, the structure itself is the element key. */ -HTABLE_DEFINE_TYPE(struct short_channel_id_dir, self_scidd, hash_scidd, - my_short_channel_id_dir_eq, scidd_map); +HTABLE_DEFINE_NODUPS_TYPE(struct short_channel_id_dir, self_scidd, hash_scidd, + my_short_channel_id_dir_eq, scidd_map); struct disabledmap { /* Channels we decided to disable for various reasons. */ diff --git a/plugins/renepay/payment.h b/plugins/renepay/payment.h index 37e104127279..d905841b8ac5 100644 --- a/plugins/renepay/payment.h +++ b/plugins/renepay/payment.h @@ -94,8 +94,9 @@ static inline bool payment_hash_eq(const struct payment *p, p->payment_info.payment_hash.u.u32[7] == h.u.u32[7]; } -HTABLE_DEFINE_TYPE(struct payment, payment_hash, payment_hash64, - payment_hash_eq, payment_map); +HTABLE_DEFINE_NODUPS_TYPE(struct payment, payment_hash, payment_hash64, + payment_hash_eq, + payment_map); struct payment *payment_new( const tal_t *ctx, diff --git a/plugins/renepay/route.h b/plugins/renepay/route.h index 52a80d7c2165..2aa9195980db 100644 --- a/plugins/renepay/route.h +++ b/plugins/renepay/route.h @@ -106,8 +106,8 @@ static inline bool routekey_equal(const struct route *route, sha256_eq(&route->key.payment_hash, &k->payment_hash); } -HTABLE_DEFINE_TYPE(struct route, route_get_key, routekey_hash, routekey_equal, - route_map); +HTABLE_DEFINE_NODUPS_TYPE(struct route, route_get_key, routekey_hash, routekey_equal, + route_map); struct route *new_route(const tal_t *ctx, u32 groupid, u32 partid, struct sha256 payment_hash, diff --git a/plugins/topology.c b/plugins/topology.c index 77d34e48bc45..b02e5df550fb 100644 --- a/plugins/topology.c +++ b/plugins/topology.c @@ -200,8 +200,8 @@ static struct command_result *json_getroute(struct command *cmd, return send_outreq(req); } -HTABLE_DEFINE_TYPE(struct node_id, node_id_keyof, node_id_hash, node_id_eq, - node_map); +HTABLE_DEFINE_NODUPS_TYPE(struct node_id, node_id_keyof, node_id_hash, node_id_eq, + node_map); /* To avoid multiple fetches, we represent directions as a bitmap * so we can do two at once. */ diff --git a/tests/plugins/channeld_fakenet.c b/tests/plugins/channeld_fakenet.c index 264bd0d96bbc..34396599e232 100644 --- a/tests/plugins/channeld_fakenet.c +++ b/tests/plugins/channeld_fakenet.c @@ -56,7 +56,7 @@ static bool node_cmp(const struct node *n, const struct node_id *node_id) { return node_id_eq(&n->id, node_id); } -HTABLE_DEFINE_TYPE(struct node, node_key, node_id_hash, node_cmp, node_map); +HTABLE_DEFINE_NODUPS_TYPE(struct node, node_key, node_id_hash, node_cmp, node_map); struct info { /* To talk to lightningd */ diff --git a/wallet/txfilter.c b/wallet/txfilter.c index 6c6446ce585f..0502fe314401 100644 --- a/wallet/txfilter.c +++ b/wallet/txfilter.c @@ -25,7 +25,8 @@ static bool scriptpubkey_eq(const u8 *a, const u8 *b) return tal_arr_eq(a, b); } -HTABLE_DEFINE_TYPE(u8, scriptpubkey_keyof, scriptpubkey_hash, scriptpubkey_eq, scriptpubkeyset); +/* FIXME: Should we disallow dups here? */ +HTABLE_DEFINE_DUPS_TYPE(u8, scriptpubkey_keyof, scriptpubkey_hash, scriptpubkey_eq, scriptpubkeyset); struct txfilter { struct scriptpubkeyset scriptpubkeyset; @@ -45,8 +46,8 @@ static const struct bitcoin_outpoint *outpoint_keyof(const struct bitcoin_outpoi return out; } -HTABLE_DEFINE_TYPE(struct bitcoin_outpoint, outpoint_keyof, outpoint_hash, bitcoin_outpoint_eq, - outpointset); +HTABLE_DEFINE_NODUPS_TYPE(struct bitcoin_outpoint, outpoint_keyof, outpoint_hash, bitcoin_outpoint_eq, + outpointset); struct outpointfilter { struct outpointset *set; @@ -95,7 +96,7 @@ bool txfilter_scriptpubkey_matches(const struct txfilter *filter, const u8 *scri { if (!scriptPubKey) return false; - return scriptpubkeyset_get(&filter->scriptpubkeyset, scriptPubKey) != NULL; + return scriptpubkeyset_exists(&filter->scriptpubkeyset, scriptPubKey); } void outpointfilter_add(struct outpointfilter *of,