tdigest tdigest::deserialize()

in tdigest/include/tdigest_impl.hpp [377:418]


tdigest<T, A> tdigest<T, A>::deserialize(std::istream& is, const A& allocator) {
  const auto preamble_longs = read<uint8_t>(is);
  const auto serial_version = read<uint8_t>(is);
  const auto sketch_type = read<uint8_t>(is);
  if (sketch_type != SKETCH_TYPE) {
    if (preamble_longs == 0 && serial_version == 0 && sketch_type == 0) return deserialize_compat(is, allocator);
    throw std::invalid_argument("sketch type mismatch: expected " + std::to_string(SKETCH_TYPE) + ", actual " + std::to_string(sketch_type));
  }
  if (serial_version != SERIAL_VERSION) {
    throw std::invalid_argument("serial version mismatch: expected " + std::to_string(SERIAL_VERSION) + ", actual " + std::to_string(serial_version));
  }
  const auto k = read<uint16_t>(is);
  const auto flags_byte = read<uint8_t>(is);
  const bool is_empty = flags_byte & (1 << flags::IS_EMPTY);
  const bool is_single_value = flags_byte & (1 << flags::IS_SINGLE_VALUE);
  const uint8_t expected_preamble_longs = is_empty || is_single_value ? PREAMBLE_LONGS_EMPTY_OR_SINGLE : PREAMBLE_LONGS_MULTIPLE;
  if (preamble_longs != expected_preamble_longs) {
    throw std::invalid_argument("preamble longs mismatch: expected " + std::to_string(expected_preamble_longs) + ", actual " + std::to_string(preamble_longs));
  }
  read<uint16_t>(is); // unused

  if (is_empty) return tdigest(k, allocator);

  const bool reverse_merge = flags_byte & (1 << flags::REVERSE_MERGE);
  if (is_single_value) {
    const T value = read<T>(is);
    return tdigest(reverse_merge, k, value, value, vector_centroid(1, centroid(value, 1), allocator), 1, vector_t(allocator));
  }

  const auto num_centroids = read<uint32_t>(is);
  const auto num_buffered = read<uint32_t>(is);

  const T min = read<T>(is);
  const T max = read<T>(is);
  vector_centroid centroids(num_centroids, centroid(0, 0), allocator);
  if (num_centroids > 0) read(is, centroids.data(), num_centroids * sizeof(centroid));
  vector_t buffer(num_buffered, 0, allocator);
  if (num_buffered > 0) read(is, buffer.data(), num_buffered * sizeof(T));
  uint64_t weight = 0;
  for (const auto& c: centroids) weight += c.get_weight();
  return tdigest(reverse_merge, k, min, max, std::move(centroids), weight, std::move(buffer));
}