Changeset View
Changeset View
Standalone View
Standalone View
src/test/cuckoocache_tests.cpp
Show All 40 Lines | |||||
/** | /** | ||||
* Test that no values not inserted into the cache are read out of it. | * Test that no values not inserted into the cache are read out of it. | ||||
* | * | ||||
* There are no repeats in the first 200000 insecure_GetRandHash calls | * There are no repeats in the first 200000 insecure_GetRandHash calls | ||||
*/ | */ | ||||
BOOST_AUTO_TEST_CASE(test_cuckoocache_no_fakes) { | BOOST_AUTO_TEST_CASE(test_cuckoocache_no_fakes) { | ||||
local_rand_ctx = FastRandomContext(true); | local_rand_ctx = FastRandomContext(true); | ||||
CuckooCache::cache<uint256, SignatureCacheHasher> cc{}; | CuckooCache::cache<uint256, SignatureCacheHasher> cc{}; | ||||
cc.setup_bytes(32 << 20); | size_t megabytes = 4; | ||||
cc.setup_bytes(megabytes << 20); | |||||
uint256 v; | uint256 v; | ||||
for (int x = 0; x < 100000; ++x) { | for (int x = 0; x < 100000; ++x) { | ||||
insecure_GetRandHash(v); | insecure_GetRandHash(v); | ||||
cc.insert(v); | cc.insert(v); | ||||
} | } | ||||
for (int x = 0; x < 100000; ++x) { | for (int x = 0; x < 100000; ++x) { | ||||
insecure_GetRandHash(v); | insecure_GetRandHash(v); | ||||
BOOST_CHECK(!cc.contains(v, false)); | BOOST_CHECK(!cc.contains(v, false)); | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | |||||
/** Check the hit rate on loads ranging from 0.1 to 2.0 */ | /** Check the hit rate on loads ranging from 0.1 to 2.0 */ | ||||
BOOST_AUTO_TEST_CASE(cuckoocache_hit_rate_ok) { | BOOST_AUTO_TEST_CASE(cuckoocache_hit_rate_ok) { | ||||
/** | /** | ||||
* Arbitrarily selected Hit Rate threshold that happens to work for this | * Arbitrarily selected Hit Rate threshold that happens to work for this | ||||
* test as a lower bound on performance. | * test as a lower bound on performance. | ||||
*/ | */ | ||||
double HitRateThresh = 0.98; | double HitRateThresh = 0.98; | ||||
size_t megabytes = 32; | size_t megabytes = 4; | ||||
for (double load = 0.1; load < 2; load *= 2) { | for (double load = 0.1; load < 2; load *= 2) { | ||||
double hits = | double hits = | ||||
test_cache<CuckooCache::cache<uint256, SignatureCacheHasher>>( | test_cache<CuckooCache::cache<uint256, SignatureCacheHasher>>( | ||||
megabytes, load); | megabytes, load); | ||||
BOOST_CHECK(normalize_hit_rate(hits, load) > HitRateThresh); | BOOST_CHECK(normalize_hit_rate(hits, load) > HitRateThresh); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | template <typename Cache> void test_cache_erase(size_t megabytes) { | ||||
// Check that our hit_rate_fresh is perfect | // Check that our hit_rate_fresh is perfect | ||||
BOOST_CHECK_EQUAL(hit_rate_fresh, 1.0); | BOOST_CHECK_EQUAL(hit_rate_fresh, 1.0); | ||||
// Check that we have a more than 2x better hit rate on stale elements than | // Check that we have a more than 2x better hit rate on stale elements than | ||||
// erased elements. | // erased elements. | ||||
BOOST_CHECK(hit_rate_stale > 2 * hit_rate_erased_but_contained); | BOOST_CHECK(hit_rate_stale > 2 * hit_rate_erased_but_contained); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(cuckoocache_erase_ok) { | BOOST_AUTO_TEST_CASE(cuckoocache_erase_ok) { | ||||
size_t megabytes = 32; | size_t megabytes = 4; | ||||
test_cache_erase<CuckooCache::cache<uint256, SignatureCacheHasher>>( | test_cache_erase<CuckooCache::cache<uint256, SignatureCacheHasher>>( | ||||
megabytes); | megabytes); | ||||
} | } | ||||
template <typename Cache> void test_cache_erase_parallel(size_t megabytes) { | template <typename Cache> void test_cache_erase_parallel(size_t megabytes) { | ||||
double load = 1; | double load = 1; | ||||
local_rand_ctx = FastRandomContext(true); | local_rand_ctx = FastRandomContext(true); | ||||
std::vector<uint256> hashes; | std::vector<uint256> hashes; | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | template <typename Cache> void test_cache_erase_parallel(size_t megabytes) { | ||||
// Check that our hit_rate_fresh is perfect | // Check that our hit_rate_fresh is perfect | ||||
BOOST_CHECK_EQUAL(hit_rate_fresh, 1.0); | BOOST_CHECK_EQUAL(hit_rate_fresh, 1.0); | ||||
// Check that we have a more than 2x better hit rate on stale elements than | // Check that we have a more than 2x better hit rate on stale elements than | ||||
// erased elements. | // erased elements. | ||||
BOOST_CHECK(hit_rate_stale > 2 * hit_rate_erased_but_contained); | BOOST_CHECK(hit_rate_stale > 2 * hit_rate_erased_but_contained); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(cuckoocache_erase_parallel_ok) { | BOOST_AUTO_TEST_CASE(cuckoocache_erase_parallel_ok) { | ||||
size_t megabytes = 32; | size_t megabytes = 4; | ||||
test_cache_erase_parallel< | test_cache_erase_parallel< | ||||
CuckooCache::cache<uint256, SignatureCacheHasher>>(megabytes); | CuckooCache::cache<uint256, SignatureCacheHasher>>(megabytes); | ||||
} | } | ||||
template <typename Cache> void test_cache_generations() { | template <typename Cache> void test_cache_generations() { | ||||
// This test checks that for a simulation of network activity, the fresh hit | // This test checks that for a simulation of network activity, the fresh hit | ||||
// rate is never below 99%, and the number of times that it is worse than | // rate is never below 99%, and the number of times that it is worse than | ||||
// 99.9% are less than 1% of the time. | // 99.9% are less than 1% of the time. | ||||
Show All 37 Lines | struct block_activity { | ||||
reads.push_back(inserts[i]); | reads.push_back(inserts[i]); | ||||
} | } | ||||
for (auto h : inserts) { | for (auto h : inserts) { | ||||
c.insert(h); | c.insert(h); | ||||
} | } | ||||
} | } | ||||
}; | }; | ||||
const uint32_t BLOCK_SIZE = 10000; | const uint32_t BLOCK_SIZE = 1000; | ||||
// We expect window size 60 to perform reasonably given that each epoch | // We expect window size 60 to perform reasonably given that each epoch | ||||
// stores 45% of the cache size (~472k). | // stores 45% of the cache size (~472k). | ||||
const uint32_t WINDOW_SIZE = 60; | const uint32_t WINDOW_SIZE = 60; | ||||
const uint32_t POP_AMOUNT = (BLOCK_SIZE / WINDOW_SIZE) / 2; | const uint32_t POP_AMOUNT = (BLOCK_SIZE / WINDOW_SIZE) / 2; | ||||
const double load = 10; | const double load = 10; | ||||
const size_t megabytes = 32; | const size_t megabytes = 4; | ||||
const size_t bytes = megabytes * (1 << 20); | const size_t bytes = megabytes * (1 << 20); | ||||
const uint32_t n_insert = | const uint32_t n_insert = | ||||
static_cast<uint32_t>(load * (bytes / sizeof(uint256))); | static_cast<uint32_t>(load * (bytes / sizeof(uint256))); | ||||
std::vector<block_activity> hashes; | std::vector<block_activity> hashes; | ||||
Cache set{}; | Cache set{}; | ||||
set.setup_bytes(bytes); | set.setup_bytes(bytes); | ||||
hashes.reserve(n_insert / BLOCK_SIZE); | hashes.reserve(n_insert / BLOCK_SIZE); | ||||
Show All 36 Lines |