XEmacs 21.2.41 "Polyhymnia".
[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_standard_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   hash_table_hash_function_t hash_function =  0;
444   hash_table_test_function_t test_function = 0;
445
446   switch (test)
447     {
448     case HASH_TABLE_EQ:
449       test_function = 0;
450       hash_function = 0;
451       break;
452
453     case HASH_TABLE_EQL:
454       test_function = lisp_object_eql_equal;
455       hash_function = lisp_object_eql_hash;
456       break;
457
458     case HASH_TABLE_EQUAL:
459       test_function = lisp_object_equal_equal;
460       hash_function = lisp_object_equal_hash;
461       break;
462
463     default:
464       abort ();
465     }
466
467   return make_general_lisp_hash_table (hash_function, test_function,
468                                        size, rehash_size, rehash_threshold,
469                                        weakness);
470 }
471
472 Lisp_Object
473 make_general_lisp_hash_table (hash_table_hash_function_t hash_function,
474                               hash_table_test_function_t test_function,
475                               size_t size,
476                               double rehash_size,
477                               double rehash_threshold,
478                               enum hash_table_weakness weakness)
479 {
480   Lisp_Object hash_table;
481   Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
482
483   ht->test_function = test_function;
484   ht->hash_function = hash_function;
485   ht->weakness = weakness;
486
487   ht->rehash_size =
488     rehash_size > 1.0 ? rehash_size : HASH_TABLE_DEFAULT_REHASH_SIZE;
489
490   ht->rehash_threshold =
491     rehash_threshold > 0.0 ? rehash_threshold :
492     size > 4096 && !ht->test_function ? 0.7 : 0.6;
493
494   if (size < HASH_TABLE_MIN_SIZE)
495     size = HASH_TABLE_MIN_SIZE;
496   ht->size = hash_table_size ((size_t) (((double) size / ht->rehash_threshold)
497                                         + 1.0));
498   ht->count = 0;
499
500   compute_hash_table_derived_values (ht);
501
502   /* We leave room for one never-occupied sentinel hentry at the end.  */
503   ht->hentries = xnew_array (hentry, ht->size + 1);
504
505   {
506     hentry *e, *sentinel;
507     for (e = ht->hentries, sentinel = e + ht->size; e <= sentinel; e++)
508       CLEAR_HENTRY (e);
509   }
510
511   XSETHASH_TABLE (hash_table, ht);
512
513   if (weakness == HASH_TABLE_NON_WEAK)
514     ht->next_weak = Qunbound;
515   else
516     ht->next_weak = Vall_weak_hash_tables, Vall_weak_hash_tables = hash_table;
517
518   return hash_table;
519 }
520
521 Lisp_Object
522 make_lisp_hash_table (size_t size,
523                       enum hash_table_weakness weakness,
524                       enum hash_table_test test)
525 {
526   return make_standard_lisp_hash_table (test, size, -1.0, -1.0, weakness);
527 }
528
529 /* Pretty reading of hash tables.
530
531    Here we use the existing structures mechanism (which is,
532    unfortunately, pretty cumbersome) for validating and instantiating
533    the hash tables.  The idea is that the side-effect of reading a
534    #s(hash-table PLIST) object is creation of a hash table with desired
535    properties, and that the hash table is returned.  */
536
537 /* Validation functions: each keyword provides its own validation
538    function.  The errors should maybe be continuable, but it is
539    unclear how this would cope with ERRB.  */
540 static int
541 hash_table_size_validate (Lisp_Object keyword, Lisp_Object value,
542                          Error_behavior errb)
543 {
544   if (NATNUMP (value))
545     return 1;
546
547   maybe_signal_error (Qwrong_type_argument, list2 (Qnatnump, value),
548                       Qhash_table, errb);
549   return 0;
550 }
551
552 static size_t
553 decode_hash_table_size (Lisp_Object obj)
554 {
555   return NILP (obj) ? HASH_TABLE_DEFAULT_SIZE : XINT (obj);
556 }
557
558 static int
559 hash_table_weakness_validate (Lisp_Object keyword, Lisp_Object value,
560                               Error_behavior errb)
561 {
562   if (EQ (value, Qnil))                 return 1;
563   if (EQ (value, Qt))                   return 1;
564   if (EQ (value, Qkey))                 return 1;
565   if (EQ (value, Qkey_and_value))       return 1;
566   if (EQ (value, Qkey_or_value))        return 1;
567   if (EQ (value, Qvalue))               return 1;
568
569   /* Following values are obsolete as of 19990901 in xemacs-21.2 */
570   if (EQ (value, Qnon_weak))            return 1;
571   if (EQ (value, Qweak))                return 1;
572   if (EQ (value, Qkey_weak))            return 1;
573   if (EQ (value, Qkey_or_value_weak))   return 1;
574   if (EQ (value, Qvalue_weak))          return 1;
575
576   maybe_signal_simple_error ("Invalid hash table weakness",
577                              value, Qhash_table, errb);
578   return 0;
579 }
580
581 static enum hash_table_weakness
582 decode_hash_table_weakness (Lisp_Object obj)
583 {
584   if (EQ (obj, Qnil))                   return HASH_TABLE_NON_WEAK;
585   if (EQ (obj, Qt))                     return HASH_TABLE_WEAK;
586   if (EQ (obj, Qkey_and_value))         return HASH_TABLE_WEAK;
587   if (EQ (obj, Qkey))                   return HASH_TABLE_KEY_WEAK;
588   if (EQ (obj, Qkey_or_value))          return HASH_TABLE_KEY_VALUE_WEAK;
589   if (EQ (obj, Qvalue))                 return HASH_TABLE_VALUE_WEAK;
590
591   /* Following values are obsolete as of 19990901 in xemacs-21.2 */
592   if (EQ (obj, Qnon_weak))              return HASH_TABLE_NON_WEAK;
593   if (EQ (obj, Qweak))                  return HASH_TABLE_WEAK;
594   if (EQ (obj, Qkey_weak))              return HASH_TABLE_KEY_WEAK;
595   if (EQ (obj, Qkey_or_value_weak))     return HASH_TABLE_KEY_VALUE_WEAK;
596   if (EQ (obj, Qvalue_weak))            return HASH_TABLE_VALUE_WEAK;
597
598   signal_simple_error ("Invalid hash table weakness", obj);
599   return HASH_TABLE_NON_WEAK; /* not reached */
600 }
601
602 static int
603 hash_table_test_validate (Lisp_Object keyword, Lisp_Object value,
604                          Error_behavior errb)
605 {
606   if (EQ (value, Qnil))   return 1;
607   if (EQ (value, Qeq))    return 1;
608   if (EQ (value, Qequal)) return 1;
609   if (EQ (value, Qeql))   return 1;
610
611   maybe_signal_simple_error ("Invalid hash table test",
612                              value, Qhash_table, errb);
613   return 0;
614 }
615
616 static enum hash_table_test
617 decode_hash_table_test (Lisp_Object obj)
618 {
619   if (EQ (obj, Qnil))   return HASH_TABLE_EQL;
620   if (EQ (obj, Qeq))    return HASH_TABLE_EQ;
621   if (EQ (obj, Qequal)) return HASH_TABLE_EQUAL;
622   if (EQ (obj, Qeql))   return HASH_TABLE_EQL;
623
624   signal_simple_error ("Invalid hash table test", obj);
625   return HASH_TABLE_EQ; /* not reached */
626 }
627
628 static int
629 hash_table_rehash_size_validate (Lisp_Object keyword, Lisp_Object value,
630                                  Error_behavior errb)
631 {
632   if (!FLOATP (value))
633     {
634       maybe_signal_error (Qwrong_type_argument, list2 (Qfloatp, value),
635                           Qhash_table, errb);
636       return 0;
637     }
638
639   {
640     double rehash_size = XFLOAT_DATA (value);
641     if (rehash_size <= 1.0)
642       {
643         maybe_signal_simple_error
644           ("Hash table rehash size must be greater than 1.0",
645            value, Qhash_table, errb);
646         return 0;
647       }
648   }
649
650   return 1;
651 }
652
653 static double
654 decode_hash_table_rehash_size (Lisp_Object rehash_size)
655 {
656   return NILP (rehash_size) ? -1.0 : XFLOAT_DATA (rehash_size);
657 }
658
659 static int
660 hash_table_rehash_threshold_validate (Lisp_Object keyword, Lisp_Object value,
661                                      Error_behavior errb)
662 {
663   if (!FLOATP (value))
664     {
665       maybe_signal_error (Qwrong_type_argument, list2 (Qfloatp, value),
666                           Qhash_table, errb);
667       return 0;
668     }
669
670   {
671     double rehash_threshold = XFLOAT_DATA (value);
672     if (rehash_threshold <= 0.0 || rehash_threshold >= 1.0)
673       {
674         maybe_signal_simple_error
675           ("Hash table rehash threshold must be between 0.0 and 1.0",
676            value, Qhash_table, errb);
677         return 0;
678       }
679   }
680
681   return 1;
682 }
683
684 static double
685 decode_hash_table_rehash_threshold (Lisp_Object rehash_threshold)
686 {
687   return NILP (rehash_threshold) ? -1.0 : XFLOAT_DATA (rehash_threshold);
688 }
689
690 static int
691 hash_table_data_validate (Lisp_Object keyword, Lisp_Object value,
692                          Error_behavior errb)
693 {
694   int len;
695
696   GET_EXTERNAL_LIST_LENGTH (value, len);
697
698   if (len & 1)
699     {
700       maybe_signal_simple_error
701         ("Hash table data must have alternating key/value pairs",
702          value, Qhash_table, errb);
703       return 0;
704     }
705   return 1;
706 }
707
708 /* The actual instantiation of a hash table.  This does practically no
709    error checking, because it relies on the fact that the paranoid
710    functions above have error-checked everything to the last details.
711    If this assumption is wrong, we will get a crash immediately (with
712    error-checking compiled in), and we'll know if there is a bug in
713    the structure mechanism.  So there.  */
714 static Lisp_Object
715 hash_table_instantiate (Lisp_Object plist)
716 {
717   Lisp_Object hash_table;
718   Lisp_Object test             = Qnil;
719   Lisp_Object size             = Qnil;
720   Lisp_Object rehash_size      = Qnil;
721   Lisp_Object rehash_threshold = Qnil;
722   Lisp_Object weakness         = Qnil;
723   Lisp_Object data             = Qnil;
724
725   while (!NILP (plist))
726     {
727       Lisp_Object key, value;
728       key   = XCAR (plist); plist = XCDR (plist);
729       value = XCAR (plist); plist = XCDR (plist);
730
731       if      (EQ (key, Qtest))             test             = value;
732       else if (EQ (key, Qsize))             size             = value;
733       else if (EQ (key, Qrehash_size))      rehash_size      = value;
734       else if (EQ (key, Qrehash_threshold)) rehash_threshold = value;
735       else if (EQ (key, Qweakness))         weakness         = value;
736       else if (EQ (key, Qdata))             data             = value;
737       else if (EQ (key, Qtype))/*obsolete*/ weakness         = value;
738       else
739         abort ();
740     }
741
742   /* Create the hash table.  */
743   hash_table = make_standard_lisp_hash_table
744     (decode_hash_table_test (test),
745      decode_hash_table_size (size),
746      decode_hash_table_rehash_size (rehash_size),
747      decode_hash_table_rehash_threshold (rehash_threshold),
748      decode_hash_table_weakness (weakness));
749
750   /* I'm not sure whether this can GC, but better safe than sorry.  */
751   {
752     struct gcpro gcpro1;
753     GCPRO1 (hash_table);
754
755     /* And fill it with data.  */
756     while (!NILP (data))
757       {
758         Lisp_Object key, value;
759         key   = XCAR (data); data = XCDR (data);
760         value = XCAR (data); data = XCDR (data);
761         Fputhash (key, value, hash_table);
762       }
763     UNGCPRO;
764   }
765
766   return hash_table;
767 }
768
769 static void
770 structure_type_create_hash_table_structure_name (Lisp_Object structure_name)
771 {
772   struct structure_type *st;
773
774   st = define_structure_type (structure_name, 0, hash_table_instantiate);
775   define_structure_type_keyword (st, Qtest, hash_table_test_validate);
776   define_structure_type_keyword (st, Qsize, hash_table_size_validate);
777   define_structure_type_keyword (st, Qrehash_size, hash_table_rehash_size_validate);
778   define_structure_type_keyword (st, Qrehash_threshold, hash_table_rehash_threshold_validate);
779   define_structure_type_keyword (st, Qweakness, hash_table_weakness_validate);
780   define_structure_type_keyword (st, Qdata, hash_table_data_validate);
781
782   /* obsolete as of 19990901 in xemacs-21.2 */
783   define_structure_type_keyword (st, Qtype, hash_table_weakness_validate);
784 }
785
786 /* Create a built-in Lisp structure type named `hash-table'.
787    We make #s(hashtable ...) equivalent to #s(hash-table ...),
788    for backward compatibility.
789    This is called from emacs.c.  */
790 void
791 structure_type_create_hash_table (void)
792 {
793   structure_type_create_hash_table_structure_name (Qhash_table);
794   structure_type_create_hash_table_structure_name (Qhashtable); /* compat */
795 }
796
797 \f
798 /************************************************************************/
799 /*              Definition of Lisp-visible methods                      */
800 /************************************************************************/
801
802 DEFUN ("hash-table-p", Fhash_table_p, 1, 1, 0, /*
803 Return t if OBJECT is a hash table, else nil.
804 */
805        (object))
806 {
807   return HASH_TABLEP (object) ? Qt : Qnil;
808 }
809
810 DEFUN ("make-hash-table", Fmake_hash_table, 0, MANY, 0, /*
811 Return a new empty hash table object.
812 Use Common Lisp style keywords to specify hash table properties.
813  (make-hash-table &key test size rehash-size rehash-threshold weakness)
814
815 Keyword :test can be `eq', `eql' (default) or `equal'.
816 Comparison between keys is done using this function.
817 If speed is important, consider using `eq'.
818 When storing strings in the hash table, you will likely need to use `equal'.
819
820 Keyword :size specifies the number of keys likely to be inserted.
821 This number of entries can be inserted without enlarging the hash table.
822
823 Keyword :rehash-size must be a float greater than 1.0, and specifies
824 the factor by which to increase the size of the hash table when enlarging.
825
826 Keyword :rehash-threshold must be a float between 0.0 and 1.0,
827 and specifies the load factor of the hash table which triggers enlarging.
828
829 Non-standard keyword :weakness can be `nil' (default), `t', `key-and-value',
830 `key', `value' or `key-or-value'. `t' is an alias for `key-and-value'.
831
832 A key-and-value-weak hash table, also known as a fully-weak or simply
833 as a weak hash table, is one whose pointers do not count as GC
834 referents: for any key-value pair in the hash table, if the only
835 remaining pointer to either the key or the value is in a weak hash
836 table, then the pair will be removed from the hash table, and the key
837 and value collected.  A non-weak hash table (or any other pointer)
838 would prevent the object from being collected.
839
840 A key-weak hash table is similar to a fully-weak hash table except that
841 a key-value pair will be removed only if the key remains unmarked
842 outside of weak hash tables.  The pair will remain in the hash table if
843 the key is pointed to by something other than a weak hash table, even
844 if the value is not.
845
846 A value-weak hash table is similar to a fully-weak hash table except
847 that a key-value pair will be removed only if the value remains
848 unmarked outside of weak hash tables.  The pair will remain in the
849 hash table if the value is pointed to by something other than a weak
850 hash table, even if the key is not.
851
852 A key-or-value-weak hash table is similar to a fully-weak hash table except
853 that a key-value pair will be removed only if the value and the key remain
854 unmarked outside of weak hash tables.  The pair will remain in the
855 hash table if the value or key are pointed to by something other than a weak
856 hash table, even if the other is not.
857 */
858        (int nargs, Lisp_Object *args))
859 {
860   int i = 0;
861   Lisp_Object test             = Qnil;
862   Lisp_Object size             = Qnil;
863   Lisp_Object rehash_size      = Qnil;
864   Lisp_Object rehash_threshold = Qnil;
865   Lisp_Object weakness         = Qnil;
866
867   while (i + 1 < nargs)
868     {
869       Lisp_Object keyword = args[i++];
870       Lisp_Object value   = args[i++];
871
872       if      (EQ (keyword, Q_test))             test             = value;
873       else if (EQ (keyword, Q_size))             size             = value;
874       else if (EQ (keyword, Q_rehash_size))      rehash_size      = value;
875       else if (EQ (keyword, Q_rehash_threshold)) rehash_threshold = value;
876       else if (EQ (keyword, Q_weakness))         weakness         = value;
877       else if (EQ (keyword, Q_type))/*obsolete*/ weakness         = value;
878       else signal_simple_error ("Invalid hash table property keyword", keyword);
879     }
880
881   if (i < nargs)
882     signal_simple_error ("Hash table property requires a value", args[i]);
883
884 #define VALIDATE_VAR(var) \
885 if (!NILP (var)) hash_table_##var##_validate (Q##var, var, ERROR_ME);
886
887   VALIDATE_VAR (test);
888   VALIDATE_VAR (size);
889   VALIDATE_VAR (rehash_size);
890   VALIDATE_VAR (rehash_threshold);
891   VALIDATE_VAR (weakness);
892
893   return make_standard_lisp_hash_table
894     (decode_hash_table_test (test),
895      decode_hash_table_size (size),
896      decode_hash_table_rehash_size (rehash_size),
897      decode_hash_table_rehash_threshold (rehash_threshold),
898      decode_hash_table_weakness (weakness));
899 }
900
901 DEFUN ("copy-hash-table", Fcopy_hash_table, 1, 1, 0, /*
902 Return a new hash table containing the same keys and values as HASH-TABLE.
903 The keys and values will not themselves be copied.
904 */
905        (hash_table))
906 {
907   const Lisp_Hash_Table *ht_old = xhash_table (hash_table);
908   Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
909
910   copy_lcrecord (ht, ht_old);
911
912   ht->hentries = xnew_array (hentry, ht_old->size + 1);
913   memcpy (ht->hentries, ht_old->hentries, (ht_old->size + 1) * sizeof (hentry));
914
915   XSETHASH_TABLE (hash_table, ht);
916
917   if (! EQ (ht->next_weak, Qunbound))
918     {
919       ht->next_weak = Vall_weak_hash_tables;
920       Vall_weak_hash_tables = hash_table;
921     }
922
923   return hash_table;
924 }
925
926 static void
927 resize_hash_table (Lisp_Hash_Table *ht, size_t new_size)
928 {
929   hentry *old_entries, *new_entries, *sentinel, *e;
930   size_t old_size;
931
932   old_size = ht->size;
933   ht->size = new_size;
934
935   old_entries = ht->hentries;
936
937   ht->hentries = xnew_array_and_zero (hentry, new_size + 1);
938   new_entries = ht->hentries;
939
940   compute_hash_table_derived_values (ht);
941
942   for (e = old_entries, sentinel = e + old_size; e < sentinel; e++)
943     if (!HENTRY_CLEAR_P (e))
944       {
945         hentry *probe = new_entries + HASH_CODE (e->key, ht);
946         LINEAR_PROBING_LOOP (probe, new_entries, new_size)
947           ;
948         *probe = *e;
949       }
950
951   if (!DUMPEDP (old_entries))
952     xfree (old_entries);
953 }
954
955 /* After a hash table has been saved to disk and later restored by the
956    portable dumper, it contains the same objects, but their addresses
957    and thus their HASH_CODEs have changed. */
958 void
959 pdump_reorganize_hash_table (Lisp_Object hash_table)
960 {
961   const Lisp_Hash_Table *ht = xhash_table (hash_table);
962   hentry *new_entries = xnew_array_and_zero (hentry, ht->size + 1);
963   hentry *e, *sentinel;
964
965   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
966     if (!HENTRY_CLEAR_P (e))
967       {
968         hentry *probe = new_entries + HASH_CODE (e->key, ht);
969         LINEAR_PROBING_LOOP (probe, new_entries, ht->size)
970           ;
971         *probe = *e;
972       }
973
974   memcpy (ht->hentries, new_entries, ht->size * sizeof (hentry));
975
976   xfree (new_entries);
977 }
978
979 static void
980 enlarge_hash_table (Lisp_Hash_Table *ht)
981 {
982   size_t new_size =
983     hash_table_size ((size_t) ((double) ht->size * ht->rehash_size));
984   resize_hash_table (ht, new_size);
985 }
986
987 static hentry *
988 find_hentry (Lisp_Object key, const Lisp_Hash_Table *ht)
989 {
990   hash_table_test_function_t test_function = ht->test_function;
991   hentry *entries = ht->hentries;
992   hentry *probe = entries + HASH_CODE (key, ht);
993
994   LINEAR_PROBING_LOOP (probe, entries, ht->size)
995     if (KEYS_EQUAL_P (probe->key, key, test_function))
996       break;
997
998   return probe;
999 }
1000
1001 DEFUN ("gethash", Fgethash, 2, 3, 0, /*
1002 Find hash value for KEY in HASH-TABLE.
1003 If there is no corresponding value, return DEFAULT (which defaults to nil).
1004 */
1005        (key, hash_table, default_))
1006 {
1007   const Lisp_Hash_Table *ht = xhash_table (hash_table);
1008   hentry *e = find_hentry (key, ht);
1009
1010   return HENTRY_CLEAR_P (e) ? default_ : e->value;
1011 }
1012
1013 DEFUN ("puthash", Fputhash, 3, 3, 0, /*
1014 Hash KEY to VALUE in HASH-TABLE.
1015 */
1016        (key, value, hash_table))
1017 {
1018   Lisp_Hash_Table *ht = xhash_table (hash_table);
1019   hentry *e = find_hentry (key, ht);
1020
1021   if (!HENTRY_CLEAR_P (e))
1022     return e->value = value;
1023
1024   e->key   = key;
1025   e->value = value;
1026
1027   if (++ht->count >= ht->rehash_count)
1028     enlarge_hash_table (ht);
1029
1030   return value;
1031 }
1032
1033 /* Remove hentry pointed at by PROBE.
1034    Subsequent entries are removed and reinserted.
1035    We don't use tombstones - too wasteful.  */
1036 static void
1037 remhash_1 (Lisp_Hash_Table *ht, hentry *entries, hentry *probe)
1038 {
1039   size_t size = ht->size;
1040   CLEAR_HENTRY (probe);
1041   probe++;
1042   ht->count--;
1043
1044   LINEAR_PROBING_LOOP (probe, entries, size)
1045     {
1046       Lisp_Object key = probe->key;
1047       hentry *probe2 = entries + HASH_CODE (key, ht);
1048       LINEAR_PROBING_LOOP (probe2, entries, size)
1049         if (EQ (probe2->key, key))
1050           /* hentry at probe doesn't need to move. */
1051           goto continue_outer_loop;
1052       /* Move hentry from probe to new home at probe2. */
1053       *probe2 = *probe;
1054       CLEAR_HENTRY (probe);
1055     continue_outer_loop: continue;
1056     }
1057 }
1058
1059 DEFUN ("remhash", Fremhash, 2, 2, 0, /*
1060 Remove the entry for KEY from HASH-TABLE.
1061 Do nothing if there is no entry for KEY in HASH-TABLE.
1062 */
1063        (key, hash_table))
1064 {
1065   Lisp_Hash_Table *ht = xhash_table (hash_table);
1066   hentry *e = find_hentry (key, ht);
1067
1068   if (HENTRY_CLEAR_P (e))
1069     return Qnil;
1070
1071   remhash_1 (ht, ht->hentries, e);
1072   return Qt;
1073 }
1074
1075 DEFUN ("clrhash", Fclrhash, 1, 1, 0, /*
1076 Remove all entries from HASH-TABLE, leaving it empty.
1077 */
1078        (hash_table))
1079 {
1080   Lisp_Hash_Table *ht = xhash_table (hash_table);
1081   hentry *e, *sentinel;
1082
1083   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1084     CLEAR_HENTRY (e);
1085   ht->count = 0;
1086
1087   return hash_table;
1088 }
1089
1090 /************************************************************************/
1091 /*                          Accessor Functions                          */
1092 /************************************************************************/
1093
1094 DEFUN ("hash-table-count", Fhash_table_count, 1, 1, 0, /*
1095 Return the number of entries in HASH-TABLE.
1096 */
1097        (hash_table))
1098 {
1099   return make_int (xhash_table (hash_table)->count);
1100 }
1101
1102 DEFUN ("hash-table-test", Fhash_table_test, 1, 1, 0, /*
1103 Return the test function of HASH-TABLE.
1104 This can be one of `eq', `eql' or `equal'.
1105 */
1106        (hash_table))
1107 {
1108   hash_table_test_function_t fun = xhash_table (hash_table)->test_function;
1109
1110   return (fun == lisp_object_eql_equal   ? Qeql   :
1111           fun == lisp_object_equal_equal ? Qequal :
1112           Qeq);
1113 }
1114
1115 DEFUN ("hash-table-size", Fhash_table_size, 1, 1, 0, /*
1116 Return the size of HASH-TABLE.
1117 This is the current number of slots in HASH-TABLE, whether occupied or not.
1118 */
1119        (hash_table))
1120 {
1121   return make_int (xhash_table (hash_table)->size);
1122 }
1123
1124 DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size, 1, 1, 0, /*
1125 Return the current rehash size of HASH-TABLE.
1126 This is a float greater than 1.0; the factor by which HASH-TABLE
1127 is enlarged when the rehash threshold is exceeded.
1128 */
1129        (hash_table))
1130 {
1131   return make_float (xhash_table (hash_table)->rehash_size);
1132 }
1133
1134 DEFUN ("hash-table-rehash-threshold", Fhash_table_rehash_threshold, 1, 1, 0, /*
1135 Return the current rehash threshold of HASH-TABLE.
1136 This is a float between 0.0 and 1.0; the maximum `load factor' of HASH-TABLE,
1137 beyond which the HASH-TABLE is enlarged by rehashing.
1138 */
1139        (hash_table))
1140 {
1141   return make_float (xhash_table (hash_table)->rehash_threshold);
1142 }
1143
1144 DEFUN ("hash-table-weakness", Fhash_table_weakness, 1, 1, 0, /*
1145 Return the weakness of HASH-TABLE.
1146 This can be one of `nil', `key-and-value', `key-or-value', `key' or `value'.
1147 */
1148        (hash_table))
1149 {
1150   switch (xhash_table (hash_table)->weakness)
1151     {
1152     case HASH_TABLE_WEAK:               return Qkey_and_value;
1153     case HASH_TABLE_KEY_WEAK:           return Qkey;
1154     case HASH_TABLE_KEY_VALUE_WEAK:     return Qkey_or_value;
1155     case HASH_TABLE_VALUE_WEAK:         return Qvalue;
1156     default:                            return Qnil;
1157     }
1158 }
1159
1160 /* obsolete as of 19990901 in xemacs-21.2 */
1161 DEFUN ("hash-table-type", Fhash_table_type, 1, 1, 0, /*
1162 Return the type of HASH-TABLE.
1163 This can be one of `non-weak', `weak', `key-weak' or `value-weak'.
1164 */
1165        (hash_table))
1166 {
1167   switch (xhash_table (hash_table)->weakness)
1168     {
1169     case HASH_TABLE_WEAK:               return Qweak;
1170     case HASH_TABLE_KEY_WEAK:           return Qkey_weak;
1171     case HASH_TABLE_KEY_VALUE_WEAK:     return Qkey_or_value_weak;
1172     case HASH_TABLE_VALUE_WEAK:         return Qvalue_weak;
1173     default:                            return Qnon_weak;
1174     }
1175 }
1176
1177 /************************************************************************/
1178 /*                          Mapping Functions                           */
1179 /************************************************************************/
1180 DEFUN ("maphash", Fmaphash, 2, 2, 0, /*
1181 Map FUNCTION over entries in HASH-TABLE, calling it with two args,
1182 each key and value in HASH-TABLE.
1183
1184 FUNCTION may not modify HASH-TABLE, with the one exception that FUNCTION
1185 may remhash or puthash the entry currently being processed by FUNCTION.
1186 */
1187        (function, hash_table))
1188 {
1189   const Lisp_Hash_Table *ht = xhash_table (hash_table);
1190   const hentry *e, *sentinel;
1191
1192   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1193     if (!HENTRY_CLEAR_P (e))
1194       {
1195         Lisp_Object args[3], key;
1196       again:
1197         key = e->key;
1198         args[0] = function;
1199         args[1] = key;
1200         args[2] = e->value;
1201         Ffuncall (countof (args), args);
1202         /* Has FUNCTION done a remhash? */
1203         if (!EQ (key, e->key) && !HENTRY_CLEAR_P (e))
1204           goto again;
1205       }
1206
1207   return Qnil;
1208 }
1209
1210 /* Map *C* function FUNCTION over the elements of a lisp hash table. */
1211 void
1212 elisp_maphash (maphash_function_t function,
1213                Lisp_Object hash_table, void *extra_arg)
1214 {
1215   const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1216   const hentry *e, *sentinel;
1217
1218   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1219     if (!HENTRY_CLEAR_P (e))
1220       {
1221         Lisp_Object key;
1222       again:
1223         key = e->key;
1224         if (function (key, e->value, extra_arg))
1225           return;
1226         /* Has FUNCTION done a remhash? */
1227         if (!EQ (key, e->key) && !HENTRY_CLEAR_P (e))
1228           goto again;
1229       }
1230 }
1231
1232 /* Remove all elements of a lisp hash table satisfying *C* predicate PREDICATE. */
1233 void
1234 elisp_map_remhash (maphash_function_t predicate,
1235                    Lisp_Object hash_table, void *extra_arg)
1236 {
1237   Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1238   hentry *e, *entries, *sentinel;
1239
1240   for (e = entries = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1241     if (!HENTRY_CLEAR_P (e))
1242       {
1243       again:
1244         if (predicate (e->key, e->value, extra_arg))
1245           {
1246             remhash_1 (ht, entries, e);
1247             if (!HENTRY_CLEAR_P (e))
1248               goto again;
1249           }
1250       }
1251 }
1252
1253 \f
1254 /************************************************************************/
1255 /*                 garbage collecting weak hash tables                  */
1256 /************************************************************************/
1257 #define MARK_OBJ(obj) do {              \
1258   Lisp_Object mo_obj = (obj);           \
1259   if (!marked_p (mo_obj))               \
1260     {                                   \
1261       mark_object (mo_obj);             \
1262       did_mark = 1;                     \
1263     }                                   \
1264 } while (0)
1265
1266
1267 /* Complete the marking for semi-weak hash tables. */
1268 int
1269 finish_marking_weak_hash_tables (void)
1270 {
1271   Lisp_Object hash_table;
1272   int did_mark = 0;
1273
1274   for (hash_table = Vall_weak_hash_tables;
1275        !NILP (hash_table);
1276        hash_table = XHASH_TABLE (hash_table)->next_weak)
1277     {
1278       const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1279       const hentry *e = ht->hentries;
1280       const hentry *sentinel = e + ht->size;
1281
1282       if (! marked_p (hash_table))
1283         /* The hash table is probably garbage.  Ignore it. */
1284         continue;
1285
1286       /* Now, scan over all the pairs.  For all pairs that are
1287          half-marked, we may need to mark the other half if we're
1288          keeping this pair. */
1289       switch (ht->weakness)
1290         {
1291         case HASH_TABLE_KEY_WEAK:
1292           for (; e < sentinel; e++)
1293             if (!HENTRY_CLEAR_P (e))
1294               if (marked_p (e->key))
1295                 MARK_OBJ (e->value);
1296           break;
1297
1298         case HASH_TABLE_VALUE_WEAK:
1299           for (; e < sentinel; e++)
1300             if (!HENTRY_CLEAR_P (e))
1301               if (marked_p (e->value))
1302                 MARK_OBJ (e->key);
1303           break;
1304
1305         case HASH_TABLE_KEY_VALUE_WEAK:
1306           for (; e < sentinel; e++)
1307             if (!HENTRY_CLEAR_P (e))
1308               {
1309                 if (marked_p (e->value))
1310                   MARK_OBJ (e->key);
1311                 else if (marked_p (e->key))
1312                   MARK_OBJ (e->value);
1313               }
1314           break;
1315
1316         case HASH_TABLE_KEY_CAR_WEAK:
1317           for (; e < sentinel; e++)
1318             if (!HENTRY_CLEAR_P (e))
1319               if (!CONSP (e->key) || marked_p (XCAR (e->key)))
1320                 {
1321                   MARK_OBJ (e->key);
1322                   MARK_OBJ (e->value);
1323                 }
1324           break;
1325
1326           /* We seem to be sprouting new weakness types at an alarming
1327              rate. At least this is not externally visible - and in
1328              fact all of these KEY_CAR_* types are only used by the
1329              glyph code. */
1330         case HASH_TABLE_KEY_CAR_VALUE_WEAK:
1331           for (; e < sentinel; e++)
1332             if (!HENTRY_CLEAR_P (e))
1333               {
1334                 if (!CONSP (e->key) || marked_p (XCAR (e->key)))
1335                   {
1336                     MARK_OBJ (e->key);
1337                     MARK_OBJ (e->value);
1338                   }
1339                 else if (marked_p (e->value))
1340                   MARK_OBJ (e->key);
1341               }
1342           break;
1343
1344         case HASH_TABLE_VALUE_CAR_WEAK:
1345           for (; e < sentinel; e++)
1346             if (!HENTRY_CLEAR_P (e))
1347               if (!CONSP (e->value) || marked_p (XCAR (e->value)))
1348                 {
1349                   MARK_OBJ (e->key);
1350                   MARK_OBJ (e->value);
1351                 }
1352           break;
1353
1354         default:
1355           break;
1356         }
1357     }
1358
1359   return did_mark;
1360 }
1361
1362 void
1363 prune_weak_hash_tables (void)
1364 {
1365   Lisp_Object hash_table, prev = Qnil;
1366   for (hash_table = Vall_weak_hash_tables;
1367        !NILP (hash_table);
1368        hash_table = XHASH_TABLE (hash_table)->next_weak)
1369     {
1370       if (! marked_p (hash_table))
1371         {
1372           /* This hash table itself is garbage.  Remove it from the list. */
1373           if (NILP (prev))
1374             Vall_weak_hash_tables = XHASH_TABLE (hash_table)->next_weak;
1375           else
1376             XHASH_TABLE (prev)->next_weak = XHASH_TABLE (hash_table)->next_weak;
1377         }
1378       else
1379         {
1380           /* Now, scan over all the pairs.  Remove all of the pairs
1381              in which the key or value, or both, is unmarked
1382              (depending on the weakness of the hash table). */
1383           Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1384           hentry *entries = ht->hentries;
1385           hentry *sentinel = entries + ht->size;
1386           hentry *e;
1387
1388           for (e = entries; e < sentinel; e++)
1389             if (!HENTRY_CLEAR_P (e))
1390               {
1391               again:
1392                 if (!marked_p (e->key) || !marked_p (e->value))
1393                   {
1394                     remhash_1 (ht, entries, e);
1395                     if (!HENTRY_CLEAR_P (e))
1396                       goto again;
1397                   }
1398               }
1399
1400           prev = hash_table;
1401         }
1402     }
1403 }
1404
1405 /* Return a hash value for an array of Lisp_Objects of size SIZE. */
1406
1407 hashcode_t
1408 internal_array_hash (Lisp_Object *arr, int size, int depth)
1409 {
1410   int i;
1411   hashcode_t hash = 0;
1412   depth++;
1413
1414   if (size <= 5)
1415     {
1416       for (i = 0; i < size; i++)
1417         hash = HASH2 (hash, internal_hash (arr[i], depth));
1418       return hash;
1419     }
1420
1421   /* just pick five elements scattered throughout the array.
1422      A slightly better approach would be to offset by some
1423      noise factor from the points chosen below. */
1424   for (i = 0; i < 5; i++)
1425     hash = HASH2 (hash, internal_hash (arr[i*size/5], depth));
1426
1427   return hash;
1428 }
1429
1430 /* Return a hash value for a Lisp_Object.  This is for use when hashing
1431    objects with the comparison being `equal' (for `eq', you can just
1432    use the Lisp_Object itself as the hash value).  You need to make a
1433    tradeoff between the speed of the hash function and how good the
1434    hashing is.  In particular, the hash function needs to be FAST,
1435    so you can't just traipse down the whole tree hashing everything
1436    together.  Most of the time, objects will differ in the first
1437    few elements you hash.  Thus, we only go to a short depth (5)
1438    and only hash at most 5 elements out of a vector.  Theoretically
1439    we could still take 5^5 time (a big big number) to compute a
1440    hash, but practically this won't ever happen. */
1441
1442 hashcode_t
1443 internal_hash (Lisp_Object obj, int depth)
1444 {
1445   if (depth > 5)
1446     return 0;
1447   if (CONSP (obj))
1448     {
1449       /* no point in worrying about tail recursion, since we're not
1450          going very deep */
1451       return HASH2 (internal_hash (XCAR (obj), depth + 1),
1452                     internal_hash (XCDR (obj), depth + 1));
1453     }
1454   if (STRINGP (obj))
1455     {
1456       return hash_string (XSTRING_DATA (obj), XSTRING_LENGTH (obj));
1457     }
1458   if (LRECORDP (obj))
1459     {
1460       const struct lrecord_implementation
1461         *imp = XRECORD_LHEADER_IMPLEMENTATION (obj);
1462       if (imp->hash)
1463         return imp->hash (obj, depth);
1464     }
1465
1466   return LISP_HASH (obj);
1467 }
1468
1469 DEFUN ("sxhash", Fsxhash, 1, 1, 0, /*
1470 Return a hash value for OBJECT.
1471 \(equal obj1 obj2) implies (= (sxhash obj1) (sxhash obj2)).
1472 */
1473        (object))
1474 {
1475   return make_int (internal_hash (object, 0));
1476 }
1477
1478 #if 0
1479 xxDEFUN ("internal-hash-value", Finternal_hash_value, 1, 1, 0, /*
1480 Hash value of OBJECT.  For debugging.
1481 The value is returned as (HIGH . LOW).
1482 */
1483        (object))
1484 {
1485   /* This function is pretty 32bit-centric. */
1486   hashcode_t hash = internal_hash (object, 0);
1487   return Fcons (hash >> 16, hash & 0xffff);
1488 }
1489 #endif
1490
1491 \f
1492 /************************************************************************/
1493 /*                            initialization                            */
1494 /************************************************************************/
1495
1496 void
1497 syms_of_elhash (void)
1498 {
1499   INIT_LRECORD_IMPLEMENTATION (hash_table);
1500
1501   DEFSUBR (Fhash_table_p);
1502   DEFSUBR (Fmake_hash_table);
1503   DEFSUBR (Fcopy_hash_table);
1504   DEFSUBR (Fgethash);
1505   DEFSUBR (Fremhash);
1506   DEFSUBR (Fputhash);
1507   DEFSUBR (Fclrhash);
1508   DEFSUBR (Fmaphash);
1509   DEFSUBR (Fhash_table_count);
1510   DEFSUBR (Fhash_table_test);
1511   DEFSUBR (Fhash_table_size);
1512   DEFSUBR (Fhash_table_rehash_size);
1513   DEFSUBR (Fhash_table_rehash_threshold);
1514   DEFSUBR (Fhash_table_weakness);
1515   DEFSUBR (Fhash_table_type); /* obsolete */
1516   DEFSUBR (Fsxhash);
1517 #if 0
1518   DEFSUBR (Finternal_hash_value);
1519 #endif
1520
1521   defsymbol (&Qhash_tablep, "hash-table-p");
1522   defsymbol (&Qhash_table, "hash-table");
1523   defsymbol (&Qhashtable, "hashtable");
1524   defsymbol (&Qweakness, "weakness");
1525   defsymbol (&Qvalue, "value");
1526   defsymbol (&Qkey_or_value, "key-or-value");
1527   defsymbol (&Qkey_and_value, "key-and-value");
1528   defsymbol (&Qrehash_size, "rehash-size");
1529   defsymbol (&Qrehash_threshold, "rehash-threshold");
1530
1531   defsymbol (&Qweak, "weak");             /* obsolete */
1532   defsymbol (&Qkey_weak, "key-weak");     /* obsolete */
1533   defsymbol (&Qkey_or_value_weak, "key-or-value-weak");    /* obsolete */
1534   defsymbol (&Qvalue_weak, "value-weak"); /* obsolete */
1535   defsymbol (&Qnon_weak, "non-weak");     /* obsolete */
1536
1537   defkeyword (&Q_test, ":test");
1538   defkeyword (&Q_size, ":size");
1539   defkeyword (&Q_rehash_size, ":rehash-size");
1540   defkeyword (&Q_rehash_threshold, ":rehash-threshold");
1541   defkeyword (&Q_weakness, ":weakness");
1542   defkeyword (&Q_type, ":type"); /* obsolete */
1543 }
1544
1545 void
1546 vars_of_elhash (void)
1547 {
1548   /* This must NOT be staticpro'd */
1549   Vall_weak_hash_tables = Qnil;
1550   dump_add_weak_object_chain (&Vall_weak_hash_tables);
1551 }