XEmacs 21.2.24 "Hecate".
[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;
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, Qnon_weak, Q_type;
39
40 typedef struct hentry
41 {
42   Lisp_Object key;
43   Lisp_Object value;
44 } hentry;
45
46 struct Lisp_Hash_Table
47 {
48   struct lcrecord_header header;
49   size_t size;
50   size_t count;
51   size_t rehash_count;
52   double rehash_size;
53   double rehash_threshold;
54   size_t golden_ratio;
55   hash_table_hash_function_t hash_function;
56   hash_table_test_function_t test_function;
57   hentry *hentries;
58   enum hash_table_weakness weakness;
59   Lisp_Object next_weak;     /* Used to chain together all of the weak
60                                 hash tables.  Don't mark through this. */
61 };
62 typedef struct Lisp_Hash_Table Lisp_Hash_Table;
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 \f
257 /* Printing hash tables.
258
259    This is non-trivial, because we use a readable structure-style
260    syntax for hash tables.  This means that a typical hash table will be
261    readably printed in the form of:
262
263    #s(hash-table size 2 data (key1 value1 key2 value2))
264
265    The supported hash table structure keywords and their values are:
266    `test'             (eql (or nil), eq or equal)
267    `size'             (a natnum or nil)
268    `rehash-size'      (a float)
269    `rehash-threshold' (a float)
270    `weakness'         (nil, t, key or value)
271    `data'             (a list)
272
273    If `print-readably' is nil, then a simpler syntax is used, for example
274
275    #<hash-table size 2/13 data (key1 value1 key2 value2) 0x874d>
276
277    The data is truncated to four pairs, and the rest is shown with
278    `...'.  This printer does not cons.  */
279
280
281 /* Print the data of the hash table.  This maps through a Lisp
282    hash table and prints key/value pairs using PRINTCHARFUN.  */
283 static void
284 print_hash_table_data (Lisp_Hash_Table *ht, Lisp_Object printcharfun)
285 {
286   int count = 0;
287   hentry *e, *sentinel;
288
289   write_c_string (" data (", printcharfun);
290
291   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
292     if (!HENTRY_CLEAR_P (e))
293       {
294         if (count > 0)
295           write_c_string (" ", printcharfun);
296         if (!print_readably && count > 3)
297           {
298             write_c_string ("...", printcharfun);
299             break;
300           }
301         print_internal (e->key, printcharfun, 1);
302         write_c_string (" ", printcharfun);
303         print_internal (e->value, printcharfun, 1);
304         count++;
305       }
306
307   write_c_string (")", printcharfun);
308 }
309
310 static void
311 print_hash_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
312 {
313   Lisp_Hash_Table *ht = XHASH_TABLE (obj);
314   char buf[128];
315
316   write_c_string (print_readably ? "#s(hash-table" : "#<hash-table",
317                   printcharfun);
318
319   /* These checks have a kludgy look to them, but they are safe.
320      Due to nature of hashing, you cannot use arbitrary
321      test functions anyway.  */
322   if (!ht->test_function)
323     write_c_string (" test eq", printcharfun);
324   else if (ht->test_function == lisp_object_equal_equal)
325     write_c_string (" test equal", printcharfun);
326   else if (ht->test_function == lisp_object_eql_equal)
327     DO_NOTHING;
328   else
329     abort ();
330
331   if (ht->count || !print_readably)
332     {
333       if (print_readably)
334         sprintf (buf, " size %lu", (unsigned long) ht->count);
335       else
336         sprintf (buf, " size %lu/%lu",
337                  (unsigned long) ht->count,
338                  (unsigned long) ht->size);
339       write_c_string (buf, printcharfun);
340     }
341
342   if (ht->weakness != HASH_TABLE_NON_WEAK)
343     {
344       sprintf (buf, " weakness %s",
345                (ht->weakness == HASH_TABLE_WEAK       ? "t"     :
346                 ht->weakness == HASH_TABLE_KEY_WEAK   ? "key"   :
347                 ht->weakness == HASH_TABLE_VALUE_WEAK ? "value" :
348                 "you-d-better-not-see-this"));
349       write_c_string (buf, printcharfun);
350     }
351
352   if (ht->count)
353     print_hash_table_data (ht, printcharfun);
354
355   if (print_readably)
356     write_c_string (")", printcharfun);
357   else
358     {
359       sprintf (buf, " 0x%x>", ht->header.uid);
360       write_c_string (buf, printcharfun);
361     }
362 }
363
364 static void
365 finalize_hash_table (void *header, int for_disksave)
366 {
367   if (!for_disksave)
368     {
369       Lisp_Hash_Table *ht = (Lisp_Hash_Table *) header;
370
371       xfree (ht->hentries);
372       ht->hentries = 0;
373     }
374 }
375
376 static const struct lrecord_description hentry_description_1[] = {
377   { XD_LISP_OBJECT, offsetof(hentry, key), 2 },
378   { XD_END }
379 };
380
381 static const struct struct_description hentry_description = {
382   sizeof(hentry),
383   hentry_description_1
384 };
385
386 const struct lrecord_description hash_table_description[] = {
387   { XD_SIZE_T,     offsetof(Lisp_Hash_Table, size) },
388   { XD_STRUCT_PTR, offsetof(Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), &hentry_description },
389   { XD_LO_LINK,    offsetof(Lisp_Hash_Table, next_weak) },
390   { XD_END }
391 };
392
393 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table,
394                                mark_hash_table, print_hash_table,
395                                finalize_hash_table,
396                                /* #### Implement hash_table_hash()! */
397                                hash_table_equal, 0,
398                                hash_table_description,
399                                Lisp_Hash_Table);
400
401 static Lisp_Hash_Table *
402 xhash_table (Lisp_Object hash_table)
403 {
404   if (!gc_in_progress)
405     CHECK_HASH_TABLE (hash_table);
406   check_hash_table_invariants (XHASH_TABLE (hash_table));
407   return XHASH_TABLE (hash_table);
408 }
409
410 \f
411 /************************************************************************/
412 /*                       Creation of Hash Tables                        */
413 /************************************************************************/
414
415 /* Creation of hash tables, without error-checking. */
416 static double
417 hash_table_rehash_threshold (Lisp_Hash_Table *ht)
418 {
419   return
420     ht->rehash_threshold > 0.0 ? ht->rehash_threshold :
421     ht->size > 4096 && !ht->test_function ? 0.7 : 0.6;
422 }
423
424 static void
425 compute_hash_table_derived_values (Lisp_Hash_Table *ht)
426 {
427   ht->rehash_count = (size_t)
428     ((double) ht->size * hash_table_rehash_threshold (ht));
429   ht->golden_ratio = (size_t)
430     ((double) ht->size * (.6180339887 / (double) sizeof (Lisp_Object)));
431 }
432
433 Lisp_Object
434 make_general_lisp_hash_table (enum hash_table_test test,
435                               size_t size,
436                               double rehash_size,
437                               double rehash_threshold,
438                               enum hash_table_weakness weakness)
439 {
440   Lisp_Object hash_table;
441   Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
442
443   ht->rehash_size      = rehash_size;
444   ht->rehash_threshold = rehash_threshold;
445   ht->weakness         = weakness;
446
447   switch (test)
448     {
449     case HASH_TABLE_EQ:
450       ht->test_function = 0;
451       ht->hash_function = 0;
452       break;
453
454     case HASH_TABLE_EQL:
455       ht->test_function = lisp_object_eql_equal;
456       ht->hash_function = lisp_object_eql_hash;
457       break;
458
459     case HASH_TABLE_EQUAL:
460       ht->test_function = lisp_object_equal_equal;
461       ht->hash_function = lisp_object_equal_hash;
462       break;
463
464     default:
465       abort ();
466     }
467
468   if (ht->rehash_size <= 0.0)
469     ht->rehash_size = HASH_TABLE_DEFAULT_REHASH_SIZE;
470   if (size < HASH_TABLE_MIN_SIZE)
471     size = HASH_TABLE_MIN_SIZE;
472   if (rehash_threshold < 0.0)
473     rehash_threshold = 0.75;
474   ht->size =
475     hash_table_size ((size_t) ((double) size / hash_table_rehash_threshold (ht)) + 1);
476   ht->count = 0;
477   compute_hash_table_derived_values (ht);
478
479   /* We leave room for one never-occupied sentinel hentry at the end.  */
480   ht->hentries = xnew_array (hentry, ht->size + 1);
481
482   {
483     hentry *e, *sentinel;
484     for (e = ht->hentries, sentinel = e + ht->size; e <= sentinel; e++)
485       CLEAR_HENTRY (e);
486   }
487
488   XSETHASH_TABLE (hash_table, ht);
489
490   if (weakness == HASH_TABLE_NON_WEAK)
491     ht->next_weak = Qunbound;
492   else
493     ht->next_weak = Vall_weak_hash_tables, Vall_weak_hash_tables = hash_table;
494
495   return hash_table;
496 }
497
498 Lisp_Object
499 make_lisp_hash_table (size_t size,
500                       enum hash_table_weakness weakness,
501                       enum hash_table_test test)
502 {
503   return make_general_lisp_hash_table
504     (test, size, HASH_TABLE_DEFAULT_REHASH_SIZE, -1.0, weakness);
505 }
506
507 /* Pretty reading of hash tables.
508
509    Here we use the existing structures mechanism (which is,
510    unfortunately, pretty cumbersome) for validating and instantiating
511    the hash tables.  The idea is that the side-effect of reading a
512    #s(hash-table PLIST) object is creation of a hash table with desired
513    properties, and that the hash table is returned.  */
514
515 /* Validation functions: each keyword provides its own validation
516    function.  The errors should maybe be continuable, but it is
517    unclear how this would cope with ERRB.  */
518 static int
519 hash_table_size_validate (Lisp_Object keyword, Lisp_Object value,
520                          Error_behavior errb)
521 {
522   if (NATNUMP (value))
523     return 1;
524
525   maybe_signal_error (Qwrong_type_argument, list2 (Qnatnump, value),
526                       Qhash_table, errb);
527   return 0;
528 }
529
530 static size_t
531 decode_hash_table_size (Lisp_Object obj)
532 {
533   return NILP (obj) ? HASH_TABLE_DEFAULT_SIZE : XINT (obj);
534 }
535
536 static int
537 hash_table_weakness_validate (Lisp_Object keyword, Lisp_Object value,
538                               Error_behavior errb)
539 {
540   if (EQ (value, Qnil))         return 1;
541   if (EQ (value, Qt))           return 1;
542   if (EQ (value, Qkey))         return 1;
543   if (EQ (value, Qvalue))       return 1;
544
545   /* Following values are obsolete as of 19990901 in xemacs-21.2 */
546   if (EQ (value, Qnon_weak))    return 1;
547   if (EQ (value, Qweak))        return 1;
548   if (EQ (value, Qkey_weak))    return 1;
549   if (EQ (value, Qvalue_weak))  return 1;
550
551   maybe_signal_simple_error ("Invalid hash table weakness",
552                              value, Qhash_table, errb);
553   return 0;
554 }
555
556 static enum hash_table_weakness
557 decode_hash_table_weakness (Lisp_Object obj)
558 {
559   if (EQ (obj, Qnil))        return HASH_TABLE_NON_WEAK;
560   if (EQ (obj, Qt))          return HASH_TABLE_WEAK;
561   if (EQ (obj, Qkey))        return HASH_TABLE_KEY_WEAK;
562   if (EQ (obj, Qvalue))      return HASH_TABLE_VALUE_WEAK;
563
564   /* Following values are obsolete as of 19990901 in xemacs-21.2 */
565   if (EQ (obj, Qnon_weak))   return HASH_TABLE_NON_WEAK;
566   if (EQ (obj, Qweak))       return HASH_TABLE_WEAK;
567   if (EQ (obj, Qkey_weak))   return HASH_TABLE_KEY_WEAK;
568   if (EQ (obj, Qvalue_weak)) return HASH_TABLE_VALUE_WEAK;
569
570   signal_simple_error ("Invalid hash table weakness", obj);
571   return HASH_TABLE_NON_WEAK; /* not reached */
572 }
573
574 static int
575 hash_table_test_validate (Lisp_Object keyword, Lisp_Object value,
576                          Error_behavior errb)
577 {
578   if (EQ (value, Qnil))   return 1;
579   if (EQ (value, Qeq))    return 1;
580   if (EQ (value, Qequal)) return 1;
581   if (EQ (value, Qeql))   return 1;
582
583   maybe_signal_simple_error ("Invalid hash table test",
584                              value, Qhash_table, errb);
585   return 0;
586 }
587
588 static enum hash_table_test
589 decode_hash_table_test (Lisp_Object obj)
590 {
591   if (EQ (obj, Qnil))   return HASH_TABLE_EQL;
592   if (EQ (obj, Qeq))    return HASH_TABLE_EQ;
593   if (EQ (obj, Qequal)) return HASH_TABLE_EQUAL;
594   if (EQ (obj, Qeql))   return HASH_TABLE_EQL;
595
596   signal_simple_error ("Invalid hash table test", obj);
597   return HASH_TABLE_EQ; /* not reached */
598 }
599
600 static int
601 hash_table_rehash_size_validate (Lisp_Object keyword, Lisp_Object value,
602                                  Error_behavior errb)
603 {
604   if (!FLOATP (value))
605     {
606       maybe_signal_error (Qwrong_type_argument, list2 (Qfloatp, value),
607                           Qhash_table, errb);
608       return 0;
609     }
610
611   {
612     double rehash_size = XFLOAT_DATA (value);
613     if (rehash_size <= 1.0)
614       {
615         maybe_signal_simple_error
616           ("Hash table rehash size must be greater than 1.0",
617            value, Qhash_table, errb);
618         return 0;
619       }
620   }
621
622   return 1;
623 }
624
625 static double
626 decode_hash_table_rehash_size (Lisp_Object rehash_size)
627 {
628   return NILP (rehash_size) ? -1.0 : XFLOAT_DATA (rehash_size);
629 }
630
631 static int
632 hash_table_rehash_threshold_validate (Lisp_Object keyword, Lisp_Object value,
633                                      Error_behavior errb)
634 {
635   if (!FLOATP (value))
636     {
637       maybe_signal_error (Qwrong_type_argument, list2 (Qfloatp, value),
638                           Qhash_table, errb);
639       return 0;
640     }
641
642   {
643     double rehash_threshold = XFLOAT_DATA (value);
644     if (rehash_threshold <= 0.0 || rehash_threshold >= 1.0)
645       {
646         maybe_signal_simple_error
647           ("Hash table rehash threshold must be between 0.0 and 1.0",
648            value, Qhash_table, errb);
649         return 0;
650       }
651   }
652
653   return 1;
654 }
655
656 static double
657 decode_hash_table_rehash_threshold (Lisp_Object rehash_threshold)
658 {
659   return NILP (rehash_threshold) ? -1.0 : XFLOAT_DATA (rehash_threshold);
660 }
661
662 static int
663 hash_table_data_validate (Lisp_Object keyword, Lisp_Object value,
664                          Error_behavior errb)
665 {
666   int len;
667
668   GET_EXTERNAL_LIST_LENGTH (value, len);
669
670   if (len & 1)
671     {
672       maybe_signal_simple_error
673         ("Hash table data must have alternating key/value pairs",
674          value, Qhash_table, errb);
675       return 0;
676     }
677   return 1;
678 }
679
680 /* The actual instantiation of a hash table.  This does practically no
681    error checking, because it relies on the fact that the paranoid
682    functions above have error-checked everything to the last details.
683    If this assumption is wrong, we will get a crash immediately (with
684    error-checking compiled in), and we'll know if there is a bug in
685    the structure mechanism.  So there.  */
686 static Lisp_Object
687 hash_table_instantiate (Lisp_Object plist)
688 {
689   Lisp_Object hash_table;
690   Lisp_Object test             = Qnil;
691   Lisp_Object size             = Qnil;
692   Lisp_Object rehash_size      = Qnil;
693   Lisp_Object rehash_threshold = Qnil;
694   Lisp_Object weakness         = Qnil;
695   Lisp_Object data             = Qnil;
696
697   while (!NILP (plist))
698     {
699       Lisp_Object key, value;
700       key   = XCAR (plist); plist = XCDR (plist);
701       value = XCAR (plist); plist = XCDR (plist);
702
703       if      (EQ (key, Qtest))             test             = value;
704       else if (EQ (key, Qsize))             size             = value;
705       else if (EQ (key, Qrehash_size))      rehash_size      = value;
706       else if (EQ (key, Qrehash_threshold)) rehash_threshold = value;
707       else if (EQ (key, Qweakness))         weakness         = value;
708       else if (EQ (key, Qdata))             data             = value;
709       else if (EQ (key, Qtype))/*obsolete*/ weakness         = value;
710       else
711         abort ();
712     }
713
714   /* Create the hash table.  */
715   hash_table = make_general_lisp_hash_table
716     (decode_hash_table_test (test),
717      decode_hash_table_size (size),
718      decode_hash_table_rehash_size (rehash_size),
719      decode_hash_table_rehash_threshold (rehash_threshold),
720      decode_hash_table_weakness (weakness));
721
722   /* I'm not sure whether this can GC, but better safe than sorry.  */
723   {
724     struct gcpro gcpro1;
725     GCPRO1 (hash_table);
726
727     /* And fill it with data.  */
728     while (!NILP (data))
729       {
730         Lisp_Object key, value;
731         key   = XCAR (data); data = XCDR (data);
732         value = XCAR (data); data = XCDR (data);
733         Fputhash (key, value, hash_table);
734       }
735     UNGCPRO;
736   }
737
738   return hash_table;
739 }
740
741 static void
742 structure_type_create_hash_table_structure_name (Lisp_Object structure_name)
743 {
744   struct structure_type *st;
745
746   st = define_structure_type (structure_name, 0, hash_table_instantiate);
747   define_structure_type_keyword (st, Qtest, hash_table_test_validate);
748   define_structure_type_keyword (st, Qsize, hash_table_size_validate);
749   define_structure_type_keyword (st, Qrehash_size, hash_table_rehash_size_validate);
750   define_structure_type_keyword (st, Qrehash_threshold, hash_table_rehash_threshold_validate);
751   define_structure_type_keyword (st, Qweakness, hash_table_weakness_validate);
752   define_structure_type_keyword (st, Qdata, hash_table_data_validate);
753
754   /* obsolete as of 19990901 in xemacs-21.2 */
755   define_structure_type_keyword (st, Qtype, hash_table_weakness_validate);
756 }
757
758 /* Create a built-in Lisp structure type named `hash-table'.
759    We make #s(hashtable ...) equivalent to #s(hash-table ...),
760    for backward compatibility.
761    This is called from emacs.c.  */
762 void
763 structure_type_create_hash_table (void)
764 {
765   structure_type_create_hash_table_structure_name (Qhash_table);
766   structure_type_create_hash_table_structure_name (Qhashtable); /* compat */
767 }
768
769 \f
770 /************************************************************************/
771 /*              Definition of Lisp-visible methods                      */
772 /************************************************************************/
773
774 DEFUN ("hash-table-p", Fhash_table_p, 1, 1, 0, /*
775 Return t if OBJECT is a hash table, else nil.
776 */
777        (object))
778 {
779   return HASH_TABLEP (object) ? Qt : Qnil;
780 }
781
782 DEFUN ("make-hash-table", Fmake_hash_table, 0, MANY, 0, /*
783 Return a new empty hash table object.
784 Use Common Lisp style keywords to specify hash table properties.
785  (make-hash-table &key test size rehash-size rehash-threshold weakness)
786
787 Keyword :test can be `eq', `eql' (default) or `equal'.
788 Comparison between keys is done using this function.
789 If speed is important, consider using `eq'.
790 When storing strings in the hash table, you will likely need to use `equal'.
791
792 Keyword :size specifies the number of keys likely to be inserted.
793 This number of entries can be inserted without enlarging the hash table.
794
795 Keyword :rehash-size must be a float greater than 1.0, and specifies
796 the factor by which to increase the size of the hash table when enlarging.
797
798 Keyword :rehash-threshold must be a float between 0.0 and 1.0,
799 and specifies the load factor of the hash table which triggers enlarging.
800
801 Non-standard keyword :weakness can be `nil' (default), `t', `key' or `value'.
802
803 A weak hash table is one whose pointers do not count as GC referents:
804 for any key-value pair in the hash table, if the only remaining pointer
805 to either the key or the value is in a weak hash table, then the pair
806 will be removed from the hash table, and the key and value collected.
807 A non-weak hash table (or any other pointer) would prevent the object
808 from being collected.
809
810 A key-weak hash table is similar to a fully-weak hash table except that
811 a key-value pair will be removed only if the key remains unmarked
812 outside of weak hash tables.  The pair will remain in the hash table if
813 the key is pointed to by something other than a weak hash table, even
814 if the value is not.
815
816 A value-weak hash table is similar to a fully-weak hash table except
817 that a key-value pair will be removed only if the value remains
818 unmarked outside of weak hash tables.  The pair will remain in the
819 hash table if the value is pointed to by something other than a weak
820 hash table, even if the key is not.
821 */
822        (int nargs, Lisp_Object *args))
823 {
824   int i = 0;
825   Lisp_Object test             = Qnil;
826   Lisp_Object size             = Qnil;
827   Lisp_Object rehash_size      = Qnil;
828   Lisp_Object rehash_threshold = Qnil;
829   Lisp_Object weakness         = Qnil;
830
831   while (i + 1 < nargs)
832     {
833       Lisp_Object keyword = args[i++];
834       Lisp_Object value   = args[i++];
835
836       if      (EQ (keyword, Q_test))             test             = value;
837       else if (EQ (keyword, Q_size))             size             = value;
838       else if (EQ (keyword, Q_rehash_size))      rehash_size      = value;
839       else if (EQ (keyword, Q_rehash_threshold)) rehash_threshold = value;
840       else if (EQ (keyword, Q_weakness))         weakness         = value;
841       else if (EQ (keyword, Q_type))/*obsolete*/ weakness         = value;
842       else signal_simple_error ("Invalid hash table property keyword", keyword);
843     }
844
845   if (i < nargs)
846     signal_simple_error ("Hash table property requires a value", args[i]);
847
848 #define VALIDATE_VAR(var) \
849 if (!NILP (var)) hash_table_##var##_validate (Q##var, var, ERROR_ME);
850
851   VALIDATE_VAR (test);
852   VALIDATE_VAR (size);
853   VALIDATE_VAR (rehash_size);
854   VALIDATE_VAR (rehash_threshold);
855   VALIDATE_VAR (weakness);
856
857   return make_general_lisp_hash_table
858     (decode_hash_table_test (test),
859      decode_hash_table_size (size),
860      decode_hash_table_rehash_size (rehash_size),
861      decode_hash_table_rehash_threshold (rehash_threshold),
862      decode_hash_table_weakness (weakness));
863 }
864
865 DEFUN ("copy-hash-table", Fcopy_hash_table, 1, 1, 0, /*
866 Return a new hash table containing the same keys and values as HASH-TABLE.
867 The keys and values will not themselves be copied.
868 */
869        (hash_table))
870 {
871   CONST Lisp_Hash_Table *ht_old = xhash_table (hash_table);
872   Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
873
874   copy_lcrecord (ht, ht_old);
875
876   ht->hentries = xnew_array (hentry, ht_old->size + 1);
877   memcpy (ht->hentries, ht_old->hentries, (ht_old->size + 1) * sizeof (hentry));
878
879   XSETHASH_TABLE (hash_table, ht);
880
881   if (! EQ (ht->next_weak, Qunbound))
882     {
883       ht->next_weak = Vall_weak_hash_tables;
884       Vall_weak_hash_tables = hash_table;
885     }
886
887   return hash_table;
888 }
889
890 static void
891 resize_hash_table (Lisp_Hash_Table *ht, size_t new_size)
892 {
893   hentry *old_entries, *new_entries, *old_sentinel, *new_sentinel, *e;
894   size_t old_size;
895
896   old_size = ht->size;
897   ht->size = new_size;
898
899   old_entries = ht->hentries;
900
901   ht->hentries = xnew_array (hentry, new_size + 1);
902   new_entries = ht->hentries;
903
904   old_sentinel = old_entries + old_size;
905   new_sentinel = new_entries + new_size;
906
907   for (e = new_entries; e <= new_sentinel; e++)
908     CLEAR_HENTRY (e);
909
910   compute_hash_table_derived_values (ht);
911
912   for (e = old_entries; e < old_sentinel; e++)
913     if (!HENTRY_CLEAR_P (e))
914       {
915         hentry *probe = new_entries + HASH_CODE (e->key, ht);
916         LINEAR_PROBING_LOOP (probe, new_entries, new_size)
917           ;
918         *probe = *e;
919       }
920
921   if (!DUMPEDP (old_entries))
922     xfree (old_entries);
923 }
924
925 void
926 reorganize_hash_table (Lisp_Hash_Table *ht)
927 {
928   resize_hash_table (ht, ht->size);
929 }
930
931 static void
932 enlarge_hash_table (Lisp_Hash_Table *ht)
933 {
934   size_t new_size =
935     hash_table_size ((size_t) ((double) ht->size * ht->rehash_size));
936   resize_hash_table (ht, new_size);
937 }
938
939 static hentry *
940 find_hentry (Lisp_Object key, CONST Lisp_Hash_Table *ht)
941 {
942   hash_table_test_function_t test_function = ht->test_function;
943   hentry *entries = ht->hentries;
944   hentry *probe = entries + HASH_CODE (key, ht);
945
946   LINEAR_PROBING_LOOP (probe, entries, ht->size)
947     if (KEYS_EQUAL_P (probe->key, key, test_function))
948       break;
949
950   return probe;
951 }
952
953 DEFUN ("gethash", Fgethash, 2, 3, 0, /*
954 Find hash value for KEY in HASH-TABLE.
955 If there is no corresponding value, return DEFAULT (which defaults to nil).
956 */
957        (key, hash_table, default_))
958 {
959   CONST Lisp_Hash_Table *ht = xhash_table (hash_table);
960   hentry *e = find_hentry (key, ht);
961
962   return HENTRY_CLEAR_P (e) ? default_ : e->value;
963 }
964
965 DEFUN ("puthash", Fputhash, 3, 3, 0, /*
966 Hash KEY to VALUE in HASH-TABLE.
967 */
968        (key, value, hash_table))
969 {
970   Lisp_Hash_Table *ht = xhash_table (hash_table);
971   hentry *e = find_hentry (key, ht);
972
973   if (!HENTRY_CLEAR_P (e))
974     return e->value = value;
975
976   e->key   = key;
977   e->value = value;
978
979   if (++ht->count >= ht->rehash_count)
980     enlarge_hash_table (ht);
981
982   return value;
983 }
984
985 /* Remove hentry pointed at by PROBE.
986    Subsequent entries are removed and reinserted.
987    We don't use tombstones - too wasteful.  */
988 static void
989 remhash_1 (Lisp_Hash_Table *ht, hentry *entries, hentry *probe)
990 {
991   size_t size = ht->size;
992   CLEAR_HENTRY (probe);
993   probe++;
994   ht->count--;
995
996   LINEAR_PROBING_LOOP (probe, entries, size)
997     {
998       Lisp_Object key = probe->key;
999       hentry *probe2 = entries + HASH_CODE (key, ht);
1000       LINEAR_PROBING_LOOP (probe2, entries, size)
1001         if (EQ (probe2->key, key))
1002           /* hentry at probe doesn't need to move. */
1003           goto continue_outer_loop;
1004       /* Move hentry from probe to new home at probe2. */
1005       *probe2 = *probe;
1006       CLEAR_HENTRY (probe);
1007     continue_outer_loop: continue;
1008     }
1009 }
1010
1011 DEFUN ("remhash", Fremhash, 2, 2, 0, /*
1012 Remove the entry for KEY from HASH-TABLE.
1013 Do nothing if there is no entry for KEY in HASH-TABLE.
1014 */
1015        (key, hash_table))
1016 {
1017   Lisp_Hash_Table *ht = xhash_table (hash_table);
1018   hentry *e = find_hentry (key, ht);
1019
1020   if (HENTRY_CLEAR_P (e))
1021     return Qnil;
1022
1023   remhash_1 (ht, ht->hentries, e);
1024   return Qt;
1025 }
1026
1027 DEFUN ("clrhash", Fclrhash, 1, 1, 0, /*
1028 Remove all entries from HASH-TABLE, leaving it empty.
1029 */
1030        (hash_table))
1031 {
1032   Lisp_Hash_Table *ht = xhash_table (hash_table);
1033   hentry *e, *sentinel;
1034
1035   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1036     CLEAR_HENTRY (e);
1037   ht->count = 0;
1038
1039   return hash_table;
1040 }
1041
1042 /************************************************************************/
1043 /*                          Accessor Functions                          */
1044 /************************************************************************/
1045
1046 DEFUN ("hash-table-count", Fhash_table_count, 1, 1, 0, /*
1047 Return the number of entries in HASH-TABLE.
1048 */
1049        (hash_table))
1050 {
1051   return make_int (xhash_table (hash_table)->count);
1052 }
1053
1054 DEFUN ("hash-table-test", Fhash_table_test, 1, 1, 0, /*
1055 Return the test function of HASH-TABLE.
1056 This can be one of `eq', `eql' or `equal'.
1057 */
1058        (hash_table))
1059 {
1060   hash_table_test_function_t fun = xhash_table (hash_table)->test_function;
1061
1062   return (fun == lisp_object_eql_equal   ? Qeql   :
1063           fun == lisp_object_equal_equal ? Qequal :
1064           Qeq);
1065 }
1066
1067 DEFUN ("hash-table-size", Fhash_table_size, 1, 1, 0, /*
1068 Return the size of HASH-TABLE.
1069 This is the current number of slots in HASH-TABLE, whether occupied or not.
1070 */
1071        (hash_table))
1072 {
1073   return make_int (xhash_table (hash_table)->size);
1074 }
1075
1076 DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size, 1, 1, 0, /*
1077 Return the current rehash size of HASH-TABLE.
1078 This is a float greater than 1.0; the factor by which HASH-TABLE
1079 is enlarged when the rehash threshold is exceeded.
1080 */
1081        (hash_table))
1082 {
1083   return make_float (xhash_table (hash_table)->rehash_size);
1084 }
1085
1086 DEFUN ("hash-table-rehash-threshold", Fhash_table_rehash_threshold, 1, 1, 0, /*
1087 Return the current rehash threshold of HASH-TABLE.
1088 This is a float between 0.0 and 1.0; the maximum `load factor' of HASH-TABLE,
1089 beyond which the HASH-TABLE is enlarged by rehashing.
1090 */
1091        (hash_table))
1092 {
1093   return make_float (hash_table_rehash_threshold (xhash_table (hash_table)));
1094 }
1095
1096 DEFUN ("hash-table-weakness", Fhash_table_weakness, 1, 1, 0, /*
1097 Return the weakness of HASH-TABLE.
1098 This can be one of `nil', `t', `key' or `value'.
1099 */
1100        (hash_table))
1101 {
1102   switch (xhash_table (hash_table)->weakness)
1103     {
1104     case HASH_TABLE_WEAK:       return Qt;
1105     case HASH_TABLE_KEY_WEAK:   return Qkey;
1106     case HASH_TABLE_VALUE_WEAK: return Qvalue;
1107     default:                    return Qnil;
1108     }
1109 }
1110
1111 /* obsolete as of 19990901 in xemacs-21.2 */
1112 DEFUN ("hash-table-type", Fhash_table_type, 1, 1, 0, /*
1113 Return the type of HASH-TABLE.
1114 This can be one of `non-weak', `weak', `key-weak' or `value-weak'.
1115 */
1116        (hash_table))
1117 {
1118   switch (xhash_table (hash_table)->weakness)
1119     {
1120     case HASH_TABLE_WEAK:       return Qweak;
1121     case HASH_TABLE_KEY_WEAK:   return Qkey_weak;
1122     case HASH_TABLE_VALUE_WEAK: return Qvalue_weak;
1123     default:                    return Qnon_weak;
1124     }
1125 }
1126
1127 /************************************************************************/
1128 /*                          Mapping Functions                           */
1129 /************************************************************************/
1130 DEFUN ("maphash", Fmaphash, 2, 2, 0, /*
1131 Map FUNCTION over entries in HASH-TABLE, calling it with two args,
1132 each key and value in HASH-TABLE.
1133
1134 FUNCTION may not modify HASH-TABLE, with the one exception that FUNCTION
1135 may remhash or puthash the entry currently being processed by FUNCTION.
1136 */
1137        (function, hash_table))
1138 {
1139   CONST Lisp_Hash_Table *ht = xhash_table (hash_table);
1140   CONST hentry *e, *sentinel;
1141
1142   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1143     if (!HENTRY_CLEAR_P (e))
1144       {
1145         Lisp_Object args[3], key;
1146       again:
1147         key = e->key;
1148         args[0] = function;
1149         args[1] = key;
1150         args[2] = e->value;
1151         Ffuncall (countof (args), args);
1152         /* Has FUNCTION done a remhash? */
1153         if (!EQ (key, e->key) && !HENTRY_CLEAR_P (e))
1154           goto again;
1155       }
1156
1157   return Qnil;
1158 }
1159
1160 /* Map *C* function FUNCTION over the elements of a lisp hash table. */
1161 void
1162 elisp_maphash (maphash_function_t function,
1163                Lisp_Object hash_table, void *extra_arg)
1164 {
1165   CONST Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1166   CONST hentry *e, *sentinel;
1167
1168   for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1169     if (!HENTRY_CLEAR_P (e))
1170       {
1171         Lisp_Object key;
1172       again:
1173         key = e->key;
1174         if (function (key, e->value, extra_arg))
1175           return;
1176         /* Has FUNCTION done a remhash? */
1177         if (!EQ (key, e->key) && !HENTRY_CLEAR_P (e))
1178           goto again;
1179       }
1180 }
1181
1182 /* Remove all elements of a lisp hash table satisfying *C* predicate PREDICATE. */
1183 void
1184 elisp_map_remhash (maphash_function_t predicate,
1185                    Lisp_Object hash_table, void *extra_arg)
1186 {
1187   Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1188   hentry *e, *entries, *sentinel;
1189
1190   for (e = entries = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1191     if (!HENTRY_CLEAR_P (e))
1192       {
1193       again:
1194         if (predicate (e->key, e->value, extra_arg))
1195           {
1196             remhash_1 (ht, entries, e);
1197             if (!HENTRY_CLEAR_P (e))
1198               goto again;
1199           }
1200       }
1201 }
1202
1203 \f
1204 /************************************************************************/
1205 /*                 garbage collecting weak hash tables                  */
1206 /************************************************************************/
1207
1208 /* Complete the marking for semi-weak hash tables. */
1209 int
1210 finish_marking_weak_hash_tables (void)
1211 {
1212   Lisp_Object hash_table;
1213   int did_mark = 0;
1214
1215   for (hash_table = Vall_weak_hash_tables;
1216        !NILP (hash_table);
1217        hash_table = XHASH_TABLE (hash_table)->next_weak)
1218     {
1219       CONST Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1220       CONST hentry *e = ht->hentries;
1221       CONST hentry *sentinel = e + ht->size;
1222
1223       if (! marked_p (hash_table))
1224         /* The hash table is probably garbage.  Ignore it. */
1225         continue;
1226
1227       /* Now, scan over all the pairs.  For all pairs that are
1228          half-marked, we may need to mark the other half if we're
1229          keeping this pair. */
1230 #define MARK_OBJ(obj) \
1231 do { if (!marked_p (obj)) mark_object (obj), did_mark = 1; } while (0)
1232
1233       switch (ht->weakness)
1234         {
1235         case HASH_TABLE_KEY_WEAK:
1236           for (; e < sentinel; e++)
1237             if (!HENTRY_CLEAR_P (e))
1238               if (marked_p (e->key))
1239                 MARK_OBJ (e->value);
1240           break;
1241
1242         case HASH_TABLE_VALUE_WEAK:
1243           for (; e < sentinel; e++)
1244             if (!HENTRY_CLEAR_P (e))
1245               if (marked_p (e->value))
1246                 MARK_OBJ (e->key);
1247           break;
1248
1249         case HASH_TABLE_KEY_CAR_WEAK:
1250           for (; e < sentinel; e++)
1251             if (!HENTRY_CLEAR_P (e))
1252               if (!CONSP (e->key) || marked_p (XCAR (e->key)))
1253                 {
1254                   MARK_OBJ (e->key);
1255                   MARK_OBJ (e->value);
1256                 }
1257           break;
1258
1259         case HASH_TABLE_VALUE_CAR_WEAK:
1260           for (; e < sentinel; e++)
1261             if (!HENTRY_CLEAR_P (e))
1262               if (!CONSP (e->value) || marked_p (XCAR (e->value)))
1263                 {
1264                   MARK_OBJ (e->key);
1265                   MARK_OBJ (e->value);
1266                 }
1267           break;
1268
1269         default:
1270           break;
1271         }
1272     }
1273
1274   return did_mark;
1275 }
1276
1277 void
1278 prune_weak_hash_tables (void)
1279 {
1280   Lisp_Object hash_table, prev = Qnil;
1281   for (hash_table = Vall_weak_hash_tables;
1282        !NILP (hash_table);
1283        hash_table = XHASH_TABLE (hash_table)->next_weak)
1284     {
1285       if (! marked_p (hash_table))
1286         {
1287           /* This hash table itself is garbage.  Remove it from the list. */
1288           if (NILP (prev))
1289             Vall_weak_hash_tables = XHASH_TABLE (hash_table)->next_weak;
1290           else
1291             XHASH_TABLE (prev)->next_weak = XHASH_TABLE (hash_table)->next_weak;
1292         }
1293       else
1294         {
1295           /* Now, scan over all the pairs.  Remove all of the pairs
1296              in which the key or value, or both, is unmarked
1297              (depending on the weakness of the hash table). */
1298           Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1299           hentry *entries = ht->hentries;
1300           hentry *sentinel = entries + ht->size;
1301           hentry *e;
1302
1303           for (e = entries; e < sentinel; e++)
1304             if (!HENTRY_CLEAR_P (e))
1305               {
1306               again:
1307                 if (!marked_p (e->key) || !marked_p (e->value))
1308                   {
1309                     remhash_1 (ht, entries, e);
1310                     if (!HENTRY_CLEAR_P (e))
1311                       goto again;
1312                   }
1313               }
1314
1315           prev = hash_table;
1316         }
1317     }
1318 }
1319
1320 /* Return a hash value for an array of Lisp_Objects of size SIZE. */
1321
1322 hashcode_t
1323 internal_array_hash (Lisp_Object *arr, int size, int depth)
1324 {
1325   int i;
1326   unsigned long hash = 0;
1327
1328   if (size <= 5)
1329     {
1330       for (i = 0; i < size; i++)
1331         hash = HASH2 (hash, internal_hash (arr[i], depth + 1));
1332       return hash;
1333     }
1334
1335   /* just pick five elements scattered throughout the array.
1336      A slightly better approach would be to offset by some
1337      noise factor from the points chosen below. */
1338   for (i = 0; i < 5; i++)
1339     hash = HASH2 (hash, internal_hash (arr[i*size/5], depth + 1));
1340
1341   return hash;
1342 }
1343
1344 /* Return a hash value for a Lisp_Object.  This is for use when hashing
1345    objects with the comparison being `equal' (for `eq', you can just
1346    use the Lisp_Object itself as the hash value).  You need to make a
1347    tradeoff between the speed of the hash function and how good the
1348    hashing is.  In particular, the hash function needs to be FAST,
1349    so you can't just traipse down the whole tree hashing everything
1350    together.  Most of the time, objects will differ in the first
1351    few elements you hash.  Thus, we only go to a short depth (5)
1352    and only hash at most 5 elements out of a vector.  Theoretically
1353    we could still take 5^5 time (a big big number) to compute a
1354    hash, but practically this won't ever happen. */
1355
1356 hashcode_t
1357 internal_hash (Lisp_Object obj, int depth)
1358 {
1359   if (depth > 5)
1360     return 0;
1361   if (CONSP (obj))
1362     {
1363       /* no point in worrying about tail recursion, since we're not
1364          going very deep */
1365       return HASH2 (internal_hash (XCAR (obj), depth + 1),
1366                     internal_hash (XCDR (obj), depth + 1));
1367     }
1368   if (STRINGP (obj))
1369     {
1370       return hash_string (XSTRING_DATA (obj), XSTRING_LENGTH (obj));
1371     }
1372   if (VECTORP (obj))
1373     {
1374       return HASH2 (XVECTOR_LENGTH (obj),
1375                     internal_array_hash (XVECTOR_DATA (obj),
1376                                          XVECTOR_LENGTH (obj),
1377                                          depth + 1));
1378     }
1379   if (LRECORDP (obj))
1380     {
1381       CONST struct lrecord_implementation
1382         *imp = XRECORD_LHEADER_IMPLEMENTATION (obj);
1383       if (imp->hash)
1384         return imp->hash (obj, depth);
1385     }
1386
1387   return LISP_HASH (obj);
1388 }
1389
1390 DEFUN ("sxhash", Fsxhash, 1, 1, 0, /*
1391 Return a hash value for OBJECT.
1392 (equal obj1 obj2) implies (= (sxhash obj1) (sxhash obj2)).
1393 */
1394        (object))
1395 {
1396   return make_int (internal_hash (object, 0));
1397 }
1398
1399 #if 0
1400 xxDEFUN ("internal-hash-value", Finternal_hash_value, 1, 1, 0, /*
1401 Hash value of OBJECT.  For debugging.
1402 The value is returned as (HIGH . LOW).
1403 */
1404        (object))
1405 {
1406   /* This function is pretty 32bit-centric. */
1407   unsigned long hash = internal_hash (object, 0);
1408   return Fcons (hash >> 16, hash & 0xffff);
1409 }
1410 #endif
1411
1412 \f
1413 /************************************************************************/
1414 /*                            initialization                            */
1415 /************************************************************************/
1416
1417 void
1418 syms_of_elhash (void)
1419 {
1420   DEFSUBR (Fhash_table_p);
1421   DEFSUBR (Fmake_hash_table);
1422   DEFSUBR (Fcopy_hash_table);
1423   DEFSUBR (Fgethash);
1424   DEFSUBR (Fremhash);
1425   DEFSUBR (Fputhash);
1426   DEFSUBR (Fclrhash);
1427   DEFSUBR (Fmaphash);
1428   DEFSUBR (Fhash_table_count);
1429   DEFSUBR (Fhash_table_test);
1430   DEFSUBR (Fhash_table_size);
1431   DEFSUBR (Fhash_table_rehash_size);
1432   DEFSUBR (Fhash_table_rehash_threshold);
1433   DEFSUBR (Fhash_table_weakness);
1434   DEFSUBR (Fhash_table_type); /* obsolete */
1435   DEFSUBR (Fsxhash);
1436 #if 0
1437   DEFSUBR (Finternal_hash_value);
1438 #endif
1439
1440   defsymbol (&Qhash_tablep, "hash-table-p");
1441   defsymbol (&Qhash_table, "hash-table");
1442   defsymbol (&Qhashtable, "hashtable");
1443   defsymbol (&Qweakness, "weakness");
1444   defsymbol (&Qvalue, "value");
1445   defsymbol (&Qrehash_size, "rehash-size");
1446   defsymbol (&Qrehash_threshold, "rehash-threshold");
1447
1448   defsymbol (&Qweak, "weak");             /* obsolete */
1449   defsymbol (&Qkey_weak, "key-weak");     /* obsolete */
1450   defsymbol (&Qvalue_weak, "value-weak"); /* obsolete */
1451   defsymbol (&Qnon_weak, "non-weak");     /* obsolete */
1452
1453   defkeyword (&Q_test, ":test");
1454   defkeyword (&Q_size, ":size");
1455   defkeyword (&Q_rehash_size, ":rehash-size");
1456   defkeyword (&Q_rehash_threshold, ":rehash-threshold");
1457   defkeyword (&Q_weakness, ":weakness");
1458   defkeyword (&Q_type, ":type"); /* obsolete */
1459 }
1460
1461 void
1462 vars_of_elhash (void)
1463 {
1464   /* This must NOT be staticpro'd */
1465   Vall_weak_hash_tables = Qnil;
1466   pdump_wire_list (&Vall_weak_hash_tables);
1467 }