update.
[chise/xemacs-chise.git-] / src / elhash.c
index 384b1e5..426f804 100644 (file)
@@ -59,7 +59,6 @@ struct Lisp_Hash_Table
   Lisp_Object next_weak;     /* Used to chain together all of the weak
                                hash tables.  Don't mark through this. */
 };
-typedef struct Lisp_Hash_Table Lisp_Hash_Table;
 
 #define HENTRY_CLEAR_P(hentry) ((*(EMACS_UINT*)(&((hentry)->key))) == 0)
 #define CLEAR_HENTRY(hentry)   \
@@ -70,13 +69,13 @@ typedef struct Lisp_Hash_Table Lisp_Hash_Table;
 #define HASH_TABLE_DEFAULT_REHASH_SIZE 1.3
 #define HASH_TABLE_MIN_SIZE 10
 
-#define HASH_CODE(key, ht)                                                     \
-  (((((ht)->hash_function ? (ht)->hash_function (key) : LISP_HASH (key))       \
-     * (ht)->golden_ratio)                                                             \
-    % (ht)->size))
+#define HASH_CODE(key, ht)                                             \
+((((ht)->hash_function ? (ht)->hash_function (key) : LISP_HASH (key))  \
+  * (ht)->golden_ratio)                                                        \
+ % (ht)->size)
 
 #define KEYS_EQUAL_P(key1, key2, testfun) \
-  (EQ ((key1), (key2)) || ((testfun) && (testfun) ((key1), (key2))))
+  (EQ (key1, key2) || ((testfun) && (testfun) (key1, key2)))
 
 #define LINEAR_PROBING_LOOP(probe, entries, size)              \
   for (;                                                       \
@@ -374,19 +373,20 @@ finalize_hash_table (void *header, int for_disksave)
 }
 
 static const struct lrecord_description hentry_description_1[] = {
-  { XD_LISP_OBJECT, offsetof(hentry, key), 2 },
+  { XD_LISP_OBJECT, offsetof (hentry, key) },
+  { XD_LISP_OBJECT, offsetof (hentry, value) },
   { XD_END }
 };
 
 static const struct struct_description hentry_description = {
-  sizeof(hentry),
+  sizeof (hentry),
   hentry_description_1
 };
 
 const struct lrecord_description hash_table_description[] = {
-  { XD_SIZE_T,     offsetof(Lisp_Hash_Table, size) },
-  { XD_STRUCT_PTR, offsetof(Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), &hentry_description },
-  { XD_LO_LINK,    offsetof(Lisp_Hash_Table, next_weak) },
+  { XD_SIZE_T,     offsetof (Lisp_Hash_Table, size) },
+  { XD_STRUCT_PTR, offsetof (Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), &hentry_description },
+  { XD_LO_LINK,    offsetof (Lisp_Hash_Table, next_weak) },
   { XD_END }
 };
 
@@ -413,19 +413,11 @@ xhash_table (Lisp_Object hash_table)
 /************************************************************************/
 
 /* 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));
+    ((double) ht->size * ht->rehash_threshold);
   ht->golden_ratio = (size_t)
     ((double) ht->size * (.6180339887 / (double) sizeof (Lisp_Object)));
 }
@@ -440,10 +432,6 @@ make_general_lisp_hash_table (enum hash_table_test test,
   Lisp_Object hash_table;
   Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
 
-  ht->rehash_size      = rehash_size;
-  ht->rehash_threshold = rehash_threshold;
-  ht->weakness         = weakness;
-
   switch (test)
     {
     case HASH_TABLE_EQ:
@@ -465,15 +453,21 @@ make_general_lisp_hash_table (enum hash_table_test test,
       abort ();
     }
 
-  if (ht->rehash_size <= 0.0)
-    ht->rehash_size = HASH_TABLE_DEFAULT_REHASH_SIZE;
+  ht->weakness = weakness;
+
+  ht->rehash_size =
+    rehash_size > 1.0 ? rehash_size : HASH_TABLE_DEFAULT_REHASH_SIZE;
+
+  ht->rehash_threshold =
+    rehash_threshold > 0.0 ? rehash_threshold :
+    size > 4096 && !ht->test_function ? 0.7 : 0.6;
+
   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->size = hash_table_size ((size_t) (((double) size / ht->rehash_threshold)
+                                       + 1.0));
   ht->count = 0;
+
   compute_hash_table_derived_values (ht);
 
   /* We leave room for one never-occupied sentinel hentry at the end.  */
