Skip to content

Commit 84d4b7b

Browse files
committed
Hashtable: Shrink nextPrime() lookup table size
The lookup table now codes the difference between 2^n to the nearest prime not greater than 2^n (i.e. https://oeis.org/A013603 ). With the change of the lookup table, (2^64 - 59) has been removed. It is believed that such removal won't cause practical problems as the number is very close to SIZE_MAX and a system is unlikely to succeed in allocating a memory block _that_ huge. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
1 parent e15547f commit 84d4b7b

1 file changed

Lines changed: 16 additions & 31 deletions

File tree

Hashtable.c

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ in the source distribution for its full text.
1010
#include "Hashtable.h"
1111

1212
#include <assert.h>
13+
#include <limits.h>
1314
#include <stdint.h>
1415
#include <stdlib.h>
1516
#include <string.h>
@@ -93,42 +94,26 @@ size_t Hashtable_count(const Hashtable* this) {
9394

9495
#endif /* NDEBUG */
9596

96-
/* https://oeis.org/A014234 */
97-
static const uint64_t OEISprimes[] = {
98-
7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191,
99-
16381, 32749, 65521,
97+
static size_t nextPrime(size_t n) {
98+
// Table of differences so that (2^m - primeDiffs[m]) is a prime.
99+
// This is OEIS sequence https://oeis.org/A013603 except for
100+
// entry 0 (2^0 = 1 as a non-prime special case).
101+
static const uint8_t primeDiffs[] = {
102+
0, 0, 1, 1, 3, 1, 3, 1, 5, 3, 3, 9, 3, 1, 3, 19,
100103
#if SIZE_MAX > UINT16_MAX
101-
131071, 262139, 524287, 1048573,
102-
2097143, 4194301, 8388593, 16777213, 33554393,
103-
67108859, 134217689, 268435399, 536870909, 1073741789,
104-
2147483647, 4294967291,
104+
15, 1, 5, 1, 3, 9, 3, 15, 3, 39, 5, 39, 57, 3, 35, 1,
105105
#if SIZE_MAX > UINT32_MAX
106-
/* https://oeis.org/A013603 */
107-
((uint64_t)1 << 33) - 9, ((uint64_t)1 << 34) - 41,
108-
((uint64_t)1 << 35) - 31, ((uint64_t)1 << 36) - 5,
109-
((uint64_t)1 << 37) - 25, ((uint64_t)1 << 38) - 45,
110-
((uint64_t)1 << 39) - 7, ((uint64_t)1 << 40) - 87,
111-
((uint64_t)1 << 41) - 21, ((uint64_t)1 << 42) - 11,
112-
((uint64_t)1 << 43) - 57, ((uint64_t)1 << 44) - 17,
113-
((uint64_t)1 << 45) - 55, ((uint64_t)1 << 46) - 21,
114-
((uint64_t)1 << 47) - 115, ((uint64_t)1 << 48) - 59,
115-
((uint64_t)1 << 49) - 81, ((uint64_t)1 << 50) - 27,
116-
((uint64_t)1 << 51) - 129, ((uint64_t)1 << 52) - 47,
117-
((uint64_t)1 << 53) - 111, ((uint64_t)1 << 54) - 33,
118-
((uint64_t)1 << 55) - 55, ((uint64_t)1 << 56) - 5,
119-
((uint64_t)1 << 57) - 13, ((uint64_t)1 << 58) - 27,
120-
((uint64_t)1 << 59) - 55, ((uint64_t)1 << 60) - 93,
121-
((uint64_t)1 << 61) - 1, ((uint64_t)1 << 62) - 57,
122-
((uint64_t)1 << 63) - 25, (uint64_t)-59,
106+
5, 9, 41, 31, 5, 25, 45, 7, 87, 21, 11, 57, 17, 55, 21, 115,
107+
59, 81, 27, 129, 47, 111, 33, 55, 5, 13, 27, 55, 93, 1, 57, 25,
123108
#endif
124109
#endif
125-
};
110+
};
126111

127-
static size_t nextPrime(size_t n) {
128-
/* on 32-bit make sure we do not return primes not fitting in size_t */
129-
for (size_t i = 0; i < ARRAYSIZE(OEISprimes); i++) {
130-
if (n <= OEISprimes[i]) {
131-
return OEISprimes[i];
112+
assert(sizeof(n) * CHAR_BIT <= ARRAYSIZE(primeDiffs));
113+
for (uint8_t shift = 3; shift < sizeof(n) * CHAR_BIT; shift++) {
114+
size_t prime = ((size_t)1 << shift) - primeDiffs[shift];
115+
if (n <= prime) {
116+
return prime;
132117
}
133118
}
134119

0 commit comments

Comments
 (0)