X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fhtable%2Fhtable.c;h=283ba3d7f1f41855370518c355d785f948794bc3;hb=9a9d6a03d99f05f3158df8520c5338324fd74c49;hp=d3c4f9b41187a9ef0481e332d710e95e42b29bea;hpb=7623d0829a63e7f95ed6f116b7e9f2f4a023e8e7;p=ccan diff --git a/ccan/htable/htable.c b/ccan/htable/htable.c index d3c4f9b4..283ba3d7 100644 --- a/ccan/htable/htable.c +++ b/ccan/htable/htable.c @@ -195,7 +195,7 @@ void *htable_prev_(const struct htable *ht, struct htable_iter *i) for (;;) { if (!i->off) return NULL; - i->off --; + i->off--; if (entry_is_valid(ht->table[i->off])) return get_raw_ptr(ht, ht->table[i->off]); } @@ -287,16 +287,7 @@ static COLD void update_common(struct htable *ht, const void *p) uintptr_t maskdiff, bitsdiff; if (ht->elems == 0) { - /* Always reveal one bit of the pointer in the bucket, - * so it's not zero or HTABLE_DELETED (1), even if - * hash happens to be 0. Assumes (void *)1 is not a - * valid pointer. */ - for (i = sizeof(uintptr_t)*CHAR_BIT - 1; i > 0; i--) { - if ((uintptr_t)p & ((uintptr_t)1 << i)) - break; - } - - ht->common_mask = ~((uintptr_t)1 << i); + ht->common_mask = -1; ht->common_bits = ((uintptr_t)p & ht->common_mask); ht->perfect_bitnum = 0; (void)htable_debug(ht, HTABLE_LOC); @@ -365,6 +356,20 @@ void htable_delval_(struct htable *ht, struct htable_iter *i) ht->deleted++; } +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;