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