]> git.ozlabs.org Git - ccan/blobdiff - ccan/htable/htable.c
htable: add a htable_prev method to oppose _next
[ccan] / ccan / htable / htable.c
index b7e65d11966acc96be83dffbb25a273fec153145..5a773cd8876d2f36b53733c659757213811651ff 100644 (file)
@@ -52,6 +52,29 @@ void htable_init(struct htable *ht,
        ht->table = &ht->perfect_bit;
 }
 
+bool htable_init_sized(struct htable *ht,
+                      size_t (*rehash)(const void *, void *),
+                      void *priv, size_t expect)
+{
+       htable_init(ht, rehash, priv);
+
+       /* Don't go insane with sizing. */
+       for (ht->bits = 1; ((size_t)3 << ht->bits) / 4 < expect; ht->bits++) {
+               if (ht->bits == 30)
+                       break;
+       }
+
+       ht->table = calloc(1 << ht->bits, sizeof(size_t));
+       if (!ht->table) {
+               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;
+
+       return true;
+}
+       
 void htable_clear(struct htable *ht)
 {
        if (ht->table != &ht->perfect_bit)
@@ -112,6 +135,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)
 {