X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fhtable%2Fhtable.c;h=e1d13699ea85811fe2f61adbb1ce4eca942406c8;hp=59048dc0ada0df95b23583e0dfbba65d3c96768c;hb=f359fde1b7c3ca60faebd4df710bf30a68784e27;hpb=64b0c5cdeea5bc00ce3b9ef89fd3aade9cb0cd2c diff --git a/ccan/htable/htable.c b/ccan/htable/htable.c index 59048dc0..e1d13699 100644 --- a/ccan/htable/htable.c +++ b/ccan/htable/htable.c @@ -5,6 +5,7 @@ #include #include #include +#include /* We use 0x1 as deleted marker. */ #define HTABLE_DELETED (0x1) @@ -52,6 +53,13 @@ void htable_init(struct htable *ht, ht->table = &ht->perfect_bit; } +/* We've changed ht->bits, update ht->max and ht->max_with_deleted */ +static void htable_adjust_capacity(struct htable *ht) +{ + ht->max = ((size_t)3 << ht->bits) / 4; + ht->max_with_deleted = ((size_t)9 << ht->bits) / 10; +} + bool htable_init_sized(struct htable *ht, size_t (*rehash)(const void *, void *), void *priv, size_t expect) @@ -69,9 +77,7 @@ bool htable_init_sized(struct htable *ht, ht->table = &ht->perfect_bit; return false; } - ht->max = ((size_t)3 << ht->bits) / 4; - ht->max_with_deleted = ((size_t)9 << ht->bits) / 10; - + htable_adjust_capacity(ht); return true; } @@ -82,6 +88,19 @@ void htable_clear(struct htable *ht) htable_init(ht, ht->rehash, ht->priv); } +bool htable_copy(struct htable *dst, const struct htable *src) +{ + uintptr_t *htable = malloc(sizeof(size_t) << src->bits); + + if (!htable) + return false; + + *dst = *src; + dst->table = htable; + memcpy(dst->table, src->table, sizeof(size_t) << src->bits); + return true; +} + static size_t hash_bucket(const struct htable *ht, size_t h) { return h & ((1 << ht->bits)-1); @@ -135,6 +154,17 @@ void *htable_next(const struct htable *ht, struct htable_iter *i) return NULL; } +void *htable_prev(const struct htable *ht, struct htable_iter *i) +{ + for (;;) { + if (!i->off) + return NULL; + i->off --; + if (entry_is_valid(ht->table[i->off])) + return get_raw_ptr(ht, ht->table[i->off]); + } +} + /* This does not expand the hash table, that's up to caller. */ static void ht_add(struct htable *ht, const void *new, size_t h) { @@ -163,8 +193,7 @@ static COLD bool double_table(struct htable *ht) return false; } ht->bits++; - ht->max = ((size_t)3 << ht->bits) / 4; - ht->max_with_deleted = ((size_t)9 << ht->bits) / 10; + htable_adjust_capacity(ht); /* If we lost our "perfect bit", get it back now. */ if (!ht->perfect_bit && ht->common_mask) {