annotate src/elhash.c @ 413:901169e5ca31

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