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