compact_tuple_sketch compact_tuple_sketch::deserialize()

in tuple/include/tuple_sketch_impl.hpp [532:594]


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));
}