diff --git a/src/cuckoocache.h b/src/cuckoocache.h --- a/src/cuckoocache.h +++ b/src/cuckoocache.h @@ -428,7 +428,7 @@ // Make sure we have not already inserted this element. // If we have, make sure that it does not get deleted. for (const uint32_t loc : locs) { - if (table[loc] == e) { + if (table[loc].matchKey(e)) { please_keep(loc); epoch_flags[loc] = last_epoch; return; @@ -506,7 +506,7 @@ inline bool contains(const Element &e, const bool erase) const { std::array locs = compute_hashes(e); for (const uint32_t loc : locs) { - if (table[loc] == e) { + if (table[loc].matchKey(e)) { if (erase) { allow_erase(loc); } @@ -516,6 +516,19 @@ return false; } }; + +/** + * Helper class used when we only want the cache to be a set rather than a map. + */ +template struct KeyOnly : public T { + // Ensure implicit conversion from T. + KeyOnly() = default; + KeyOnly(const T &x) : T(x) {} + + // Implement required features. + bool matchKey(const T &key) const { return *this == key; } +}; + } // namespace CuckooCache #endif // BITCOIN_CUCKOOCACHE_H diff --git a/src/script/scriptcache.cpp b/src/script/scriptcache.cpp --- a/src/script/scriptcache.cpp +++ b/src/script/scriptcache.cpp @@ -13,7 +13,8 @@ #include #include -static CuckooCache::cache scriptExecutionCache; +static CuckooCache::cache, SignatureCacheHasher> + scriptExecutionCache; static uint256 scriptExecutionCacheNonce(GetRandHash()); void InitScriptExecutionCache() { diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -25,7 +25,9 @@ private: //! Entries are SHA256(nonce || signature hash || public key || signature): uint256 nonce; - typedef CuckooCache::cache map_type; + typedef CuckooCache::cache, + SignatureCacheHasher> + map_type; map_type setValid; boost::shared_mutex cs_sigcache; diff --git a/src/test/cuckoocache_tests.cpp b/src/test/cuckoocache_tests.cpp --- a/src/test/cuckoocache_tests.cpp +++ b/src/test/cuckoocache_tests.cpp @@ -34,7 +34,8 @@ */ BOOST_AUTO_TEST_CASE(test_cuckoocache_no_fakes) { SeedInsecureRand(true); - CuckooCache::cache cc{}; + CuckooCache::cache, SignatureCacheHasher> + cc{}; size_t megabytes = 4; cc.setup_bytes(megabytes << 20); for (int x = 0; x < 100000; ++x) { @@ -115,8 +116,9 @@ size_t megabytes = 4; for (double load = 0.1; load < 2; load *= 2) { double hits = - test_cache>( - megabytes, load); + test_cache, + SignatureCacheHasher>>(megabytes, + load); BOOST_CHECK(normalize_hit_rate(hits, load) > HitRateThresh); } } @@ -191,8 +193,8 @@ BOOST_AUTO_TEST_CASE(cuckoocache_erase_ok) { size_t megabytes = 4; - test_cache_erase>( - megabytes); + test_cache_erase, + SignatureCacheHasher>>(megabytes); } template @@ -287,8 +289,9 @@ BOOST_AUTO_TEST_CASE(cuckoocache_erase_parallel_ok) { size_t megabytes = 4; - test_cache_erase_parallel< - CuckooCache::cache>(megabytes); + test_cache_erase_parallel, + SignatureCacheHasher>>( + megabytes); } template static void test_cache_generations() { @@ -389,7 +392,8 @@ max_rate_less_than_tight_hit_rate); } BOOST_AUTO_TEST_CASE(cuckoocache_generations) { - test_cache_generations>(); + test_cache_generations, + SignatureCacheHasher>>(); } BOOST_AUTO_TEST_SUITE_END();