import xemacs-21.2.37
[chise/xemacs-chise.git.1] / src / elhash.c
1 /* Implementation of the hash table lisp object type.
2    Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
3    Copyright (C) 1995, 1996 Ben Wing.
4    Copyright (C) 1997 Free Software Foundation, Inc.
5
6 This file is part of XEmacs.
7
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCNTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING.  If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23 /* Synched up with: Not in FSF. */
24
25 #include <config.h>
26 #include "lisp.h"
27 #include "bytecode.h"
28 #include "elhash.h"
29
30 Lisp_Object Qhash_tablep;
31 static Lisp_Object Qhashtable, Qhash_table;
32 static Lisp_Object Qweakness, Qvalue, Qkey_or_value, Qkey_and_value;
33 static Lisp_Object Vall_weak_hash_tables;
34 static Lisp_Object Qrehash_size, Qrehash_threshold;
35 static Lisp_Object Q_size, Q_test, Q_weakness, Q_rehash_size, Q_rehash_threshold;
36
37 /* obsolete as of 19990901 in xemacs-21.2 */
38 static Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qkey_or_value_weak;
39 static Lisp_Object Qnon_weak, Q_type;
40
41 typedef struct hentry
42 {
43   Lisp_Object key;
44   Lisp_Object value;
45 } hentry;
46
47 struct Lisp_Hash_Table
48 {
49   struct lcrecord_header header;
50   size_t size;
51   size_t count;
52   size_t rehash_count;
53   double rehash_size;
54   double rehash_threshold;
55   size_t golden_ratio;
56   hash_table_hash_function_t hash_function;
57   hash_table_test_function_t test_function;
58   hentry *hentries;
59   enum hash_table_weakness weakness;
60   Lisp_Object next_weak;     /* Used to chain together all of the weak
61                                 hash tables.  Don't mark through this. */
62 };
63
64 #define HENTRY_CLEAR_P(hentry) ((*(EMACS_UINT*)(&((hentry)->key))) == 0)
65 #define CLEAR_HENTRY(hentry)   \
66   ((*(EMACS_UINT*)(&((hentry)->key)))   = 0, \
67    (*(EMACS_UINT*)(&((hentry)->value))) = 0)
68
69 #define HASH_TABLE_DEFAULT_SIZE 16
70 #define HASH_TABLE_DEFAULT_REHASH_SIZE 1.3
71 #define HASH_TABLE_MIN_SIZE 10
72
73 #define HASH_CODE(key, ht)                                              \
74   ((((ht)->hash_function ? (ht)->hash_function (key) : LISP_HASH (key)) \
75     * (ht)->golden_ratio)                                               \
76    % (ht)->size)
77
78 #define KEYS_EQUAL_P(key1, key2, testfun) \
79   (EQ (key1, key2) || ((testfun) && (testfun) (key1, key2)))
80
81 #define LINEAR_PROBING_LOOP(probe, entries, size)               \
82   for (;                                                        \
83        !HENTRY_CLEAR_P (probe) ||                               \
84          (probe == entries + size ?                             \
85           (probe = entries, !HENTRY_CLEAR_P (probe)) : 0);      \
86        probe++)
87
88 #ifndef ERROR_CHECK_HASH_TABLE
89 # ifdef ERROR_CHECK_TYPECHECK
90 #  define ERROR_CHECK_HASH_TABLE 1
91 # else
92 #  define ERROR_CHECK_HASH_TABLE 0
93 # endif
94 #endif
95
96 #if ERROR_CHECK_HASH_TABLE
97 static void
98 check_hash_table_invariants (Lisp_Hash_Table *ht)
99 {
100   assert (ht->count < ht->size);
101   assert (ht->count <= ht->rehash_count);
102   assert (ht->rehash_count < ht->size);
103   assert ((double) ht->count * ht->rehash_threshold - 1 <= (double) ht->rehash_count);
104   assert (HENTRY_CLEAR_P (ht->hentries + ht->size));
105 }
106 #else
107 #define check_hash_table_invariants(ht)
108 #endif
109
110 /* We use linear probing instead of double hashing, despite its lack
111    of blessing by Knuth and company, because, as a result of the
112    increasing discrepancy between CPU speeds and memory speeds, cache
113    behavior is becoming increasingly important, e.g:
114
115    For a trivial loop, the penalty for non-sequential access of an array is:
116     - a factor of 3-4 on Pentium Pro 200 Mhz
117     - a factor of 10  on Ultrasparc  300 Mhz */
118
119 /* Return a suitable size for a hash table, with at least SIZE slots. */
120 static size_t
121 hash_table_size (size_t requested_size)
122 {
123   /* Return some prime near, but greater than or equal to, SIZE.
124      Decades from the time of writing, someone will have a system large
125      enough that the list below will be too short... */
126   static const size_t primes [] =
127   {
128     19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031,
129     1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783,
130     19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941,
131     204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519,
132     1664681, 2164111, 2813353, 3657361, 4754591, 6180989, 8035301,
133     10445899, 13579681, 17653589, 22949669, 29834603, 38784989,
134     50420551, 65546729, 85210757, 110774011, 144006217, 187208107,
135     243370577, 316381771, 411296309, 534685237, 695090819, 903618083,
136     1174703521, 1527114613, 1985248999, 2580823717UL, 3355070839UL
137   };
138   /* We've heard of binary search. */
139   int low, high;
140   for (low = 0, high = countof (primes) - 1; high - low > 1;)
141     {
142       /* Loop Invariant: size < primes [high] */
143       int mid = (low + high) / 2;
144       if (primes [mid] < requested_size)
145         low = mid;
146       else
147         high = mid;
148     }
149   return primes [high];
150 }
151
152 \f
153 #if 0 /* I don't think these are needed any more.
154          If using the general lisp_object_equal_*() functions
155          causes efficiency problems, these can be resurrected. --ben */
156 /* equality and hash functions for Lisp strings */
157 int
158 lisp_string_equal (Lisp_Object str1, Lisp_Object str2)
159 {
160   /* This is wrong anyway.  You can't use strcmp() on Lisp strings,
161      because they can contain zero characters.  */
162   return !strcmp ((char *) XSTRING_DATA (str1), (char *) XSTRING_DATA (str2));
163 }
164
165 static hashcode_t
166 lisp_string_hash (Lisp_Object obj)
167 {
168   return hash_string (XSTRING_DATA (str), XSTRING_LENGTH (str));
169 }
170
171 #endif /* 0 */
172
173 static int
174 lisp_object_eql_equal (Lisp_Object obj1, Lisp_Object obj2)
175 {
176   return EQ (obj1, obj2) || (FLOATP (obj1) && internal_equal (obj1, obj2, 0));
177 }
178
179 static hashcode_t
180 lisp_object_eql_hash (Lisp_Object obj)
181 {
182   return FLOATP (obj) ? internal_hash (obj, 0) : LISP_HASH (obj);
183 }
184
185 static int
186 lisp_object_equal_equal (Lisp_Object obj1, Lisp_Object obj2)
187 {
188   return internal_equal (obj1, obj2, 0);
189 }
190
191 static hashcode_t
192 lisp_object_equal_hash (Lisp_Object obj)
193 {
194   return internal_hash (obj, 0);
195 }
196
197 \f
198 static Lisp_Object
199 mark_hash_table (Lisp_Object obj)
200 {
201   Lisp_Hash_Table *ht = XHASH_TABLE (obj);
202
203   /* If the hash table is weak, we don't want to mark the keys and
204      values (we scan over them after everything else has been marked,
205      and mark or remove them as necessary).  */
206   if (ht->weakness == HASH_TABLE_NON_WEAK)
207     {
208       hentry *e, *sentinel;
209
210       for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
211         if (!HENTRY_CLEAR_P (e))
212           {
213             mark_object (e->key);
214             mark_object (e->value);
215           }
216     }
217   return Qnil;
218 }
219 \f
220 /* Equality of hash tables.  Two hash tables are equal when they are of
221    the same weakness and test function, they have the same number of
222    elements, and for each key in the hash table, the values are `equal'.
223
224    This is similar to Common Lisp `equalp' of hash tables, with the
225    difference that CL requires the keys to be compared with the test
226    function, which we don't do.  Doing that would require consing, and
227    consing is a bad idea in `equal'.  Anyway, our method should provide
228    the same result -- if the keys are not equal according to the test
229    function, then Fgethash() in hash_table_equal_mapper() will fail.  */
230 static int
231 hash_table_equal (Lisp_Object hash_table1, Lisp_Object hash_table2, int depth)
232 {
233   Lisp_Hash_Table *ht1 = XHASH_TABLE (hash_table1);
234   Lisp_Hash_Table *ht2 = XHASH_TABLE (hash_table2);
235   hentry *e, *sentinel;
236
237   if ((ht1->test_function != ht2->test_function) ||
238       (ht1->weakness      != ht2->weakness)      ||
239       (ht1->count         != ht2->count))
240     return 0;
241
242   depth++;
243
244   for (e = ht1->hentries, sentinel = e + ht1->size; e < sentinel; e++)
245     if (!HENTRY_CLEAR_P (e))
246       /* Look up the key in the other hash table, and compare the values. */
247       {
248         Lisp_Object value_in_other = Fgethash (e->key, hash_table2, Qunbound);
249         if (UNBOUNDP (value_in_other) ||
250             !internal_equal (e->value, value_in_other, depth))
251           return 0;             /* Give up */
252       }
253
254   return 1;
255 }
256
257 /* This is not a great hash function, but it _is_ correct and fast.
258    Examining all entries is too expensive, and examining a random
259    subset does not yield a correct hash function. */
260 static hashcode_t
261 hash_table_hash (Lisp_Object hash_table, int depth)
262 {
263   return XHASH_TABLE (hash_table)->count;
264 }
265
266 \f
267 /* Printing hash tables.
268
269    This is non-trivial, because we use a readable structure-style
270    syntax for hash tables.  This means that a typical hash table will be
271    readably printed in the form of:
272
273    #s(hash-table size 2 data (key1 value1 key2 value2))
274
275    The supported hash table structure keywords and their values are:
276    `test'             (eql (or nil), eq or equal)
277    `size'             (a natnum or nil)
278    `rehash-size'      (a float)
279    `rehash-threshold' (a float)
280    `weakness'         (nil, key, value, key-and-value, or key-or-value)
281    `data'             (a list)
282
283    If `print-readably' is nil, then a simpler syntax is used, for example
284
285    #<hash-table size 2/13 data (key1 value1 key2 value2) 0x874d>
286
287    The data is truncated to four pairs, and the rest is shown with
288    `...'.  This printer does not cons.  */
289
290
291 /* Print the data of the hash table.  This maps through a Lisp
292    hash table and prints key/value pairs using PRINTCHARFUN.  */
293 static void
294 print_hash_table_data (Lisp_Hash_Table *ht, Lisp_Object printcharfun)
295 {
296   int count = 0;
297   hentry *e, *sentinel;
298
299   write_c_string (" data (", printcharfun);
300
301   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
302     if (!HENTRY_CLEAR_P (e))
303       {
304         if (count > 0)
305           write_c_string (" ", printcharfun);
306         if (!print_readably && count > 3)
307           {
308             write_c_string ("...", printcharfun);
309             break;
310           }
311         print_internal (e->key, printcharfun, 1);
312         write_c_string (" ", printcharfun);
313         print_internal (e->value, printcharfun, 1);
314         count++;
315       }
316
317   write_c_string (")", printcharfun);
318 }
319
320 static void
321 print_hash_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
322 {
323   Lisp_Hash_Table *ht = XHASH_TABLE (obj);
324   char buf[128];
325
326   write_c_string (print_readably ? "#s(hash-table" : "#<hash-table",
327                   printcharfun);
328
329   /* These checks have a kludgy look to them, but they are safe.
330      Due to nature of hashing, you cannot use arbitrary
331      test functions anyway.  */
332   if (!ht->test_function)
333     write_c_string (" test eq", printcharfun);
334   else if (ht->test_function == lisp_object_equal_equal)
335     write_c_string (" test equal", printcharfun);
336   else if (ht->test_function == lisp_object_eql_equal)
337     DO_NOTHING;
338   else
339     abort ();
340
341   if (ht->count || !print_readably)
342     {
343       if (print_readably)
344         sprintf (buf, " size %lu", (unsigned long) ht->count);
345       else
346         sprintf (buf, " size %lu/%lu",
347                  (unsigned long) ht->count,
348                  (unsigned long) ht->size);
349       write_c_string (buf, printcharfun);
350     }
351
352   if (ht->weakness != HASH_TABLE_NON_WEAK)
353     {
354       sprintf (buf, " weakness %s",
355                (ht->weakness == HASH_TABLE_WEAK           ? "key-and-value" :
356                 ht->weakness == HASH_TABLE_KEY_WEAK       ? "key" :
357                 ht->weakness == HASH_TABLE_VALUE_WEAK     ? "value" :
358                 ht->weakness == HASH_TABLE_KEY_VALUE_WEAK ? "key-or-value" :
359                 "you-d-better-not-see-this"));
360       write_c_string (buf, printcharfun);
361     }
362
363   if (ht->count)
364     print_hash_table_data (ht, printcharfun);
365
366   if (print_readably)
367     write_c_string (")", printcharfun);
368   else
369     {
370       sprintf (buf, " 0x%x>", ht->header.uid);
371       write_c_string (buf, printcharfun);
372     }
373 }
374
375 static void
376 finalize_hash_table (void *header, int for_disksave)
377 {
378   if (!for_disksave)
379     {
380       Lisp_Hash_Table *ht = (Lisp_Hash_Table *) header;
381
382       xfree (ht->hentries);
383       ht->hentries = 0;
384     }
385 }
386
387 static const struct lrecord_description hentry_description_1[] = {
388   { XD_LISP_OBJECT, offsetof (hentry, key) },
389   { XD_LISP_OBJECT, offsetof (hentry, value) },
390   { XD_END }
391 };
392
393 static const struct struct_description hentry_description = {
394   sizeof (hentry),
395   hentry_description_1
396 };
397
398 const struct lrecord_description hash_table_description[] = {
399   { XD_SIZE_T,     offsetof (Lisp_Hash_Table, size) },
400   { XD_STRUCT_PTR, offsetof (Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), &hentry_description },
401   { XD_LO_LINK,    offsetof (Lisp_Hash_Table, next_weak) },
402   { XD_END }
403 };
404
405 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table,
406                                mark_hash_table, print_hash_table,
407                                finalize_hash_table,
408                                hash_table_equal, hash_table_hash,
409                                hash_table_description,
410                                Lisp_Hash_Table);
411
412 static Lisp_Hash_Table *
413 xhash_table (Lisp_Object hash_table)
414 {
415   if (!gc_in_progress)
416     CHECK_HASH_TABLE (hash_table);
417   check_hash_table_invariants (XHASH_TABLE (hash_table));
418   return XHASH_TABLE (hash_table);
419 }
420
421 \f
422 /************************************************************************/
423 /*                       Creation of Hash Tables                        */
424 /************************************************************************/
425
426 /* Creation of hash tables, without error-checking. */
427 static void
428 compute_hash_table_derived_values (Lisp_Hash_Table *ht)
429 {
430   ht->rehash_count = (size_t)
431     ((double) ht->size * ht->rehash_threshold);
432   ht->golden_ratio = (size_t)
433     ((double) ht->size * (.6180339887 / (double) sizeof (Lisp_Object)));
434 }
435
436 Lisp_Object
437 make_general_lisp_hash_table (enum hash_table_test test,
438                               size_t size,
439                               double rehash_size,
440                               double rehash_threshold,
441                               enum hash_table_weakness weakness)
442 {
443   Lisp_Object hash_table;
444   Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
445
446   switch (test)
447     {
448     case HASH_TABLE_EQ:
449       ht->test_function = 0;
450       ht->hash_function = 0;
451       break;
452
453     case HASH_TABLE_EQL:
454       ht->test_function = lisp_object_eql_equal;
455       ht->hash_function = lisp_object_eql_hash;
456       break;
457
458     case HASH_TABLE_EQUAL:
459       ht->test_function = lisp_object_equal_equal;
460       ht->hash_function = lisp_object_equal_hash;
461       break;
462
463     default:
464       abort ();
465     }
466
467   ht->weakness = weakness;
468
469   ht->rehash_size =
470     rehash_size > 1.0 ? rehash_size : HASH_TABLE_DEFAULT_REHASH_SIZE;
471
472   ht->rehash_threshold =
473     rehash_threshold > 0.0 ? rehash_threshold :
474     size > 4096 && !ht->test_function ? 0.7 : 0.6;
475
476   if (size < HASH_TABLE_MIN_SIZE)
477     size = HASH_TABLE_MIN_SIZE;
478   ht->size = hash_table_size ((size_t) (((double) size / ht->rehash_threshold)
479                                         + 1.0));
480   ht->count = 0;
481
482   compute_hash_table_derived_values (ht);
483
484   /* We leave room for one never-occupied sentinel hentry at the end.  */
485   ht->hentries = xnew_array (hentry, ht->size + 1);
486
487   {
488     hentry *e, *sentinel;
489     for (e = ht->hentries, sentinel = e + ht->size; e <= sentinel; e++)
490       CLEAR_HENTRY (e);
491   }
492
493   XSETHASH_TABLE (hash_table, ht);
494
495   if (weakness == HASH_TABLE_NON_WEAK)
496     ht->next_weak = Qunbound;
497   else
498     ht->next_weak = Vall_weak_hash_tables, Vall_weak_hash_tables = hash_table;
499
500   return hash_table;
501 }
502
503 Lisp_Object
504 make_lisp_hash_table (size_t size,
505                       enum hash_table_weakness weakness,
506                       enum hash_table_test test)
507 {
508   return make_general_lisp_hash_table (test, size, -1.0, -1.0, weakness);
509 }
510
511 /* Pretty reading of hash tables.
512
513    Here we use the existing structures mechanism (which is,
514    unfortunately, pretty cumbersome) for validating and instantiating
515    the hash tables.  The idea is that the side-effect of reading a
516    #s(hash-table PLIST) object is creation of a hash table with desired
517    properties, and that the hash table is returned.  */
518
519 /* Validation functions: each keyword provides its own validation
520    function.  The errors should maybe be continuable, but it is
521    unclear how this would cope with ERRB.  */
522 static int
523 hash_table_size_validate (Lisp_Object keyword, Lisp_Object value,
524                          Error_behavior errb)
525 {
526   if (NATNUMP (value))
527     return 1;
528
529   maybe_signal_error (Qwrong_type_argument, list2 (Qnatnump, value),
530                       Qhash_table, errb);
531   return 0;
532 }
533
534 static size_t
535 decode_hash_table_size (Lisp_Object obj)
536 {
537   return NILP (obj) ? HASH_TABLE_DEFAULT_SIZE : XINT (obj);
538 }
539
540 static int
541 hash_table_weakness_validate (Lisp_Object keyword, Lisp_Object value,
542                               Error_behavior errb)
543 {
544   if (EQ (value, Qnil))                 return 1;
545   if (EQ (value, Qt))                   return 1;
546   if (EQ (value, Qkey))                 return 1;
547   if (EQ (value, Qkey_and_value))       return 1;
548   if (EQ (value, Qkey_or_value))        return 1;
549   if (EQ (value, Qvalue))               return 1;
550
551   /* Following values are obsolete as of 19990901 in xemacs-21.2 */
552   if (EQ (value, Qnon_weak))            return 1;
553   if (EQ (value, Qweak))                return 1;
554   if (EQ (value, Qkey_weak))            return 1;
555   if (EQ (value, Qkey_or_value_weak))   return 1;
556   if (EQ (value, Qvalue_weak))          return 1;
557
558   maybe_signal_simple_error ("Invalid hash table weakness",
559                              value, Qhash_table, errb);
560   return 0;
561 }
562
563 static enum hash_table_weakness
564 decode_hash_table_weakness (Lisp_Object obj)
565 {
566   if (EQ (obj, Qnil))                   return HASH_TABLE_NON_WEAK;
567   if (EQ (obj, Qt))                     return HASH_TABLE_WEAK;
568   if (EQ (obj, Qkey_and_value))         return HASH_TABLE_WEAK;
569   if (EQ (obj, Qkey))                   return HASH_TABLE_KEY_WEAK;
570   if (EQ (obj, Qkey_or_value))          return HASH_TABLE_KEY_VALUE_WEAK;
571   if (EQ (obj, Qvalue))                 return HASH_TABLE_VALUE_WEAK;
572
573   /* Following values are obsolete as of 19990901 in xemacs-21.2 */
574   if (EQ (obj, Qnon_weak))              return HASH_TABLE_NON_WEAK;
575   if (EQ (obj, Qweak))                  return HASH_TABLE_WEAK;
576   if (EQ (obj, Qkey_weak))              return HASH_TABLE_KEY_WEAK;
577   if (EQ (obj, Qkey_or_value_weak))     return HASH_TABLE_KEY_VALUE_WEAK;
578   if (EQ (obj, Qvalue_weak))            return HASH_TABLE_VALUE_WEAK;
579
580   signal_simple_error ("Invalid hash table weakness", obj);
581   return HASH_TABLE_NON_WEAK; /* not reached */
582 }
583
584 static int
585 hash_table_test_validate (Lisp_Object keyword, Lisp_Object value,
586                          Error_behavior errb)
587 {
588   if (EQ (value, Qnil))   return 1;
589   if (EQ (value, Qeq))    return 1;
590   if (EQ (value, Qequal)) return 1;
591   if (EQ (value, Qeql))   return 1;
592
593   maybe_signal_simple_error ("Invalid hash table test",
594                              value, Qhash_table, errb);
595   return 0;
596 }
597
598 static enum hash_table_test
599 decode_hash_table_test (Lisp_Object obj)
600 {
601   if (EQ (obj, Qnil))   return HASH_TABLE_EQL;
602   if (EQ (obj, Qeq))    return HASH_TABLE_EQ;
603   if (EQ (obj, Qequal)) return HASH_TABLE_EQUAL;
604   if (EQ (obj, Qeql))   return HASH_TABLE_EQL;
605
606   signal_simple_error ("Invalid hash table test", obj);
607   return HASH_TABLE_EQ; /* not reached */
608 }
609
610 static int
611 hash_table_rehash_size_validate (Lisp_Object keyword, Lisp_Object value,
612                                  Error_behavior errb)
613 {
614   if (!FLOATP (value))
615     {
616       maybe_signal_error (Qwrong_type_argument, list2 (Qfloatp, value),
617                           Qhash_table, errb);
618       return 0;
619     }
620
621   {
622     double rehash_size = XFLOAT_DATA (value);
623     if (rehash_size <= 1.0)
624       {
625         maybe_signal_simple_error
626           ("Hash table rehash size must be greater than 1.0",
627            value, Qhash_table, errb);
628         return 0;
629       }
630   }
631
632   return 1;
633 }
634
635 static double
636 decode_hash_table_rehash_size (Lisp_Object rehash_size)
637 {
638   return NILP (rehash_size) ? -1.0 : XFLOAT_DATA (rehash_size);
639 }
640
641 static int
642 hash_table_rehash_threshold_validate (Lisp_Object keyword, Lisp_Object value,
643                                      Error_behavior errb)
644 {
645   if (!FLOATP (value))
646     {
647       maybe_signal_error (Qwrong_type_argument, list2 (Qfloatp, value),
648                           Qhash_table, errb);
649       return 0;
650     }
651
652   {
653     double rehash_threshold = XFLOAT_DATA (value);
654     if (rehash_threshold <= 0.0 || rehash_threshold >= 1.0)
655       {
656         maybe_signal_simple_error
657           ("Hash table rehash threshold must be between 0.0 and 1.0",
658            value, Qhash_table, errb);
659         return 0;
660       }
661   }
662
663   return 1;
664 }
665
666 static double
667 decode_hash_table_rehash_threshold (Lisp_Object rehash_threshold)
668 {
669   return NILP (rehash_threshold) ? -1.0 : XFLOAT_DATA (rehash_threshold);
670 }
671
672 static int
673 hash_table_data_validate (Lisp_Object keyword, Lisp_Object value,
674                          Error_behavior errb)
675 {
676   int len;
677
678   GET_EXTERNAL_LIST_LENGTH (value, len);
679
680   if (len & 1)
681     {
682       maybe_signal_simple_error
683         ("Hash table data must have alternating key/value pairs",
684          value, Qhash_table, errb);
685       return 0;
686     }
687   return 1;
688 }
689
690 /* The actual instantiation of a hash table.  This does practically no
691    error checking, because it relies on the fact that the paranoid
692    functions above have error-checked everything to the last details.
693    If this assumption is wrong, we will get a crash immediately (with
694    error-checking compiled in), and we'll know if there is a bug in
695    the structure mechanism.  So there.  */
696 static Lisp_Object
697 hash_table_instantiate (Lisp_Object plist)
698 {
699   Lisp_Object hash_table;
700   Lisp_Object test             = Qnil;
701   Lisp_Object size             = Qnil;
702   Lisp_Object rehash_size      = Qnil;
703   Lisp_Object rehash_threshold = Qnil;
704   Lisp_Object weakness         = Qnil;
705   Lisp_Object data             = Qnil;
706
707   while (!NILP (plist))
708     {
709       Lisp_Object key, value;
710       key   = XCAR (plist); plist = XCDR (plist);
711       value = XCAR (plist); plist = XCDR (plist);
712
713       if      (EQ (key, Qtest))             test             = value;
714       else if (EQ (key, Qsize))             size             = value;
715       else if (EQ (key, Qrehash_size))      rehash_size      = value;
716       else if (EQ (key, Qrehash_threshold)) rehash_threshold = value;
717       else if (EQ (key, Qweakness))         weakness         = value;
718       else if (EQ (key, Qdata))             data             = value;
719       else if (EQ (key, Qtype))/*obsolete*/ weakness         = value;
720       else
721         abort ();
722     }
723
724   /* Create the hash table.  */
725   hash_table = make_general_lisp_hash_table
726     (decode_hash_table_test (test),
727      decode_hash_table_size (size),
728      decode_hash_table_rehash_size (rehash_size),
729      decode_hash_table_rehash_threshold (rehash_threshold),
730      decode_hash_table_weakness (weakness));
731
732   /* I'm not sure whether this can GC, but better safe than sorry.  */
733   {
734     struct gcpro gcpro1;
735     GCPRO1 (hash_table);
736
737     /* And fill it with data.  */
738     while (!NILP (data))
739       {
740         Lisp_Object key, value;
741         key   = XCAR (data); data = XCDR (data);
742         value = XCAR (data); data = XCDR (data);
743         Fputhash (key, value, hash_table);
744       }
745     UNGCPRO;
746   }
747
748   return hash_table;
749 }
750
751 static void
752 structure_type_create_hash_table_structure_name (Lisp_Object structure_name)
753 {
754   struct structure_type *st;
755
756   st = define_structure_type (structure_name, 0, hash_table_instantiate);
757   define_structure_type_keyword (st, Qtest, hash_table_test_validate);
758   define_structure_type_keyword (st, Qsize, hash_table_size_validate);
759   define_structure_type_keyword (st, Qrehash_size, hash_table_rehash_size_validate);
760   define_structure_type_keyword (st, Qrehash_threshold, hash_table_rehash_threshold_validate);
761   define_structure_type_keyword (st, Qweakness, hash_table_weakness_validate);
762   define_structure_type_keyword (st, Qdata, hash_table_data_validate);
763
764   /* obsolete as of 19990901 in xemacs-21.2 */
765   define_structure_type_keyword (st, Qtype, hash_table_weakness_validate);
766 }
767
768 /* Create a built-in Lisp structure type named `hash-table'.
769    We make #s(hashtable ...) equivalent to #s(hash-table ...),
770    for backward compatibility.
771    This is called from emacs.c.  */
772 void
773 structure_type_create_hash_table (void)
774 {
775   structure_type_create_hash_table_structure_name (Qhash_table);
776   structure_type_create_hash_table_structure_name (Qhashtable); /* compat */
777 }
778
779 \f
780 /************************************************************************/
781 /*              Definition of Lisp-visible methods                      */
782 /************************************************************************/
783
784 DEFUN ("hash-table-p", Fhash_table_p, 1, 1, 0, /*
785 Return t if OBJECT is a hash table, else nil.
786 */
787        (object))
788 {
789   return HASH_TABLEP (object) ? Qt : Qnil;
790 }
791
792 DEFUN ("make-hash-table", Fmake_hash_table, 0, MANY, 0, /*
793 Return a new empty hash table object.
794 Use Common Lisp style keywords to specify hash table properties.
795  (make-hash-table &key test size rehash-size rehash-threshold weakness)
796
797 Keyword :test can be `eq', `eql' (default) or `equal'.
798 Comparison between keys is done using this function.
799 If speed is important, consider using `eq'.
800 When storing strings in the hash table, you will likely need to use `equal'.
801
802 Keyword :size specifies the number of keys likely to be inserted.
803 This number of entries can be inserted without enlarging the hash table.
804
805 Keyword :rehash-size must be a float greater than 1.0, and specifies
806 the factor by which to increase the size of the hash table when enlarging.
807
808 Keyword :rehash-threshold must be a float between 0.0 and 1.0,
809 and specifies the load factor of the hash table which triggers enlarging.
810
811 Non-standard keyword :weakness can be `nil' (default), `t', `key-and-value',
812 `key', `value' or `key-or-value'. `t' is an alias for `key-and-value'.
813
814 A key-and-value-weak hash table, also known as a fully-weak or simply
815 as a weak hash table, is one whose pointers do not count as GC
816 referents: for any key-value pair in the hash table, if the only
817 remaining pointer to either the key or the value is in a weak hash
818 table, then the pair will be removed from the hash table, and the key
819 and value collected.  A non-weak hash table (or any other pointer)
820 would prevent the object from being collected.
821
822 A key-weak hash table is similar to a fully-weak hash table except that
823 a key-value pair will be removed only if the key remains unmarked
824 outside of weak hash tables.  The pair will remain in the hash table if
825 the key is pointed to by something other than a weak hash table, even
826 if the value is not.
827
828 A value-weak hash table is similar to a fully-weak hash table except
829 that a key-value pair will be removed only if the value remains
830 unmarked outside of weak hash tables.  The pair will remain in the
831 hash table if the value is pointed to by something other than a weak
832 hash table, even if the key is not.
833
834 A key-or-value-weak hash table is similar to a fully-weak hash table except
835 that a key-value pair will be removed only if the value and the key remain
836 unmarked outside of weak hash tables.  The pair will remain in the
837 hash table if the value or key are pointed to by something other than a weak
838 hash table, even if the other is not.
839 */
840        (int nargs, Lisp_Object *args))
841 {
842   int i = 0;
843   Lisp_Object test             = Qnil;
844   Lisp_Object size             = Qnil;
845   Lisp_Object rehash_size      = Qnil;
846   Lisp_Object rehash_threshold = Qnil;
847   Lisp_Object weakness         = Qnil;
848
849   while (i + 1 < nargs)
850     {
851       Lisp_Object keyword = args[i++];
852       Lisp_Object value   = args[i++];
853
854       if      (EQ (keyword, Q_test))             test             = value;
855       else if (EQ (keyword, Q_size))             size             = value;
856       else if (EQ (keyword, Q_rehash_size))      rehash_size      = value;
857       else if (EQ (keyword, Q_rehash_threshold)) rehash_threshold = value;
858       else if (EQ (keyword, Q_weakness))         weakness         = value;
859       else if (EQ (keyword, Q_type))/*obsolete*/ weakness         = value;
860       else signal_simple_error ("Invalid hash table property keyword", keyword);
861     }
862
863   if (i < nargs)
864     signal_simple_error ("Hash table property requires a value", args[i]);
865
866 #define VALIDATE_VAR(var) \
867 if (!NILP (var)) hash_table_##var##_validate (Q##var, var, ERROR_ME);
868
869   VALIDATE_VAR (test);
870   VALIDATE_VAR (size);
871   VALIDATE_VAR (rehash_size);
872   VALIDATE_VAR (rehash_threshold);
873   VALIDATE_VAR (weakness);
874
875   return make_general_lisp_hash_table
876     (decode_hash_table_test (test),
877      decode_hash_table_size (size),
878      decode_hash_table_rehash_size (rehash_size),
879      decode_hash_table_rehash_threshold (rehash_threshold),
880      decode_hash_table_weakness (weakness));
881 }
882
883 DEFUN ("copy-hash-table", Fcopy_hash_table, 1, 1, 0, /*
884 Return a new hash table containing the same keys and values as HASH-TABLE.
885 The keys and values will not themselves be copied.
886 */
887        (hash_table))
888 {
889   const Lisp_Hash_Table *ht_old = xhash_table (hash_table);
890   Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
891
892   copy_lcrecord (ht, ht_old);
893
894   ht->hentries = xnew_array (hentry, ht_old->size + 1);
895   memcpy (ht->hentries, ht_old->hentries, (ht_old->size + 1) * sizeof (hentry));
896
897   XSETHASH_TABLE (hash_table, ht);
898
899   if (! EQ (ht->next_weak, Qunbound))
900     {
901       ht->next_weak = Vall_weak_hash_tables;
902       Vall_weak_hash_tables = hash_table;
903     }
904
905   return hash_table;
906 }
907
908 static void
909 resize_hash_table (Lisp_Hash_Table *ht, size_t new_size)
910 {
911   hentry *old_entries, *new_entries, *sentinel, *e;
912   size_t old_size;
913
914   old_size = ht->size;
915   ht->size = new_size;
916
917   old_entries = ht->hentries;
918
919   ht->hentries = xnew_array_and_zero (hentry, new_size + 1);
920   new_entries = ht->hentries;
921
922   compute_hash_table_derived_values (ht);
923
924   for (e = old_entries, sentinel = e + old_size; e < sentinel; e++)
925     if (!HENTRY_CLEAR_P (e))
926       {
927         hentry *probe = new_entries + HASH_CODE (e->key, ht);
928         LINEAR_PROBING_LOOP (probe, new_entries, new_size)
929           ;
930         *probe = *e;
931       }
932
933   if (!DUMPEDP (old_entries))
934     xfree (old_entries);
935 }
936
937 /* After a hash table has been saved to disk and later restored by the
938    portable dumper, it contains the same objects, but their addresses
939    and thus their HASH_CODEs have changed. */
940 void
941 pdump_reorganize_hash_table (Lisp_Object hash_table)
942 {
943   const Lisp_Hash_Table *ht = xhash_table (hash_table);
944   hentry *new_entries = xnew_array_and_zero (hentry, ht->size + 1);
945   hentry *e, *sentinel;
946
947   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
948     if (!HENTRY_CLEAR_P (e))
949       {
950         hentry *probe = new_entries + HASH_CODE (e->key, ht);
951         LINEAR_PROBING_LOOP (probe, new_entries, ht->size)
952           ;
953         *probe = *e;
954       }
955
956   memcpy (ht->hentries, new_entries, ht->size * sizeof (hentry));
957
958   xfree (new_entries);
959 }
960
961 static void
962 enlarge_hash_table (Lisp_Hash_Table *ht)
963 {
964   size_t new_size =
965     hash_table_size ((size_t) ((double) ht->size * ht->rehash_size));
966   resize_hash_table (ht, new_size);
967 }
968
969 static hentry *
970 find_hentry (Lisp_Object key, const Lisp_Hash_Table *ht)
971 {
972   hash_table_test_function_t test_function = ht->test_function;
973   hentry *entries = ht->hentries;
974   hentry *probe = entries + HASH_CODE (key, ht);
975
976   LINEAR_PROBING_LOOP (probe, entries, ht->size)
977     if (KEYS_EQUAL_P (probe->key, key, test_function))
978       break;
979
980   return probe;
981 }
982
983 DEFUN ("gethash", Fgethash, 2, 3, 0, /*
984 Find hash value for KEY in HASH-TABLE.
985 If there is no corresponding value, return DEFAULT (which defaults to nil).
986 */
987        (key, hash_table, default_))
988 {
989   const Lisp_Hash_Table *ht = xhash_table (hash_table);
990   hentry *e = find_hentry (key, ht);
991
992   return HENTRY_CLEAR_P (e) ? default_ : e->value;
993 }
994
995 DEFUN ("puthash", Fputhash, 3, 3, 0, /*
996 Hash KEY to VALUE in HASH-TABLE.
997 */
998        (key, value, hash_table))
999 {
1000   Lisp_Hash_Table *ht = xhash_table (hash_table);
1001   hentry *e = find_hentry (key, ht);
1002
1003   if (!HENTRY_CLEAR_P (e))
1004     return e->value = value;
1005
1006   e->key   = key;
1007   e->value = value;
1008
1009   if (++ht->count >= ht->rehash_count)
1010     enlarge_hash_table (ht);
1011
1012   return value;
1013 }
1014
1015 /* Remove hentry pointed at by PROBE.
1016    Subsequent entries are removed and reinserted.
1017    We don't use tombstones - too wasteful.  */
1018 static void
1019 remhash_1 (Lisp_Hash_Table *ht, hentry *entries, hentry *probe)
1020 {
1021   size_t size = ht->size;
1022   CLEAR_HENTRY (probe);
1023   probe++;
1024   ht->count--;
1025
1026   LINEAR_PROBING_LOOP (probe, entries, size)
1027     {
1028       Lisp_Object key = probe->key;
1029       hentry *probe2 = entries + HASH_CODE (key, ht);
1030       LINEAR_PROBING_LOOP (probe2, entries, size)
1031         if (EQ (probe2->key, key))
1032           /* hentry at probe doesn't need to move. */
1033           goto continue_outer_loop;
1034       /* Move hentry from probe to new home at probe2. */
1035       *probe2 = *probe;
1036       CLEAR_HENTRY (probe);
1037     continue_outer_loop: continue;
1038     }
1039 }
1040
1041 DEFUN ("remhash", Fremhash, 2, 2, 0, /*
1042 Remove the entry for KEY from HASH-TABLE.
1043 Do nothing if there is no entry for KEY in HASH-TABLE.
1044 */
1045        (key, hash_table))
1046 {
1047   Lisp_Hash_Table *ht = xhash_table (hash_table);
1048   hentry *e = find_hentry (key, ht);
1049
1050   if (HENTRY_CLEAR_P (e))
1051     return Qnil;
1052
1053   remhash_1 (ht, ht->hentries, e);
1054   return Qt;
1055 }
1056
1057 DEFUN ("clrhash", Fclrhash, 1, 1, 0, /*
1058 Remove all entries from HASH-TABLE, leaving it empty.
1059 */
1060        (hash_table))
1061 {
1062   Lisp_Hash_Table *ht = xhash_table (hash_table);
1063   hentry *e, *sentinel;
1064
1065   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1066     CLEAR_HENTRY (e);
1067   ht->count = 0;
1068
1069   return hash_table;
1070 }
1071
1072 /************************************************************************/
1073 /*                          Accessor Functions                          */
1074 /************************************************************************/
1075
1076 DEFUN ("hash-table-count", Fhash_table_count, 1, 1, 0, /*
1077 Return the number of entries in HASH-TABLE.
1078 */
1079        (hash_table))
1080 {
1081   return make_int (xhash_table (hash_table)->count);
1082 }
1083
1084 DEFUN ("hash-table-test", Fhash_table_test, 1, 1, 0, /*
1085 Return the test function of HASH-TABLE.
1086 This can be one of `eq', `eql' or `equal'.
1087 */
1088        (hash_table))
1089 {
1090   hash_table_test_function_t fun = xhash_table (hash_table)->test_function;
1091
1092   return (fun == lisp_object_eql_equal   ? Qeql   :
1093           fun == lisp_object_equal_equal ? Qequal :
1094           Qeq);
1095 }
1096
1097 DEFUN ("hash-table-size", Fhash_table_size, 1, 1, 0, /*
1098 Return the size of HASH-TABLE.
1099 This is the current number of slots in HASH-TABLE, whether occupied or not.
1100 */
1101        (hash_table))
1102 {
1103   return make_int (xhash_table (hash_table)->size);
1104 }
1105
1106 DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size, 1, 1, 0, /*
1107 Return the current rehash size of HASH-TABLE.
1108 This is a float greater than 1.0; the factor by which HASH-TABLE
1109 is enlarged when the rehash threshold is exceeded.
1110 */
1111        (hash_table))
1112 {
1113   return make_float (xhash_table (hash_table)->rehash_size);
1114 }
1115
1116 DEFUN ("hash-table-rehash-threshold", Fhash_table_rehash_threshold, 1, 1, 0, /*
1117 Return the current rehash threshold of HASH-TABLE.
1118 This is a float between 0.0 and 1.0; the maximum `load factor' of HASH-TABLE,
1119 beyond which the HASH-TABLE is enlarged by rehashing.
1120 */
1121        (hash_table))
1122 {
1123   return make_float (xhash_table (hash_table)->rehash_threshold);
1124 }
1125
1126 DEFUN ("hash-table-weakness", Fhash_table_weakness, 1, 1, 0, /*
1127 Return the weakness of HASH-TABLE.
1128 This can be one of `nil', `key-and-value', `key-or-value', `key' or `value'.
1129 */
1130        (hash_table))
1131 {
1132   switch (xhash_table (hash_table)->weakness)
1133     {
1134     case HASH_TABLE_WEAK:               return Qkey_and_value;
1135     case HASH_TABLE_KEY_WEAK:           return Qkey;
1136     case HASH_TABLE_KEY_VALUE_WEAK:     return Qkey_or_value;
1137     case HASH_TABLE_VALUE_WEAK:         return Qvalue;
1138     default:                            return Qnil;
1139     }
1140 }
1141
1142 /* obsolete as of 19990901 in xemacs-21.2 */
1143 DEFUN ("hash-table-type", Fhash_table_type, 1, 1, 0, /*
1144 Return the type of HASH-TABLE.
1145 This can be one of `non-weak', `weak', `key-weak' or `value-weak'.
1146 */
1147        (hash_table))
1148 {
1149   switch (xhash_table (hash_table)->weakness)
1150     {
1151     case HASH_TABLE_WEAK:               return Qweak;
1152     case HASH_TABLE_KEY_WEAK:           return Qkey_weak;
1153     case HASH_TABLE_KEY_VALUE_WEAK:     return Qkey_or_value_weak;
1154     case HASH_TABLE_VALUE_WEAK:         return Qvalue_weak;
1155     default:                            return Qnon_weak;
1156     }
1157 }
1158
1159 /************************************************************************/
1160 /*                          Mapping Functions                           */
1161 /************************************************************************/
1162 DEFUN ("maphash", Fmaphash, 2, 2, 0, /*
1163 Map FUNCTION over entries in HASH-TABLE, calling it with two args,
1164 each key and value in HASH-TABLE.
1165
1166 FUNCTION may not modify HASH-TABLE, with the one exception that FUNCTION
1167 may remhash or puthash the entry currently being processed by FUNCTION.
1168 */
1169        (function, hash_table))
1170 {
1171   const Lisp_Hash_Table *ht = xhash_table (hash_table);
1172   const hentry *e, *sentinel;
1173
1174   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1175     if (!HENTRY_CLEAR_P (e))
1176       {
1177         Lisp_Object args[3], key;
1178       again:
1179         key = e->key;
1180         args[0] = function;
1181         args[1] = key;
1182         args[2] = e->value;
1183         Ffuncall (countof (args), args);
1184         /* Has FUNCTION done a remhash? */
1185         if (!EQ (key, e->key) && !HENTRY_CLEAR_P (e))
1186           goto again;
1187       }
1188
1189   return Qnil;
1190 }
1191
1192 /* Map *C* function FUNCTION over the elements of a lisp hash table. */
1193 void
1194 elisp_maphash (maphash_function_t function,
1195                Lisp_Object hash_table, void *extra_arg)
1196 {
1197   const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1198   const hentry *e, *sentinel;
1199
1200   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1201     if (!HENTRY_CLEAR_P (e))
1202       {
1203         Lisp_Object key;
1204       again:
1205         key = e->key;
1206         if (function (key, e->value, extra_arg))
1207           return;
1208         /* Has FUNCTION done a remhash? */
1209         if (!EQ (key, e->key) && !HENTRY_CLEAR_P (e))
1210           goto again;
1211       }
1212 }
1213
1214 /* Remove all elements of a lisp hash table satisfying *C* predicate PREDICATE. */
1215 void
1216 elisp_map_remhash (maphash_function_t predicate,
1217                    Lisp_Object hash_table, void *extra_arg)
1218 {
1219   Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1220   hentry *e, *entries, *sentinel;
1221
1222   for (e = entries = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1223     if (!HENTRY_CLEAR_P (e))
1224       {
1225       again:
1226         if (predicate (e->key, e->value, extra_arg))
1227           {
1228             remhash_1 (ht, entries, e);
1229             if (!HENTRY_CLEAR_P (e))
1230               goto again;
1231           }
1232       }
1233 }
1234
1235 \f
1236 /************************************************************************/
1237 /*                 garbage collecting weak hash tables                  */
1238 /************************************************************************/
1239 #define MARK_OBJ(obj) do {              \
1240   Lisp_Object mo_obj = (obj);           \
1241   if (!marked_p (mo_obj))               \
1242     {                                   \
1243       mark_object (mo_obj);             \
1244       did_mark = 1;                     \
1245     }                                   \
1246 } while (0)
1247
1248
1249 /* Complete the marking for semi-weak hash tables. */
1250 int
1251 finish_marking_weak_hash_tables (void)
1252 {
1253   Lisp_Object hash_table;
1254   int did_mark = 0;
1255
1256   for (hash_table = Vall_weak_hash_tables;
1257        !NILP (hash_table);
1258        hash_table = XHASH_TABLE (hash_table)->next_weak)
1259     {
1260       const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1261       const hentry *e = ht->hentries;
1262       const hentry *sentinel = e + ht->size;
1263
1264       if (! marked_p (hash_table))
1265         /* The hash table is probably garbage.  Ignore it. */
1266         continue;
1267
1268       /* Now, scan over all the pairs.  For all pairs that are
1269          half-marked, we may need to mark the other half if we're
1270          keeping this pair. */
1271       switch (ht->weakness)
1272         {
1273         case HASH_TABLE_KEY_WEAK:
1274           for (; e < sentinel; e++)
1275             if (!HENTRY_CLEAR_P (e))
1276               if (marked_p (e->key))
1277                 MARK_OBJ (e->value);
1278           break;
1279
1280         case HASH_TABLE_VALUE_WEAK:
1281           for (; e < sentinel; e++)
1282             if (!HENTRY_CLEAR_P (e))
1283               if (marked_p (e->value))
1284                 MARK_OBJ (e->key);
1285           break;
1286
1287         case HASH_TABLE_KEY_VALUE_WEAK:
1288           for (; e < sentinel; e++)
1289             if (!HENTRY_CLEAR_P (e))
1290               {
1291                 if (marked_p (e->value))
1292                   MARK_OBJ (e->key);
1293                 else if (marked_p (e->key))
1294                   MARK_OBJ (e->value);
1295               }
1296           break;
1297
1298         case HASH_TABLE_KEY_CAR_WEAK:
1299           for (; e < sentinel; e++)
1300             if (!HENTRY_CLEAR_P (e))
1301               if (!CONSP (e->key) || marked_p (XCAR (e->key)))
1302                 {
1303                   MARK_OBJ (e->key);
1304                   MARK_OBJ (e->value);
1305                 }
1306           break;
1307
1308         case HASH_TABLE_VALUE_CAR_WEAK:
1309           for (; e < sentinel; e++)
1310             if (!HENTRY_CLEAR_P (e))
1311               if (!CONSP (e->value) || marked_p (XCAR (e->value)))
1312                 {
1313                   MARK_OBJ (e->key);
1314                   MARK_OBJ (e->value);
1315                 }
1316           break;
1317
1318         default:
1319           break;
1320         }
1321     }
1322
1323   return did_mark;
1324 }
1325
1326 void
1327 prune_weak_hash_tables (void)
1328 {
1329   Lisp_Object hash_table, prev = Qnil;
1330   for (hash_table = Vall_weak_hash_tables;
1331        !NILP (hash_table);
1332        hash_table = XHASH_TABLE (hash_table)->next_weak)
1333     {
1334       if (! marked_p (hash_table))
1335         {
1336           /* This hash table itself is garbage.  Remove it from the list. */
1337           if (NILP (prev))
1338             Vall_weak_hash_tables = XHASH_TABLE (hash_table)->next_weak;
1339           else
1340             XHASH_TABLE (prev)->next_weak = XHASH_TABLE (hash_table)->next_weak;
1341         }
1342       else
1343         {
1344           /* Now, scan over all the pairs.  Remove all of the pairs
1345              in which the key or value, or both, is unmarked
1346              (depending on the weakness of the hash table). */
1347           Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1348           hentry *entries = ht->hentries;
1349           hentry *sentinel = entries + ht->size;
1350           hentry *e;
1351
1352           for (e = entries; e < sentinel; e++)
1353             if (!HENTRY_CLEAR_P (e))
1354               {
1355               again:
1356                 if (!marked_p (e->key) || !marked_p (e->value))
1357                   {
1358                     remhash_1 (ht, entries, e);
1359                     if (!HENTRY_CLEAR_P (e))
1360                       goto again;
1361                   }
1362               }
1363
1364           prev = hash_table;
1365         }
1366     }
1367 }
1368
1369 /* Return a hash value for an array of Lisp_Objects of size SIZE. */
1370
1371 hashcode_t
1372 internal_array_hash (Lisp_Object *arr, int size, int depth)
1373 {
1374   int i;
1375   hashcode_t hash = 0;
1376   depth++;
1377
1378   if (size <= 5)
1379     {
1380       for (i = 0; i < size; i++)
1381         hash = HASH2 (hash, internal_hash (arr[i], depth));
1382       return hash;
1383     }
1384
1385   /* just pick five elements scattered throughout the array.
1386      A slightly better approach would be to offset by some
1387      noise factor from the points chosen below. */
1388   for (i = 0; i < 5; i++)
1389     hash = HASH2 (hash, internal_hash (arr[i*size/5], depth));
1390
1391   return hash;
1392 }
1393
1394 /* Return a hash value for a Lisp_Object.  This is for use when hashing
1395    objects with the comparison being `equal' (for `eq', you can just
1396    use the Lisp_Object itself as the hash value).  You need to make a
1397    tradeoff between the speed of the hash function and how good the
1398    hashing is.  In particular, the hash function needs to be FAST,
1399    so you can't just traipse down the whole tree hashing everything
1400    together.  Most of the time, objects will differ in the first
1401    few elements you hash.  Thus, we only go to a short depth (5)
1402    and only hash at most 5 elements out of a vector.  Theoretically
1403    we could still take 5^5 time (a big big number) to compute a
1404    hash, but practically this won't ever happen. */
1405
1406 hashcode_t
1407 internal_hash (Lisp_Object obj, int depth)
1408 {
1409   if (depth > 5)
1410     return 0;
1411   if (CONSP (obj))
1412     {
1413       /* no point in worrying about tail recursion, since we're not
1414          going very deep */
1415       return HASH2 (internal_hash (XCAR (obj), depth + 1),
1416                     internal_hash (XCDR (obj), depth + 1));
1417     }
1418   if (STRINGP (obj))
1419     {
1420       return hash_string (XSTRING_DATA (obj), XSTRING_LENGTH (obj));
1421     }
1422   if (LRECORDP (obj))
1423     {
1424       const struct lrecord_implementation
1425         *imp = XRECORD_LHEADER_IMPLEMENTATION (obj);
1426       if (imp->hash)
1427         return imp->hash (obj, depth);
1428     }
1429
1430   return LISP_HASH (obj);
1431 }
1432
1433 DEFUN ("sxhash", Fsxhash, 1, 1, 0, /*
1434 Return a hash value for OBJECT.
1435 \(equal obj1 obj2) implies (= (sxhash obj1) (sxhash obj2)).
1436 */
1437        (object))
1438 {
1439   return make_int (internal_hash (object, 0));
1440 }
1441
1442 #if 0
1443 xxDEFUN ("internal-hash-value", Finternal_hash_value, 1, 1, 0, /*
1444 Hash value of OBJECT.  For debugging.
1445 The value is returned as (HIGH . LOW).
1446 */
1447        (object))
1448 {
1449   /* This function is pretty 32bit-centric. */
1450   hashcode_t hash = internal_hash (object, 0);
1451   return Fcons (hash >> 16, hash & 0xffff);
1452 }
1453 #endif
1454
1455 \f
1456 /************************************************************************/
1457 /*                            initialization                            */
1458 /************************************************************************/
1459
1460 void
1461 syms_of_elhash (void)
1462 {
1463   INIT_LRECORD_IMPLEMENTATION (hash_table);
1464
1465   DEFSUBR (Fhash_table_p);
1466   DEFSUBR (Fmake_hash_table);
1467   DEFSUBR (Fcopy_hash_table);
1468   DEFSUBR (Fgethash);
1469   DEFSUBR (Fremhash);
1470   DEFSUBR (Fputhash);
1471   DEFSUBR (Fclrhash);
1472   DEFSUBR (Fmaphash);
1473   DEFSUBR (Fhash_table_count);
1474   DEFSUBR (Fhash_table_test);
1475   DEFSUBR (Fhash_table_size);
1476   DEFSUBR (Fhash_table_rehash_size);
1477   DEFSUBR (Fhash_table_rehash_threshold);
1478   DEFSUBR (Fhash_table_weakness);
1479   DEFSUBR (Fhash_table_type); /* obsolete */
1480   DEFSUBR (Fsxhash);
1481 #if 0
1482   DEFSUBR (Finternal_hash_value);
1483 #endif
1484
1485   defsymbol (&Qhash_tablep, "hash-table-p");
1486   defsymbol (&Qhash_table, "hash-table");
1487   defsymbol (&Qhashtable, "hashtable");
1488   defsymbol (&Qweakness, "weakness");
1489   defsymbol (&Qvalue, "value");
1490   defsymbol (&Qkey_or_value, "key-or-value");
1491   defsymbol (&Qkey_and_value, "key-and-value");
1492   defsymbol (&Qrehash_size, "rehash-size");
1493   defsymbol (&Qrehash_threshold, "rehash-threshold");
1494
1495   defsymbol (&Qweak, "weak");             /* obsolete */
1496   defsymbol (&Qkey_weak, "key-weak");     /* obsolete */
1497   defsymbol (&Qkey_or_value_weak, "key-or-value-weak");    /* obsolete */
1498   defsymbol (&Qvalue_weak, "value-weak"); /* obsolete */
1499   defsymbol (&Qnon_weak, "non-weak");     /* obsolete */
1500
1501   defkeyword (&Q_test, ":test");
1502   defkeyword (&Q_size, ":size");
1503   defkeyword (&Q_rehash_size, ":rehash-size");
1504   defkeyword (&Q_rehash_threshold, ":rehash-threshold");
1505   defkeyword (&Q_weakness, ":weakness");
1506   defkeyword (&Q_type, ":type"); /* obsolete */
1507 }
1508
1509 void
1510 vars_of_elhash (void)
1511 {
1512   /* This must NOT be staticpro'd */
1513   Vall_weak_hash_tables = Qnil;
1514   pdump_wire_list (&Vall_weak_hash_tables);
1515 }