comparison src/elhash.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
27 #include "bytecode.h" 27 #include "bytecode.h"
28 #include "elhash.h" 28 #include "elhash.h"
29 29
30 Lisp_Object Qhash_tablep; 30 Lisp_Object Qhash_tablep;
31 static Lisp_Object Qhashtable, Qhash_table; 31 static Lisp_Object Qhashtable, Qhash_table;
32 static Lisp_Object Qweakness, Qvalue; 32 static Lisp_Object Qweakness, Qvalue, Qkey_or_value, Qkey_and_value;
33 static Lisp_Object Vall_weak_hash_tables; 33 static Lisp_Object Vall_weak_hash_tables;
34 static Lisp_Object Qrehash_size, Qrehash_threshold; 34 static Lisp_Object Qrehash_size, Qrehash_threshold;
35 static Lisp_Object Q_size, Q_test, Q_weakness, Q_rehash_size, Q_rehash_threshold; 35 static Lisp_Object Q_size, Q_test, Q_weakness, Q_rehash_size, Q_rehash_threshold;
36 36
37 /* obsolete as of 19990901 in xemacs-21.2 */ 37 /* obsolete as of 19990901 in xemacs-21.2 */
38 static Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qnon_weak, Q_type; 38 static Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qkey_or_value_weak;
39 static Lisp_Object Qnon_weak, Q_type;
39 40
40 typedef struct hentry 41 typedef struct hentry
41 { 42 {
42 Lisp_Object key; 43 Lisp_Object key;
43 Lisp_Object value; 44 Lisp_Object value;
120 hash_table_size (size_t requested_size) 121 hash_table_size (size_t requested_size)
121 { 122 {
122 /* Return some prime near, but greater than or equal to, SIZE. 123 /* Return some prime near, but greater than or equal to, SIZE.
123 Decades from the time of writing, someone will have a system large 124 Decades from the time of writing, someone will have a system large
124 enough that the list below will be too short... */ 125 enough that the list below will be too short... */
125 static CONST size_t primes [] = 126 static const size_t primes [] =
126 { 127 {
127 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031, 128 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031,
128 1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783, 129 1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783,
129 19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941, 130 19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941,
130 204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519, 131 204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519,
250 return 0; /* Give up */ 251 return 0; /* Give up */
251 } 252 }
252 253
253 return 1; 254 return 1;
254 } 255 }
256
257 /* This is not a great hash function, but it _is_ correct and fast.
258 Examining all entries is too expensive, and examining a random
259 subset does not yield a correct hash function. */
260 static hashcode_t
261 hash_table_hash (Lisp_Object hash_table, int depth)
262 {
263 return XHASH_TABLE (hash_table)->count;
264 }
265
255 266
256 /* Printing hash tables. 267 /* Printing hash tables.
257 268
258 This is non-trivial, because we use a readable structure-style 269 This is non-trivial, because we use a readable structure-style
259 syntax for hash tables. This means that a typical hash table will be 270 syntax for hash tables. This means that a typical hash table will be
264 The supported hash table structure keywords and their values are: 275 The supported hash table structure keywords and their values are:
265 `test' (eql (or nil), eq or equal) 276 `test' (eql (or nil), eq or equal)
266 `size' (a natnum or nil) 277 `size' (a natnum or nil)
267 `rehash-size' (a float) 278 `rehash-size' (a float)
268 `rehash-threshold' (a float) 279 `rehash-threshold' (a float)
269 `weakness' (nil, t, key or value) 280 `weakness' (nil, key, value, key-and-value, or key-or-value)
270 `data' (a list) 281 `data' (a list)
271 282
272 If `print-readably' is nil, then a simpler syntax is used, for example 283 If `print-readably' is nil, then a simpler syntax is used, for example
273 284
274 #<hash-table size 2/13 data (key1 value1 key2 value2) 0x874d> 285 #<hash-table size 2/13 data (key1 value1 key2 value2) 0x874d>
339 } 350 }
340 351
341 if (ht->weakness != HASH_TABLE_NON_WEAK) 352 if (ht->weakness != HASH_TABLE_NON_WEAK)
342 { 353 {
343 sprintf (buf, " weakness %s", 354 sprintf (buf, " weakness %s",
344 (ht->weakness == HASH_TABLE_WEAK ? "t" : 355 (ht->weakness == HASH_TABLE_WEAK ? "key-and-value" :
345 ht->weakness == HASH_TABLE_KEY_WEAK ? "key" : 356 ht->weakness == HASH_TABLE_KEY_WEAK ? "key" :
346 ht->weakness == HASH_TABLE_VALUE_WEAK ? "value" : 357 ht->weakness == HASH_TABLE_VALUE_WEAK ? "value" :
358 ht->weakness == HASH_TABLE_KEY_VALUE_WEAK ? "key-or-value" :
347 "you-d-better-not-see-this")); 359 "you-d-better-not-see-this"));
348 write_c_string (buf, printcharfun); 360 write_c_string (buf, printcharfun);
349 } 361 }
350 362
351 if (ht->count) 363 if (ht->count)
391 }; 403 };
392 404
393 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table, 405 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table,
394 mark_hash_table, print_hash_table, 406 mark_hash_table, print_hash_table,
395 finalize_hash_table, 407 finalize_hash_table,
396 /* #### Implement hash_table_hash()! */ 408 hash_table_equal, hash_table_hash,
397 hash_table_equal, 0,
398 hash_table_description, 409 hash_table_description,
399 Lisp_Hash_Table); 410 Lisp_Hash_Table);
400 411
401 static Lisp_Hash_Table * 412 static Lisp_Hash_Table *
402 xhash_table (Lisp_Object hash_table) 413 xhash_table (Lisp_Object hash_table)
528 539
529 static int 540 static int
530 hash_table_weakness_validate (Lisp_Object keyword, Lisp_Object value, 541 hash_table_weakness_validate (Lisp_Object keyword, Lisp_Object value,
531 Error_behavior errb) 542 Error_behavior errb)
532 { 543 {
533 if (EQ (value, Qnil)) return 1; 544 if (EQ (value, Qnil)) return 1;
534 if (EQ (value, Qt)) return 1; 545 if (EQ (value, Qt)) return 1;
535 if (EQ (value, Qkey)) return 1; 546 if (EQ (value, Qkey)) return 1;
536 if (EQ (value, Qvalue)) return 1; 547 if (EQ (value, Qkey_and_value)) return 1;
548 if (EQ (value, Qkey_or_value)) return 1;
549 if (EQ (value, Qvalue)) return 1;
537 550
538 /* Following values are obsolete as of 19990901 in xemacs-21.2 */ 551 /* Following values are obsolete as of 19990901 in xemacs-21.2 */
539 if (EQ (value, Qnon_weak)) return 1; 552 if (EQ (value, Qnon_weak)) return 1;
540 if (EQ (value, Qweak)) return 1; 553 if (EQ (value, Qweak)) return 1;
541 if (EQ (value, Qkey_weak)) return 1; 554 if (EQ (value, Qkey_weak)) return 1;
542 if (EQ (value, Qvalue_weak)) return 1; 555 if (EQ (value, Qkey_or_value_weak)) return 1;
556 if (EQ (value, Qvalue_weak)) return 1;
543 557
544 maybe_signal_simple_error ("Invalid hash table weakness", 558 maybe_signal_simple_error ("Invalid hash table weakness",
545 value, Qhash_table, errb); 559 value, Qhash_table, errb);
546 return 0; 560 return 0;
547 } 561 }
548 562
549 static enum hash_table_weakness 563 static enum hash_table_weakness
550 decode_hash_table_weakness (Lisp_Object obj) 564 decode_hash_table_weakness (Lisp_Object obj)
551 { 565 {
552 if (EQ (obj, Qnil)) return HASH_TABLE_NON_WEAK; 566 if (EQ (obj, Qnil)) return HASH_TABLE_NON_WEAK;
553 if (EQ (obj, Qt)) return HASH_TABLE_WEAK; 567 if (EQ (obj, Qt)) return HASH_TABLE_WEAK;
554 if (EQ (obj, Qkey)) return HASH_TABLE_KEY_WEAK; 568 if (EQ (obj, Qkey_and_value)) return HASH_TABLE_WEAK;
555 if (EQ (obj, Qvalue)) return HASH_TABLE_VALUE_WEAK; 569 if (EQ (obj, Qkey)) return HASH_TABLE_KEY_WEAK;
570 if (EQ (obj, Qkey_or_value)) return HASH_TABLE_KEY_VALUE_WEAK;
571 if (EQ (obj, Qvalue)) return HASH_TABLE_VALUE_WEAK;
556 572
557 /* Following values are obsolete as of 19990901 in xemacs-21.2 */ 573 /* Following values are obsolete as of 19990901 in xemacs-21.2 */
558 if (EQ (obj, Qnon_weak)) return HASH_TABLE_NON_WEAK; 574 if (EQ (obj, Qnon_weak)) return HASH_TABLE_NON_WEAK;
559 if (EQ (obj, Qweak)) return HASH_TABLE_WEAK; 575 if (EQ (obj, Qweak)) return HASH_TABLE_WEAK;
560 if (EQ (obj, Qkey_weak)) return HASH_TABLE_KEY_WEAK; 576 if (EQ (obj, Qkey_weak)) return HASH_TABLE_KEY_WEAK;
561 if (EQ (obj, Qvalue_weak)) return HASH_TABLE_VALUE_WEAK; 577 if (EQ (obj, Qkey_or_value_weak)) return HASH_TABLE_KEY_VALUE_WEAK;
578 if (EQ (obj, Qvalue_weak)) return HASH_TABLE_VALUE_WEAK;
562 579
563 signal_simple_error ("Invalid hash table weakness", obj); 580 signal_simple_error ("Invalid hash table weakness", obj);
564 return HASH_TABLE_NON_WEAK; /* not reached */ 581 return HASH_TABLE_NON_WEAK; /* not reached */
565 } 582 }
566 583
789 the factor by which to increase the size of the hash table when enlarging. 806 the factor by which to increase the size of the hash table when enlarging.
790 807
791 Keyword :rehash-threshold must be a float between 0.0 and 1.0, 808 Keyword :rehash-threshold must be a float between 0.0 and 1.0,
792 and specifies the load factor of the hash table which triggers enlarging. 809 and specifies the load factor of the hash table which triggers enlarging.
793 810
794 Non-standard keyword :weakness can be `nil' (default), `t', `key' or `value'. 811 Non-standard keyword :weakness can be `nil' (default), `t', `key-and-value',
795 812 `key', `value' or `key-or-value'. `t' is an alias for `key-and-value'.
796 A weak hash table is one whose pointers do not count as GC referents: 813
797 for any key-value pair in the hash table, if the only remaining pointer 814 A key-and-value-weak hash table, also known as a fully-weak or simply
798 to either the key or the value is in a weak hash table, then the pair 815 as a weak hash table, is one whose pointers do not count as GC
799 will be removed from the hash table, and the key and value collected. 816 referents: for any key-value pair in the hash table, if the only
800 A non-weak hash table (or any other pointer) would prevent the object 817 remaining pointer to either the key or the value is in a weak hash
801 from being collected. 818 table, then the pair will be removed from the hash table, and the key
819 and value collected. A non-weak hash table (or any other pointer)
820 would prevent the object from being collected.
802 821
803 A key-weak hash table is similar to a fully-weak hash table except that 822 A key-weak hash table is similar to a fully-weak hash table except that
804 a key-value pair will be removed only if the key remains unmarked 823 a key-value pair will be removed only if the key remains unmarked
805 outside of weak hash tables. The pair will remain in the hash table if 824 outside of weak hash tables. The pair will remain in the hash table if
806 the key is pointed to by something other than a weak hash table, even 825 the key is pointed to by something other than a weak hash table, even
809 A value-weak hash table is similar to a fully-weak hash table except 828 A value-weak hash table is similar to a fully-weak hash table except
810 that a key-value pair will be removed only if the value remains 829 that a key-value pair will be removed only if the value remains
811 unmarked outside of weak hash tables. The pair will remain in the 830 unmarked outside of weak hash tables. The pair will remain in the
812 hash table if the value is pointed to by something other than a weak 831 hash table if the value is pointed to by something other than a weak
813 hash table, even if the key is not. 832 hash table, even if the key is not.
833
834 A key-or-value-weak hash table is similar to a fully-weak hash table except
835 that a key-value pair will be removed only if the value and the key remain
836 unmarked outside of weak hash tables. The pair will remain in the
837 hash table if the value or key are pointed to by something other than a weak
838 hash table, even if the other is not.
814 */ 839 */
815 (int nargs, Lisp_Object *args)) 840 (int nargs, Lisp_Object *args))
816 { 841 {
817 int i = 0; 842 int i = 0;
818 Lisp_Object test = Qnil; 843 Lisp_Object test = Qnil;
859 Return a new hash table containing the same keys and values as HASH-TABLE. 884 Return a new hash table containing the same keys and values as HASH-TABLE.
860 The keys and values will not themselves be copied. 885 The keys and values will not themselves be copied.
861 */ 886 */
862 (hash_table)) 887 (hash_table))
863 { 888 {
864 CONST Lisp_Hash_Table *ht_old = xhash_table (hash_table); 889 const Lisp_Hash_Table *ht_old = xhash_table (hash_table);
865 Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table); 890 Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
866 891
867 copy_lcrecord (ht, ht_old); 892 copy_lcrecord (ht, ht_old);
868 893
869 ht->hentries = xnew_array (hentry, ht_old->size + 1); 894 ht->hentries = xnew_array (hentry, ht_old->size + 1);
913 portable dumper, it contains the same objects, but their addresses 938 portable dumper, it contains the same objects, but their addresses
914 and thus their HASH_CODEs have changed. */ 939 and thus their HASH_CODEs have changed. */
915 void 940 void
916 pdump_reorganize_hash_table (Lisp_Object hash_table) 941 pdump_reorganize_hash_table (Lisp_Object hash_table)
917 { 942 {
918 CONST Lisp_Hash_Table *ht = xhash_table (hash_table); 943 const Lisp_Hash_Table *ht = xhash_table (hash_table);
919 hentry *new_entries = xnew_array_and_zero (hentry, ht->size + 1); 944 hentry *new_entries = xnew_array_and_zero (hentry, ht->size + 1);
920 hentry *e, *sentinel; 945 hentry *e, *sentinel;
921 946
922 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) 947 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
923 if (!HENTRY_CLEAR_P (e)) 948 if (!HENTRY_CLEAR_P (e))
940 hash_table_size ((size_t) ((double) ht->size * ht->rehash_size)); 965 hash_table_size ((size_t) ((double) ht->size * ht->rehash_size));
941 resize_hash_table (ht, new_size); 966 resize_hash_table (ht, new_size);
942 } 967 }
943 968
944 static hentry * 969 static hentry *
945 find_hentry (Lisp_Object key, CONST Lisp_Hash_Table *ht) 970 find_hentry (Lisp_Object key, const Lisp_Hash_Table *ht)
946 { 971 {
947 hash_table_test_function_t test_function = ht->test_function; 972 hash_table_test_function_t test_function = ht->test_function;
948 hentry *entries = ht->hentries; 973 hentry *entries = ht->hentries;
949 hentry *probe = entries + HASH_CODE (key, ht); 974 hentry *probe = entries + HASH_CODE (key, ht);
950 975
959 Find hash value for KEY in HASH-TABLE. 984 Find hash value for KEY in HASH-TABLE.
960 If there is no corresponding value, return DEFAULT (which defaults to nil). 985 If there is no corresponding value, return DEFAULT (which defaults to nil).
961 */ 986 */
962 (key, hash_table, default_)) 987 (key, hash_table, default_))
963 { 988 {
964 CONST Lisp_Hash_Table *ht = xhash_table (hash_table); 989 const Lisp_Hash_Table *ht = xhash_table (hash_table);
965 hentry *e = find_hentry (key, ht); 990 hentry *e = find_hentry (key, ht);
966 991
967 return HENTRY_CLEAR_P (e) ? default_ : e->value; 992 return HENTRY_CLEAR_P (e) ? default_ : e->value;
968 } 993 }
969 994
1098 return make_float (xhash_table (hash_table)->rehash_threshold); 1123 return make_float (xhash_table (hash_table)->rehash_threshold);
1099 } 1124 }
1100 1125
1101 DEFUN ("hash-table-weakness", Fhash_table_weakness, 1, 1, 0, /* 1126 DEFUN ("hash-table-weakness", Fhash_table_weakness, 1, 1, 0, /*
1102 Return the weakness of HASH-TABLE. 1127 Return the weakness of HASH-TABLE.
1103 This can be one of `nil', `t', `key' or `value'. 1128 This can be one of `nil', `key-and-value', `key-or-value', `key' or `value'.
1104 */ 1129 */
1105 (hash_table)) 1130 (hash_table))
1106 { 1131 {
1107 switch (xhash_table (hash_table)->weakness) 1132 switch (xhash_table (hash_table)->weakness)
1108 { 1133 {
1109 case HASH_TABLE_WEAK: return Qt; 1134 case HASH_TABLE_WEAK: return Qkey_and_value;
1110 case HASH_TABLE_KEY_WEAK: return Qkey; 1135 case HASH_TABLE_KEY_WEAK: return Qkey;
1111 case HASH_TABLE_VALUE_WEAK: return Qvalue; 1136 case HASH_TABLE_KEY_VALUE_WEAK: return Qkey_or_value;
1112 default: return Qnil; 1137 case HASH_TABLE_VALUE_WEAK: return Qvalue;
1138 default: return Qnil;
1113 } 1139 }
1114 } 1140 }
1115 1141
1116 /* obsolete as of 19990901 in xemacs-21.2 */ 1142 /* obsolete as of 19990901 in xemacs-21.2 */
1117 DEFUN ("hash-table-type", Fhash_table_type, 1, 1, 0, /* 1143 DEFUN ("hash-table-type", Fhash_table_type, 1, 1, 0, /*
1120 */ 1146 */
1121 (hash_table)) 1147 (hash_table))
1122 { 1148 {
1123 switch (xhash_table (hash_table)->weakness) 1149 switch (xhash_table (hash_table)->weakness)
1124 { 1150 {
1125 case HASH_TABLE_WEAK: return Qweak; 1151 case HASH_TABLE_WEAK: return Qweak;
1126 case HASH_TABLE_KEY_WEAK: return Qkey_weak; 1152 case HASH_TABLE_KEY_WEAK: return Qkey_weak;
1127 case HASH_TABLE_VALUE_WEAK: return Qvalue_weak; 1153 case HASH_TABLE_KEY_VALUE_WEAK: return Qkey_or_value_weak;
1128 default: return Qnon_weak; 1154 case HASH_TABLE_VALUE_WEAK: return Qvalue_weak;
1155 default: return Qnon_weak;
1129 } 1156 }
1130 } 1157 }
1131 1158
1132 /************************************************************************/ 1159 /************************************************************************/
1133 /* Mapping Functions */ 1160 /* Mapping Functions */
1139 FUNCTION may not modify HASH-TABLE, with the one exception that FUNCTION 1166 FUNCTION may not modify HASH-TABLE, with the one exception that FUNCTION
1140 may remhash or puthash the entry currently being processed by FUNCTION. 1167 may remhash or puthash the entry currently being processed by FUNCTION.
1141 */ 1168 */
1142 (function, hash_table)) 1169 (function, hash_table))
1143 { 1170 {
1144 CONST Lisp_Hash_Table *ht = xhash_table (hash_table); 1171 const Lisp_Hash_Table *ht = xhash_table (hash_table);
1145 CONST hentry *e, *sentinel; 1172 const hentry *e, *sentinel;
1146 1173
1147 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) 1174 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1148 if (!HENTRY_CLEAR_P (e)) 1175 if (!HENTRY_CLEAR_P (e))
1149 { 1176 {
1150 Lisp_Object args[3], key; 1177 Lisp_Object args[3], key;
1165 /* Map *C* function FUNCTION over the elements of a lisp hash table. */ 1192 /* Map *C* function FUNCTION over the elements of a lisp hash table. */
1166 void 1193 void
1167 elisp_maphash (maphash_function_t function, 1194 elisp_maphash (maphash_function_t function,
1168 Lisp_Object hash_table, void *extra_arg) 1195 Lisp_Object hash_table, void *extra_arg)
1169 { 1196 {
1170 CONST Lisp_Hash_Table *ht = XHASH_TABLE (hash_table); 1197 const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1171 CONST hentry *e, *sentinel; 1198 const hentry *e, *sentinel;
1172 1199
1173 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) 1200 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1174 if (!HENTRY_CLEAR_P (e)) 1201 if (!HENTRY_CLEAR_P (e))
1175 { 1202 {
1176 Lisp_Object key; 1203 Lisp_Object key;
1207 1234
1208 1235
1209 /************************************************************************/ 1236 /************************************************************************/
1210 /* garbage collecting weak hash tables */ 1237 /* garbage collecting weak hash tables */
1211 /************************************************************************/ 1238 /************************************************************************/
1239 #define MARK_OBJ(obj) do { \
1240 Lisp_Object mo_obj = (obj); \
1241 if (!marked_p (mo_obj)) \
1242 { \
1243 mark_object (mo_obj); \
1244 did_mark = 1; \
1245 } \
1246 } while (0)
1247
1212 1248
1213 /* Complete the marking for semi-weak hash tables. */ 1249 /* Complete the marking for semi-weak hash tables. */
1214 int 1250 int
1215 finish_marking_weak_hash_tables (void) 1251 finish_marking_weak_hash_tables (void)
1216 { 1252 {
1219 1255
1220 for (hash_table = Vall_weak_hash_tables; 1256 for (hash_table = Vall_weak_hash_tables;
1221 !NILP (hash_table); 1257 !NILP (hash_table);
1222 hash_table = XHASH_TABLE (hash_table)->next_weak) 1258 hash_table = XHASH_TABLE (hash_table)->next_weak)
1223 { 1259 {
1224 CONST Lisp_Hash_Table *ht = XHASH_TABLE (hash_table); 1260 const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1225 CONST hentry *e = ht->hentries; 1261 const hentry *e = ht->hentries;
1226 CONST hentry *sentinel = e + ht->size; 1262 const hentry *sentinel = e + ht->size;
1227 1263
1228 if (! marked_p (hash_table)) 1264 if (! marked_p (hash_table))
1229 /* The hash table is probably garbage. Ignore it. */ 1265 /* The hash table is probably garbage. Ignore it. */
1230 continue; 1266 continue;
1231 1267
1232 /* Now, scan over all the pairs. For all pairs that are 1268 /* Now, scan over all the pairs. For all pairs that are
1233 half-marked, we may need to mark the other half if we're 1269 half-marked, we may need to mark the other half if we're
1234 keeping this pair. */ 1270 keeping this pair. */
1235 #define MARK_OBJ(obj) \
1236 do { if (!marked_p (obj)) mark_object (obj), did_mark = 1; } while (0)
1237
1238 switch (ht->weakness) 1271 switch (ht->weakness)
1239 { 1272 {
1240 case HASH_TABLE_KEY_WEAK: 1273 case HASH_TABLE_KEY_WEAK:
1241 for (; e < sentinel; e++) 1274 for (; e < sentinel; e++)
1242 if (!HENTRY_CLEAR_P (e)) 1275 if (!HENTRY_CLEAR_P (e))
1247 case HASH_TABLE_VALUE_WEAK: 1280 case HASH_TABLE_VALUE_WEAK:
1248 for (; e < sentinel; e++) 1281 for (; e < sentinel; e++)
1249 if (!HENTRY_CLEAR_P (e)) 1282 if (!HENTRY_CLEAR_P (e))
1250 if (marked_p (e->value)) 1283 if (marked_p (e->value))
1251 MARK_OBJ (e->key); 1284 MARK_OBJ (e->key);
1285 break;
1286
1287 case HASH_TABLE_KEY_VALUE_WEAK:
1288 for (; e < sentinel; e++)
1289 if (!HENTRY_CLEAR_P (e))
1290 {
1291 if (marked_p (e->value))
1292 MARK_OBJ (e->key);
1293 else if (marked_p (e->key))
1294 MARK_OBJ (e->value);
1295 }
1252 break; 1296 break;
1253 1297
1254 case HASH_TABLE_KEY_CAR_WEAK: 1298 case HASH_TABLE_KEY_CAR_WEAK:
1255 for (; e < sentinel; e++) 1299 for (; e < sentinel; e++)
1256 if (!HENTRY_CLEAR_P (e)) 1300 if (!HENTRY_CLEAR_P (e))
1326 1370
1327 hashcode_t 1371 hashcode_t
1328 internal_array_hash (Lisp_Object *arr, int size, int depth) 1372 internal_array_hash (Lisp_Object *arr, int size, int depth)
1329 { 1373 {
1330 int i; 1374 int i;
1331 unsigned long hash = 0; 1375 hashcode_t hash = 0;
1376 depth++;
1332 1377
1333 if (size <= 5) 1378 if (size <= 5)
1334 { 1379 {
1335 for (i = 0; i < size; i++) 1380 for (i = 0; i < size; i++)
1336 hash = HASH2 (hash, internal_hash (arr[i], depth + 1)); 1381 hash = HASH2 (hash, internal_hash (arr[i], depth));
1337 return hash; 1382 return hash;
1338 } 1383 }
1339 1384
1340 /* just pick five elements scattered throughout the array. 1385 /* just pick five elements scattered throughout the array.
1341 A slightly better approach would be to offset by some 1386 A slightly better approach would be to offset by some
1342 noise factor from the points chosen below. */ 1387 noise factor from the points chosen below. */
1343 for (i = 0; i < 5; i++) 1388 for (i = 0; i < 5; i++)
1344 hash = HASH2 (hash, internal_hash (arr[i*size/5], depth + 1)); 1389 hash = HASH2 (hash, internal_hash (arr[i*size/5], depth));
1345 1390
1346 return hash; 1391 return hash;
1347 } 1392 }
1348 1393
1349 /* Return a hash value for a Lisp_Object. This is for use when hashing 1394 /* Return a hash value for a Lisp_Object. This is for use when hashing
1372 } 1417 }
1373 if (STRINGP (obj)) 1418 if (STRINGP (obj))
1374 { 1419 {
1375 return hash_string (XSTRING_DATA (obj), XSTRING_LENGTH (obj)); 1420 return hash_string (XSTRING_DATA (obj), XSTRING_LENGTH (obj));
1376 } 1421 }
1377 if (VECTORP (obj))
1378 {
1379 return HASH2 (XVECTOR_LENGTH (obj),
1380 internal_array_hash (XVECTOR_DATA (obj),
1381 XVECTOR_LENGTH (obj),
1382 depth + 1));
1383 }
1384 if (LRECORDP (obj)) 1422 if (LRECORDP (obj))
1385 { 1423 {
1386 CONST struct lrecord_implementation 1424 const struct lrecord_implementation
1387 *imp = XRECORD_LHEADER_IMPLEMENTATION (obj); 1425 *imp = XRECORD_LHEADER_IMPLEMENTATION (obj);
1388 if (imp->hash) 1426 if (imp->hash)
1389 return imp->hash (obj, depth); 1427 return imp->hash (obj, depth);
1390 } 1428 }
1391 1429
1407 The value is returned as (HIGH . LOW). 1445 The value is returned as (HIGH . LOW).
1408 */ 1446 */
1409 (object)) 1447 (object))
1410 { 1448 {
1411 /* This function is pretty 32bit-centric. */ 1449 /* This function is pretty 32bit-centric. */
1412 unsigned long hash = internal_hash (object, 0); 1450 hashcode_t hash = internal_hash (object, 0);
1413 return Fcons (hash >> 16, hash & 0xffff); 1451 return Fcons (hash >> 16, hash & 0xffff);
1414 } 1452 }
1415 #endif 1453 #endif
1416 1454
1417 1455
1420 /************************************************************************/ 1458 /************************************************************************/
1421 1459
1422 void 1460 void
1423 syms_of_elhash (void) 1461 syms_of_elhash (void)
1424 { 1462 {
1463 INIT_LRECORD_IMPLEMENTATION (hash_table);
1464
1425 DEFSUBR (Fhash_table_p); 1465 DEFSUBR (Fhash_table_p);
1426 DEFSUBR (Fmake_hash_table); 1466 DEFSUBR (Fmake_hash_table);
1427 DEFSUBR (Fcopy_hash_table); 1467 DEFSUBR (Fcopy_hash_table);
1428 DEFSUBR (Fgethash); 1468 DEFSUBR (Fgethash);
1429 DEFSUBR (Fremhash); 1469 DEFSUBR (Fremhash);
1445 defsymbol (&Qhash_tablep, "hash-table-p"); 1485 defsymbol (&Qhash_tablep, "hash-table-p");
1446 defsymbol (&Qhash_table, "hash-table"); 1486 defsymbol (&Qhash_table, "hash-table");
1447 defsymbol (&Qhashtable, "hashtable"); 1487 defsymbol (&Qhashtable, "hashtable");
1448 defsymbol (&Qweakness, "weakness"); 1488 defsymbol (&Qweakness, "weakness");
1449 defsymbol (&Qvalue, "value"); 1489 defsymbol (&Qvalue, "value");
1490 defsymbol (&Qkey_or_value, "key-or-value");
1491 defsymbol (&Qkey_and_value, "key-and-value");
1450 defsymbol (&Qrehash_size, "rehash-size"); 1492 defsymbol (&Qrehash_size, "rehash-size");
1451 defsymbol (&Qrehash_threshold, "rehash-threshold"); 1493 defsymbol (&Qrehash_threshold, "rehash-threshold");
1452 1494
1453 defsymbol (&Qweak, "weak"); /* obsolete */ 1495 defsymbol (&Qweak, "weak"); /* obsolete */
1454 defsymbol (&Qkey_weak, "key-weak"); /* obsolete */ 1496 defsymbol (&Qkey_weak, "key-weak"); /* obsolete */
1497 defsymbol (&Qkey_or_value_weak, "key-or-value-weak"); /* obsolete */
1455 defsymbol (&Qvalue_weak, "value-weak"); /* obsolete */ 1498 defsymbol (&Qvalue_weak, "value-weak"); /* obsolete */
1456 defsymbol (&Qnon_weak, "non-weak"); /* obsolete */ 1499 defsymbol (&Qnon_weak, "non-weak"); /* obsolete */
1457 1500
1458 defkeyword (&Q_test, ":test"); 1501 defkeyword (&Q_test, ":test");
1459 defkeyword (&Q_size, ":size"); 1502 defkeyword (&Q_size, ":size");