Skip to content

Commit 63e7f75

Browse files
committed
Serialize count_min_sketch sketch array in a single write call
1 parent 764cdf1 commit 63e7f75

3 files changed

Lines changed: 18 additions & 5 deletions

File tree

count/include/count_min.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#define COUNT_MIN_HPP_
2222

2323
#include <iterator>
24+
#include <type_traits>
25+
#include <vector>
2426
#include "common_defs.hpp"
2527

2628
namespace datasketches {
@@ -36,6 +38,7 @@ template <typename W,
3638
typename Allocator = std::allocator<W>>
3739
class count_min_sketch{
3840
static_assert(std::is_arithmetic<W>::value, "Arithmetic type expected");
41+
static_assert(!std::is_same<W, bool>::value, "Boolean weight type is not supported");
3942
public:
4043
using allocator_type = Allocator;
4144
using const_iterator = typename std::vector<W, Allocator>::const_iterator;

count/include/count_min_impl.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,11 @@ size_t count_min_sketch<W,A>::serialize_to(WriteBytes&& write_bytes) const {
313313
write_count_min_value(write_bytes, bytes_written, t_weight);
314314

315315
// Long 3 onwards: remaining bytes are consumed by writing the weight and the array values.
316-
for (const auto& value: _sketch_array) write_count_min_value(write_bytes, bytes_written, value);
316+
const size_t sketch_array_bytes = sizeof(W) * _sketch_array.size();
317+
if (sketch_array_bytes > 0) {
318+
write_bytes(_sketch_array.data(), sketch_array_bytes);
319+
bytes_written += sketch_array_bytes;
320+
}
317321

318322
return bytes_written;
319323
}

count/test/count_min_test.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,26 +301,32 @@ TEST_CASE("CountMin sketch: bytes serialize-deserialize non-empty", "[cm_sketch]
301301
}
302302

303303
TEST_CASE("CountMin sketch: sink serialize matches bytes", "[cm_sketch]") {
304-
auto check_sink_serialize = [](const count_min_sketch<uint64_t>& c) {
304+
auto check_sink_serialize = [](const count_min_sketch<uint64_t>& c, size_t expected_fragments, size_t expected_last_fragment_size = 0) {
305305
auto bytes = c.serialize();
306306
std::vector<uint8_t> sink_bytes;
307307
sink_bytes.reserve(c.get_serialized_size_bytes());
308+
std::vector<size_t> fragment_sizes;
308309

309-
const size_t bytes_written = c.serialize_to([&sink_bytes](const void* data, size_t size) {
310+
const size_t bytes_written = c.serialize_to([&sink_bytes, &fragment_sizes](const void* data, size_t size) {
310311
const auto* begin = static_cast<const uint8_t*>(data);
311312
sink_bytes.insert(sink_bytes.end(), begin, begin + size);
313+
fragment_sizes.push_back(size);
312314
});
313315

314316
REQUIRE(bytes_written == bytes.size());
315317
REQUIRE(sink_bytes == bytes);
318+
REQUIRE(fragment_sizes.size() == expected_fragments);
319+
if (expected_last_fragment_size > 0) {
320+
REQUIRE(fragment_sizes.back() == expected_last_fragment_size);
321+
}
316322
};
317323

318324
count_min_sketch<uint64_t> empty(3, 32);
319-
check_sink_serialize(empty);
325+
check_sink_serialize(empty, 9);
320326

321327
count_min_sketch<uint64_t> non_empty(5, 64);
322328
for (uint64_t i=0; i < 10; ++i) non_empty.update(i, 10 * i * i);
323-
check_sink_serialize(non_empty);
329+
check_sink_serialize(non_empty, 11, sizeof(uint64_t) * non_empty.get_num_hashes() * non_empty.get_num_buckets());
324330
}
325331

326332
} /* namespace datasketches */

0 commit comments

Comments
 (0)