comparison src/elhash.c @ 398:74fd4e045ea6 r21-2-29

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