+/************************************************************************/
+/* Creation of Hash Tables */
+/************************************************************************/
+
+/* Creation of hash tables, without error-checking. */
+static double
+hash_table_rehash_threshold (Lisp_Hash_Table *ht)
+{
+ return
+ ht->rehash_threshold > 0.0 ? ht->rehash_threshold :
+ ht->size > 4096 && !ht->test_function ? 0.7 : 0.6;
+}
+
+static void
+compute_hash_table_derived_values (Lisp_Hash_Table *ht)
+{
+ ht->rehash_count = (size_t)
+ ((double) ht->size * hash_table_rehash_threshold (ht));
+ ht->golden = (size_t)
+ ((double) ht->size * (.6180339887 / (double) sizeof (Lisp_Object)));
+}
+
+Lisp_Object
+make_general_lisp_hash_table (size_t size,
+ enum hash_table_type type,
+ enum hash_table_test test,
+ double rehash_size,
+ double rehash_threshold)
+{
+ Lisp_Object hash_table;
+ Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, lrecord_hash_table);
+
+ ht->type = type;
+ ht->rehash_size = rehash_size;
+ ht->rehash_threshold = rehash_threshold;
+
+ switch (test)
+ {
+ case HASH_TABLE_EQ:
+ ht->test_function = 0;
+ ht->hash_function = 0;
+ break;
+
+ case HASH_TABLE_EQL:
+ ht->test_function = lisp_object_eql_equal;
+ ht->hash_function = lisp_object_eql_hash;
+ break;
+
+ case HASH_TABLE_EQUAL:
+ ht->test_function = lisp_object_equal_equal;
+ ht->hash_function = lisp_object_equal_hash;
+ break;
+
+ default:
+ abort ();
+ }
+
+ if (ht->rehash_size <= 0.0)
+ ht->rehash_size = HASH_TABLE_DEFAULT_REHASH_SIZE;
+ if (size < HASH_TABLE_MIN_SIZE)
+ size = HASH_TABLE_MIN_SIZE;
+ if (rehash_threshold < 0.0)
+ rehash_threshold = 0.75;
+ ht->size =
+ hash_table_size ((size_t) ((double) size / hash_table_rehash_threshold (ht)) + 1);
+ ht->count = 0;
+ compute_hash_table_derived_values (ht);
+
+ /* We leave room for one never-occupied sentinel hentry at the end. */
+ ht->hentries = xnew_array (hentry, ht->size + 1);
+
+ {
+ hentry *e, *sentinel;
+ for (e = ht->hentries, sentinel = e + ht->size; e <= sentinel; e++)
+ CLEAR_HENTRY (e);
+ }
+
+ XSETHASH_TABLE (hash_table, ht);
+
+ if (type == HASH_TABLE_NON_WEAK)
+ ht->next_weak = Qunbound;
+ else
+ ht->next_weak = Vall_weak_hash_tables, Vall_weak_hash_tables = hash_table;
+
+ return hash_table;
+}
+
+Lisp_Object
+make_lisp_hash_table (size_t size,
+ enum hash_table_type type,
+ enum hash_table_test test)
+{
+ return make_general_lisp_hash_table (size, type, test,
+ HASH_TABLE_DEFAULT_REHASH_SIZE, -1.0);
+}
+
+/* Pretty reading of hash tables.