+static bool resize_buckets(Hashmap *h) {
+ struct hashmap_entry **n, *i;
+ unsigned m;
+ uint8_t nkey[HASH_KEY_SIZE];
+
+ assert(h);
+
+ if (_likely_(h->n_entries*4 < h->n_buckets*3))
+ return false;
+
+ /* Increase by four */
+ m = (h->n_entries+1)*4-1;
+
+ /* If we hit OOM we simply risk packed hashmaps... */
+ n = new0(struct hashmap_entry*, m);
+ if (!n)
+ return false;
+
+ /* Let's use a different randomized hash key for the
+ * extension, so that people cannot guess what we are using
+ * here forever */
+ get_hash_key(nkey, false);
+
+ for (i = h->iterate_list_head; i; i = i->iterate_next) {
+ unsigned long old_bucket, new_bucket;
+
+ old_bucket = h->hash_func(i->key, h->hash_key) % h->n_buckets;
+
+ /* First, drop from old bucket table */
+ if (i->bucket_next)
+ i->bucket_next->bucket_previous = i->bucket_previous;
+
+ if (i->bucket_previous)
+ i->bucket_previous->bucket_next = i->bucket_next;
+ else
+ h->buckets[old_bucket] = i->bucket_next;
+
+ /* Then, add to new backet table */
+ new_bucket = h->hash_func(i->key, nkey) % m;
+
+ i->bucket_next = n[new_bucket];
+ i->bucket_previous = NULL;
+ if (n[new_bucket])
+ n[new_bucket]->bucket_previous = i;
+ n[new_bucket] = i;
+ }
+
+ if (h->buckets != (struct hashmap_entry**) ((uint8_t*) h + ALIGN(sizeof(Hashmap))))
+ free(h->buckets);
+
+ h->buckets = n;
+ h->n_buckets = m;
+
+ memcpy(h->hash_key, nkey, HASH_KEY_SIZE);
+
+ return true;
+}
+