diff --git a/tdigest/include/tdigest_impl.hpp b/tdigest/include/tdigest_impl.hpp index 958c8c40..ab9da04c 100644 --- a/tdigest/include/tdigest_impl.hpp +++ b/tdigest/include/tdigest_impl.hpp @@ -378,7 +378,7 @@ size_t tdigest::get_serialized_size_bytes(bool with_buffer) const { template auto tdigest::serialize(unsigned header_size_bytes, bool with_buffer) const -> vector_bytes { if (!with_buffer) const_cast(this)->compress(); // side effect - vector_bytes bytes(get_serialized_size_bytes(with_buffer), 0, buffer_.get_allocator()); + vector_bytes bytes(header_size_bytes + get_serialized_size_bytes(with_buffer), 0, buffer_.get_allocator()); uint8_t* ptr = bytes.data() + header_size_bytes; *ptr++ = get_preamble_longs(); *ptr++ = SERIAL_VERSION; diff --git a/tdigest/test/tdigest_test.cpp b/tdigest/test/tdigest_test.cpp index 30b1fc1a..8c8535ad 100644 --- a/tdigest/test/tdigest_test.cpp +++ b/tdigest/test/tdigest_test.cpp @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -347,6 +348,27 @@ TEST_CASE("serialize deserialize bytes many values with buffer", "[tdigest]") { REQUIRE(td.get_quantile(0.5) == deserialized_td.get_quantile(0.5)); } +TEST_CASE("serialize bytes with header", "[tdigest]") { + const unsigned header_size_bytes = 7; + auto check = [header_size_bytes](const tdigest& td, bool with_buffer) { + auto bytes = td.serialize(header_size_bytes, with_buffer); + auto bytes_no_header = td.serialize(0, with_buffer); + REQUIRE(bytes.size() == header_size_bytes + bytes_no_header.size()); + REQUIRE(bytes.size() == header_size_bytes + td.get_serialized_size_bytes(with_buffer)); + REQUIRE(std::equal(bytes_no_header.begin(), bytes_no_header.end(), bytes.begin() + header_size_bytes)); + auto deserialized_td = tdigest::deserialize(bytes.data() + header_size_bytes, bytes.size() - header_size_bytes); + REQUIRE(td.get_total_weight() == deserialized_td.get_total_weight()); + }; + tdigest td(100); + check(td, false); + td.update(123); + check(td, false); + check(td, true); + for (int i = 0; i < 10000; ++i) td.update(i); + check(td, true); + check(td, false); +} + TEST_CASE("serialize deserialize steam and bytes equivalence empty", "[tdigest]") { tdigest td(100); std::stringstream s(std::ios::in | std::ios::out | std::ios::binary);