Mercurial > hg > xemacs-beta
comparison src/elhash.c @ 647:b39c14581166
[xemacs-hg @ 2001-08-13 04:45:47 by ben]
removal of unsigned, size_t, etc.
author | ben |
---|---|
date | Mon, 13 Aug 2001 04:46:48 +0000 |
parents | af57a77cbc92 |
children | fdefd0186b75 |
comparison
equal
deleted
inserted
replaced
646:00c54252fe4f | 647:b39c14581166 |
---|---|
80 } hentry; | 80 } hentry; |
81 | 81 |
82 struct Lisp_Hash_Table | 82 struct Lisp_Hash_Table |
83 { | 83 { |
84 struct lcrecord_header header; | 84 struct lcrecord_header header; |
85 size_t size; | 85 Element_Count size; |
86 size_t count; | 86 Element_Count count; |
87 size_t rehash_count; | 87 Element_Count rehash_count; |
88 double rehash_size; | 88 double rehash_size; |
89 double rehash_threshold; | 89 double rehash_threshold; |
90 size_t golden_ratio; | 90 Element_Count golden_ratio; |
91 hash_table_hash_function_t hash_function; | 91 hash_table_hash_function_t hash_function; |
92 hash_table_test_function_t test_function; | 92 hash_table_test_function_t test_function; |
93 hentry *hentries; | 93 hentry *hentries; |
94 enum hash_table_weakness weakness; | 94 enum hash_table_weakness weakness; |
95 Lisp_Object next_weak; /* Used to chain together all of the weak | 95 Lisp_Object next_weak; /* Used to chain together all of the weak |
141 #else | 141 #else |
142 #define check_hash_table_invariants(ht) | 142 #define check_hash_table_invariants(ht) |
143 #endif | 143 #endif |
144 | 144 |
145 /* Return a suitable size for a hash table, with at least SIZE slots. */ | 145 /* Return a suitable size for a hash table, with at least SIZE slots. */ |
146 static size_t | 146 static Element_Count |
147 hash_table_size (size_t requested_size) | 147 hash_table_size (Element_Count requested_size) |
148 { | 148 { |
149 /* Return some prime near, but greater than or equal to, SIZE. | 149 /* Return some prime near, but greater than or equal to, SIZE. |
150 Decades from the time of writing, someone will have a system large | 150 Decades from the time of writing, someone will have a system large |
151 enough that the list below will be too short... */ | 151 enough that the list below will be too short... */ |
152 static const size_t primes [] = | 152 static const Element_Count primes [] = |
153 { | 153 { |
154 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031, | 154 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031, |
155 1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783, | 155 1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783, |
156 19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941, | 156 19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941, |
157 204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519, | 157 204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519, |
158 1664681, 2164111, 2813353, 3657361, 4754591, 6180989, 8035301, | 158 1664681, 2164111, 2813353, 3657361, 4754591, 6180989, 8035301, |
159 10445899, 13579681, 17653589, 22949669, 29834603, 38784989, | 159 10445899, 13579681, 17653589, 22949669, 29834603, 38784989, |
160 50420551, 65546729, 85210757, 110774011, 144006217, 187208107, | 160 50420551, 65546729, 85210757, 110774011, 144006217, 187208107, |
161 243370577, 316381771, 411296309, 534685237, 695090819, 903618083, | 161 243370577, 316381771, 411296309, 534685237, 695090819, 903618083, |
162 1174703521, 1527114613, 1985248999, 2580823717UL, 3355070839UL | 162 1174703521, 1527114613, 1985248999 /* , 2580823717UL, 3355070839UL */ |
163 }; | 163 }; |
164 /* We've heard of binary search. */ | 164 /* We've heard of binary search. */ |
165 int low, high; | 165 int low, high; |
166 for (low = 0, high = countof (primes) - 1; high - low > 1;) | 166 for (low = 0, high = countof (primes) - 1; high - low > 1;) |
167 { | 167 { |
186 /* This is wrong anyway. You can't use strcmp() on Lisp strings, | 186 /* This is wrong anyway. You can't use strcmp() on Lisp strings, |
187 because they can contain zero characters. */ | 187 because they can contain zero characters. */ |
188 return !strcmp ((char *) XSTRING_DATA (str1), (char *) XSTRING_DATA (str2)); | 188 return !strcmp ((char *) XSTRING_DATA (str1), (char *) XSTRING_DATA (str2)); |
189 } | 189 } |
190 | 190 |
191 static hashcode_t | 191 static Hash_Code |
192 lisp_string_hash (Lisp_Object obj) | 192 lisp_string_hash (Lisp_Object obj) |
193 { | 193 { |
194 return hash_string (XSTRING_DATA (str), XSTRING_LENGTH (str)); | 194 return hash_string (XSTRING_DATA (str), XSTRING_LENGTH (str)); |
195 } | 195 } |
196 | 196 |
200 lisp_object_eql_equal (Lisp_Object obj1, Lisp_Object obj2) | 200 lisp_object_eql_equal (Lisp_Object obj1, Lisp_Object obj2) |
201 { | 201 { |
202 return EQ (obj1, obj2) || (FLOATP (obj1) && internal_equal (obj1, obj2, 0)); | 202 return EQ (obj1, obj2) || (FLOATP (obj1) && internal_equal (obj1, obj2, 0)); |
203 } | 203 } |
204 | 204 |
205 static hashcode_t | 205 static Hash_Code |
206 lisp_object_eql_hash (Lisp_Object obj) | 206 lisp_object_eql_hash (Lisp_Object obj) |
207 { | 207 { |
208 return FLOATP (obj) ? internal_hash (obj, 0) : LISP_HASH (obj); | 208 return FLOATP (obj) ? internal_hash (obj, 0) : LISP_HASH (obj); |
209 } | 209 } |
210 | 210 |
212 lisp_object_equal_equal (Lisp_Object obj1, Lisp_Object obj2) | 212 lisp_object_equal_equal (Lisp_Object obj1, Lisp_Object obj2) |
213 { | 213 { |
214 return internal_equal (obj1, obj2, 0); | 214 return internal_equal (obj1, obj2, 0); |
215 } | 215 } |
216 | 216 |
217 static hashcode_t | 217 static Hash_Code |
218 lisp_object_equal_hash (Lisp_Object obj) | 218 lisp_object_equal_hash (Lisp_Object obj) |
219 { | 219 { |
220 return internal_hash (obj, 0); | 220 return internal_hash (obj, 0); |
221 } | 221 } |
222 | 222 |
281 } | 281 } |
282 | 282 |
283 /* This is not a great hash function, but it _is_ correct and fast. | 283 /* This is not a great hash function, but it _is_ correct and fast. |
284 Examining all entries is too expensive, and examining a random | 284 Examining all entries is too expensive, and examining a random |
285 subset does not yield a correct hash function. */ | 285 subset does not yield a correct hash function. */ |
286 static hashcode_t | 286 static Hash_Code |
287 hash_table_hash (Lisp_Object hash_table, int depth) | 287 hash_table_hash (Lisp_Object hash_table, int depth) |
288 { | 288 { |
289 return XHASH_TABLE (hash_table)->count; | 289 return XHASH_TABLE (hash_table)->count; |
290 } | 290 } |
291 | 291 |
365 abort (); | 365 abort (); |
366 | 366 |
367 if (ht->count || !print_readably) | 367 if (ht->count || !print_readably) |
368 { | 368 { |
369 if (print_readably) | 369 if (print_readably) |
370 sprintf (buf, " size %lu", (unsigned long) ht->count); | 370 sprintf (buf, " size %ld", (long) ht->count); |
371 else | 371 else |
372 sprintf (buf, " size %lu/%lu", | 372 sprintf (buf, " size %ld/%ld", (long) ht->count, (long) ht->size); |
373 (unsigned long) ht->count, | |
374 (unsigned long) ht->size); | |
375 write_c_string (buf, printcharfun); | 373 write_c_string (buf, printcharfun); |
376 } | 374 } |
377 | 375 |
378 if (ht->weakness != HASH_TABLE_NON_WEAK) | 376 if (ht->weakness != HASH_TABLE_NON_WEAK) |
379 { | 377 { |
434 sizeof (hentry), | 432 sizeof (hentry), |
435 hentry_description_1 | 433 hentry_description_1 |
436 }; | 434 }; |
437 | 435 |
438 const struct lrecord_description hash_table_description[] = { | 436 const struct lrecord_description hash_table_description[] = { |
439 { XD_SIZE_T, offsetof (Lisp_Hash_Table, size) }, | 437 { XD_ELEMENT_COUNT, offsetof (Lisp_Hash_Table, size) }, |
440 { XD_STRUCT_PTR, offsetof (Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), &hentry_description }, | 438 { XD_STRUCT_PTR, offsetof (Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), &hentry_description }, |
441 { XD_LO_LINK, offsetof (Lisp_Hash_Table, next_weak) }, | 439 { XD_LO_LINK, offsetof (Lisp_Hash_Table, next_weak) }, |
442 { XD_END } | 440 { XD_END } |
443 }; | 441 }; |
444 | 442 |
465 | 463 |
466 /* Creation of hash tables, without error-checking. */ | 464 /* Creation of hash tables, without error-checking. */ |
467 static void | 465 static void |
468 compute_hash_table_derived_values (Lisp_Hash_Table *ht) | 466 compute_hash_table_derived_values (Lisp_Hash_Table *ht) |
469 { | 467 { |
470 ht->rehash_count = (size_t) | 468 ht->rehash_count = (Element_Count) |
471 ((double) ht->size * ht->rehash_threshold); | 469 ((double) ht->size * ht->rehash_threshold); |
472 ht->golden_ratio = (size_t) | 470 ht->golden_ratio = (Element_Count) |
473 ((double) ht->size * (.6180339887 / (double) sizeof (Lisp_Object))); | 471 ((double) ht->size * (.6180339887 / (double) sizeof (Lisp_Object))); |
474 } | 472 } |
475 | 473 |
476 Lisp_Object | 474 Lisp_Object |
477 make_standard_lisp_hash_table (enum hash_table_test test, | 475 make_standard_lisp_hash_table (enum hash_table_test test, |
478 size_t size, | 476 Element_Count size, |
479 double rehash_size, | 477 double rehash_size, |
480 double rehash_threshold, | 478 double rehash_threshold, |
481 enum hash_table_weakness weakness) | 479 enum hash_table_weakness weakness) |
482 { | 480 { |
483 hash_table_hash_function_t hash_function = 0; | 481 hash_table_hash_function_t hash_function = 0; |
510 } | 508 } |
511 | 509 |
512 Lisp_Object | 510 Lisp_Object |
513 make_general_lisp_hash_table (hash_table_hash_function_t hash_function, | 511 make_general_lisp_hash_table (hash_table_hash_function_t hash_function, |
514 hash_table_test_function_t test_function, | 512 hash_table_test_function_t test_function, |
515 size_t size, | 513 Element_Count size, |
516 double rehash_size, | 514 double rehash_size, |
517 double rehash_threshold, | 515 double rehash_threshold, |
518 enum hash_table_weakness weakness) | 516 enum hash_table_weakness weakness) |
519 { | 517 { |
520 Lisp_Object hash_table; | 518 Lisp_Object hash_table; |
531 rehash_threshold > 0.0 ? rehash_threshold : | 529 rehash_threshold > 0.0 ? rehash_threshold : |
532 size > 4096 && !ht->test_function ? 0.7 : 0.6; | 530 size > 4096 && !ht->test_function ? 0.7 : 0.6; |
533 | 531 |
534 if (size < HASH_TABLE_MIN_SIZE) | 532 if (size < HASH_TABLE_MIN_SIZE) |
535 size = HASH_TABLE_MIN_SIZE; | 533 size = HASH_TABLE_MIN_SIZE; |
536 ht->size = hash_table_size ((size_t) (((double) size / ht->rehash_threshold) | 534 ht->size = hash_table_size ((Element_Count) (((double) size / ht->rehash_threshold) |
537 + 1.0)); | 535 + 1.0)); |
538 ht->count = 0; | 536 ht->count = 0; |
539 | 537 |
540 compute_hash_table_derived_values (ht); | 538 compute_hash_table_derived_values (ht); |
541 | 539 |
551 | 549 |
552 return hash_table; | 550 return hash_table; |
553 } | 551 } |
554 | 552 |
555 Lisp_Object | 553 Lisp_Object |
556 make_lisp_hash_table (size_t size, | 554 make_lisp_hash_table (Element_Count size, |
557 enum hash_table_weakness weakness, | 555 enum hash_table_weakness weakness, |
558 enum hash_table_test test) | 556 enum hash_table_test test) |
559 { | 557 { |
560 return make_standard_lisp_hash_table (test, size, -1.0, -1.0, weakness); | 558 return make_standard_lisp_hash_table (test, size, -1.0, -1.0, weakness); |
561 } | 559 } |
581 maybe_signal_error_1 (Qwrong_type_argument, list2 (Qnatnump, value), | 579 maybe_signal_error_1 (Qwrong_type_argument, list2 (Qnatnump, value), |
582 Qhash_table, errb); | 580 Qhash_table, errb); |
583 return 0; | 581 return 0; |
584 } | 582 } |
585 | 583 |
586 static size_t | 584 static Element_Count |
587 decode_hash_table_size (Lisp_Object obj) | 585 decode_hash_table_size (Lisp_Object obj) |
588 { | 586 { |
589 return NILP (obj) ? HASH_TABLE_DEFAULT_SIZE : XINT (obj); | 587 return NILP (obj) ? HASH_TABLE_DEFAULT_SIZE : XINT (obj); |
590 } | 588 } |
591 | 589 |
956 | 954 |
957 return hash_table; | 955 return hash_table; |
958 } | 956 } |
959 | 957 |
960 static void | 958 static void |
961 resize_hash_table (Lisp_Hash_Table *ht, size_t new_size) | 959 resize_hash_table (Lisp_Hash_Table *ht, Element_Count new_size) |
962 { | 960 { |
963 hentry *old_entries, *new_entries, *sentinel, *e; | 961 hentry *old_entries, *new_entries, *sentinel, *e; |
964 size_t old_size; | 962 Element_Count old_size; |
965 | 963 |
966 old_size = ht->size; | 964 old_size = ht->size; |
967 ht->size = new_size; | 965 ht->size = new_size; |
968 | 966 |
969 old_entries = ht->hentries; | 967 old_entries = ht->hentries; |
1010 } | 1008 } |
1011 | 1009 |
1012 static void | 1010 static void |
1013 enlarge_hash_table (Lisp_Hash_Table *ht) | 1011 enlarge_hash_table (Lisp_Hash_Table *ht) |
1014 { | 1012 { |
1015 size_t new_size = | 1013 Element_Count new_size = |
1016 hash_table_size ((size_t) ((double) ht->size * ht->rehash_size)); | 1014 hash_table_size ((Element_Count) ((double) ht->size * ht->rehash_size)); |
1017 resize_hash_table (ht, new_size); | 1015 resize_hash_table (ht, new_size); |
1018 } | 1016 } |
1019 | 1017 |
1020 static hentry * | 1018 static hentry * |
1021 find_hentry (Lisp_Object key, const Lisp_Hash_Table *ht) | 1019 find_hentry (Lisp_Object key, const Lisp_Hash_Table *ht) |
1067 Subsequent entries are removed and reinserted. | 1065 Subsequent entries are removed and reinserted. |
1068 We don't use tombstones - too wasteful. */ | 1066 We don't use tombstones - too wasteful. */ |
1069 static void | 1067 static void |
1070 remhash_1 (Lisp_Hash_Table *ht, hentry *entries, hentry *probe) | 1068 remhash_1 (Lisp_Hash_Table *ht, hentry *entries, hentry *probe) |
1071 { | 1069 { |
1072 size_t size = ht->size; | 1070 Element_Count size = ht->size; |
1073 CLEAR_HENTRY (probe); | 1071 CLEAR_HENTRY (probe); |
1074 probe++; | 1072 probe++; |
1075 ht->count--; | 1073 ht->count--; |
1076 | 1074 |
1077 LINEAR_PROBING_LOOP (probe, entries, size) | 1075 LINEAR_PROBING_LOOP (probe, entries, size) |
1550 } | 1548 } |
1551 } | 1549 } |
1552 | 1550 |
1553 /* Return a hash value for an array of Lisp_Objects of size SIZE. */ | 1551 /* Return a hash value for an array of Lisp_Objects of size SIZE. */ |
1554 | 1552 |
1555 hashcode_t | 1553 Hash_Code |
1556 internal_array_hash (Lisp_Object *arr, int size, int depth) | 1554 internal_array_hash (Lisp_Object *arr, int size, int depth) |
1557 { | 1555 { |
1558 int i; | 1556 int i; |
1559 hashcode_t hash = 0; | 1557 Hash_Code hash = 0; |
1560 depth++; | 1558 depth++; |
1561 | 1559 |
1562 if (size <= 5) | 1560 if (size <= 5) |
1563 { | 1561 { |
1564 for (i = 0; i < size; i++) | 1562 for (i = 0; i < size; i++) |
1585 few elements you hash. Thus, we only go to a short depth (5) | 1583 few elements you hash. Thus, we only go to a short depth (5) |
1586 and only hash at most 5 elements out of a vector. Theoretically | 1584 and only hash at most 5 elements out of a vector. Theoretically |
1587 we could still take 5^5 time (a big big number) to compute a | 1585 we could still take 5^5 time (a big big number) to compute a |
1588 hash, but practically this won't ever happen. */ | 1586 hash, but practically this won't ever happen. */ |
1589 | 1587 |
1590 hashcode_t | 1588 Hash_Code |
1591 internal_hash (Lisp_Object obj, int depth) | 1589 internal_hash (Lisp_Object obj, int depth) |
1592 { | 1590 { |
1593 if (depth > 5) | 1591 if (depth > 5) |
1594 return 0; | 1592 return 0; |
1595 if (CONSP (obj)) | 1593 if (CONSP (obj)) |
1629 The value is returned as (HIGH . LOW). | 1627 The value is returned as (HIGH . LOW). |
1630 */ | 1628 */ |
1631 (object)) | 1629 (object)) |
1632 { | 1630 { |
1633 /* This function is pretty 32bit-centric. */ | 1631 /* This function is pretty 32bit-centric. */ |
1634 hashcode_t hash = internal_hash (object, 0); | 1632 Hash_Code hash = internal_hash (object, 0); |
1635 return Fcons (hash >> 16, hash & 0xffff); | 1633 return Fcons (hash >> 16, hash & 0xffff); |
1636 } | 1634 } |
1637 #endif | 1635 #endif |
1638 | 1636 |
1639 | 1637 |