comparison src/elhash.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents de805c49cfc1
children 41dbb7a9d5f2
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
25 #include <config.h> 25 #include <config.h>
26 #include "lisp.h" 26 #include "lisp.h"
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, Qhashtable, Qhash_table;
31 static Lisp_Object Qhashtable, Qhash_table; 31 Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qnon_weak;
32 static Lisp_Object Qweakness, Qvalue, Qkey_value;
33 static Lisp_Object Vall_weak_hash_tables; 32 static Lisp_Object Vall_weak_hash_tables;
34 static Lisp_Object Qrehash_size, Qrehash_threshold; 33 static Lisp_Object Qrehash_size, Qrehash_threshold;
35 static Lisp_Object Q_size, Q_test, Q_weakness, Q_rehash_size, Q_rehash_threshold; 34 static Lisp_Object Q_size, Q_test, Q_type, Q_rehash_size, Q_rehash_threshold;
36
37 /* obsolete as of 19990901 in xemacs-21.2 */
38 static Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qkey_value_weak;
39 static Lisp_Object Qnon_weak, Q_type;
40 35
41 typedef struct hentry 36 typedef struct hentry
42 { 37 {
43 Lisp_Object key; 38 Lisp_Object key;
44 Lisp_Object value; 39 Lisp_Object value;
54 double rehash_threshold; 49 double rehash_threshold;
55 size_t golden_ratio; 50 size_t golden_ratio;
56 hash_table_hash_function_t hash_function; 51 hash_table_hash_function_t hash_function;
57 hash_table_test_function_t test_function; 52 hash_table_test_function_t test_function;
58 hentry *hentries; 53 hentry *hentries;
59 enum hash_table_weakness weakness; 54 enum hash_table_type type; /* whether and how this hash table is weak */
60 Lisp_Object next_weak; /* Used to chain together all of the weak 55 Lisp_Object next_weak; /* Used to chain together all of the weak
61 hash tables. Don't mark through this. */ 56 hash tables. Don't mark through this. */
62 }; 57 };
58 typedef struct Lisp_Hash_Table Lisp_Hash_Table;
63 59
64 #define HENTRY_CLEAR_P(hentry) ((*(EMACS_UINT*)(&((hentry)->key))) == 0) 60 #define HENTRY_CLEAR_P(hentry) ((*(EMACS_UINT*)(&((hentry)->key))) == 0)
65 #define CLEAR_HENTRY(hentry) \ 61 #define CLEAR_HENTRY(hentry) ((*(EMACS_UINT*)(&((hentry)->key))) = 0)
66 ((*(EMACS_UINT*)(&((hentry)->key))) = 0, \
67 (*(EMACS_UINT*)(&((hentry)->value))) = 0)
68 62
69 #define HASH_TABLE_DEFAULT_SIZE 16 63 #define HASH_TABLE_DEFAULT_SIZE 16
70 #define HASH_TABLE_DEFAULT_REHASH_SIZE 1.3 64 #define HASH_TABLE_DEFAULT_REHASH_SIZE 1.3
71 #define HASH_TABLE_MIN_SIZE 10 65 #define HASH_TABLE_MIN_SIZE 10
72 66
73 #define HASH_CODE(key, ht) \ 67 #define HASH_CODE(key, ht) \
74 ((((ht)->hash_function ? (ht)->hash_function (key) : LISP_HASH (key)) \ 68 (((((ht)->hash_function ? (ht)->hash_function (key) : LISP_HASH (key)) \
75 * (ht)->golden_ratio) \ 69 * (ht)->golden_ratio) \
76 % (ht)->size) 70 % (ht)->size))
77 71
78 #define KEYS_EQUAL_P(key1, key2, testfun) \ 72 #define KEYS_EQUAL_P(key1, key2, testfun) \
79 (EQ (key1, key2) || ((testfun) && (testfun) (key1, key2))) 73 (EQ ((key1), (key2)) || ((testfun) && (testfun) ((key1), (key2))))
80 74
81 #define LINEAR_PROBING_LOOP(probe, entries, size) \ 75 #define LINEAR_PROBING_LOOP(probe, entries, size) \
82 for (; \ 76 for (; \
83 !HENTRY_CLEAR_P (probe) || \ 77 !HENTRY_CLEAR_P (probe) || \
84 (probe == entries + size ? \ 78 (probe == entries + size ? \
121 hash_table_size (size_t requested_size) 115 hash_table_size (size_t requested_size)
122 { 116 {
123 /* Return some prime near, but greater than or equal to, SIZE. 117 /* Return some prime near, but greater than or equal to, SIZE.
124 Decades from the time of writing, someone will have a system large 118 Decades from the time of writing, someone will have a system large
125 enough that the list below will be too short... */ 119 enough that the list below will be too short... */
126 static const size_t primes [] = 120 static CONST size_t primes [] =
127 { 121 {
128 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031, 122 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031,
129 1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783, 123 1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783,
130 19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941, 124 19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941,
131 204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519, 125 204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519,
194 return internal_hash (obj, 0); 188 return internal_hash (obj, 0);
195 } 189 }
196 190
197 191
198 static Lisp_Object 192 static Lisp_Object
199 mark_hash_table (Lisp_Object obj) 193 mark_hash_table (Lisp_Object obj, void (*markobj) (Lisp_Object))
200 { 194 {
201 Lisp_Hash_Table *ht = XHASH_TABLE (obj); 195 Lisp_Hash_Table *ht = XHASH_TABLE (obj);
202 196
203 /* If the hash table is weak, we don't want to mark the keys and 197 /* If the hash table is weak, we don't want to mark the keys and
204 values (we scan over them after everything else has been marked, 198 values (we scan over them after everything else has been marked,
205 and mark or remove them as necessary). */ 199 and mark or remove them as necessary). */
206 if (ht->weakness == HASH_TABLE_NON_WEAK) 200 if (ht->type == HASH_TABLE_NON_WEAK)
207 { 201 {
208 hentry *e, *sentinel; 202 hentry *e, *sentinel;
209 203
210 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) 204 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
211 if (!HENTRY_CLEAR_P (e)) 205 if (!HENTRY_CLEAR_P (e))
212 { 206 {
213 mark_object (e->key); 207 markobj (e->key);
214 mark_object (e->value); 208 markobj (e->value);
215 } 209 }
216 } 210 }
217 return Qnil; 211 return Qnil;
218 } 212 }
219 213
220 /* Equality of hash tables. Two hash tables are equal when they are of 214 /* Equality of hash tables. Two hash tables are equal when they are of
221 the same weakness and test function, they have the same number of 215 the same type and test function, they have the same number of
222 elements, and for each key in the hash table, the values are `equal'. 216 elements, and for each key in the hash table, the values are `equal'.
223 217
224 This is similar to Common Lisp `equalp' of hash tables, with the 218 This is similar to Common Lisp `equalp' of hash tables, with the
225 difference that CL requires the keys to be compared with the test 219 difference that CL requires the keys to be compared with the test
226 function, which we don't do. Doing that would require consing, and 220 function, which we don't do. Doing that would require consing, and
233 Lisp_Hash_Table *ht1 = XHASH_TABLE (hash_table1); 227 Lisp_Hash_Table *ht1 = XHASH_TABLE (hash_table1);
234 Lisp_Hash_Table *ht2 = XHASH_TABLE (hash_table2); 228 Lisp_Hash_Table *ht2 = XHASH_TABLE (hash_table2);
235 hentry *e, *sentinel; 229 hentry *e, *sentinel;
236 230
237 if ((ht1->test_function != ht2->test_function) || 231 if ((ht1->test_function != ht2->test_function) ||
238 (ht1->weakness != ht2->weakness) || 232 (ht1->type != ht2->type) ||
239 (ht1->count != ht2->count)) 233 (ht1->count != ht2->count))
240 return 0; 234 return 0;
241 235
242 depth++; 236 depth++;
243 237
251 return 0; /* Give up */ 245 return 0; /* Give up */
252 } 246 }
253 247
254 return 1; 248 return 1;
255 } 249 }
256
257 /* This is not a great hash function, but it _is_ correct and fast.
258 Examining all entries is too expensive, and examining a random
259 subset does not yield a correct hash function. */
260 static hashcode_t
261 hash_table_hash (Lisp_Object hash_table, int depth)
262 {
263 return XHASH_TABLE (hash_table)->count;
264 }
265
266 250
267 /* Printing hash tables. 251 /* Printing hash tables.
268 252
269 This is non-trivial, because we use a readable structure-style 253 This is non-trivial, because we use a readable structure-style
270 syntax for hash tables. This means that a typical hash table will be 254 syntax for hash tables. This means that a typical hash table will be
271 readably printed in the form of: 255 readably printed in the form of:
272 256
273 #s(hash-table size 2 data (key1 value1 key2 value2)) 257 #s(hash-table size 2 data (key1 value1 key2 value2))
274 258
275 The supported hash table structure keywords and their values are: 259 The supported keywords are `type' (non-weak (or nil), weak,
276 `test' (eql (or nil), eq or equal) 260 key-weak and value-weak), `test' (eql (or nil), eq or equal),
277 `size' (a natnum or nil) 261 `size' (a natnum or nil) and `data' (a list).
278 `rehash-size' (a float) 262
279 `rehash-threshold' (a float) 263 If `print-readably' is non-nil, then a simpler syntax is used; for
280 `weakness' (nil, t, key or value) 264 instance:
281 `data' (a list)
282
283 If `print-readably' is nil, then a simpler syntax is used, for example
284 265
285 #<hash-table size 2/13 data (key1 value1 key2 value2) 0x874d> 266 #<hash-table size 2/13 data (key1 value1 key2 value2) 0x874d>
286 267
287 The data is truncated to four pairs, and the rest is shown with 268 The data is truncated to four pairs, and the rest is shown with
288 `...'. This printer does not cons. */ 269 `...'. This printer does not cons. */
324 char buf[128]; 305 char buf[128];
325 306
326 write_c_string (print_readably ? "#s(hash-table" : "#<hash-table", 307 write_c_string (print_readably ? "#s(hash-table" : "#<hash-table",
327 printcharfun); 308 printcharfun);
328 309
310 if (ht->type != HASH_TABLE_NON_WEAK)
311 {
312 sprintf (buf, " type %s",
313 (ht->type == HASH_TABLE_WEAK ? "weak" :
314 ht->type == HASH_TABLE_KEY_WEAK ? "key-weak" :
315 ht->type == HASH_TABLE_VALUE_WEAK ? "value-weak" :
316 "you-d-better-not-see-this"));
317 write_c_string (buf, printcharfun);
318 }
319
329 /* These checks have a kludgy look to them, but they are safe. 320 /* These checks have a kludgy look to them, but they are safe.
330 Due to nature of hashing, you cannot use arbitrary 321 Due to nature of hashing, you cannot use arbitrary
331 test functions anyway. */ 322 test functions anyway. */
332 if (!ht->test_function) 323 if (!ht->test_function)
333 write_c_string (" test eq", printcharfun); 324 write_c_string (" test eq", printcharfun);
347 (unsigned long) ht->count, 338 (unsigned long) ht->count,
348 (unsigned long) ht->size); 339 (unsigned long) ht->size);
349 write_c_string (buf, printcharfun); 340 write_c_string (buf, printcharfun);
350 } 341 }
351 342
352 if (ht->weakness != HASH_TABLE_NON_WEAK)
353 {
354 sprintf (buf, " weakness %s",
355 (ht->weakness == HASH_TABLE_WEAK ? "t" :
356 ht->weakness == HASH_TABLE_KEY_WEAK ? "key" :
357 ht->weakness == HASH_TABLE_VALUE_WEAK ? "value" :
358 ht->weakness == HASH_TABLE_KEY_VALUE_WEAK ? "key-value" :
359 "you-d-better-not-see-this"));
360 write_c_string (buf, printcharfun);
361 }
362
363 if (ht->count) 343 if (ht->count)
364 print_hash_table_data (ht, printcharfun); 344 print_hash_table_data (ht, printcharfun);
365 345
366 if (print_readably) 346 if (print_readably)
367 write_c_string (")", printcharfun); 347 write_c_string (")", printcharfun);
382 xfree (ht->hentries); 362 xfree (ht->hentries);
383 ht->hentries = 0; 363 ht->hentries = 0;
384 } 364 }
385 } 365 }
386 366
387 static const struct lrecord_description hentry_description_1[] = {
388 { XD_LISP_OBJECT, offsetof (hentry, key) },
389 { XD_LISP_OBJECT, offsetof (hentry, value) },
390 { XD_END }
391 };
392
393 static const struct struct_description hentry_description = {
394 sizeof (hentry),
395 hentry_description_1
396 };
397
398 const struct lrecord_description hash_table_description[] = {
399 { XD_SIZE_T, offsetof (Lisp_Hash_Table, size) },
400 { XD_STRUCT_PTR, offsetof (Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), &hentry_description },
401 { XD_LO_LINK, offsetof (Lisp_Hash_Table, next_weak) },
402 { XD_END }
403 };
404
405 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table, 367 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table,
406 mark_hash_table, print_hash_table, 368 mark_hash_table, print_hash_table,
407 finalize_hash_table, 369 finalize_hash_table,
408 hash_table_equal, hash_table_hash, 370 /* #### Implement hash_table_hash()! */
409 hash_table_description, 371 hash_table_equal, 0,
410 Lisp_Hash_Table); 372 Lisp_Hash_Table);
411 373
412 static Lisp_Hash_Table * 374 static Lisp_Hash_Table *
413 xhash_table (Lisp_Object hash_table) 375 xhash_table (Lisp_Object hash_table)
414 { 376 {
422 /************************************************************************/ 384 /************************************************************************/
423 /* Creation of Hash Tables */ 385 /* Creation of Hash Tables */
424 /************************************************************************/ 386 /************************************************************************/
425 387
426 /* Creation of hash tables, without error-checking. */ 388 /* Creation of hash tables, without error-checking. */
389 static double
390 hash_table_rehash_threshold (Lisp_Hash_Table *ht)
391 {
392 return
393 ht->rehash_threshold > 0.0 ? ht->rehash_threshold :
394 ht->size > 4096 && !ht->test_function ? 0.7 : 0.6;
395 }
396
427 static void 397 static void
428 compute_hash_table_derived_values (Lisp_Hash_Table *ht) 398 compute_hash_table_derived_values (Lisp_Hash_Table *ht)
429 { 399 {
430 ht->rehash_count = (size_t) 400 ht->rehash_count = (size_t)
431 ((double) ht->size * ht->rehash_threshold); 401 ((double) ht->size * hash_table_rehash_threshold (ht));
432 ht->golden_ratio = (size_t) 402 ht->golden_ratio = (size_t)
433 ((double) ht->size * (.6180339887 / (double) sizeof (Lisp_Object))); 403 ((double) ht->size * (.6180339887 / (double) sizeof (Lisp_Object)));
434 } 404 }
435 405
436 Lisp_Object 406 Lisp_Object
437 make_general_lisp_hash_table (enum hash_table_test test, 407 make_general_lisp_hash_table (size_t size,
438 size_t size, 408 enum hash_table_type type,
439 double rehash_size, 409 enum hash_table_test test,
440 double rehash_threshold, 410 double rehash_size,
441 enum hash_table_weakness weakness) 411 double rehash_threshold)
442 { 412 {
443 Lisp_Object hash_table; 413 Lisp_Object hash_table;
444 Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table); 414 Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
415
416 ht->type = type;
417 ht->rehash_size = rehash_size;
418 ht->rehash_threshold = rehash_threshold;
445 419
446 switch (test) 420 switch (test)
447 { 421 {
448 case HASH_TABLE_EQ: 422 case HASH_TABLE_EQ:
449 ht->test_function = 0; 423 ht->test_function = 0;
462 436
463 default: 437 default:
464 abort (); 438 abort ();
465 } 439 }
466 440
467 ht->weakness = weakness; 441 if (ht->rehash_size <= 0.0)
468 442 ht->rehash_size = HASH_TABLE_DEFAULT_REHASH_SIZE;
469 ht->rehash_size =
470 rehash_size > 1.0 ? rehash_size : HASH_TABLE_DEFAULT_REHASH_SIZE;
471
472 ht->rehash_threshold =
473 rehash_threshold > 0.0 ? rehash_threshold :
474 size > 4096 && !ht->test_function ? 0.7 : 0.6;
475
476 if (size < HASH_TABLE_MIN_SIZE) 443 if (size < HASH_TABLE_MIN_SIZE)
477 size = HASH_TABLE_MIN_SIZE; 444 size = HASH_TABLE_MIN_SIZE;
478 ht->size = hash_table_size ((size_t) (((double) size / ht->rehash_threshold) 445 if (rehash_threshold < 0.0)
479 + 1.0)); 446 rehash_threshold = 0.75;
447 ht->size =
448 hash_table_size ((size_t) ((double) size / hash_table_rehash_threshold (ht)) + 1);
480 ht->count = 0; 449 ht->count = 0;
481
482 compute_hash_table_derived_values (ht); 450 compute_hash_table_derived_values (ht);
483 451
484 /* We leave room for one never-occupied sentinel hentry at the end. */ 452 /* We leave room for one never-occupied sentinel hentry at the end. */
485 ht->hentries = xnew_array (hentry, ht->size + 1); 453 ht->hentries = xnew_array (hentry, ht->size + 1);
486 454
490 CLEAR_HENTRY (e); 458 CLEAR_HENTRY (e);
491 } 459 }
492 460
493 XSETHASH_TABLE (hash_table, ht); 461 XSETHASH_TABLE (hash_table, ht);
494 462
495 if (weakness == HASH_TABLE_NON_WEAK) 463 if (type == HASH_TABLE_NON_WEAK)
496 ht->next_weak = Qunbound; 464 ht->next_weak = Qunbound;
497 else 465 else
498 ht->next_weak = Vall_weak_hash_tables, Vall_weak_hash_tables = hash_table; 466 ht->next_weak = Vall_weak_hash_tables, Vall_weak_hash_tables = hash_table;
499 467
500 return hash_table; 468 return hash_table;
501 } 469 }
502 470
503 Lisp_Object 471 Lisp_Object
504 make_lisp_hash_table (size_t size, 472 make_lisp_hash_table (size_t size,
505 enum hash_table_weakness weakness, 473 enum hash_table_type type,
506 enum hash_table_test test) 474 enum hash_table_test test)
507 { 475 {
508 return make_general_lisp_hash_table (test, size, -1.0, -1.0, weakness); 476 return make_general_lisp_hash_table (size, type, test,
477 HASH_TABLE_DEFAULT_REHASH_SIZE, -1.0);
509 } 478 }
510 479
511 /* Pretty reading of hash tables. 480 /* Pretty reading of hash tables.
512 481
513 Here we use the existing structures mechanism (which is, 482 Here we use the existing structures mechanism (which is,
536 { 505 {
537 return NILP (obj) ? HASH_TABLE_DEFAULT_SIZE : XINT (obj); 506 return NILP (obj) ? HASH_TABLE_DEFAULT_SIZE : XINT (obj);
538 } 507 }
539 508
540 static int 509 static int
541 hash_table_weakness_validate (Lisp_Object keyword, Lisp_Object value, 510 hash_table_type_validate (Lisp_Object keyword, Lisp_Object value,
542 Error_behavior errb) 511 Error_behavior errb)
543 { 512 {
544 if (EQ (value, Qnil)) return 1; 513 if (EQ (value, Qnil)) return 1;
545 if (EQ (value, Qt)) return 1;
546 if (EQ (value, Qkey)) return 1;
547 if (EQ (value, Qkey_value)) return 1;
548 if (EQ (value, Qvalue)) return 1;
549
550 /* Following values are obsolete as of 19990901 in xemacs-21.2 */
551 if (EQ (value, Qnon_weak)) return 1; 514 if (EQ (value, Qnon_weak)) return 1;
552 if (EQ (value, Qweak)) return 1; 515 if (EQ (value, Qweak)) return 1;
553 if (EQ (value, Qkey_weak)) return 1; 516 if (EQ (value, Qkey_weak)) return 1;
554 if (EQ (value, Qkey_value_weak)) return 1;
555 if (EQ (value, Qvalue_weak)) return 1; 517 if (EQ (value, Qvalue_weak)) return 1;
556 518
557 maybe_signal_simple_error ("Invalid hash table weakness", 519 maybe_signal_simple_error ("Invalid hash table type",
558 value, Qhash_table, errb); 520 value, Qhash_table, errb);
559 return 0; 521 return 0;
560 } 522 }
561 523
562 static enum hash_table_weakness 524 static enum hash_table_type
563 decode_hash_table_weakness (Lisp_Object obj) 525 decode_hash_table_type (Lisp_Object obj)
564 { 526 {
565 if (EQ (obj, Qnil)) return HASH_TABLE_NON_WEAK; 527 if (EQ (obj, Qnil)) return HASH_TABLE_NON_WEAK;
566 if (EQ (obj, Qt)) return HASH_TABLE_WEAK;
567 if (EQ (obj, Qkey)) return HASH_TABLE_KEY_WEAK;
568 if (EQ (obj, Qkey_value)) return HASH_TABLE_KEY_VALUE_WEAK;
569 if (EQ (obj, Qvalue)) return HASH_TABLE_VALUE_WEAK;
570
571 /* Following values are obsolete as of 19990901 in xemacs-21.2 */
572 if (EQ (obj, Qnon_weak)) return HASH_TABLE_NON_WEAK; 528 if (EQ (obj, Qnon_weak)) return HASH_TABLE_NON_WEAK;
573 if (EQ (obj, Qweak)) return HASH_TABLE_WEAK; 529 if (EQ (obj, Qweak)) return HASH_TABLE_WEAK;
574 if (EQ (obj, Qkey_weak)) return HASH_TABLE_KEY_WEAK; 530 if (EQ (obj, Qkey_weak)) return HASH_TABLE_KEY_WEAK;
575 if (EQ (obj, Qkey_value_weak)) return HASH_TABLE_KEY_VALUE_WEAK;
576 if (EQ (obj, Qvalue_weak)) return HASH_TABLE_VALUE_WEAK; 531 if (EQ (obj, Qvalue_weak)) return HASH_TABLE_VALUE_WEAK;
577 532
578 signal_simple_error ("Invalid hash table weakness", obj); 533 signal_simple_error ("Invalid hash table type", obj);
579 return HASH_TABLE_NON_WEAK; /* not reached */ 534 return HASH_TABLE_NON_WEAK; /* not reached */
580 } 535 }
581 536
582 static int 537 static int
583 hash_table_test_validate (Lisp_Object keyword, Lisp_Object value, 538 hash_table_test_validate (Lisp_Object keyword, Lisp_Object value,
605 return HASH_TABLE_EQ; /* not reached */ 560 return HASH_TABLE_EQ; /* not reached */
606 } 561 }
607 562
608 static int 563 static int
609 hash_table_rehash_size_validate (Lisp_Object keyword, Lisp_Object value, 564 hash_table_rehash_size_validate (Lisp_Object keyword, Lisp_Object value,
610 Error_behavior errb) 565 Error_behavior errb)
611 { 566 {
612 if (!FLOATP (value)) 567 if (!FLOATP (value))
613 { 568 {
614 maybe_signal_error (Qwrong_type_argument, list2 (Qfloatp, value), 569 maybe_signal_error (Qwrong_type_argument, list2 (Qfloatp, value),
615 Qhash_table, errb); 570 Qhash_table, errb);
694 static Lisp_Object 649 static Lisp_Object
695 hash_table_instantiate (Lisp_Object plist) 650 hash_table_instantiate (Lisp_Object plist)
696 { 651 {
697 Lisp_Object hash_table; 652 Lisp_Object hash_table;
698 Lisp_Object test = Qnil; 653 Lisp_Object test = Qnil;
654 Lisp_Object type = Qnil;
699 Lisp_Object size = Qnil; 655 Lisp_Object size = Qnil;
656 Lisp_Object data = Qnil;
700 Lisp_Object rehash_size = Qnil; 657 Lisp_Object rehash_size = Qnil;
701 Lisp_Object rehash_threshold = Qnil; 658 Lisp_Object rehash_threshold = Qnil;
702 Lisp_Object weakness = Qnil;
703 Lisp_Object data = Qnil;
704 659
705 while (!NILP (plist)) 660 while (!NILP (plist))
706 { 661 {
707 Lisp_Object key, value; 662 Lisp_Object key, value;
708 key = XCAR (plist); plist = XCDR (plist); 663 key = XCAR (plist); plist = XCDR (plist);
709 value = XCAR (plist); plist = XCDR (plist); 664 value = XCAR (plist); plist = XCDR (plist);
710 665
711 if (EQ (key, Qtest)) test = value; 666 if (EQ (key, Qtest)) test = value;
667 else if (EQ (key, Qtype)) type = value;
712 else if (EQ (key, Qsize)) size = value; 668 else if (EQ (key, Qsize)) size = value;
669 else if (EQ (key, Qdata)) data = value;
713 else if (EQ (key, Qrehash_size)) rehash_size = value; 670 else if (EQ (key, Qrehash_size)) rehash_size = value;
714 else if (EQ (key, Qrehash_threshold)) rehash_threshold = value; 671 else if (EQ (key, Qrehash_threshold)) rehash_threshold = value;
715 else if (EQ (key, Qweakness)) weakness = value;
716 else if (EQ (key, Qdata)) data = value;
717 else if (EQ (key, Qtype))/*obsolete*/ weakness = value;
718 else 672 else
719 abort (); 673 abort ();
720 } 674 }
721 675
722 /* Create the hash table. */ 676 /* Create the hash table. */
723 hash_table = make_general_lisp_hash_table 677 hash_table = make_general_lisp_hash_table
724 (decode_hash_table_test (test), 678 (decode_hash_table_size (size),
725 decode_hash_table_size (size), 679 decode_hash_table_type (type),
680 decode_hash_table_test (test),
726 decode_hash_table_rehash_size (rehash_size), 681 decode_hash_table_rehash_size (rehash_size),
727 decode_hash_table_rehash_threshold (rehash_threshold), 682 decode_hash_table_rehash_threshold (rehash_threshold));
728 decode_hash_table_weakness (weakness));
729 683
730 /* I'm not sure whether this can GC, but better safe than sorry. */ 684 /* I'm not sure whether this can GC, but better safe than sorry. */
731 { 685 {
732 struct gcpro gcpro1; 686 struct gcpro gcpro1;
733 GCPRO1 (hash_table); 687 GCPRO1 (hash_table);
750 structure_type_create_hash_table_structure_name (Lisp_Object structure_name) 704 structure_type_create_hash_table_structure_name (Lisp_Object structure_name)
751 { 705 {
752 struct structure_type *st; 706 struct structure_type *st;
753 707
754 st = define_structure_type (structure_name, 0, hash_table_instantiate); 708 st = define_structure_type (structure_name, 0, hash_table_instantiate);
709 define_structure_type_keyword (st, Qsize, hash_table_size_validate);
755 define_structure_type_keyword (st, Qtest, hash_table_test_validate); 710 define_structure_type_keyword (st, Qtest, hash_table_test_validate);
756 define_structure_type_keyword (st, Qsize, hash_table_size_validate); 711 define_structure_type_keyword (st, Qtype, hash_table_type_validate);
712 define_structure_type_keyword (st, Qdata, hash_table_data_validate);
757 define_structure_type_keyword (st, Qrehash_size, hash_table_rehash_size_validate); 713 define_structure_type_keyword (st, Qrehash_size, hash_table_rehash_size_validate);
758 define_structure_type_keyword (st, Qrehash_threshold, hash_table_rehash_threshold_validate); 714 define_structure_type_keyword (st, Qrehash_threshold, hash_table_rehash_threshold_validate);
759 define_structure_type_keyword (st, Qweakness, hash_table_weakness_validate);
760 define_structure_type_keyword (st, Qdata, hash_table_data_validate);
761
762 /* obsolete as of 19990901 in xemacs-21.2 */
763 define_structure_type_keyword (st, Qtype, hash_table_weakness_validate);
764 } 715 }
765 716
766 /* Create a built-in Lisp structure type named `hash-table'. 717 /* Create a built-in Lisp structure type named `hash-table'.
767 We make #s(hashtable ...) equivalent to #s(hash-table ...), 718 We make #s(hashtable ...) equivalent to #s(hash-table ...),
768 for backward compatibility. 719 for backward comptabibility.
769 This is called from emacs.c. */ 720 This is called from emacs.c. */
770 void 721 void
771 structure_type_create_hash_table (void) 722 structure_type_create_hash_table (void)
772 { 723 {
773 structure_type_create_hash_table_structure_name (Qhash_table); 724 structure_type_create_hash_table_structure_name (Qhash_table);
788 } 739 }
789 740
790 DEFUN ("make-hash-table", Fmake_hash_table, 0, MANY, 0, /* 741 DEFUN ("make-hash-table", Fmake_hash_table, 0, MANY, 0, /*
791 Return a new empty hash table object. 742 Return a new empty hash table object.
792 Use Common Lisp style keywords to specify hash table properties. 743 Use Common Lisp style keywords to specify hash table properties.
793 (make-hash-table &key test size rehash-size rehash-threshold weakness) 744 (make-hash-table &key :size :test :type :rehash-size :rehash-threshold)
745
746 Keyword :size specifies the number of keys likely to be inserted.
747 This number of entries can be inserted without enlarging the hash table.
794 748
795 Keyword :test can be `eq', `eql' (default) or `equal'. 749 Keyword :test can be `eq', `eql' (default) or `equal'.
796 Comparison between keys is done using this function. 750 Comparison between keys is done using this function.
797 If speed is important, consider using `eq'. 751 If speed is important, consider using `eq'.
798 When storing strings in the hash table, you will likely need to use `equal'. 752 When storing strings in the hash table, you will likely need to use `equal'.
799 753
800 Keyword :size specifies the number of keys likely to be inserted. 754 Keyword :type can be `non-weak' (default), `weak', `key-weak' or `value-weak'.
801 This number of entries can be inserted without enlarging the hash table.
802
803 Keyword :rehash-size must be a float greater than 1.0, and specifies
804 the factor by which to increase the size of the hash table when enlarging.
805
806 Keyword :rehash-threshold must be a float between 0.0 and 1.0,
807 and specifies the load factor of the hash table which triggers enlarging.
808
809 Non-standard keyword :weakness can be `nil' (default), `t', `key', `value'
810 or `key-value'.
811 755
812 A weak hash table is one whose pointers do not count as GC referents: 756 A weak hash table is one whose pointers do not count as GC referents:
813 for any key-value pair in the hash table, if the only remaining pointer 757 for any key-value pair in the hash table, if the only remaining pointer
814 to either the key or the value is in a weak hash table, then the pair 758 to either the key or the value is in a weak hash table, then the pair
815 will be removed from the hash table, and the key and value collected. 759 will be removed from the hash table, and the key and value collected.
826 that a key-value pair will be removed only if the value remains 770 that a key-value pair will be removed only if the value remains
827 unmarked outside of weak hash tables. The pair will remain in the 771 unmarked outside of weak hash tables. The pair will remain in the
828 hash table if the value is pointed to by something other than a weak 772 hash table if the value is pointed to by something other than a weak
829 hash table, even if the key is not. 773 hash table, even if the key is not.
830 774
831 A key-value-weak hash table is similar to a fully-weak hash table except 775 Keyword :rehash-size must be a float greater than 1.0, and specifies
832 that a key-value pair will be removed only if the value and the key remain 776 the factor by which to increase the size of the hash table when enlarging.
833 unmarked outside of weak hash tables. The pair will remain in the 777
834 hash table if the value or key are pointed to by something other than a weak 778 Keyword :rehash-threshold must be a float between 0.0 and 1.0,
835 hash table, even if the other is not. 779 and specifies the load factor of the hash table which triggers enlarging.
780
836 */ 781 */
837 (int nargs, Lisp_Object *args)) 782 (int nargs, Lisp_Object *args))
838 { 783 {
839 int i = 0; 784 int j = 0;
785 Lisp_Object size = Qnil;
786 Lisp_Object type = Qnil;
840 Lisp_Object test = Qnil; 787 Lisp_Object test = Qnil;
841 Lisp_Object size = Qnil;
842 Lisp_Object rehash_size = Qnil; 788 Lisp_Object rehash_size = Qnil;
843 Lisp_Object rehash_threshold = Qnil; 789 Lisp_Object rehash_threshold = Qnil;
844 Lisp_Object weakness = Qnil; 790
845 791 while (j < nargs)
846 while (i + 1 < nargs) 792 {
847 { 793 Lisp_Object keyword, value;
848 Lisp_Object keyword = args[i++]; 794
849 Lisp_Object value = args[i++]; 795 keyword = args[j++];
850 796 if (!KEYWORDP (keyword))
851 if (EQ (keyword, Q_test)) test = value; 797 signal_simple_error ("Invalid hash table property keyword", keyword);
852 else if (EQ (keyword, Q_size)) size = value; 798 if (j == nargs)
799 signal_simple_error ("Hash table property requires a value", keyword);
800
801 value = args[j++];
802
803 if (EQ (keyword, Q_size)) size = value;
804 else if (EQ (keyword, Q_type)) type = value;
805 else if (EQ (keyword, Q_test)) test = value;
853 else if (EQ (keyword, Q_rehash_size)) rehash_size = value; 806 else if (EQ (keyword, Q_rehash_size)) rehash_size = value;
854 else if (EQ (keyword, Q_rehash_threshold)) rehash_threshold = value; 807 else if (EQ (keyword, Q_rehash_threshold)) rehash_threshold = value;
855 else if (EQ (keyword, Q_weakness)) weakness = value;
856 else if (EQ (keyword, Q_type))/*obsolete*/ weakness = value;
857 else signal_simple_error ("Invalid hash table property keyword", keyword); 808 else signal_simple_error ("Invalid hash table property keyword", keyword);
858 } 809 }
859
860 if (i < nargs)
861 signal_simple_error ("Hash table property requires a value", args[i]);
862 810
863 #define VALIDATE_VAR(var) \ 811 #define VALIDATE_VAR(var) \
864 if (!NILP (var)) hash_table_##var##_validate (Q##var, var, ERROR_ME); 812 if (!NILP (var)) hash_table_##var##_validate (Q##var, var, ERROR_ME);
865 813
814 VALIDATE_VAR (size);
815 VALIDATE_VAR (type);
866 VALIDATE_VAR (test); 816 VALIDATE_VAR (test);
867 VALIDATE_VAR (size);
868 VALIDATE_VAR (rehash_size); 817 VALIDATE_VAR (rehash_size);
869 VALIDATE_VAR (rehash_threshold); 818 VALIDATE_VAR (rehash_threshold);
870 VALIDATE_VAR (weakness);
871 819
872 return make_general_lisp_hash_table 820 return make_general_lisp_hash_table
873 (decode_hash_table_test (test), 821 (decode_hash_table_size (size),
874 decode_hash_table_size (size), 822 decode_hash_table_type (type),
823 decode_hash_table_test (test),
875 decode_hash_table_rehash_size (rehash_size), 824 decode_hash_table_rehash_size (rehash_size),
876 decode_hash_table_rehash_threshold (rehash_threshold), 825 decode_hash_table_rehash_threshold (rehash_threshold));
877 decode_hash_table_weakness (weakness));
878 } 826 }
879 827
880 DEFUN ("copy-hash-table", Fcopy_hash_table, 1, 1, 0, /* 828 DEFUN ("copy-hash-table", Fcopy_hash_table, 1, 1, 0, /*
881 Return a new hash table containing the same keys and values as HASH-TABLE. 829 Return a new hash table containing the same keys and values as HASH-TABLE.
882 The keys and values will not themselves be copied. 830 The keys and values will not themselves be copied.
883 */ 831 */
884 (hash_table)) 832 (hash_table))
885 { 833 {
886 const Lisp_Hash_Table *ht_old = xhash_table (hash_table); 834 CONST Lisp_Hash_Table *ht_old = xhash_table (hash_table);
887 Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table); 835 Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
888 836
889 copy_lcrecord (ht, ht_old); 837 copy_lcrecord (ht, ht_old);
890 838
891 ht->hentries = xnew_array (hentry, ht_old->size + 1); 839 ht->hentries = xnew_array (hentry, ht_old->size + 1);
901 849
902 return hash_table; 850 return hash_table;
903 } 851 }
904 852
905 static void 853 static void
906 resize_hash_table (Lisp_Hash_Table *ht, size_t new_size) 854 enlarge_hash_table (Lisp_Hash_Table *ht)
907 { 855 {
908 hentry *old_entries, *new_entries, *sentinel, *e; 856 hentry *old_entries, *new_entries, *old_sentinel, *new_sentinel, *e;
909 size_t old_size; 857 size_t old_size, new_size;
910 858
911 old_size = ht->size; 859 old_size = ht->size;
912 ht->size = new_size; 860 new_size = ht->size =
861 hash_table_size ((size_t) ((double) old_size * ht->rehash_size));
913 862
914 old_entries = ht->hentries; 863 old_entries = ht->hentries;
915 864
916 ht->hentries = xnew_array_and_zero (hentry, new_size + 1); 865 ht->hentries = xnew_array (hentry, new_size + 1);
917 new_entries = ht->hentries; 866 new_entries = ht->hentries;
918 867
868 old_sentinel = old_entries + old_size;
869 new_sentinel = new_entries + new_size;
870
871 for (e = new_entries; e <= new_sentinel; e++)
872 CLEAR_HENTRY (e);
873
919 compute_hash_table_derived_values (ht); 874 compute_hash_table_derived_values (ht);
920 875
921 for (e = old_entries, sentinel = e + old_size; e < sentinel; e++) 876 for (e = old_entries; e < old_sentinel; e++)
922 if (!HENTRY_CLEAR_P (e)) 877 if (!HENTRY_CLEAR_P (e))
923 { 878 {
924 hentry *probe = new_entries + HASH_CODE (e->key, ht); 879 hentry *probe = new_entries + HASH_CODE (e->key, ht);
925 LINEAR_PROBING_LOOP (probe, new_entries, new_size) 880 LINEAR_PROBING_LOOP (probe, new_entries, new_size)
926 ; 881 ;
927 *probe = *e; 882 *probe = *e;
928 } 883 }
929 884
930 if (!DUMPEDP (old_entries)) 885 xfree (old_entries);
931 xfree (old_entries);
932 }
933
934 /* After a hash table has been saved to disk and later restored by the
935 portable dumper, it contains the same objects, but their addresses
936 and thus their HASH_CODEs have changed. */
937 void
938 pdump_reorganize_hash_table (Lisp_Object hash_table)
939 {
940 const Lisp_Hash_Table *ht = xhash_table (hash_table);
941 hentry *new_entries = xnew_array_and_zero (hentry, ht->size + 1);
942 hentry *e, *sentinel;
943
944 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
945 if (!HENTRY_CLEAR_P (e))
946 {
947 hentry *probe = new_entries + HASH_CODE (e->key, ht);
948 LINEAR_PROBING_LOOP (probe, new_entries, ht->size)
949 ;
950 *probe = *e;
951 }
952
953 memcpy (ht->hentries, new_entries, ht->size * sizeof (hentry));
954
955 xfree (new_entries);
956 }
957
958 static void
959 enlarge_hash_table (Lisp_Hash_Table *ht)
960 {
961 size_t new_size =
962 hash_table_size ((size_t) ((double) ht->size * ht->rehash_size));
963 resize_hash_table (ht, new_size);
964 } 886 }
965 887
966 static hentry * 888 static hentry *
967 find_hentry (Lisp_Object key, const Lisp_Hash_Table *ht) 889 find_hentry (Lisp_Object key, CONST Lisp_Hash_Table *ht)
968 { 890 {
969 hash_table_test_function_t test_function = ht->test_function; 891 hash_table_test_function_t test_function = ht->test_function;
970 hentry *entries = ht->hentries; 892 hentry *entries = ht->hentries;
971 hentry *probe = entries + HASH_CODE (key, ht); 893 hentry *probe = entries + HASH_CODE (key, ht);
972 894
981 Find hash value for KEY in HASH-TABLE. 903 Find hash value for KEY in HASH-TABLE.
982 If there is no corresponding value, return DEFAULT (which defaults to nil). 904 If there is no corresponding value, return DEFAULT (which defaults to nil).
983 */ 905 */
984 (key, hash_table, default_)) 906 (key, hash_table, default_))
985 { 907 {
986 const Lisp_Hash_Table *ht = xhash_table (hash_table); 908 CONST Lisp_Hash_Table *ht = xhash_table (hash_table);
987 hentry *e = find_hentry (key, ht); 909 hentry *e = find_hentry (key, ht);
988 910
989 return HENTRY_CLEAR_P (e) ? default_ : e->value; 911 return HENTRY_CLEAR_P (e) ? default_ : e->value;
990 } 912 }
991 913
1014 We don't use tombstones - too wasteful. */ 936 We don't use tombstones - too wasteful. */
1015 static void 937 static void
1016 remhash_1 (Lisp_Hash_Table *ht, hentry *entries, hentry *probe) 938 remhash_1 (Lisp_Hash_Table *ht, hentry *entries, hentry *probe)
1017 { 939 {
1018 size_t size = ht->size; 940 size_t size = ht->size;
1019 CLEAR_HENTRY (probe); 941 CLEAR_HENTRY (probe++);
1020 probe++;
1021 ht->count--; 942 ht->count--;
1022 943
1023 LINEAR_PROBING_LOOP (probe, entries, size) 944 LINEAR_PROBING_LOOP (probe, entries, size)
1024 { 945 {
1025 Lisp_Object key = probe->key; 946 Lisp_Object key = probe->key;
1076 (hash_table)) 997 (hash_table))
1077 { 998 {
1078 return make_int (xhash_table (hash_table)->count); 999 return make_int (xhash_table (hash_table)->count);
1079 } 1000 }
1080 1001
1002 DEFUN ("hash-table-size", Fhash_table_size, 1, 1, 0, /*
1003 Return the size of HASH-TABLE.
1004 This is the current number of slots in HASH-TABLE, whether occupied or not.
1005 */
1006 (hash_table))
1007 {
1008 return make_int (xhash_table (hash_table)->size);
1009 }
1010
1011 DEFUN ("hash-table-type", Fhash_table_type, 1, 1, 0, /*
1012 Return the type of HASH-TABLE.
1013 This can be one of `non-weak', `weak', `key-weak' or `value-weak'.
1014 */
1015 (hash_table))
1016 {
1017 switch (xhash_table (hash_table)->type)
1018 {
1019 case HASH_TABLE_WEAK: return Qweak;
1020 case HASH_TABLE_KEY_WEAK: return Qkey_weak;
1021 case HASH_TABLE_VALUE_WEAK: return Qvalue_weak;
1022 default: return Qnon_weak;
1023 }
1024 }
1025
1081 DEFUN ("hash-table-test", Fhash_table_test, 1, 1, 0, /* 1026 DEFUN ("hash-table-test", Fhash_table_test, 1, 1, 0, /*
1082 Return the test function of HASH-TABLE. 1027 Return the test function of HASH-TABLE.
1083 This can be one of `eq', `eql' or `equal'. 1028 This can be one of `eq', `eql' or `equal'.
1084 */ 1029 */
1085 (hash_table)) 1030 (hash_table))
1087 hash_table_test_function_t fun = xhash_table (hash_table)->test_function; 1032 hash_table_test_function_t fun = xhash_table (hash_table)->test_function;
1088 1033
1089 return (fun == lisp_object_eql_equal ? Qeql : 1034 return (fun == lisp_object_eql_equal ? Qeql :
1090 fun == lisp_object_equal_equal ? Qequal : 1035 fun == lisp_object_equal_equal ? Qequal :
1091 Qeq); 1036 Qeq);
1092 }
1093
1094 DEFUN ("hash-table-size", Fhash_table_size, 1, 1, 0, /*
1095 Return the size of HASH-TABLE.
1096 This is the current number of slots in HASH-TABLE, whether occupied or not.
1097 */
1098 (hash_table))
1099 {
1100 return make_int (xhash_table (hash_table)->size);
1101 } 1037 }
1102 1038
1103 DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size, 1, 1, 0, /* 1039 DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size, 1, 1, 0, /*
1104 Return the current rehash size of HASH-TABLE. 1040 Return the current rehash size of HASH-TABLE.
1105 This is a float greater than 1.0; the factor by which HASH-TABLE 1041 This is a float greater than 1.0; the factor by which HASH-TABLE
1115 This is a float between 0.0 and 1.0; the maximum `load factor' of HASH-TABLE, 1051 This is a float between 0.0 and 1.0; the maximum `load factor' of HASH-TABLE,
1116 beyond which the HASH-TABLE is enlarged by rehashing. 1052 beyond which the HASH-TABLE is enlarged by rehashing.
1117 */ 1053 */
1118 (hash_table)) 1054 (hash_table))
1119 { 1055 {
1120 return make_float (xhash_table (hash_table)->rehash_threshold); 1056 return make_float (hash_table_rehash_threshold (xhash_table (hash_table)));
1121 }
1122
1123 DEFUN ("hash-table-weakness", Fhash_table_weakness, 1, 1, 0, /*
1124 Return the weakness of HASH-TABLE.
1125 This can be one of `nil', `t', `key' or `value'.
1126 */
1127 (hash_table))
1128 {
1129 switch (xhash_table (hash_table)->weakness)
1130 {
1131 case HASH_TABLE_WEAK: return Qt;
1132 case HASH_TABLE_KEY_WEAK: return Qkey;
1133 case HASH_TABLE_KEY_VALUE_WEAK: return Qkey_value;
1134 case HASH_TABLE_VALUE_WEAK: return Qvalue;
1135 default: return Qnil;
1136 }
1137 }
1138
1139 /* obsolete as of 19990901 in xemacs-21.2 */
1140 DEFUN ("hash-table-type", Fhash_table_type, 1, 1, 0, /*
1141 Return the type of HASH-TABLE.
1142 This can be one of `non-weak', `weak', `key-weak' or `value-weak'.
1143 */
1144 (hash_table))
1145 {
1146 switch (xhash_table (hash_table)->weakness)
1147 {
1148 case HASH_TABLE_WEAK: return Qweak;
1149 case HASH_TABLE_KEY_WEAK: return Qkey_weak;
1150 case HASH_TABLE_KEY_VALUE_WEAK: return Qkey_value_weak;
1151 case HASH_TABLE_VALUE_WEAK: return Qvalue_weak;
1152 default: return Qnon_weak;
1153 }
1154 } 1057 }
1155 1058
1156 /************************************************************************/ 1059 /************************************************************************/
1157 /* Mapping Functions */ 1060 /* Mapping Functions */
1158 /************************************************************************/ 1061 /************************************************************************/
1163 FUNCTION may not modify HASH-TABLE, with the one exception that FUNCTION 1066 FUNCTION may not modify HASH-TABLE, with the one exception that FUNCTION
1164 may remhash or puthash the entry currently being processed by FUNCTION. 1067 may remhash or puthash the entry currently being processed by FUNCTION.
1165 */ 1068 */
1166 (function, hash_table)) 1069 (function, hash_table))
1167 { 1070 {
1168 const Lisp_Hash_Table *ht = xhash_table (hash_table); 1071 CONST Lisp_Hash_Table *ht = xhash_table (hash_table);
1169 const hentry *e, *sentinel; 1072 CONST hentry *e, *sentinel;
1170 1073
1171 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) 1074 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1172 if (!HENTRY_CLEAR_P (e)) 1075 if (!HENTRY_CLEAR_P (e))
1173 { 1076 {
1174 Lisp_Object args[3], key; 1077 Lisp_Object args[3], key;
1189 /* Map *C* function FUNCTION over the elements of a lisp hash table. */ 1092 /* Map *C* function FUNCTION over the elements of a lisp hash table. */
1190 void 1093 void
1191 elisp_maphash (maphash_function_t function, 1094 elisp_maphash (maphash_function_t function,
1192 Lisp_Object hash_table, void *extra_arg) 1095 Lisp_Object hash_table, void *extra_arg)
1193 { 1096 {
1194 const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table); 1097 CONST Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1195 const hentry *e, *sentinel; 1098 CONST hentry *e, *sentinel;
1196 1099
1197 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) 1100 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1198 if (!HENTRY_CLEAR_P (e)) 1101 if (!HENTRY_CLEAR_P (e))
1199 { 1102 {
1200 Lisp_Object key; 1103 Lisp_Object key;
1231 1134
1232 1135
1233 /************************************************************************/ 1136 /************************************************************************/
1234 /* garbage collecting weak hash tables */ 1137 /* garbage collecting weak hash tables */
1235 /************************************************************************/ 1138 /************************************************************************/
1236 #define MARK_OBJ(obj) do { \
1237 Lisp_Object mo_obj = (obj); \
1238 if (!marked_p (mo_obj)) \
1239 { \
1240 mark_object (mo_obj); \
1241 did_mark = 1; \
1242 } \
1243 } while (0)
1244
1245 1139
1246 /* Complete the marking for semi-weak hash tables. */ 1140 /* Complete the marking for semi-weak hash tables. */
1247 int 1141 int
1248 finish_marking_weak_hash_tables (void) 1142 finish_marking_weak_hash_tables (int (*obj_marked_p) (Lisp_Object),
1143 void (*markobj) (Lisp_Object))
1249 { 1144 {
1250 Lisp_Object hash_table; 1145 Lisp_Object hash_table;
1251 int did_mark = 0; 1146 int did_mark = 0;
1252 1147
1253 for (hash_table = Vall_weak_hash_tables; 1148 for (hash_table = Vall_weak_hash_tables;
1254 !NILP (hash_table); 1149 !GC_NILP (hash_table);
1255 hash_table = XHASH_TABLE (hash_table)->next_weak) 1150 hash_table = XHASH_TABLE (hash_table)->next_weak)
1256 { 1151 {
1257 const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table); 1152 CONST Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1258 const hentry *e = ht->hentries; 1153 CONST hentry *e = ht->hentries;
1259 const hentry *sentinel = e + ht->size; 1154 CONST hentry *sentinel = e + ht->size;
1260 1155
1261 if (! marked_p (hash_table)) 1156 if (! obj_marked_p (hash_table))
1262 /* The hash table is probably garbage. Ignore it. */ 1157 /* The hash table is probably garbage. Ignore it. */
1263 continue; 1158 continue;
1264 1159
1265 /* Now, scan over all the pairs. For all pairs that are 1160 /* Now, scan over all the pairs. For all pairs that are
1266 half-marked, we may need to mark the other half if we're 1161 half-marked, we may need to mark the other half if we're
1267 keeping this pair. */ 1162 keeping this pair. */
1268 switch (ht->weakness) 1163 #define MARK_OBJ(obj) \
1164 do { if (!obj_marked_p (obj)) markobj (obj), did_mark = 1; } while (0)
1165
1166 switch (ht->type)
1269 { 1167 {
1270 case HASH_TABLE_KEY_WEAK: 1168 case HASH_TABLE_KEY_WEAK:
1271 for (; e < sentinel; e++) 1169 for (; e < sentinel; e++)
1272 if (!HENTRY_CLEAR_P (e)) 1170 if (!HENTRY_CLEAR_P (e))
1273 if (marked_p (e->key)) 1171 if (obj_marked_p (e->key))
1274 MARK_OBJ (e->value); 1172 MARK_OBJ (e->value);
1275 break; 1173 break;
1276 1174
1277 case HASH_TABLE_VALUE_WEAK: 1175 case HASH_TABLE_VALUE_WEAK:
1278 for (; e < sentinel; e++) 1176 for (; e < sentinel; e++)
1279 if (!HENTRY_CLEAR_P (e)) 1177 if (!HENTRY_CLEAR_P (e))
1280 if (marked_p (e->value)) 1178 if (obj_marked_p (e->value))
1281 MARK_OBJ (e->key); 1179 MARK_OBJ (e->key);
1282 break;
1283
1284 case HASH_TABLE_KEY_VALUE_WEAK:
1285 for (; e < sentinel; e++)
1286 if (!HENTRY_CLEAR_P (e))
1287 {
1288 if (marked_p (e->value))
1289 MARK_OBJ (e->key);
1290 else if (marked_p (e->key))
1291 MARK_OBJ (e->value);
1292 }
1293 break; 1180 break;
1294 1181
1295 case HASH_TABLE_KEY_CAR_WEAK: 1182 case HASH_TABLE_KEY_CAR_WEAK:
1296 for (; e < sentinel; e++) 1183 for (; e < sentinel; e++)
1297 if (!HENTRY_CLEAR_P (e)) 1184 if (!HENTRY_CLEAR_P (e))
1298 if (!CONSP (e->key) || marked_p (XCAR (e->key))) 1185 if (!CONSP (e->key) || obj_marked_p (XCAR (e->key)))
1299 { 1186 {
1300 MARK_OBJ (e->key); 1187 MARK_OBJ (e->key);
1301 MARK_OBJ (e->value); 1188 MARK_OBJ (e->value);
1302 } 1189 }
1303 break; 1190 break;
1304 1191
1305 case HASH_TABLE_VALUE_CAR_WEAK: 1192 case HASH_TABLE_VALUE_CAR_WEAK:
1306 for (; e < sentinel; e++) 1193 for (; e < sentinel; e++)
1307 if (!HENTRY_CLEAR_P (e)) 1194 if (!HENTRY_CLEAR_P (e))
1308 if (!CONSP (e->value) || marked_p (XCAR (e->value))) 1195 if (!CONSP (e->value) || obj_marked_p (XCAR (e->value)))
1309 { 1196 {
1310 MARK_OBJ (e->key); 1197 MARK_OBJ (e->key);
1311 MARK_OBJ (e->value); 1198 MARK_OBJ (e->value);
1312 } 1199 }
1313 break; 1200 break;
1319 1206
1320 return did_mark; 1207 return did_mark;
1321 } 1208 }
1322 1209
1323 void 1210 void
1324 prune_weak_hash_tables (void) 1211 prune_weak_hash_tables (int (*obj_marked_p) (Lisp_Object))
1325 { 1212 {
1326 Lisp_Object hash_table, prev = Qnil; 1213 Lisp_Object hash_table, prev = Qnil;
1327 for (hash_table = Vall_weak_hash_tables; 1214 for (hash_table = Vall_weak_hash_tables;
1328 !NILP (hash_table); 1215 !GC_NILP (hash_table);
1329 hash_table = XHASH_TABLE (hash_table)->next_weak) 1216 hash_table = XHASH_TABLE (hash_table)->next_weak)
1330 { 1217 {
1331 if (! marked_p (hash_table)) 1218 if (! obj_marked_p (hash_table))
1332 { 1219 {
1333 /* This hash table itself is garbage. Remove it from the list. */ 1220 /* This hash table itself is garbage. Remove it from the list. */
1334 if (NILP (prev)) 1221 if (GC_NILP (prev))
1335 Vall_weak_hash_tables = XHASH_TABLE (hash_table)->next_weak; 1222 Vall_weak_hash_tables = XHASH_TABLE (hash_table)->next_weak;
1336 else 1223 else
1337 XHASH_TABLE (prev)->next_weak = XHASH_TABLE (hash_table)->next_weak; 1224 XHASH_TABLE (prev)->next_weak = XHASH_TABLE (hash_table)->next_weak;
1338 } 1225 }
1339 else 1226 else
1340 { 1227 {
1341 /* Now, scan over all the pairs. Remove all of the pairs 1228 /* Now, scan over all the pairs. Remove all of the pairs
1342 in which the key or value, or both, is unmarked 1229 in which the key or value, or both, is unmarked
1343 (depending on the weakness of the hash table). */ 1230 (depending on the type of weak hash table). */
1344 Lisp_Hash_Table *ht = XHASH_TABLE (hash_table); 1231 Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1345 hentry *entries = ht->hentries; 1232 hentry *entries = ht->hentries;
1346 hentry *sentinel = entries + ht->size; 1233 hentry *sentinel = entries + ht->size;
1347 hentry *e; 1234 hentry *e;
1348 1235
1349 for (e = entries; e < sentinel; e++) 1236 for (e = entries; e < sentinel; e++)
1350 if (!HENTRY_CLEAR_P (e)) 1237 if (!HENTRY_CLEAR_P (e))
1351 { 1238 {
1352 again: 1239 again:
1353 if (!marked_p (e->key) || !marked_p (e->value)) 1240 if (!obj_marked_p (e->key) || !obj_marked_p (e->value))
1354 { 1241 {
1355 remhash_1 (ht, entries, e); 1242 remhash_1 (ht, entries, e);
1356 if (!HENTRY_CLEAR_P (e)) 1243 if (!HENTRY_CLEAR_P (e))
1357 goto again; 1244 goto again;
1358 } 1245 }
1367 1254
1368 hashcode_t 1255 hashcode_t
1369 internal_array_hash (Lisp_Object *arr, int size, int depth) 1256 internal_array_hash (Lisp_Object *arr, int size, int depth)
1370 { 1257 {
1371 int i; 1258 int i;
1372 hashcode_t hash = 0; 1259 unsigned long hash = 0;
1373 depth++;
1374 1260
1375 if (size <= 5) 1261 if (size <= 5)
1376 { 1262 {
1377 for (i = 0; i < size; i++) 1263 for (i = 0; i < size; i++)
1378 hash = HASH2 (hash, internal_hash (arr[i], depth)); 1264 hash = HASH2 (hash, internal_hash (arr[i], depth + 1));
1379 return hash; 1265 return hash;
1380 } 1266 }
1381 1267
1382 /* just pick five elements scattered throughout the array. 1268 /* just pick five elements scattered throughout the array.
1383 A slightly better approach would be to offset by some 1269 A slightly better approach would be to offset by some
1384 noise factor from the points chosen below. */ 1270 noise factor from the points chosen below. */
1385 for (i = 0; i < 5; i++) 1271 for (i = 0; i < 5; i++)
1386 hash = HASH2 (hash, internal_hash (arr[i*size/5], depth)); 1272 hash = HASH2 (hash, internal_hash (arr[i*size/5], depth + 1));
1387 1273
1388 return hash; 1274 return hash;
1389 } 1275 }
1390 1276
1391 /* Return a hash value for a Lisp_Object. This is for use when hashing 1277 /* Return a hash value for a Lisp_Object. This is for use when hashing
1414 } 1300 }
1415 if (STRINGP (obj)) 1301 if (STRINGP (obj))
1416 { 1302 {
1417 return hash_string (XSTRING_DATA (obj), XSTRING_LENGTH (obj)); 1303 return hash_string (XSTRING_DATA (obj), XSTRING_LENGTH (obj));
1418 } 1304 }
1305 if (VECTORP (obj))
1306 {
1307 return HASH2 (XVECTOR_LENGTH (obj),
1308 internal_array_hash (XVECTOR_DATA (obj),
1309 XVECTOR_LENGTH (obj),
1310 depth + 1));
1311 }
1419 if (LRECORDP (obj)) 1312 if (LRECORDP (obj))
1420 { 1313 {
1421 const struct lrecord_implementation 1314 CONST struct lrecord_implementation
1422 *imp = XRECORD_LHEADER_IMPLEMENTATION (obj); 1315 *imp = XRECORD_LHEADER_IMPLEMENTATION (obj);
1423 if (imp->hash) 1316 if (imp->hash)
1424 return imp->hash (obj, depth); 1317 return imp->hash (obj, depth);
1425 } 1318 }
1426 1319
1427 return LISP_HASH (obj); 1320 return LISP_HASH (obj);
1428 }
1429
1430 DEFUN ("sxhash", Fsxhash, 1, 1, 0, /*
1431 Return a hash value for OBJECT.
1432 (equal obj1 obj2) implies (= (sxhash obj1) (sxhash obj2)).
1433 */
1434 (object))
1435 {
1436 return make_int (internal_hash (object, 0));
1437 } 1321 }
1438 1322
1439 #if 0 1323 #if 0
1440 xxDEFUN ("internal-hash-value", Finternal_hash_value, 1, 1, 0, /* 1324 xxDEFUN ("internal-hash-value", Finternal_hash_value, 1, 1, 0, /*
1441 Hash value of OBJECT. For debugging. 1325 Hash value of OBJECT. For debugging.
1442 The value is returned as (HIGH . LOW). 1326 The value is returned as (HIGH . LOW).
1443 */ 1327 */
1444 (object)) 1328 (object))
1445 { 1329 {
1446 /* This function is pretty 32bit-centric. */ 1330 /* This function is pretty 32bit-centric. */
1447 hashcode_t hash = internal_hash (object, 0); 1331 unsigned long hash = internal_hash (object, 0);
1448 return Fcons (hash >> 16, hash & 0xffff); 1332 return Fcons (hash >> 16, hash & 0xffff);
1449 } 1333 }
1450 #endif 1334 #endif
1451 1335
1452 1336
1455 /************************************************************************/ 1339 /************************************************************************/
1456 1340
1457 void 1341 void
1458 syms_of_elhash (void) 1342 syms_of_elhash (void)
1459 { 1343 {
1460 INIT_LRECORD_IMPLEMENTATION (hash_table);
1461
1462 DEFSUBR (Fhash_table_p); 1344 DEFSUBR (Fhash_table_p);
1463 DEFSUBR (Fmake_hash_table); 1345 DEFSUBR (Fmake_hash_table);
1464 DEFSUBR (Fcopy_hash_table); 1346 DEFSUBR (Fcopy_hash_table);
1465 DEFSUBR (Fgethash); 1347 DEFSUBR (Fgethash);
1466 DEFSUBR (Fremhash); 1348 DEFSUBR (Fremhash);
1467 DEFSUBR (Fputhash); 1349 DEFSUBR (Fputhash);
1468 DEFSUBR (Fclrhash); 1350 DEFSUBR (Fclrhash);
1469 DEFSUBR (Fmaphash); 1351 DEFSUBR (Fmaphash);
1470 DEFSUBR (Fhash_table_count); 1352 DEFSUBR (Fhash_table_count);
1471 DEFSUBR (Fhash_table_test);
1472 DEFSUBR (Fhash_table_size); 1353 DEFSUBR (Fhash_table_size);
1473 DEFSUBR (Fhash_table_rehash_size); 1354 DEFSUBR (Fhash_table_rehash_size);
1474 DEFSUBR (Fhash_table_rehash_threshold); 1355 DEFSUBR (Fhash_table_rehash_threshold);
1475 DEFSUBR (Fhash_table_weakness); 1356 DEFSUBR (Fhash_table_type);
1476 DEFSUBR (Fhash_table_type); /* obsolete */ 1357 DEFSUBR (Fhash_table_test);
1477 DEFSUBR (Fsxhash);
1478 #if 0 1358 #if 0
1479 DEFSUBR (Finternal_hash_value); 1359 DEFSUBR (Finternal_hash_value);
1480 #endif 1360 #endif
1481 1361
1482 defsymbol (&Qhash_tablep, "hash-table-p"); 1362 defsymbol (&Qhash_tablep, "hash-table-p");
1483 defsymbol (&Qhash_table, "hash-table"); 1363 defsymbol (&Qhash_table, "hash-table");
1484 defsymbol (&Qhashtable, "hashtable"); 1364 defsymbol (&Qhashtable, "hashtable");
1485 defsymbol (&Qweakness, "weakness"); 1365 defsymbol (&Qweak, "weak");
1486 defsymbol (&Qvalue, "value"); 1366 defsymbol (&Qkey_weak, "key-weak");
1487 defsymbol (&Qkey_value, "key-value"); 1367 defsymbol (&Qvalue_weak, "value-weak");
1368 defsymbol (&Qnon_weak, "non-weak");
1488 defsymbol (&Qrehash_size, "rehash-size"); 1369 defsymbol (&Qrehash_size, "rehash-size");
1489 defsymbol (&Qrehash_threshold, "rehash-threshold"); 1370 defsymbol (&Qrehash_threshold, "rehash-threshold");
1490 1371
1491 defsymbol (&Qweak, "weak"); /* obsolete */ 1372 defkeyword (&Q_size, ":size");
1492 defsymbol (&Qkey_weak, "key-weak"); /* obsolete */
1493 defsymbol (&Qkey_value_weak, "key-value-weak"); /* obsolete */
1494 defsymbol (&Qvalue_weak, "value-weak"); /* obsolete */
1495 defsymbol (&Qnon_weak, "non-weak"); /* obsolete */
1496
1497 defkeyword (&Q_test, ":test"); 1373 defkeyword (&Q_test, ":test");
1498 defkeyword (&Q_size, ":size"); 1374 defkeyword (&Q_type, ":type");
1499 defkeyword (&Q_rehash_size, ":rehash-size"); 1375 defkeyword (&Q_rehash_size, ":rehash-size");
1500 defkeyword (&Q_rehash_threshold, ":rehash-threshold"); 1376 defkeyword (&Q_rehash_threshold, ":rehash-threshold");
1501 defkeyword (&Q_weakness, ":weakness");
1502 defkeyword (&Q_type, ":type"); /* obsolete */
1503 } 1377 }
1504 1378
1505 void 1379 void
1506 vars_of_elhash (void) 1380 vars_of_elhash (void)
1507 { 1381 {
1508 /* This must NOT be staticpro'd */ 1382 /* This must NOT be staticpro'd */
1509 Vall_weak_hash_tables = Qnil; 1383 Vall_weak_hash_tables = Qnil;
1510 pdump_wire_list (&Vall_weak_hash_tables); 1384 }
1511 }