+/* Wild guess at the initial hash size */
+#define INITIAL_HASH_SIZE 9
+
+/* We leave more room in smaller hash but do not let it
+ * grow to have unused hole too much.
+ */
+#define INITIAL_FREE(sz_log2) ((1<<(sz_log2))*(sz_log2-3)/(sz_log2))
+
+/* A prime rather carefully chosen between 2^16..2^17, so that
+ * HASHBASE < INITIAL_FREE(17). We want to keep the maximum hashtable
+ * size under the current 2<<17 maximum, which can hold this many
+ * different values before overflowing to hashtable of size 2<<18.
+ */
+#define HASHBASE 107927
+
+struct spanhash {
+ unsigned int hashval;
+ unsigned int cnt;
+};
+struct spanhash_top {
+ int alloc_log2;
+ int free;
+ struct spanhash data[FLEX_ARRAY];
+};
+
+static struct spanhash_top *spanhash_rehash(struct spanhash_top *orig)
+{
+ struct spanhash_top *new;
+ int i;
+ int osz = 1 << orig->alloc_log2;
+ int sz = osz << 1;
+
+ new = xmalloc(sizeof(*orig) + sizeof(struct spanhash) * sz);
+ new->alloc_log2 = orig->alloc_log2 + 1;
+ new->free = INITIAL_FREE(new->alloc_log2);
+ memset(new->data, 0, sizeof(struct spanhash) * sz);
+ for (i = 0; i < osz; i++) {
+ struct spanhash *o = &(orig->data[i]);
+ int bucket;
+ if (!o->cnt)
+ continue;
+ bucket = o->hashval & (sz - 1);
+ while (1) {
+ struct spanhash *h = &(new->data[bucket++]);
+ if (!h->cnt) {
+ h->hashval = o->hashval;
+ h->cnt = o->cnt;
+ new->free--;
+ break;
+ }
+ if (sz <= bucket)
+ bucket = 0;
+ }
+ }
+ free(orig);
+ return new;
+}