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