diff --git a/density/include/density_sketch.hpp b/density/include/density_sketch.hpp index e5674c6c..57f29eaf 100755 --- a/density/include/density_sketch.hpp +++ b/density/include/density_sketch.hpp @@ -32,7 +32,9 @@ namespace datasketches { template struct gaussian_kernel { - T operator()(const std::vector& v1, const std::vector& v2) const { + // any two vectors of T, so the sketch's points can use its allocator + template + T operator()(const V1& v1, const V2& v2) const { return exp(-std::inner_product(v1.begin(), v1.end(), v2.begin(), 0.0, std::plus(), [](T a, T b){return (a-b)*(a-b);})); } }; @@ -203,7 +205,6 @@ class density_sketch { static const uint8_t SERIAL_VERSION = 1; static const size_t LEVELS_ARRAY_START = 5; - Allocator allocator_; Kernel kernel_; uint16_t k_; uint32_t dim_; diff --git a/density/test/density_sketch_test.cpp b/density/test/density_sketch_test.cpp index 2a09d529..f8c5d528 100755 --- a/density/test/density_sketch_test.cpp +++ b/density/test/density_sketch_test.cpp @@ -21,6 +21,7 @@ #include #include +#include namespace datasketches { @@ -241,4 +242,33 @@ TEST_CASE("serialize stream", "[density_sketch]") { } } +TEST_CASE("density sketch: custom allocator", "[density_sketch]") { + using alloc = test_allocator; + using sketch = density_sketch, alloc>; + using point = std::vector; + test_allocator_total_bytes = 0; + test_allocator_net_allocations = 0; + { + sketch s(10, 3, gaussian_kernel(), alloc(0)); + // Keep every retained point close to the query so the Gaussian kernel cannot underflow to zero. + for (int i = 0; i < 1000; ++i) s.update(point({i / 1000.0, 1.0, 2.0}, alloc(0))); + REQUIRE(s.get_n() == 1000); + REQUIRE(s.is_estimation_mode()); + REQUIRE(s.get_estimate({0.5, 1.0, 2.0}) > 0); + REQUIRE(test_allocator_total_bytes > 0); + + sketch other(10, 3, gaussian_kernel(), alloc(0)); + for (int i = 0; i < 100; ++i) other.update(point({i / 1000.0, 1.0, 2.0}, alloc(0))); + s.merge(other); + REQUIRE(s.get_n() == 1100); + + auto bytes = s.serialize(); + auto copy = sketch::deserialize(bytes.data(), bytes.size(), gaussian_kernel(), alloc(0)); + REQUIRE(copy.get_n() == s.get_n()); + REQUIRE(copy.get_estimate({0.5, 1.0, 2.0}) == s.get_estimate({0.5, 1.0, 2.0})); + } + REQUIRE(test_allocator_total_bytes == 0); + REQUIRE(test_allocator_net_allocations == 0); +} + } /* namespace datasketches */