@@ -500,8 +494,7 @@ make_lisp_hash_table (size_t size,
                      enum hash_table_weakness weakness,
                      enum hash_table_test test)
 {
-  return make_general_lisp_hash_table
-    (test, size, HASH_TABLE_DEFAULT_REHASH_SIZE, -1.0, weakness);
+  return make_general_lisp_hash_table (test, size, -1.0, -1.0, weakness);
 }
 
 /* Pretty reading of hash tables.
@@ -890,7 +883,7 @@ The keys and values will not themselves be copied.
 static void
 resize_hash_table (Lisp_Hash_Table *ht, size_t new_size)
 {
-  hentry *old_entries, *new_entries, *old_sentinel, *new_sentinel, *e;
+  hentry *old_entries, *new_entries, *sentinel, *e;
   size_t old_size;
 
   old_size = ht->size;
@@ -898,18 +891,12 @@ resize_hash_table (Lisp_Hash_Table *ht, size_t new_size)
 
   old_entries = ht->hentries;
 
-  ht->hentries = xnew_array (hentry, new_size + 1);
+  ht->hentries = xnew_array_and_zero (hentry, new_size + 1);
   new_entries = ht->hentries;
 
-  old_sentinel = old_entries + old_size;
-  new_sentinel = new_entries + new_size;
-
-  for (e = new_entries; e <= new_sentinel; e++)
-    CLEAR_HENTRY (e);
-
   compute_hash_table_derived_values (ht);
 
-  for (e = old_entries; e < old_sentinel; e++)
+  for (e = old_entries, sentinel = e + old_size; e < sentinel; e++)
     if (!HENTRY_CLEAR_P (e))
       {
        hentry *probe = new_entries + HASH_CODE (e->key, ht);
@@ -922,10 +909,28 @@ resize_hash_table (Lisp_Hash_Table *ht, size_t new_size)
     xfree (old_entries);
 }
 
+/* After a hash table has been saved to disk and later restored by the
+   portable dumper, it contains the same objects, but their addresses
+   and thus their HASH_CODEs have changed. */
 void
-reorganize_hash_table (Lisp_Hash_Table *ht)
+pdump_reorganize_hash_table (Lisp_Object hash_table)
 {
-  resize_hash_table (ht, ht->size);
+  CONST Lisp_Hash_Table *ht = xhash_table (hash_table);
+  hentry *new_entries = xnew_array_and_zero (hentry, ht->size + 1);
+  hentry *e, *sentinel;
+
+  for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
+    if (!HENTRY_CLEAR_P (e))
+      {
+       hentry *probe = new_entries + HASH_CODE (e->key, ht);
+       LINEAR_PROBING_LOOP (probe, new_entries, ht->size)
+         ;
+       *probe = *e;
+      }
+
+  memcpy (ht->hentries, new_entries, ht->size * sizeof (hentry));
+
+  xfree (new_entries);
 }
 
 static void
@@ -1090,7 +1095,7 @@ beyond which the HASH-TABLE is enlarged by rehashing.
 */
        (hash_table))
 {
-  return make_float (hash_table_rehash_threshold (xhash_table (hash_table)));
+  return make_float (xhash_table (hash_table)->rehash_threshold);
 }
 
 DEFUN ("hash-table-weakness", Fhash_table_weakness, 1, 1, 0, /*