- struct htable *ht = malloc(sizeof(struct htable));
- if (ht) {
- ht->bits = HTABLE_BASE_BITS;
- ht->rehash = rehash;
- ht->priv = priv;
- ht->elems = 0;
- ht->deleted = 0;
- ht->max = (1 << ht->bits) * 2 / 3;
- ht->max_with_deleted = (1 << ht->bits) * 4 / 5;
- /* This guarantees we enter update_common first add. */
- ht->common_mask = -1;
- ht->common_bits = 0;
- ht->table = calloc(1 << ht->bits, sizeof(uintptr_t));
- if (!ht->table) {
- free(ht);
- ht = NULL;
- }
+ struct htable empty = HTABLE_INITIALIZER(empty, NULL, NULL);
+ *ht = empty;
+ ht->rehash = rehash;
+ ht->priv = priv;
+ 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)
+{
+ 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;