| 122 | * that the hit rate of "fresher" keys is reasonable*/ |
| 123 | template <typename Cache> |
| 124 | static void test_cache_erase(size_t megabytes) |
| 125 | { |
| 126 | double load = 1; |
| 127 | SeedInsecureRand(SeedRand::ZEROS); |
| 128 | std::vector<uint256> hashes; |
| 129 | Cache set{}; |
| 130 | size_t bytes = megabytes * (1 << 20); |
| 131 | set.setup_bytes(bytes); |
| 132 | uint32_t n_insert = static_cast<uint32_t>(load * (bytes / sizeof(uint256))); |
| 133 | hashes.resize(n_insert); |
| 134 | for (uint32_t i = 0; i < n_insert; ++i) { |
| 135 | uint32_t* ptr = (uint32_t*)hashes[i].begin(); |
| 136 | for (uint8_t j = 0; j < 8; ++j) |
| 137 | *(ptr++) = InsecureRand32(); |
| 138 | } |
| 139 | /** We make a copy of the hashes because future optimizations of the |
| 140 | * cuckoocache may overwrite the inserted element, so the test is |
| 141 | * "future proofed". |
| 142 | */ |
| 143 | std::vector<uint256> hashes_insert_copy = hashes; |
| 144 | |
| 145 | /** Insert the first half */ |
| 146 | for (uint32_t i = 0; i < (n_insert / 2); ++i) |
| 147 | set.insert(hashes_insert_copy[i]); |
| 148 | /** Erase the first quarter */ |
| 149 | for (uint32_t i = 0; i < (n_insert / 4); ++i) |
| 150 | BOOST_CHECK(set.contains(hashes[i], true)); |
| 151 | /** Insert the second half */ |
| 152 | for (uint32_t i = (n_insert / 2); i < n_insert; ++i) |
| 153 | set.insert(hashes_insert_copy[i]); |
| 154 | |
| 155 | /** elements that we marked as erased but are still there */ |
| 156 | size_t count_erased_but_contained = 0; |
| 157 | /** elements that we did not erase but are older */ |
| 158 | size_t count_stale = 0; |
| 159 | /** elements that were most recently inserted */ |
| 160 | size_t count_fresh = 0; |
| 161 | |
| 162 | for (uint32_t i = 0; i < (n_insert / 4); ++i) |
| 163 | count_erased_but_contained += set.contains(hashes[i], false); |
| 164 | for (uint32_t i = (n_insert / 4); i < (n_insert / 2); ++i) |
| 165 | count_stale += set.contains(hashes[i], false); |
| 166 | for (uint32_t i = (n_insert / 2); i < n_insert; ++i) |
| 167 | count_fresh += set.contains(hashes[i], false); |
| 168 | |
| 169 | double hit_rate_erased_but_contained = double(count_erased_but_contained) / (double(n_insert) / 4.0); |
| 170 | double hit_rate_stale = double(count_stale) / (double(n_insert) / 4.0); |
| 171 | double hit_rate_fresh = double(count_fresh) / (double(n_insert) / 2.0); |
| 172 | |
| 173 | // Check that our hit_rate_fresh is perfect |
| 174 | BOOST_CHECK_EQUAL(hit_rate_fresh, 1.0); |
| 175 | // Check that we have a more than 2x better hit rate on stale elements than |
| 176 | // erased elements. |
| 177 | BOOST_CHECK(hit_rate_stale > 2 * hit_rate_erased_but_contained); |
| 178 | } |
| 179 | |
| 180 | BOOST_AUTO_TEST_CASE(cuckoocache_erase_ok) |
| 181 | { |
nothing calls this directly
no test coverage detected