in cpc/include/cpc_sketch_impl.hpp [593:682]
cpc_sketch_alloc<A> cpc_sketch_alloc<A>::deserialize(const void* bytes, size_t size, uint64_t seed, const A& allocator) {
ensure_minimum_memory(size, 8);
const char* ptr = static_cast<const char*>(bytes);
const char* base = static_cast<const char*>(bytes);
uint8_t preamble_ints;
ptr += copy_from_mem(ptr, preamble_ints);
uint8_t serial_version;
ptr += copy_from_mem(ptr, serial_version);
uint8_t family_id;
ptr += copy_from_mem(ptr, family_id);
uint8_t lg_k;
ptr += copy_from_mem(ptr, lg_k);
uint8_t first_interesting_column;
ptr += copy_from_mem(ptr, first_interesting_column);
uint8_t flags_byte;
ptr += copy_from_mem(ptr, flags_byte);
uint16_t seed_hash;
ptr += copy_from_mem(ptr, seed_hash);
const bool has_hip = flags_byte & (1 << flags::HAS_HIP);
const bool has_table = flags_byte & (1 << flags::HAS_TABLE);
const bool has_window = flags_byte & (1 << flags::HAS_WINDOW);
ensure_minimum_memory(size, preamble_ints << 2);
compressed_state<A> compressed(allocator);
compressed.table_data_words = 0;
compressed.table_num_entries = 0;
compressed.window_data_words = 0;
uint32_t num_coupons = 0;
double kxp = 0;
double hip_est_accum = 0;
if (has_table || has_window) {
check_memory_size(ptr - base + sizeof(num_coupons), size);
ptr += copy_from_mem(ptr, num_coupons);
if (has_table && has_window) {
check_memory_size(ptr - base + sizeof(compressed.table_num_entries), size);
ptr += copy_from_mem(ptr, compressed.table_num_entries);
if (has_hip) {
check_memory_size(ptr - base + sizeof(kxp) + sizeof(hip_est_accum), size);
ptr += copy_from_mem(ptr, kxp);
ptr += copy_from_mem(ptr, hip_est_accum);
}
}
if (has_table) {
check_memory_size(ptr - base + sizeof(compressed.table_data_words), size);
ptr += copy_from_mem(ptr, compressed.table_data_words);
}
if (has_window) {
check_memory_size(ptr - base + sizeof(compressed.window_data_words), size);
ptr += copy_from_mem(ptr, compressed.window_data_words);
}
if (has_hip && !(has_table && has_window)) {
check_memory_size(ptr - base + sizeof(kxp) + sizeof(hip_est_accum), size);
ptr += copy_from_mem(ptr, kxp);
ptr += copy_from_mem(ptr, hip_est_accum);
}
if (has_window) {
compressed.window_data.resize(compressed.window_data_words);
check_memory_size(ptr - base + (compressed.window_data_words * sizeof(uint32_t)), size);
ptr += copy_from_mem(ptr, compressed.window_data.data(), compressed.window_data_words * sizeof(uint32_t));
}
if (has_table) {
compressed.table_data.resize(compressed.table_data_words);
check_memory_size(ptr - base + (compressed.table_data_words * sizeof(uint32_t)), size);
ptr += copy_from_mem(ptr, compressed.table_data.data(), compressed.table_data_words * sizeof(uint32_t));
}
if (!has_window) compressed.table_num_entries = num_coupons;
}
if (ptr != static_cast<const char*>(bytes) + size) throw std::logic_error("deserialized size mismatch");
uint8_t expected_preamble_ints = get_preamble_ints(num_coupons, has_hip, has_table, has_window);
if (preamble_ints != expected_preamble_ints) {
throw std::invalid_argument("Possible corruption: preamble ints: expected "
+ std::to_string(expected_preamble_ints) + ", got " + std::to_string(preamble_ints));
}
if (serial_version != SERIAL_VERSION) {
throw std::invalid_argument("Possible corruption: serial version: expected "
+ std::to_string(SERIAL_VERSION) + ", got " + std::to_string(serial_version));
}
if (family_id != FAMILY) {
throw std::invalid_argument("Possible corruption: family: expected "
+ std::to_string(FAMILY) + ", got " + std::to_string(family_id));
}
if (seed_hash != compute_seed_hash(seed)) {
throw std::invalid_argument("Incompatible seed hashes: " + std::to_string(seed_hash) + ", "
+ std::to_string(compute_seed_hash(seed)));
}
uncompressed_state<A> uncompressed(allocator);
get_compressor<A>().uncompress(compressed, uncompressed, lg_k, num_coupons);
return cpc_sketch_alloc(lg_k, num_coupons, first_interesting_column, std::move(uncompressed.table),
std::move(uncompressed.window), has_hip, kxp, hip_est_accum, seed);
}