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)
void htable_init(struct htable *ht,
size_t (*rehash)(const void *elem, void *priv), void *priv);
+/**
+ * htable_init_sized - initialize an empty hash table of given size.
+ * @ht: the hash table to initialize
+ * @rehash: hash function to use for rehashing.
+ * @priv: private argument to @rehash function.
+ * @size: the number of element.
+ *
+ * If this returns false, @ht is still usable, but may need to do reallocation
+ * upon an add. If this returns true, it will not need to reallocate within
+ * @size htable_adds.
+ */
+bool htable_init_sized(struct htable *ht,
+ size_t (*rehash)(const void *elem, void *priv),
+ void *priv, size_t size);
+
/**
* htable_clear - empty a hash table.
* @ht: the hash table to clear
*
* It also defines initialization and freeing functions:
* void <name>_init(struct <name> *);
+ * void <name>_init_sized(struct <name> *, size_t);
* void <name>_clear(struct <name> *);
*
* Add function only fails if we run out of memory:
{ \
htable_init(&ht->raw, name##_hash, NULL); \
} \
+ static inline void name##_init_sized(struct name *ht, size_t s) \
+ { \
+ htable_init_sized(&ht->raw, name##_hash, NULL, s); \
+ } \
static inline void name##_clear(struct name *ht) \
{ \
htable_clear(&ht->raw); \
void *p;
struct htable_iter iter;
- plan_tests(29);
+ plan_tests(35);
for (i = 0; i < NUM_VALS; i++)
val[i] = i;
dne = i;
ok1(ht.perfect_bit != 0);
htable_clear(&ht);
+ ok1(htable_init_sized(&ht, hash, NULL, 1024));
+ ok1(ht.max >= 1024);
+ htable_clear(&ht);
+
+ ok1(htable_init_sized(&ht, hash, NULL, 1023));
+ ok1(ht.max >= 1023);
+ htable_clear(&ht);
+
+ ok1(htable_init_sized(&ht, hash, NULL, 1025));
+ ok1(ht.max >= 1025);
+ htable_clear(&ht);
+
return exit_status();
}