return NULL;
}
-static int resize_buckets(Hashmap *h) {
+static int resize_buckets(Hashmap *h, unsigned entries_add) {
struct hashmap_entry **n, *i;
- unsigned m;
+ unsigned m, new_n_entries, new_n_buckets;
uint8_t nkey[HASH_KEY_SIZE];
assert(h);
- if (_likely_(h->n_entries*4 < h->n_buckets*3))
+ new_n_entries = h->n_entries + entries_add;
+
+ /* overflow? */
+ if (_unlikely_(new_n_entries < entries_add || new_n_entries > UINT_MAX / 4))
+ return -ENOMEM;
+
+ new_n_buckets = new_n_entries * 4 / 3;
+
+ if (_likely_(new_n_buckets <= h->n_buckets))
return 0;
- /* Increase by four */
- m = (h->n_entries+1)*4-1;
+ /* Increase by four at least */
+ m = MAX((h->n_entries+1)*4-1, new_n_buckets);
/* If we hit OOM we simply risk packed hashmaps... */
n = new0(struct hashmap_entry*, m);
struct hashmap_entry *e;
- if (resize_buckets(h) > 0)
+ if (resize_buckets(h, 1) > 0)
hash = bucket_hash(h, key);
if (h->from_pool)
return 0;
}
+int hashmap_reserve(Hashmap *h, unsigned entries_add) {
+ int r;
+
+ assert(h);
+
+ r = resize_buckets(h, entries_add);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
void hashmap_move(Hashmap *h, Hashmap *other) {
struct hashmap_entry *e, *n;
static inline int ordered_hashmap_merge(OrderedHashmap *h, OrderedHashmap *other) {
return hashmap_merge((Hashmap*) h, (Hashmap*) other);
}
+int hashmap_reserve(Hashmap *h, unsigned entries_add);
+static inline int ordered_hashmap_reserve(OrderedHashmap *h, unsigned entries_add) {
+ return hashmap_reserve((Hashmap*) h, entries_add);
+}
void hashmap_move(Hashmap *h, Hashmap *other);
static inline void ordered_hashmap_move(OrderedHashmap *h, OrderedHashmap *other) {
hashmap_move((Hashmap*) h, (Hashmap*) other);
return hashmap_merge(MAKE_HASHMAP(s), MAKE_HASHMAP(other));
}
+int set_reserve(Set *s, unsigned entries_add) {
+ return hashmap_reserve(MAKE_HASHMAP(s), entries_add);
+}
+
void set_move(Set *s, Set *other) {
return hashmap_move(MAKE_HASHMAP(s), MAKE_HASHMAP(other));
}
int set_remove_and_put(Set *s, void *old_value, void *new_value);
int set_merge(Set *s, Set *other);
+int set_reserve(Set *s, unsigned entries_add);
void set_move(Set *s, Set *other);
int set_move_one(Set *s, Set *other, void *value);