-
- #include <cstdint>
- #include <cstddef>
- #include <functional>
- #include <vector>
- #include <cmath>
- #include <array>
- #include <algorithm>
- #include <iterator>
- #include <utility>
- #include <type_traits>
- struct prime_number_hash_policy
- {
- size_t index_for_hash(size_t hash, size_t /*num_slots_minus_one*/) const
- {
- switch(prime_index)
- {
- case 0:
- return 0llu;
- case 1:
- return hash % 2llu;
- case 2:
- return hash % 3llu;
- case 3:
- return hash % 5llu;
- case 4:
- return hash % 7llu;
- case 5:
- return hash % 11llu;
- case 6:
- return hash % 13llu;
- case 7:
- return hash % 17llu;
- case 8:
- return hash % 23llu;
- case 9:
- return hash % 29llu;
- case 10:
- return hash % 37llu;
- case 11:
- return hash % 47llu;
- case 12:
- return hash % 59llu;
- case 13:
- return hash % 73llu;
- case 14:
- return hash % 97llu;
- case 15:
- return hash % 127llu;
- case 16:
- return hash % 151llu;
- case 17:
- return hash % 197llu;
- case 18:
- return hash % 251llu;
- case 19:
- return hash % 313llu;
- case 20:
- return hash % 397llu;
- case 21:
- return hash % 499llu;
- case 22:
- return hash % 631llu;
- case 23:
- return hash % 797llu;
- case 24:
- return hash % 1009llu;
- case 25:
- return hash % 1259llu;
- case 26:
- return hash % 1597llu;
- case 27:
- return hash % 2011llu;
- case 28:
- return hash % 2539llu;
- case 29:
- return hash % 3203llu;
- case 30:
- return hash % 4027llu;
- case 31:
- return hash % 5087llu;
- case 32:
- return hash % 6421llu;
- case 33:
- return hash % 8089llu;
- case 34:
- return hash % 10193llu;
- case 35:
- return hash % 12853llu;
- case 36:
- return hash % 16193llu;
- case 37:
- return hash % 20399llu;
- case 38:
- return hash % 25717llu;
- case 39:
- return hash % 32401llu;
- case 40:
- return hash % 40823llu;
- case 41:
- return hash % 51437llu;
- case 42:
- return hash % 64811llu;
- case 43:
- return hash % 81649llu;
- case 44:
- return hash % 102877llu;
- case 45:
- return hash % 129607llu;
- case 46:
- return hash % 163307llu;
- case 47:
- return hash % 205759llu;
- case 48:
- return hash % 259229llu;
- case 49:
- return hash % 326617llu;
- case 50:
- return hash % 411527llu;
- case 51:
- return hash % 518509llu;
- case 52:
- return hash % 653267llu;
- case 53:
- return hash % 823117llu;
- case 54:
- return hash % 1037059llu;
- case 55:
- return hash % 1306601llu;
- case 56:
- return hash % 1646237llu;
- case 57:
- return hash % 2074129llu;
- case 58:
- return hash % 2613229llu;
- case 59:
- return hash % 3292489llu;
- case 60:
- return hash % 4148279llu;
- case 61:
- return hash % 5226491llu;
- case 62:
- return hash % 6584983llu;
- case 63:
- return hash % 8296553llu;
- case 64:
- return hash % 10453007llu;
- case 65:
- return hash % 13169977llu;
- case 66:
- return hash % 16593127llu;
- case 67:
- return hash % 20906033llu;
- case 68:
- return hash % 26339969llu;
- case 69:
- return hash % 33186281llu;
- case 70:
- return hash % 41812097llu;
- case 71:
- return hash % 52679969llu;
- case 72:
- return hash % 66372617llu;
- case 73:
- return hash % 83624237llu;
- case 74:
- return hash % 105359939llu;
- case 75:
- return hash % 132745199llu;
- case 76:
- return hash % 167248483llu;
- case 77:
- return hash % 210719881llu;
- case 78:
- return hash % 265490441llu;
- case 79:
- return hash % 334496971llu;
- case 80:
- return hash % 421439783llu;
- case 81:
- return hash % 530980861llu;
- case 82:
- return hash % 668993977llu;
- case 83:
- return hash % 842879579llu;
- case 84:
- return hash % 1061961721llu;
- case 85:
- return hash % 1337987929llu;
- case 86:
- return hash % 1685759167llu;
- case 87:
- return hash % 2123923447llu;
- case 88:
- return hash % 2675975881llu;
- case 89:
- return hash % 3371518343llu;
- case 90:
- return hash % 4247846927llu;
- case 91:
- return hash % 5351951779llu;
- case 92:
- return hash % 6743036717llu;
- case 93:
- return hash % 8495693897llu;
- case 94:
- return hash % 10703903591llu;
- case 95:
- return hash % 13486073473llu;
- case 96:
- return hash % 16991387857llu;
- case 97:
- return hash % 21407807219llu;
- case 98:
- return hash % 26972146961llu;
- case 99:
- return hash % 33982775741llu;
- case 100:
- return hash % 42815614441llu;
- case 101:
- return hash % 53944293929llu;
- case 102:
- return hash % 67965551447llu;
- case 103:
- return hash % 85631228929llu;
- case 104:
- return hash % 107888587883llu;
- case 105:
- return hash % 135931102921llu;
- case 106:
- return hash % 171262457903llu;
- case 107:
- return hash % 215777175787llu;
- case 108:
- return hash % 271862205833llu;
- case 109:
- return hash % 342524915839llu;
- case 110:
- return hash % 431554351609llu;
- case 111:
- return hash % 543724411781llu;
- case 112:
- return hash % 685049831731llu;
- case 113:
- return hash % 863108703229llu;
- case 114:
- return hash % 1087448823553llu;
- case 115:
- return hash % 1370099663459llu;
- case 116:
- return hash % 1726217406467llu;
- case 117:
- return hash % 2174897647073llu;
- case 118:
- return hash % 2740199326961llu;
- case 119:
- return hash % 3452434812973llu;
- case 120:
- return hash % 4349795294267llu;
- case 121:
- return hash % 5480398654009llu;
- case 122:
- return hash % 6904869625999llu;
- case 123:
- return hash % 8699590588571llu;
- case 124:
- return hash % 10960797308051llu;
- case 125:
- return hash % 13809739252051llu;
- case 126:
- return hash % 17399181177241llu;
- case 127:
- return hash % 21921594616111llu;
- case 128:
- return hash % 27619478504183llu;
- case 129:
- return hash % 34798362354533llu;
- case 130:
- return hash % 43843189232363llu;
- case 131:
- return hash % 55238957008387llu;
- case 132:
- return hash % 69596724709081llu;
- case 133:
- return hash % 87686378464759llu;
- case 134:
- return hash % 110477914016779llu;
- case 135:
- return hash % 139193449418173llu;
- case 136:
- return hash % 175372756929481llu;
- case 137:
- return hash % 220955828033581llu;
- case 138:
- return hash % 278386898836457llu;
- case 139:
- return hash % 350745513859007llu;
- case 140:
- return hash % 441911656067171llu;
- case 141:
- return hash % 556773797672909llu;
- case 142:
- return hash % 701491027718027llu;
- case 143:
- return hash % 883823312134381llu;
- case 144:
- return hash % 1113547595345903llu;
- case 145:
- return hash % 1402982055436147llu;
- case 146:
- return hash % 1767646624268779llu;
- case 147:
- return hash % 2227095190691797llu;
- case 148:
- return hash % 2805964110872297llu;
- case 149:
- return hash % 3535293248537579llu;
- case 150:
- return hash % 4454190381383713llu;
- case 151:
- return hash % 5611928221744609llu;
- case 152:
- return hash % 7070586497075177llu;
- case 153:
- return hash % 8908380762767489llu;
- case 154:
- return hash % 11223856443489329llu;
- case 155:
- return hash % 14141172994150357llu;
- case 156:
- return hash % 17816761525534927llu;
- case 157:
- return hash % 22447712886978529llu;
- case 158:
- return hash % 28282345988300791llu;
- case 159:
- return hash % 35633523051069991llu;
- case 160:
- return hash % 44895425773957261llu;
- case 161:
- return hash % 56564691976601587llu;
- case 162:
- return hash % 71267046102139967llu;
- case 163:
- return hash % 89790851547914507llu;
- case 164:
- return hash % 113129383953203213llu;
- case 165:
- return hash % 142534092204280003llu;
- case 166:
- return hash % 179581703095829107llu;
- case 167:
- return hash % 226258767906406483llu;
- case 168:
- return hash % 285068184408560057llu;
- case 169:
- return hash % 359163406191658253llu;
- case 170:
- return hash % 452517535812813007llu;
- case 171:
- return hash % 570136368817120201llu;
- case 172:
- return hash % 718326812383316683llu;
- case 173:
- return hash % 905035071625626043llu;
- case 174:
- return hash % 1140272737634240411llu;
- case 175:
- return hash % 1436653624766633509llu;
- case 176:
- return hash % 1810070143251252131llu;
- case 177:
- return hash % 2280545475268481167llu;
- case 178:
- return hash % 2873307249533267101llu;
- case 179:
- return hash % 3620140286502504283llu;
- case 180:
- return hash % 4561090950536962147llu;
- case 181:
- return hash % 5746614499066534157llu;
- case 182:
- return hash % 7240280573005008577llu;
- case 183:
- return hash % 9122181901073924329llu;
- case 184:
- return hash % 11493228998133068689llu;
- case 185:
- return hash % 14480561146010017169llu;
- case 186:
- return hash % 18446744073709551557llu;
- default:
- return hash;
- }
- }
- size_t index_for_hash_2(size_t hash, size_t /*num_slots_minus_one*/) const
- {
- static constexpr const size_t prime_list[] =
- {
- 2llu, 3llu, 5llu, 7llu, 11llu, 13llu, 17llu, 23llu, 29llu, 37llu, 47llu,
- 59llu, 73llu, 97llu, 127llu, 151llu, 197llu, 251llu, 313llu, 397llu,
- 499llu, 631llu, 797llu, 1009llu, 1259llu, 1597llu, 2011llu, 2539llu,
- 3203llu, 4027llu, 5087llu, 6421llu, 8089llu, 10193llu, 12853llu, 16193llu,
- 20399llu, 25717llu, 32401llu, 40823llu, 51437llu, 64811llu, 81649llu,
- 102877llu, 129607llu, 163307llu, 205759llu, 259229llu, 326617llu,
- 411527llu, 518509llu, 653267llu, 823117llu, 1037059llu, 1306601llu,
- 1646237llu, 2074129llu, 2613229llu, 3292489llu, 4148279llu, 5226491llu,
- 6584983llu, 8296553llu, 10453007llu, 13169977llu, 16593127llu, 20906033llu,
- 26339969llu, 33186281llu, 41812097llu, 52679969llu, 66372617llu,
- 83624237llu, 105359939llu, 132745199llu, 167248483llu, 210719881llu,
- 265490441llu, 334496971llu, 421439783llu, 530980861llu, 668993977llu,
- 842879579llu, 1061961721llu, 1337987929llu, 1685759167llu, 2123923447llu,
- 2675975881llu, 3371518343llu, 4247846927llu, 5351951779llu, 6743036717llu,
- 8495693897llu, 10703903591llu, 13486073473llu, 16991387857llu,
- 21407807219llu, 26972146961llu, 33982775741llu, 42815614441llu,
- 53944293929llu, 67965551447llu, 85631228929llu, 107888587883llu,
- 135931102921llu, 171262457903llu, 215777175787llu, 271862205833llu,
- 342524915839llu, 431554351609llu, 543724411781llu, 685049831731llu,
- 863108703229llu, 1087448823553llu, 1370099663459llu, 1726217406467llu,
- 2174897647073llu, 2740199326961llu, 3452434812973llu, 4349795294267llu,
- 5480398654009llu, 6904869625999llu, 8699590588571llu, 10960797308051llu,
- 13809739252051llu, 17399181177241llu, 21921594616111llu, 27619478504183llu,
- 34798362354533llu, 43843189232363llu, 55238957008387llu, 69596724709081llu,
- 87686378464759llu, 110477914016779llu, 139193449418173llu,
- 175372756929481llu, 220955828033581llu, 278386898836457llu,
- 350745513859007llu, 441911656067171llu, 556773797672909llu,
- 701491027718027llu, 883823312134381llu, 1113547595345903llu,
- 1402982055436147llu, 1767646624268779llu, 2227095190691797llu,
- 2805964110872297llu, 3535293248537579llu, 4454190381383713llu,
- 5611928221744609llu, 7070586497075177llu, 8908380762767489llu,
- 11223856443489329llu, 14141172994150357llu, 17816761525534927llu,
- 22447712886978529llu, 28282345988300791llu, 35633523051069991llu,
- 44895425773957261llu, 56564691976601587llu, 71267046102139967llu,
- 89790851547914507llu, 113129383953203213llu, 142534092204280003llu,
- 179581703095829107llu, 226258767906406483llu, 285068184408560057llu,
- 359163406191658253llu, 452517535812813007llu, 570136368817120201llu,
- 718326812383316683llu, 905035071625626043llu, 1140272737634240411llu,
- 1436653624766633509llu, 1810070143251252131llu, 2280545475268481167llu,
- 2873307249533267101llu, 3620140286502504283llu, 4561090950536962147llu,
- 5746614499066534157llu, 7240280573005008577llu, 9122181901073924329llu,
- 11493228998133068689llu, 14480561146010017169llu, 18446744073709551557llu
- };
- if (prime_index == 0) {
- return 0llu;
- } else if (prime_index > sizeof(prime_list)) {
- return hash;
- } else {
- return hash % prime_list[prime_index - 1];
- }
- }
- uint8_t next_size_over(size_t & size) const
- {
- // prime numbers generated by the following method:
- // 1. start with a prime p = 2
- // 2. go to wolfram alpha and get p = NextPrime(2 * p)
- // 3. repeat 2. until you overflow 64 bits
- // you now have large gaps which you would hit if somebody called reserve() with an unlucky number.
- // 4. to fill the gaps for every prime p go to wolfram alpha and get ClosestPrime(p * 2^(1/3)) and ClosestPrime(p * 2^(2/3)) and put those in the gaps
- // 5. get PrevPrime(2^64) and put it at the end
- static constexpr const size_t prime_list[] =
- {
- 2llu, 3llu, 5llu, 7llu, 11llu, 13llu, 17llu, 23llu, 29llu, 37llu, 47llu,
- 59llu, 73llu, 97llu, 127llu, 151llu, 197llu, 251llu, 313llu, 397llu,
- 499llu, 631llu, 797llu, 1009llu, 1259llu, 1597llu, 2011llu, 2539llu,
- 3203llu, 4027llu, 5087llu, 6421llu, 8089llu, 10193llu, 12853llu, 16193llu,
- 20399llu, 25717llu, 32401llu, 40823llu, 51437llu, 64811llu, 81649llu,
- 102877llu, 129607llu, 163307llu, 205759llu, 259229llu, 326617llu,
- 411527llu, 518509llu, 653267llu, 823117llu, 1037059llu, 1306601llu,
- 1646237llu, 2074129llu, 2613229llu, 3292489llu, 4148279llu, 5226491llu,
- 6584983llu, 8296553llu, 10453007llu, 13169977llu, 16593127llu, 20906033llu,
- 26339969llu, 33186281llu, 41812097llu, 52679969llu, 66372617llu,
- 83624237llu, 105359939llu, 132745199llu, 167248483llu, 210719881llu,
- 265490441llu, 334496971llu, 421439783llu, 530980861llu, 668993977llu,
- 842879579llu, 1061961721llu, 1337987929llu, 1685759167llu, 2123923447llu,
- 2675975881llu, 3371518343llu, 4247846927llu, 5351951779llu, 6743036717llu,
- 8495693897llu, 10703903591llu, 13486073473llu, 16991387857llu,
- 21407807219llu, 26972146961llu, 33982775741llu, 42815614441llu,
- 53944293929llu, 67965551447llu, 85631228929llu, 107888587883llu,
- 135931102921llu, 171262457903llu, 215777175787llu, 271862205833llu,
- 342524915839llu, 431554351609llu, 543724411781llu, 685049831731llu,
- 863108703229llu, 1087448823553llu, 1370099663459llu, 1726217406467llu,
- 2174897647073llu, 2740199326961llu, 3452434812973llu, 4349795294267llu,
- 5480398654009llu, 6904869625999llu, 8699590588571llu, 10960797308051llu,
- 13809739252051llu, 17399181177241llu, 21921594616111llu, 27619478504183llu,
- 34798362354533llu, 43843189232363llu, 55238957008387llu, 69596724709081llu,
- 87686378464759llu, 110477914016779llu, 139193449418173llu,
- 175372756929481llu, 220955828033581llu, 278386898836457llu,
- 350745513859007llu, 441911656067171llu, 556773797672909llu,
- 701491027718027llu, 883823312134381llu, 1113547595345903llu,
- 1402982055436147llu, 1767646624268779llu, 2227095190691797llu,
- 2805964110872297llu, 3535293248537579llu, 4454190381383713llu,
- 5611928221744609llu, 7070586497075177llu, 8908380762767489llu,
- 11223856443489329llu, 14141172994150357llu, 17816761525534927llu,
- 22447712886978529llu, 28282345988300791llu, 35633523051069991llu,
- 44895425773957261llu, 56564691976601587llu, 71267046102139967llu,
- 89790851547914507llu, 113129383953203213llu, 142534092204280003llu,
- 179581703095829107llu, 226258767906406483llu, 285068184408560057llu,
- 359163406191658253llu, 452517535812813007llu, 570136368817120201llu,
- 718326812383316683llu, 905035071625626043llu, 1140272737634240411llu,
- 1436653624766633509llu, 1810070143251252131llu, 2280545475268481167llu,
- 2873307249533267101llu, 3620140286502504283llu, 4561090950536962147llu,
- 5746614499066534157llu, 7240280573005008577llu, 9122181901073924329llu,
- 11493228998133068689llu, 14480561146010017169llu, 18446744073709551557llu
- };
- const size_t * found = std::lower_bound(std::begin(prime_list), std::end(prime_list) - 1, size);
- size = *found;
- return static_cast<uint8_t>(1 + found - prime_list);
- }
- void commit(uint8_t new_prime_index)
- {
- prime_index = new_prime_index;
- }
- void reset()
- {
- prime_index = 0;
- }
-
- private:
- uint8_t prime_index = 0;
- };
- int main(int argc, char **argv, char **environ)
- {
- prime_number_hash_policy h;
- h.commit((uint8_t)argc);
- printf("%zu\n", h.index_for_hash((size_t)argv, (size_t)environ));
- printf("%zu\n", h.index_for_hash_2((size_t)argv, (size_t)environ));
- return 0;
- }
-