Changeset 1908 for trunk/src/kmk/strcache2.c
- Timestamp:
- Oct 21, 2008, 11:35:29 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/strcache2.c
r1906 r1908 56 56 *******************************************************************************/ 57 57 /* The default size of a memory segment (1MB). */ 58 #define STRCACHE2_SEG_SIZE (1024U*1024U)58 #define STRCACHE2_SEG_SIZE (1024U*1024U) 59 59 /* The default hash table shift (hash size give as a power of two). */ 60 #define STRCACHE2_HASH_SHIFT 16 60 #define STRCACHE2_HASH_SHIFT 16 61 /** Does the modding / masking of a hash number into an index. */ 62 #ifdef STRCACHE2_USE_MASK 63 # define STRCACHE2_MOD_IT(cache, hash) ((hash) & (cache)->hash_mask) 64 #else 65 # define STRCACHE2_MOD_IT(cache, hash) ((hash) % (cache)->hash_div) 66 #endif 61 67 62 68 … … 69 75 70 76 77 /** Finds the closest primary number for power of two value (or something else 78 * useful if not support). */ 79 MY_INLINE strcache2_find_prime(unsigned int shift) 80 { 81 switch (shift) 82 { 83 case 5: return 31; 84 case 6: return 61; 85 case 7: return 127; 86 case 8: return 251; 87 case 9: return 509; 88 case 10: return 1021; 89 case 11: return 2039; 90 case 12: return 4093; 91 case 13: return 8191; 92 case 14: return 16381; 93 case 15: return 32749; 94 case 16: return 65521; 95 case 17: return 131063; 96 case 18: return 262139; 97 case 19: return 524269; 98 case 20: return 1048573; 99 case 21: return 2097143; 100 case 22: return 4194301; 101 case 23: return 8388593; 102 103 default: 104 assert (0); 105 return (1 << shift) - 1; 106 } 107 } 108 71 109 static struct strcache2_seg * 72 110 strcache2_new_seg (struct strcache2 *cache, unsigned int minlen) … … 105 143 strcache2_case_sensitive_hash_1 (const char *str, unsigned int len) 106 144 { 145 #if 1 107 146 /* Note! This implementation is 18% faster than return_STRING_N_HASH_1 108 147 when running the two 100 times over typical kBuild strings that … … 144 183 hash = 0; 145 184 return hash; 185 #else 186 # if 1 187 /* This is SDBM. This specific form and loop unroll was benchmarked to 188 be 28% faster than return_STRING_N_HASH_1. (Now the weird thing is 189 that putting the (ch) first in the assignment made it noticably slower.) 190 191 However, it is noticably slower in practice, most likely because of more 192 collisions. Hrmpf. 193 */ 194 # define UPDATE_HASH(ch) hash = (hash << 6) + (hash << 16) - hash + (ch) 195 unsigned int hash = 0; 196 # else 197 /* This is DJB2. This specific form/unroll was benchmarked to be 27% 198 fast than return_STRING_N_HASH_1. 199 200 Ditto. 2x Hrmpf */ 201 # define UPDATE_HASH(ch) hash = (hash << 5) + hash + (ch) 202 unsigned int hash = 5381; 203 # endif 204 while (len >= 4) 205 { 206 UPDATE_HASH (str[0]); 207 UPDATE_HASH (str[1]); 208 UPDATE_HASH (str[2]); 209 UPDATE_HASH (str[3]); 210 str += 4; 211 len -= 4; 212 } 213 switch (len) 214 { 215 default: 216 case 0: 217 return hash; 218 case 1: 219 UPDATE_HASH (str[0]); 220 return hash; 221 case 2: 222 UPDATE_HASH (str[0]); 223 UPDATE_HASH (str[1]); 224 return hash; 225 case 3: 226 UPDATE_HASH (str[0]); 227 UPDATE_HASH (str[1]); 228 UPDATE_HASH (str[2]); 229 return hash; 230 } 231 #endif 146 232 } 147 233 … … 506 592 struct strcache2_entry **src_tab = cache->hash_tab; 507 593 struct strcache2_entry **dst_tab; 594 #ifdef STRCACHE2_USE_MASK 508 595 unsigned int hash_mask; 596 #else 597 unsigned int hash_div; 598 #endif 509 599 510 600 /* Allocate a new hash table twice the size of the current. */ 511 601 cache->hash_size <<= 1; 602 #ifdef STRCACHE2_USE_MASK 512 603 cache->hash_mask <<= 1; 513 604 cache->hash_mask |= 1; 605 #else 606 for (hash_div = 1; (1U << hash_div) < cache->hash_size; hash_div++) 607 /* nothing */; 608 cache->hash_div = strcache2_find_prime(hash_div); 609 #endif 514 610 cache->rehash_count <<= 1; 515 611 cache->hash_tab = dst_tab = (struct strcache2_entry **) … … 518 614 519 615 /* Copy the entries from the old to the new hash table. */ 616 #ifdef STRCACHE2_USE_MASK 520 617 hash_mask = cache->hash_mask; 618 #else 619 hash_div = cache->hash_div; 620 #endif 521 621 while (src-- > 0) 522 622 { … … 524 624 if (entry) 525 625 { 626 #ifdef STRCACHE2_USE_MASK 526 627 unsigned int dst = entry->hash1 & hash_mask; 628 #else 629 unsigned int dst = entry->hash1 % hash_div; 630 #endif 527 631 if (dst_tab[dst]) 528 632 { … … 533 637 : strcache2_case_sensitive_hash_2 ((const char *)(entry + 1), entry->length); 534 638 dst += hash2; 639 #ifdef STRCACHE2_USE_MASK 535 640 dst &= hash_mask; 641 #else 642 dst %= hash_div; 643 #endif 536 644 while (dst_tab[dst]) 537 645 { 538 646 dst += hash2; 647 #ifdef STRCACHE2_USE_MASK 539 648 dst &= hash_mask; 649 #else 650 dst %= hash_div; 651 #endif 540 652 } 541 653 } … … 612 724 /* Lookup the entry in the hash table, hoping for an 613 725 early match. */ 614 idx = hash1 & cache->hash_mask;726 idx = STRCACHE2_MOD_IT(cache, hash1); 615 727 entry = cache->hash_tab[idx]; 616 728 if (strcache2_is_equal (cache, entry, str, length, hash1)) … … 624 736 hash2 = strcache2_case_sensitive_hash_2 (str, length); 625 737 idx += hash2; 626 idx &= cache->hash_mask;738 idx = STRCACHE2_MOD_IT(cache, idx); 627 739 entry = cache->hash_tab[idx]; 628 740 if (strcache2_is_equal (cache, entry, str, length, hash1)) … … 635 747 { 636 748 idx += hash2; 637 idx &= cache->hash_mask;749 idx = STRCACHE2_MOD_IT(cache, idx); 638 750 entry = cache->hash_tab[idx]; 639 751 cache->collision_3rd_count++; … … 674 786 /* Lookup the entry in the hash table, hoping for an 675 787 early match. */ 676 idx = hash1 & cache->hash_mask;788 idx = STRCACHE2_MOD_IT(cache, hash1); 677 789 entry = cache->hash_tab[idx]; 678 790 if (strcache2_is_equal (cache, entry, str, length, hash1)) … … 687 799 : strcache2_case_sensitive_hash_2 (str, length); 688 800 idx += hash2; 689 idx &= cache->hash_mask;801 idx = STRCACHE2_MOD_IT(cache, idx); 690 802 entry = cache->hash_tab[idx]; 691 803 if (strcache2_is_equal (cache, entry, str, length, hash1)) … … 698 810 { 699 811 idx += hash2; 700 idx &= cache->hash_mask;812 idx = STRCACHE2_MOD_IT(cache, idx); 701 813 entry = cache->hash_tab[idx]; 702 814 cache->collision_3rd_count++; … … 727 839 /* Lookup the entry in the hash table, hoping for an 728 840 early match. */ 729 idx = hash1 & cache->hash_mask;841 idx = STRCACHE2_MOD_IT(cache, hash1); 730 842 entry = cache->hash_tab[idx]; 731 843 if (strcache2_is_equal (cache, entry, str, length, hash1)) … … 739 851 hash2 = strcache2_case_sensitive_hash_2 (str, length); 740 852 idx += hash2; 741 idx &= cache->hash_mask;853 idx = STRCACHE2_MOD_IT(cache, idx); 742 854 entry = cache->hash_tab[idx]; 743 855 if (strcache2_is_equal (cache, entry, str, length, hash1)) … … 750 862 { 751 863 idx += hash2; 752 idx &= cache->hash_mask;864 idx = STRCACHE2_MOD_IT(cache, idx); 753 865 entry = cache->hash_tab[idx]; 754 866 cache->collision_3rd_count++; … … 780 892 /* Lookup the entry in the hash table, hoping for an 781 893 early match. */ 782 idx = hash1 & cache->hash_mask;894 idx = STRCACHE2_MOD_IT(cache, hash1); 783 895 entry = cache->hash_tab[idx]; 784 896 if (strcache2_is_iequal (cache, entry, str, length, hash1)) … … 792 904 hash2 = strcache2_case_insensitive_hash_2 (str, length); 793 905 idx += hash2; 794 idx &= cache->hash_mask;906 idx = STRCACHE2_MOD_IT(cache, idx); 795 907 entry = cache->hash_tab[idx]; 796 908 if (strcache2_is_iequal (cache, entry, str, length, hash1)) … … 803 915 { 804 916 idx += hash2; 805 idx &= cache->hash_mask;917 idx = STRCACHE2_MOD_IT(cache, idx); 806 918 entry = cache->hash_tab[idx]; 807 919 cache->collision_3rd_count++; … … 842 954 /* Lookup the entry in the hash table, hoping for an 843 955 early match. */ 844 idx = hash1 & cache->hash_mask;956 idx = STRCACHE2_MOD_IT(cache, hash1); 845 957 entry = cache->hash_tab[idx]; 846 958 if (strcache2_is_iequal (cache, entry, str, length, hash1)) … … 853 965 hash2 = strcache2_case_insensitive_hash_2 (str, length); 854 966 idx += hash2; 855 idx &= cache->hash_mask;967 idx = STRCACHE2_MOD_IT(cache, idx); 856 968 entry = cache->hash_tab[idx]; 857 969 if (strcache2_is_iequal (cache, entry, str, length, hash1)) … … 864 976 { 865 977 idx += hash2; 866 idx &= cache->hash_mask;978 idx = STRCACHE2_MOD_IT(cache, idx); 867 979 entry = cache->hash_tab[idx]; 868 980 cache->collision_3rd_count++; … … 893 1005 /* Lookup the entry in the hash table, hoping for an 894 1006 early match. */ 895 idx = hash1 & cache->hash_mask;1007 idx = STRCACHE2_MOD_IT(cache, hash1); 896 1008 entry = cache->hash_tab[idx]; 897 1009 if (strcache2_is_iequal (cache, entry, str, length, hash1)) … … 905 1017 hash2 = strcache2_case_insensitive_hash_2 (str, length); 906 1018 idx += hash2; 907 idx &= cache->hash_mask;1019 idx = STRCACHE2_MOD_IT(cache, idx); 908 1020 entry = cache->hash_tab[idx]; 909 1021 if (strcache2_is_iequal (cache, entry, str, length, hash1)) … … 916 1028 { 917 1029 idx += hash2; 918 idx &= cache->hash_mask;1030 idx = STRCACHE2_MOD_IT(cache, idx); 919 1031 entry = cache->hash_tab[idx]; 920 1032 cache->collision_3rd_count++; … … 1064 1176 /* init the structure. */ 1065 1177 cache->case_insensitive = case_insensitive; 1178 #ifdef STRCACHE2_USE_MASK 1066 1179 cache->hash_mask = (1U << hash_shift) - 1U; 1180 #else 1181 cache->hash_div = strcache2_find_prime(hash_shift); 1182 #endif 1067 1183 cache->count = 0; 1068 1184 cache->lookup_count = 0; … … 1181 1297 } 1182 1298 1299 #ifdef STRCACHE2_USE_MASK 1183 1300 printf (_("%s hash size = %u mask = %#x rehashed %u times lookups = %lu\n"), 1184 1301 prefix, cache->hash_size, cache->hash_mask, rehashes, cache->lookup_count); 1302 #else 1303 printf (_("%s hash size = %u div = %#x rehashed %u times lookups = %lu\n"), 1304 prefix, cache->hash_size, cache->hash_div, rehashes, cache->lookup_count); 1305 #endif 1185 1306 printf (_("%s hash collisions 1st = %lu (%u%%) 2nd = %lu (%u%%) 3rd = %lu (%u%%)\n"), 1186 1307 prefix,
Note:
See TracChangeset
for help on using the changeset viewer.