| 223 | } |
| 224 | |
| 225 | void TestComputeFunctions() { |
| 226 | for (uint32_t bits = 0; bits <= 256; ++bits) { |
| 227 | for (uint32_t fpbits = 0; fpbits <= 512; ++fpbits) { |
| 228 | std::vector<size_t> table_max_elements(1025); |
| 229 | for (size_t capacity = 0; capacity <= 1024; ++capacity) { |
| 230 | table_max_elements[capacity] = minisketch_compute_max_elements(bits, capacity, fpbits); |
| 231 | // Exception for bits==0 |
| 232 | if (bits == 0) CHECK(table_max_elements[capacity] == 0); |
| 233 | // A sketch with capacity N cannot guarantee decoding more than N elements. |
| 234 | CHECK(table_max_elements[capacity] <= capacity); |
| 235 | // When asking for N bits of false positive protection, either no solution exists, or no more than ceil(N / bits) excess capacity should be needed. |
| 236 | if (bits > 0) CHECK(table_max_elements[capacity] == 0 || capacity - table_max_elements[capacity] <= (fpbits + bits - 1) / bits); |
| 237 | // Increasing capacity by one, if there is a solution, should always increment the max_elements by at least one as well. |
| 238 | if (capacity > 0) CHECK(table_max_elements[capacity] == 0 || table_max_elements[capacity] > table_max_elements[capacity - 1]); |
| 239 | } |
| 240 | |
| 241 | std::vector<size_t> table_capacity(513); |
| 242 | for (size_t max_elements = 0; max_elements <= 512; ++max_elements) { |
| 243 | table_capacity[max_elements] = minisketch_compute_capacity(bits, max_elements, fpbits); |
| 244 | // Exception for bits==0 |
| 245 | if (bits == 0) CHECK(table_capacity[max_elements] == 0); |
| 246 | // To be able to decode N elements, capacity needs to be at least N. |
| 247 | if (bits > 0) CHECK(table_capacity[max_elements] >= max_elements); |
| 248 | // A sketch of N bits in total cannot have more than N bits of false positive protection; |
| 249 | if (bits > 0) CHECK(bits * table_capacity[max_elements] >= fpbits); |
| 250 | // When asking for N bits of false positive protection, no more than ceil(N / bits) excess capacity should be needed. |
| 251 | if (bits > 0) CHECK(table_capacity[max_elements] - max_elements <= (fpbits + bits - 1) / bits); |
| 252 | // Increasing max_elements by one can only increment the capacity by 0 or 1. |
| 253 | if (max_elements > 0 && fpbits < 256) CHECK(table_capacity[max_elements] == table_capacity[max_elements - 1] || table_capacity[max_elements] == table_capacity[max_elements - 1] + 1); |
| 254 | // Check round-tripping max_elements->capacity->max_elements (only a lower bound) |
| 255 | CHECK(table_capacity[max_elements] <= 1024); |
| 256 | CHECK(table_max_elements[table_capacity[max_elements]] == 0 || table_max_elements[table_capacity[max_elements]] >= max_elements); |
| 257 | } |
| 258 | |
| 259 | for (size_t capacity = 0; capacity <= 512; ++capacity) { |
| 260 | // Check round-tripping capacity->max_elements->capacity (exact, if it exists) |
| 261 | CHECK(table_max_elements[capacity] <= 512); |
| 262 | CHECK(table_max_elements[capacity] == 0 || table_capacity[table_max_elements[capacity]] == capacity); |
| 263 | } |
| 264 | } |
| 265 | } |
| 266 | } |
| 267 | |
| 268 | } // namespace |
| 269 |
no test coverage detected