+static bool resize_buckets(Hashmap *h) {
+ struct hashmap_entry **n, *i;
+ unsigned m, nxor;
+
+ 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 xor value for the
+ * extension, so that people cannot guess what we are using
+ * here forever */
+ nxor = random_u();
+
+ for (i = h->iterate_list_head; i; i = i->iterate_next) {
+ unsigned hash, x;
+
+ hash = h->hash_func(i->key);
+
+ /* 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[(hash ^ h->random_xor) % h->n_buckets] = i->bucket_next;
+
+ /* Then, add to new backet table */
+ x = (hash ^ nxor) % m;
+
+ i->bucket_next = n[x];
+ i->bucket_previous = NULL;
+ if (n[x])
+ n[x]->bucket_previous = i;
+ n[x] = i;
+ }
+
+ if (h->buckets != (struct hashmap_entry**) ((uint8_t*) h + ALIGN(sizeof(Hashmap))))
+ free(h->buckets);
+
+ h->buckets = n;
+ h->n_buckets = m;
+ h->random_xor = nxor;
+
+ return true;
+}
+