X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fhtable%2Fhtable.c;h=b7e65d11966acc96be83dffbb25a273fec153145;hp=f3e529211d5b2456bad5165d3baa848de4314d3d;hb=c321a1d02755a77ae790d6e8976b2ff15edba89d;hpb=0c3590dc33d644f73bb8587db454c491830aaf26;ds=sidebyside diff --git a/ccan/htable/htable.c b/ccan/htable/htable.c index f3e52921..b7e65d11 100644 --- a/ccan/htable/htable.c +++ b/ccan/htable/htable.c @@ -45,18 +45,10 @@ static inline uintptr_t get_hash_ptr_bits(const struct htable *ht, void htable_init(struct htable *ht, size_t (*rehash)(const void *elem, void *priv), void *priv) { - ht->bits = 0; + struct htable empty = HTABLE_INITIALIZER(empty, NULL, NULL); + *ht = empty; ht->rehash = rehash; ht->priv = priv; - ht->elems = 0; - ht->deleted = 0; - ht->max = 0; - ht->max_with_deleted = 0; - /* This guarantees we enter update_common first add. */ - ht->common_mask = -1; - ht->common_bits = 0; - ht->perfect_bit = 0; - /* Dummy table until first insert. */ ht->table = &ht->perfect_bit; } @@ -205,8 +197,17 @@ static COLD void update_common(struct htable *ht, const void *p) uintptr_t maskdiff, bitsdiff; if (ht->elems == 0) { - ht->common_mask = -1; - ht->common_bits = (uintptr_t)p; + /* 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_bits = ((uintptr_t)p & ht->common_mask); ht->perfect_bit = 1; return; }