in cpc/include/cpc_union_impl.hpp [312:346]
void cpc_union_alloc<A>::reduce_k(uint8_t new_lg_k) {
if (new_lg_k >= lg_k) throw std::logic_error("new LgK >= union lgK");
if (accumulator == nullptr && bit_matrix.size() == 0) throw std::logic_error("both accumulator and bit_matrix are absent");
if (bit_matrix.size() > 0) { // downsample the unioner's bit matrix
if (accumulator != nullptr) throw std::logic_error("accumulator is not null");
vector_u64<A> old_matrix = std::move(bit_matrix);
const uint8_t old_lg_k = lg_k;
const uint32_t new_k = 1 << new_lg_k;
bit_matrix = vector_u64<A>(new_k, 0, old_matrix.get_allocator());
lg_k = new_lg_k;
or_matrix_into_matrix(old_matrix, old_lg_k);
return;
}
if (accumulator != nullptr) { // downsample the unioner's sketch
if (bit_matrix.size() > 0) throw std::logic_error("bit_matrix is not expected");
if (!accumulator->is_empty()) {
cpc_sketch_alloc<A> old_accumulator(*accumulator);
*accumulator = cpc_sketch_alloc<A>(new_lg_k, seed, old_accumulator.get_allocator());
walk_table_updating_sketch(old_accumulator.surprising_value_table);
}
lg_k = new_lg_k;
const auto final_new_flavor = accumulator->determine_flavor();
// if the new sketch has graduated beyond sparse, convert to bit_matrix
if (final_new_flavor != cpc_sketch_alloc<A>::flavor::EMPTY &&
final_new_flavor != cpc_sketch_alloc<A>::flavor::SPARSE) {
switch_to_bit_matrix();
}
return;
}
throw std::logic_error("invalid state");
}