/* We use 0x1 as deleted marker. */
#define HTABLE_DELETED (0x1)
+static void *htable_default_alloc(struct htable *ht, size_t len)
+{
+ return calloc(len, 1);
+}
+
+static void htable_default_free(struct htable *ht, void *p)
+{
+ free(p);
+}
+
+static void *(*htable_alloc)(struct htable *, size_t) = htable_default_alloc;
+static void (*htable_free)(struct htable *, void *) = htable_default_free;
+
+void htable_set_allocator(void *(*alloc)(struct htable *, size_t len),
+ void (*free)(struct htable *, void *p))
+{
+ if (!alloc)
+ alloc = htable_default_alloc;
+ if (!free)
+ free = htable_default_free;
+ htable_alloc = alloc;
+ htable_free = free;
+}
+
/* We clear out the bits which are always the same, and put metadata there. */
static inline uintptr_t get_extra_ptr_bits(const struct htable *ht,
uintptr_t e)
break;
}
- ht->table = calloc(1 << ht->bits, sizeof(size_t));
+ ht->table = htable_alloc(ht, sizeof(size_t) << ht->bits);
if (!ht->table) {
ht->table = &ht->perfect_bit;
return false;
void htable_clear(struct htable *ht)
{
if (ht->table != &ht->perfect_bit)
- free((void *)ht->table);
+ htable_free(ht, (void *)ht->table);
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);
+ uintptr_t *htable = htable_alloc(dst, sizeof(size_t) << src->bits);
if (!htable)
return false;
uintptr_t *oldtable, e;
oldtable = ht->table;
- ht->table = calloc(1 << (ht->bits+1), sizeof(size_t));
+ ht->table = htable_alloc(ht, sizeof(size_t) << (ht->bits+1));
if (!ht->table) {
ht->table = oldtable;
return false;
ht_add(ht, p, ht->rehash(p, ht->priv));
}
}
- free(oldtable);
+ htable_free(ht, oldtable);
}
ht->deleted = 0;