From 7482781347c34977b95e99589cac94888979dafa Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 12 Jan 2017 10:16:31 -0800 Subject: [PATCH] Allow non-power-of-2 signature cache sizes --- src/cuckoocache.h | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/cuckoocache.h b/src/cuckoocache.h index efd6a820b5..83355dc5e1 100644 --- a/src/cuckoocache.h +++ b/src/cuckoocache.h @@ -154,7 +154,7 @@ public: * @tparam Element should be a movable and copyable type * @tparam Hash should be a function/callable which takes a template parameter * hash_select and an Element and extracts a hash from it. Should return - * high-entropy hashes for `Hash h; h<0>(e) ... h<7>(e)`. + * high-entropy uint32_t hashes for `Hash h; h<0>(e) ... h<7>(e)`. */ template class cache @@ -193,12 +193,6 @@ private: */ uint32_t epoch_size; - /** hash_mask should be set to appropriately mask out a hash such that every - * masked hash is [0,size), eg, if floor(log2(size)) == 20, then hash_mask - * should be (1<<20)-1 - */ - uint32_t hash_mask; - /** depth_limit determines how many elements insert should try to replace. * Should be set to log2(n)*/ uint8_t depth_limit; @@ -217,14 +211,14 @@ private: */ inline std::array compute_hashes(const Element& e) const { - return {{hash_function.template operator()<0>(e) & hash_mask, - hash_function.template operator()<1>(e) & hash_mask, - hash_function.template operator()<2>(e) & hash_mask, - hash_function.template operator()<3>(e) & hash_mask, - hash_function.template operator()<4>(e) & hash_mask, - hash_function.template operator()<5>(e) & hash_mask, - hash_function.template operator()<6>(e) & hash_mask, - hash_function.template operator()<7>(e) & hash_mask}}; + return {{(uint32_t)((hash_function.template operator()<0>(e) * (uint64_t)size) >> 32), + (uint32_t)((hash_function.template operator()<1>(e) * (uint64_t)size) >> 32), + (uint32_t)((hash_function.template operator()<2>(e) * (uint64_t)size) >> 32), + (uint32_t)((hash_function.template operator()<3>(e) * (uint64_t)size) >> 32), + (uint32_t)((hash_function.template operator()<4>(e) * (uint64_t)size) >> 32), + (uint32_t)((hash_function.template operator()<5>(e) * (uint64_t)size) >> 32), + (uint32_t)((hash_function.template operator()<6>(e) * (uint64_t)size) >> 32), + (uint32_t)((hash_function.template operator()<7>(e) * (uint64_t)size) >> 32)}}; } /* end @@ -305,7 +299,7 @@ public: } /** setup initializes the container to store no more than new_size - * elements. setup rounds down to a power of two size. + * elements. * * setup should only be called once. * @@ -316,8 +310,7 @@ public: { // depth_limit must be at least one otherwise errors can occur. depth_limit = static_cast(std::log2(static_cast(std::max((uint32_t)2, new_size)))); - size = 1 << depth_limit; - hash_mask = size-1; + size = std::max(2, new_size); table.resize(size); collection_flags.setup(size); epoch_flags.resize(size);