+
+void *htable_pick_(const struct htable *ht, size_t seed, struct htable_iter *i)
+{
+ void *e;
+ struct htable_iter unwanted;
+
+ if (!i)
+ i = &unwanted;
+ i->off = seed % ((size_t)1 << ht->bits);
+ e = htable_next(ht, i);
+ if (!e)
+ e = htable_first(ht, i);
+ return e;
+}
+
+struct htable *htable_check(const struct htable *ht, const char *abortstr)
+{
+ void *p;
+ struct htable_iter i;
+ size_t n = 0;
+
+ /* Use non-DEBUG versions here, to avoid infinite recursion with
+ * CCAN_HTABLE_DEBUG! */
+ for (p = htable_first_(ht, &i); p; p = htable_next_(ht, &i)) {
+ struct htable_iter i2;
+ void *c;
+ size_t h = ht->rehash(p, ht->priv);
+ bool found = false;
+
+ n++;
+
+ /* Open-code htable_get to avoid CCAN_HTABLE_DEBUG */
+ for (c = htable_firstval_(ht, &i2, h);
+ c;
+ c = htable_nextval_(ht, &i2, h)) {
+ if (c == p) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ if (abortstr) {
+ fprintf(stderr,
+ "%s: element %p in position %zu"
+ " cannot find itself\n",
+ abortstr, p, i.off);
+ abort();
+ }
+ return NULL;
+ }
+ }
+ if (n != ht->elems) {
+ if (abortstr) {
+ fprintf(stderr,
+ "%s: found %zu elems, expected %zu\n",
+ abortstr, n, ht->elems);
+ abort();
+ }
+ return NULL;
+ }
+
+ return (struct htable *)ht;
+}