in tuple/include/tuple_sketch_impl.hpp [499:561]
compact_tuple_sketch<S, A> compact_tuple_sketch<S, A>::deserialize(const void* bytes, size_t size, uint64_t seed, const SerDe& sd, const A& allocator) {
ensure_minimum_memory(size, 8);
const char* ptr = static_cast<const char*>(bytes);
const char* base = ptr;
uint8_t preamble_longs;
ptr += copy_from_mem(ptr, preamble_longs);
uint8_t serial_version;
ptr += copy_from_mem(ptr, serial_version);
uint8_t family;
ptr += copy_from_mem(ptr, family);
uint8_t type;
ptr += copy_from_mem(ptr, type);
ptr += sizeof(uint8_t); // unused
uint8_t flags_byte;
ptr += copy_from_mem(ptr, flags_byte);
uint16_t seed_hash;
ptr += copy_from_mem(ptr, seed_hash);
if (serial_version != SERIAL_VERSION && serial_version != SERIAL_VERSION_LEGACY) {
throw std::invalid_argument("serial version mismatch: expected " + std::to_string(SERIAL_VERSION) + " or "
+ std::to_string(SERIAL_VERSION_LEGACY) + ", actual " + std::to_string(serial_version));
}
checker<true>::check_sketch_family(family, SKETCH_FAMILY);
if (type != SKETCH_TYPE && type != SKETCH_TYPE_LEGACY) {
throw std::invalid_argument("sketch type mismatch: expected " + std::to_string(SKETCH_TYPE) + " or "
+ std::to_string(SKETCH_TYPE_LEGACY) + ", actual " + std::to_string(type));
}
const bool is_empty = flags_byte & (1 << flags::IS_EMPTY);
if (!is_empty) checker<true>::check_seed_hash(seed_hash, compute_seed_hash(seed));
uint64_t theta = theta_constants::MAX_THETA;
uint32_t num_entries = 0;
if (!is_empty) {
if (preamble_longs == 1) {
num_entries = 1;
} else {
ensure_minimum_memory(size, 8); // read the first prelong before this method
ptr += copy_from_mem(ptr, num_entries);
ptr += sizeof(uint32_t); // unused
if (preamble_longs > 2) {
ensure_minimum_memory(size, (preamble_longs - 1) << 3);
ptr += copy_from_mem(ptr, theta);
}
}
}
const size_t keys_size_bytes = sizeof(uint64_t) * num_entries;
ensure_minimum_memory(size, ptr - base + keys_size_bytes);
A alloc(allocator);
std::vector<Entry, AllocEntry> entries(alloc);
if (!is_empty) {
entries.reserve(num_entries);
std::unique_ptr<S, deleter_of_summaries> summary(alloc.allocate(1), deleter_of_summaries(1, false, allocator));
for (size_t i = 0; i < num_entries; ++i) {
uint64_t key;
ptr += copy_from_mem(ptr, key);
ptr += sd.deserialize(ptr, base + size - ptr, summary.get(), 1);
entries.push_back(Entry(key, std::move(*summary)));
(*summary).~S();
}
}
const bool is_ordered = flags_byte & (1 << flags::IS_ORDERED);
return compact_tuple_sketch(is_empty, is_ordered, seed_hash, theta, std::move(entries));
}