Skip to content

Commit 7482781

Browse files
committed
Allow non-power-of-2 signature cache sizes
1 parent 02e5308 commit 7482781

File tree

1 file changed

+11
-18
lines changed

1 file changed

+11
-18
lines changed

src/cuckoocache.h

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ class bit_packed_atomic_flags
154154
* @tparam Element should be a movable and copyable type
155155
* @tparam Hash should be a function/callable which takes a template parameter
156156
* hash_select and an Element and extracts a hash from it. Should return
157-
* high-entropy hashes for `Hash h; h<0>(e) ... h<7>(e)`.
157+
* high-entropy uint32_t hashes for `Hash h; h<0>(e) ... h<7>(e)`.
158158
*/
159159
template <typename Element, typename Hash>
160160
class cache
@@ -193,12 +193,6 @@ class cache
193193
*/
194194
uint32_t epoch_size;
195195

196-
/** hash_mask should be set to appropriately mask out a hash such that every
197-
* masked hash is [0,size), eg, if floor(log2(size)) == 20, then hash_mask
198-
* should be (1<<20)-1
199-
*/
200-
uint32_t hash_mask;
201-
202196
/** depth_limit determines how many elements insert should try to replace.
203197
* Should be set to log2(n)*/
204198
uint8_t depth_limit;
@@ -217,14 +211,14 @@ class cache
217211
*/
218212
inline std::array<uint32_t, 8> compute_hashes(const Element& e) const
219213
{
220-
return {{hash_function.template operator()<0>(e) & hash_mask,
221-
hash_function.template operator()<1>(e) & hash_mask,
222-
hash_function.template operator()<2>(e) & hash_mask,
223-
hash_function.template operator()<3>(e) & hash_mask,
224-
hash_function.template operator()<4>(e) & hash_mask,
225-
hash_function.template operator()<5>(e) & hash_mask,
226-
hash_function.template operator()<6>(e) & hash_mask,
227-
hash_function.template operator()<7>(e) & hash_mask}};
214+
return {{(uint32_t)((hash_function.template operator()<0>(e) * (uint64_t)size) >> 32),
215+
(uint32_t)((hash_function.template operator()<1>(e) * (uint64_t)size) >> 32),
216+
(uint32_t)((hash_function.template operator()<2>(e) * (uint64_t)size) >> 32),
217+
(uint32_t)((hash_function.template operator()<3>(e) * (uint64_t)size) >> 32),
218+
(uint32_t)((hash_function.template operator()<4>(e) * (uint64_t)size) >> 32),
219+
(uint32_t)((hash_function.template operator()<5>(e) * (uint64_t)size) >> 32),
220+
(uint32_t)((hash_function.template operator()<6>(e) * (uint64_t)size) >> 32),
221+
(uint32_t)((hash_function.template operator()<7>(e) * (uint64_t)size) >> 32)}};
228222
}
229223

230224
/* end
@@ -305,7 +299,7 @@ class cache
305299
}
306300

307301
/** setup initializes the container to store no more than new_size
308-
* elements. setup rounds down to a power of two size.
302+
* elements.
309303
*
310304
* setup should only be called once.
311305
*
@@ -316,8 +310,7 @@ class cache
316310
{
317311
// depth_limit must be at least one otherwise errors can occur.
318312
depth_limit = static_cast<uint8_t>(std::log2(static_cast<float>(std::max((uint32_t)2, new_size))));
319-
size = 1 << depth_limit;
320-
hash_mask = size-1;
313+
size = std::max<uint32_t>(2, new_size);
321314
table.resize(size);
322315
collection_flags.setup(size);
323316
epoch_flags.resize(size);

0 commit comments

Comments
 (0)