datasketches 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/ext/datasketches/cpc_wrapper.cpp +12 -13
- data/ext/datasketches/ext.cpp +1 -1
- data/ext/datasketches/ext.h +4 -0
- data/ext/datasketches/extconf.rb +1 -1
- data/ext/datasketches/fi_wrapper.cpp +6 -8
- data/ext/datasketches/hll_wrapper.cpp +13 -14
- data/ext/datasketches/kll_wrapper.cpp +28 -76
- data/ext/datasketches/theta_wrapper.cpp +27 -41
- data/ext/datasketches/vo_wrapper.cpp +4 -6
- data/lib/datasketches/version.rb +1 -1
- data/vendor/datasketches-cpp/CMakeLists.txt +1 -0
- data/vendor/datasketches-cpp/README.md +4 -4
- data/vendor/datasketches-cpp/common/include/MurmurHash3.h +7 -0
- data/vendor/datasketches-cpp/common/include/memory_operations.hpp +12 -0
- data/vendor/datasketches-cpp/common/test/CMakeLists.txt +24 -0
- data/vendor/datasketches-cpp/common/test/integration_test.cpp +77 -0
- data/vendor/datasketches-cpp/common/test/test_allocator.hpp +9 -1
- data/vendor/datasketches-cpp/cpc/include/cpc_common.hpp +3 -0
- data/vendor/datasketches-cpp/cpc/include/cpc_compressor.hpp +2 -2
- data/vendor/datasketches-cpp/cpc/include/cpc_compressor_impl.hpp +28 -19
- data/vendor/datasketches-cpp/cpc/include/cpc_sketch.hpp +8 -5
- data/vendor/datasketches-cpp/cpc/include/cpc_sketch_impl.hpp +19 -14
- data/vendor/datasketches-cpp/cpc/include/cpc_union.hpp +2 -2
- data/vendor/datasketches-cpp/cpc/include/cpc_union_impl.hpp +6 -6
- data/vendor/datasketches-cpp/cpc/include/cpc_util.hpp +0 -6
- data/vendor/datasketches-cpp/cpc/include/icon_estimator.hpp +3 -3
- data/vendor/datasketches-cpp/cpc/include/u32_table.hpp +3 -3
- data/vendor/datasketches-cpp/cpc/include/u32_table_impl.hpp +9 -9
- data/vendor/datasketches-cpp/cpc/test/CMakeLists.txt +1 -0
- data/vendor/datasketches-cpp/cpc/test/cpc_sketch_allocation_test.cpp +237 -0
- data/vendor/datasketches-cpp/fi/include/frequent_items_sketch.hpp +15 -10
- data/vendor/datasketches-cpp/fi/include/frequent_items_sketch_impl.hpp +40 -28
- data/vendor/datasketches-cpp/fi/include/reverse_purge_hash_map.hpp +19 -13
- data/vendor/datasketches-cpp/fi/include/reverse_purge_hash_map_impl.hpp +140 -124
- data/vendor/datasketches-cpp/fi/test/frequent_items_sketch_custom_type_test.cpp +15 -12
- data/vendor/datasketches-cpp/fi/test/reverse_purge_hash_map_test.cpp +3 -3
- data/vendor/datasketches-cpp/hll/CMakeLists.txt +3 -0
- data/vendor/datasketches-cpp/hll/include/AuxHashMap-internal.hpp +32 -57
- data/vendor/datasketches-cpp/hll/include/AuxHashMap.hpp +9 -8
- data/vendor/datasketches-cpp/hll/include/CompositeInterpolationXTable.hpp +2 -2
- data/vendor/datasketches-cpp/hll/include/CouponHashSet-internal.hpp +34 -48
- data/vendor/datasketches-cpp/hll/include/CouponHashSet.hpp +10 -10
- data/vendor/datasketches-cpp/hll/include/CouponList-internal.hpp +45 -77
- data/vendor/datasketches-cpp/hll/include/CouponList.hpp +11 -12
- data/vendor/datasketches-cpp/hll/include/CubicInterpolation.hpp +2 -2
- data/vendor/datasketches-cpp/hll/include/HarmonicNumbers.hpp +2 -2
- data/vendor/datasketches-cpp/hll/include/Hll4Array-internal.hpp +15 -14
- data/vendor/datasketches-cpp/hll/include/Hll4Array.hpp +1 -1
- data/vendor/datasketches-cpp/hll/include/Hll6Array-internal.hpp +10 -21
- data/vendor/datasketches-cpp/hll/include/Hll6Array.hpp +2 -3
- data/vendor/datasketches-cpp/hll/include/Hll8Array-internal.hpp +10 -21
- data/vendor/datasketches-cpp/hll/include/Hll8Array.hpp +2 -3
- data/vendor/datasketches-cpp/hll/include/HllArray-internal.hpp +28 -55
- data/vendor/datasketches-cpp/hll/include/HllArray.hpp +8 -8
- data/vendor/datasketches-cpp/hll/include/HllSketch-internal.hpp +9 -11
- data/vendor/datasketches-cpp/hll/include/HllSketchImpl.hpp +2 -1
- data/vendor/datasketches-cpp/hll/include/HllSketchImplFactory.hpp +34 -31
- data/vendor/datasketches-cpp/hll/include/HllUnion-internal.hpp +3 -28
- data/vendor/datasketches-cpp/hll/include/HllUtil.hpp +1 -1
- data/vendor/datasketches-cpp/hll/include/RelativeErrorTables.hpp +1 -1
- data/vendor/datasketches-cpp/hll/include/hll.hpp +6 -34
- data/vendor/datasketches-cpp/hll/test/AuxHashMapTest.cpp +7 -7
- data/vendor/datasketches-cpp/hll/test/CouponHashSetTest.cpp +2 -2
- data/vendor/datasketches-cpp/hll/test/CouponListTest.cpp +3 -3
- data/vendor/datasketches-cpp/hll/test/HllArrayTest.cpp +2 -2
- data/vendor/datasketches-cpp/hll/test/HllSketchTest.cpp +46 -50
- data/vendor/datasketches-cpp/kll/include/kll_quantile_calculator.hpp +1 -1
- data/vendor/datasketches-cpp/kll/include/kll_quantile_calculator_impl.hpp +3 -3
- data/vendor/datasketches-cpp/kll/include/kll_sketch.hpp +10 -3
- data/vendor/datasketches-cpp/kll/include/kll_sketch_impl.hpp +93 -75
- data/vendor/datasketches-cpp/kll/test/kll_sketch_custom_type_test.cpp +11 -10
- data/vendor/datasketches-cpp/kll/test/kll_sketch_test.cpp +45 -42
- data/vendor/datasketches-cpp/python/CMakeLists.txt +2 -0
- data/vendor/datasketches-cpp/python/README.md +6 -3
- data/vendor/datasketches-cpp/python/src/datasketches.cpp +2 -0
- data/vendor/datasketches-cpp/python/src/hll_wrapper.cpp +0 -2
- data/vendor/datasketches-cpp/python/src/kll_wrapper.cpp +3 -1
- data/vendor/datasketches-cpp/python/src/req_wrapper.cpp +246 -0
- data/vendor/datasketches-cpp/python/src/theta_wrapper.cpp +36 -26
- data/vendor/datasketches-cpp/python/tests/hll_test.py +0 -1
- data/vendor/datasketches-cpp/python/tests/kll_test.py +3 -3
- data/vendor/datasketches-cpp/python/tests/req_test.py +126 -0
- data/vendor/datasketches-cpp/python/tests/theta_test.py +28 -3
- data/vendor/datasketches-cpp/req/CMakeLists.txt +60 -0
- data/vendor/datasketches-cpp/{tuple/include/theta_a_not_b_experimental_impl.hpp → req/include/req_common.hpp} +17 -8
- data/vendor/datasketches-cpp/req/include/req_compactor.hpp +137 -0
- data/vendor/datasketches-cpp/req/include/req_compactor_impl.hpp +501 -0
- data/vendor/datasketches-cpp/req/include/req_quantile_calculator.hpp +69 -0
- data/vendor/datasketches-cpp/req/include/req_quantile_calculator_impl.hpp +60 -0
- data/vendor/datasketches-cpp/req/include/req_sketch.hpp +395 -0
- data/vendor/datasketches-cpp/req/include/req_sketch_impl.hpp +810 -0
- data/vendor/datasketches-cpp/req/test/CMakeLists.txt +43 -0
- data/vendor/datasketches-cpp/req/test/req_float_empty_from_java.sk +0 -0
- data/vendor/datasketches-cpp/req/test/req_float_estimation_from_java.sk +0 -0
- data/vendor/datasketches-cpp/req/test/req_float_exact_from_java.sk +0 -0
- data/vendor/datasketches-cpp/req/test/req_float_raw_items_from_java.sk +0 -0
- data/vendor/datasketches-cpp/req/test/req_float_single_item_from_java.sk +0 -0
- data/vendor/datasketches-cpp/req/test/req_sketch_custom_type_test.cpp +128 -0
- data/vendor/datasketches-cpp/req/test/req_sketch_test.cpp +494 -0
- data/vendor/datasketches-cpp/sampling/include/var_opt_sketch.hpp +10 -9
- data/vendor/datasketches-cpp/sampling/include/var_opt_sketch_impl.hpp +82 -70
- data/vendor/datasketches-cpp/sampling/include/var_opt_union.hpp +5 -5
- data/vendor/datasketches-cpp/sampling/include/var_opt_union_impl.hpp +7 -7
- data/vendor/datasketches-cpp/sampling/test/CMakeLists.txt +1 -0
- data/vendor/datasketches-cpp/sampling/test/var_opt_allocation_test.cpp +96 -0
- data/vendor/datasketches-cpp/sampling/test/var_opt_union_test.cpp +0 -31
- data/vendor/datasketches-cpp/setup.py +5 -3
- data/vendor/datasketches-cpp/theta/CMakeLists.txt +30 -3
- data/vendor/datasketches-cpp/{tuple → theta}/include/bounds_on_ratios_in_sampled_sets.hpp +2 -1
- data/vendor/datasketches-cpp/{tuple → theta}/include/bounds_on_ratios_in_theta_sketched_sets.hpp +1 -1
- data/vendor/datasketches-cpp/theta/include/theta_a_not_b.hpp +12 -29
- data/vendor/datasketches-cpp/theta/include/theta_a_not_b_impl.hpp +5 -46
- data/vendor/datasketches-cpp/{tuple → theta}/include/theta_comparators.hpp +0 -0
- data/vendor/datasketches-cpp/{tuple → theta}/include/theta_constants.hpp +2 -0
- data/vendor/datasketches-cpp/{tuple → theta}/include/theta_helpers.hpp +0 -0
- data/vendor/datasketches-cpp/theta/include/theta_intersection.hpp +22 -29
- data/vendor/datasketches-cpp/{tuple → theta}/include/theta_intersection_base.hpp +0 -0
- data/vendor/datasketches-cpp/{tuple → theta}/include/theta_intersection_base_impl.hpp +0 -0
- data/vendor/datasketches-cpp/theta/include/theta_intersection_impl.hpp +8 -90
- data/vendor/datasketches-cpp/{tuple/test/theta_union_experimental_test.cpp → theta/include/theta_jaccard_similarity.hpp} +11 -18
- data/vendor/datasketches-cpp/{tuple/include/jaccard_similarity.hpp → theta/include/theta_jaccard_similarity_base.hpp} +6 -22
- data/vendor/datasketches-cpp/{tuple → theta}/include/theta_set_difference_base.hpp +0 -0
- data/vendor/datasketches-cpp/{tuple → theta}/include/theta_set_difference_base_impl.hpp +5 -0
- data/vendor/datasketches-cpp/theta/include/theta_sketch.hpp +132 -266
- data/vendor/datasketches-cpp/theta/include/theta_sketch_impl.hpp +200 -650
- data/vendor/datasketches-cpp/theta/include/theta_union.hpp +27 -60
- data/vendor/datasketches-cpp/{tuple → theta}/include/theta_union_base.hpp +1 -1
- data/vendor/datasketches-cpp/{tuple → theta}/include/theta_union_base_impl.hpp +5 -0
- data/vendor/datasketches-cpp/theta/include/theta_union_impl.hpp +13 -69
- data/vendor/datasketches-cpp/{tuple → theta}/include/theta_update_sketch_base.hpp +3 -19
- data/vendor/datasketches-cpp/{tuple → theta}/include/theta_update_sketch_base_impl.hpp +6 -1
- data/vendor/datasketches-cpp/theta/test/CMakeLists.txt +1 -0
- data/vendor/datasketches-cpp/{tuple → theta}/test/theta_jaccard_similarity_test.cpp +2 -3
- data/vendor/datasketches-cpp/theta/test/theta_sketch_test.cpp +37 -234
- data/vendor/datasketches-cpp/tuple/CMakeLists.txt +3 -35
- data/vendor/datasketches-cpp/tuple/include/tuple_jaccard_similarity.hpp +38 -0
- data/vendor/datasketches-cpp/tuple/include/tuple_sketch.hpp +28 -13
- data/vendor/datasketches-cpp/tuple/include/tuple_sketch_impl.hpp +6 -6
- data/vendor/datasketches-cpp/tuple/test/CMakeLists.txt +1 -6
- data/vendor/datasketches-cpp/tuple/test/tuple_a_not_b_test.cpp +1 -4
- data/vendor/datasketches-cpp/tuple/test/tuple_intersection_test.cpp +1 -4
- data/vendor/datasketches-cpp/tuple/test/tuple_jaccard_similarity_test.cpp +2 -1
- data/vendor/datasketches-cpp/tuple/test/tuple_sketch_allocation_test.cpp +2 -2
- data/vendor/datasketches-cpp/tuple/test/tuple_union_test.cpp +1 -4
- metadata +43 -34
- data/vendor/datasketches-cpp/tuple/include/theta_a_not_b_experimental.hpp +0 -53
- data/vendor/datasketches-cpp/tuple/include/theta_intersection_experimental.hpp +0 -78
- data/vendor/datasketches-cpp/tuple/include/theta_intersection_experimental_impl.hpp +0 -43
- data/vendor/datasketches-cpp/tuple/include/theta_sketch_experimental.hpp +0 -393
- data/vendor/datasketches-cpp/tuple/include/theta_sketch_experimental_impl.hpp +0 -481
- data/vendor/datasketches-cpp/tuple/include/theta_union_experimental.hpp +0 -88
- data/vendor/datasketches-cpp/tuple/include/theta_union_experimental_impl.hpp +0 -47
- data/vendor/datasketches-cpp/tuple/test/theta_a_not_b_experimental_test.cpp +0 -250
- data/vendor/datasketches-cpp/tuple/test/theta_compact_empty_from_java.sk +0 -0
- data/vendor/datasketches-cpp/tuple/test/theta_compact_estimation_from_java.sk +0 -0
- data/vendor/datasketches-cpp/tuple/test/theta_compact_single_item_from_java.sk +0 -0
- data/vendor/datasketches-cpp/tuple/test/theta_intersection_experimental_test.cpp +0 -224
- data/vendor/datasketches-cpp/tuple/test/theta_sketch_experimental_test.cpp +0 -247
|
@@ -28,7 +28,7 @@ template <typename T, typename C, typename A>
|
|
|
28
28
|
class kll_quantile_calculator {
|
|
29
29
|
public:
|
|
30
30
|
// assumes that all levels are sorted including level 0
|
|
31
|
-
kll_quantile_calculator(const T* items, const uint32_t* levels, uint8_t num_levels, uint64_t n);
|
|
31
|
+
kll_quantile_calculator(const T* items, const uint32_t* levels, uint8_t num_levels, uint64_t n, const A& allocator);
|
|
32
32
|
T get_quantile(double fraction) const;
|
|
33
33
|
|
|
34
34
|
private:
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
namespace datasketches {
|
|
30
30
|
|
|
31
31
|
template <typename T, typename C, typename A>
|
|
32
|
-
kll_quantile_calculator<T, C, A>::kll_quantile_calculator(const T* items, const uint32_t* levels, uint8_t num_levels, uint64_t n):
|
|
33
|
-
n_(n), levels_(num_levels + 1)
|
|
32
|
+
kll_quantile_calculator<T, C, A>::kll_quantile_calculator(const T* items, const uint32_t* levels, uint8_t num_levels, uint64_t n, const A& allocator):
|
|
33
|
+
n_(n), levels_(num_levels + 1, 0, allocator), entries_(allocator)
|
|
34
34
|
{
|
|
35
35
|
const uint32_t num_items = levels[num_levels] - levels[0];
|
|
36
36
|
entries_.reserve(num_items);
|
|
@@ -116,7 +116,7 @@ uint32_t kll_quantile_calculator<T, C, A>::search_for_chunk_containing_pos(uint6
|
|
|
116
116
|
template <typename T, typename C, typename A>
|
|
117
117
|
void kll_quantile_calculator<T, C, A>::merge_sorted_blocks(Container& entries, const uint32_t* levels, uint8_t num_levels, uint32_t num_items) {
|
|
118
118
|
if (num_levels == 1) return;
|
|
119
|
-
Container temporary;
|
|
119
|
+
Container temporary(entries.get_allocator());
|
|
120
120
|
temporary.reserve(num_items);
|
|
121
121
|
merge_sorted_blocks_direct(entries, temporary, levels, 0, num_levels);
|
|
122
122
|
}
|
|
@@ -161,7 +161,7 @@ class kll_sketch {
|
|
|
161
161
|
static const uint16_t MIN_K = DEFAULT_M;
|
|
162
162
|
static const uint16_t MAX_K = (1 << 16) - 1;
|
|
163
163
|
|
|
164
|
-
explicit kll_sketch(uint16_t k = DEFAULT_K);
|
|
164
|
+
explicit kll_sketch(uint16_t k = DEFAULT_K, const A& allocator = A());
|
|
165
165
|
kll_sketch(const kll_sketch& other);
|
|
166
166
|
kll_sketch(kll_sketch&& other) noexcept;
|
|
167
167
|
~kll_sketch();
|
|
@@ -202,6 +202,12 @@ class kll_sketch {
|
|
|
202
202
|
*/
|
|
203
203
|
bool is_empty() const;
|
|
204
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Returns configured parameter k
|
|
207
|
+
* @return parameter k
|
|
208
|
+
*/
|
|
209
|
+
uint16_t get_k() const;
|
|
210
|
+
|
|
205
211
|
/**
|
|
206
212
|
* Returns the length of the input stream.
|
|
207
213
|
* @return stream length
|
|
@@ -401,7 +407,7 @@ class kll_sketch {
|
|
|
401
407
|
* @param is input stream
|
|
402
408
|
* @return an instance of a sketch
|
|
403
409
|
*/
|
|
404
|
-
static kll_sketch deserialize(std::istream& is);
|
|
410
|
+
static kll_sketch<T, C, S, A> deserialize(std::istream& is, const A& allocator = A());
|
|
405
411
|
|
|
406
412
|
/**
|
|
407
413
|
* This method deserializes a sketch from a given array of bytes.
|
|
@@ -409,7 +415,7 @@ class kll_sketch {
|
|
|
409
415
|
* @param size the size of the array
|
|
410
416
|
* @return an instance of a sketch
|
|
411
417
|
*/
|
|
412
|
-
static kll_sketch deserialize(const void* bytes, size_t size);
|
|
418
|
+
static kll_sketch<T, C, S, A> deserialize(const void* bytes, size_t size, const A& allocator = A());
|
|
413
419
|
|
|
414
420
|
/*
|
|
415
421
|
* Gets the normalized rank error given k and pmf.
|
|
@@ -461,6 +467,7 @@ class kll_sketch {
|
|
|
461
467
|
static const uint8_t PREAMBLE_INTS_SHORT = 2; // for empty and single item
|
|
462
468
|
static const uint8_t PREAMBLE_INTS_FULL = 5;
|
|
463
469
|
|
|
470
|
+
A allocator_;
|
|
464
471
|
uint16_t k_;
|
|
465
472
|
uint8_t m_; // minimum buffer "width"
|
|
466
473
|
uint16_t min_k_; // for error estimation after merging with different k
|
|
@@ -30,13 +30,14 @@
|
|
|
30
30
|
namespace datasketches {
|
|
31
31
|
|
|
32
32
|
template<typename T, typename C, typename S, typename A>
|
|
33
|
-
kll_sketch<T, C, S, A>::kll_sketch(uint16_t k):
|
|
33
|
+
kll_sketch<T, C, S, A>::kll_sketch(uint16_t k, const A& allocator):
|
|
34
|
+
allocator_(allocator),
|
|
34
35
|
k_(k),
|
|
35
36
|
m_(DEFAULT_M),
|
|
36
37
|
min_k_(k),
|
|
37
38
|
n_(0),
|
|
38
39
|
num_levels_(1),
|
|
39
|
-
levels_(2),
|
|
40
|
+
levels_(2, 0, allocator),
|
|
40
41
|
items_(nullptr),
|
|
41
42
|
items_size_(k_),
|
|
42
43
|
min_value_(nullptr),
|
|
@@ -47,11 +48,12 @@ is_level_zero_sorted_(false)
|
|
|
47
48
|
throw std::invalid_argument("K must be >= " + std::to_string(MIN_K) + " and <= " + std::to_string(MAX_K) + ": " + std::to_string(k));
|
|
48
49
|
}
|
|
49
50
|
levels_[0] = levels_[1] = k;
|
|
50
|
-
items_ =
|
|
51
|
+
items_ = allocator_.allocate(items_size_);
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
template<typename T, typename C, typename S, typename A>
|
|
54
55
|
kll_sketch<T, C, S, A>::kll_sketch(const kll_sketch& other):
|
|
56
|
+
allocator_(other.allocator_),
|
|
55
57
|
k_(other.k_),
|
|
56
58
|
m_(other.m_),
|
|
57
59
|
min_k_(other.min_k_),
|
|
@@ -64,14 +66,15 @@ min_value_(nullptr),
|
|
|
64
66
|
max_value_(nullptr),
|
|
65
67
|
is_level_zero_sorted_(other.is_level_zero_sorted_)
|
|
66
68
|
{
|
|
67
|
-
items_ =
|
|
69
|
+
items_ = allocator_.allocate(items_size_);
|
|
68
70
|
std::copy(&other.items_[levels_[0]], &other.items_[levels_[num_levels_]], &items_[levels_[0]]);
|
|
69
|
-
if (other.min_value_ != nullptr) min_value_ = new (
|
|
70
|
-
if (other.max_value_ != nullptr) max_value_ = new (
|
|
71
|
+
if (other.min_value_ != nullptr) min_value_ = new (allocator_.allocate(1)) T(*other.min_value_);
|
|
72
|
+
if (other.max_value_ != nullptr) max_value_ = new (allocator_.allocate(1)) T(*other.max_value_);
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
template<typename T, typename C, typename S, typename A>
|
|
74
76
|
kll_sketch<T, C, S, A>::kll_sketch(kll_sketch&& other) noexcept:
|
|
77
|
+
allocator_(std::move(other.allocator_)),
|
|
75
78
|
k_(other.k_),
|
|
76
79
|
m_(other.m_),
|
|
77
80
|
min_k_(other.min_k_),
|
|
@@ -91,7 +94,8 @@ is_level_zero_sorted_(other.is_level_zero_sorted_)
|
|
|
91
94
|
|
|
92
95
|
template<typename T, typename C, typename S, typename A>
|
|
93
96
|
kll_sketch<T, C, S, A>& kll_sketch<T, C, S, A>::operator=(const kll_sketch& other) {
|
|
94
|
-
kll_sketch copy(other);
|
|
97
|
+
kll_sketch<T, C, S, A> copy(other);
|
|
98
|
+
std::swap(allocator_, copy.allocator_);
|
|
95
99
|
std::swap(k_, copy.k_);
|
|
96
100
|
std::swap(m_, copy.m_);
|
|
97
101
|
std::swap(min_k_, copy.min_k_);
|
|
@@ -108,6 +112,7 @@ kll_sketch<T, C, S, A>& kll_sketch<T, C, S, A>::operator=(const kll_sketch& othe
|
|
|
108
112
|
|
|
109
113
|
template<typename T, typename C, typename S, typename A>
|
|
110
114
|
kll_sketch<T, C, S, A>& kll_sketch<T, C, S, A>::operator=(kll_sketch&& other) {
|
|
115
|
+
std::swap(allocator_, other.allocator_);
|
|
111
116
|
std::swap(k_, other.k_);
|
|
112
117
|
std::swap(m_, other.m_);
|
|
113
118
|
std::swap(min_k_, other.min_k_);
|
|
@@ -128,15 +133,15 @@ kll_sketch<T, C, S, A>::~kll_sketch() {
|
|
|
128
133
|
const uint32_t begin = levels_[0];
|
|
129
134
|
const uint32_t end = levels_[num_levels_];
|
|
130
135
|
for (uint32_t i = begin; i < end; i++) items_[i].~T();
|
|
131
|
-
|
|
136
|
+
allocator_.deallocate(items_, items_size_);
|
|
132
137
|
}
|
|
133
138
|
if (min_value_ != nullptr) {
|
|
134
139
|
min_value_->~T();
|
|
135
|
-
|
|
140
|
+
allocator_.deallocate(min_value_, 1);
|
|
136
141
|
}
|
|
137
142
|
if (max_value_ != nullptr) {
|
|
138
143
|
max_value_->~T();
|
|
139
|
-
|
|
144
|
+
allocator_.deallocate(max_value_, 1);
|
|
140
145
|
}
|
|
141
146
|
}
|
|
142
147
|
|
|
@@ -159,8 +164,8 @@ void kll_sketch<T, C, S, A>::update(T&& value) {
|
|
|
159
164
|
template<typename T, typename C, typename S, typename A>
|
|
160
165
|
void kll_sketch<T, C, S, A>::update_min_max(const T& value) {
|
|
161
166
|
if (is_empty()) {
|
|
162
|
-
min_value_ = new (
|
|
163
|
-
max_value_ = new (
|
|
167
|
+
min_value_ = new (allocator_.allocate(1)) T(value);
|
|
168
|
+
max_value_ = new (allocator_.allocate(1)) T(value);
|
|
164
169
|
} else {
|
|
165
170
|
if (C()(value, *min_value_)) *min_value_ = value;
|
|
166
171
|
if (C()(*max_value_, value)) *max_value_ = value;
|
|
@@ -182,8 +187,8 @@ void kll_sketch<T, C, S, A>::merge(const kll_sketch& other) {
|
|
|
182
187
|
throw std::invalid_argument("incompatible M: " + std::to_string(m_) + " and " + std::to_string(other.m_));
|
|
183
188
|
}
|
|
184
189
|
if (is_empty()) {
|
|
185
|
-
min_value_ = new (
|
|
186
|
-
max_value_ = new (
|
|
190
|
+
min_value_ = new (allocator_.allocate(1)) T(*other.min_value_);
|
|
191
|
+
max_value_ = new (allocator_.allocate(1)) T(*other.max_value_);
|
|
187
192
|
} else {
|
|
188
193
|
if (C()(*other.min_value_, *min_value_)) *min_value_ = *other.min_value_;
|
|
189
194
|
if (C()(*max_value_, *other.max_value_)) *max_value_ = *other.max_value_;
|
|
@@ -206,8 +211,8 @@ void kll_sketch<T, C, S, A>::merge(kll_sketch&& other) {
|
|
|
206
211
|
throw std::invalid_argument("incompatible M: " + std::to_string(m_) + " and " + std::to_string(other.m_));
|
|
207
212
|
}
|
|
208
213
|
if (is_empty()) {
|
|
209
|
-
min_value_ = new (
|
|
210
|
-
max_value_ = new (
|
|
214
|
+
min_value_ = new (allocator_.allocate(1)) T(std::move(*other.min_value_));
|
|
215
|
+
max_value_ = new (allocator_.allocate(1)) T(std::move(*other.max_value_));
|
|
211
216
|
} else {
|
|
212
217
|
if (C()(*other.min_value_, *min_value_)) *min_value_ = std::move(*other.min_value_);
|
|
213
218
|
if (C()(*max_value_, *other.max_value_)) *max_value_ = std::move(*other.max_value_);
|
|
@@ -228,6 +233,11 @@ bool kll_sketch<T, C, S, A>::is_empty() const {
|
|
|
228
233
|
return n_ == 0;
|
|
229
234
|
}
|
|
230
235
|
|
|
236
|
+
template<typename T, typename C, typename S, typename A>
|
|
237
|
+
uint16_t kll_sketch<T, C, S, A>::get_k() const {
|
|
238
|
+
return k_;
|
|
239
|
+
}
|
|
240
|
+
|
|
231
241
|
template<typename T, typename C, typename S, typename A>
|
|
232
242
|
uint64_t kll_sketch<T, C, S, A>::get_n() const {
|
|
233
243
|
return n_;
|
|
@@ -270,8 +280,7 @@ T kll_sketch<T, C, S, A>::get_quantile(double fraction) const {
|
|
|
270
280
|
|
|
271
281
|
template<typename T, typename C, typename S, typename A>
|
|
272
282
|
std::vector<T, A> kll_sketch<T, C, S, A>::get_quantiles(const double* fractions, uint32_t size) const {
|
|
273
|
-
std::vector<T, A> quantiles;
|
|
274
|
-
quantiles.reserve(size);
|
|
283
|
+
std::vector<T, A> quantiles(allocator_);
|
|
275
284
|
if (is_empty()) return quantiles;
|
|
276
285
|
std::unique_ptr<kll_quantile_calculator<T, C, A>, std::function<void(kll_quantile_calculator<T, C, A>*)>> quantile_calculator;
|
|
277
286
|
quantiles.reserve(size);
|
|
@@ -295,11 +304,11 @@ std::vector<T, A> kll_sketch<T, C, S, A>::get_quantiles(const double* fractions,
|
|
|
295
304
|
|
|
296
305
|
template<typename T, typename C, typename S, typename A>
|
|
297
306
|
std::vector<T, A> kll_sketch<T, C, S, A>::get_quantiles(size_t num) const {
|
|
298
|
-
if (is_empty()) return std::vector<T, A>();
|
|
307
|
+
if (is_empty()) return std::vector<T, A>(allocator_);
|
|
299
308
|
if (num == 0) {
|
|
300
309
|
throw std::invalid_argument("num must be > 0");
|
|
301
310
|
}
|
|
302
|
-
|
|
311
|
+
vector_d<A> fractions(num, 0, allocator_);
|
|
303
312
|
fractions[0] = 0.0;
|
|
304
313
|
for (size_t i = 1; i < num; i++) {
|
|
305
314
|
fractions[i] = static_cast<double>(i) / (num - 1);
|
|
@@ -411,7 +420,7 @@ template<typename T, typename C, typename S, typename A>
|
|
|
411
420
|
vector_u8<A> kll_sketch<T, C, S, A>::serialize(unsigned header_size_bytes) const {
|
|
412
421
|
const bool is_single_item = n_ == 1;
|
|
413
422
|
const size_t size = header_size_bytes + get_serialized_size_bytes();
|
|
414
|
-
vector_u8<A> bytes(size);
|
|
423
|
+
vector_u8<A> bytes(size, 0, allocator_);
|
|
415
424
|
uint8_t* ptr = bytes.data() + header_size_bytes;
|
|
416
425
|
const uint8_t* end_ptr = ptr + size;
|
|
417
426
|
const uint8_t preamble_ints(is_empty() || is_single_item ? PREAMBLE_INTS_SHORT : PREAMBLE_INTS_FULL);
|
|
@@ -449,7 +458,7 @@ vector_u8<A> kll_sketch<T, C, S, A>::serialize(unsigned header_size_bytes) const
|
|
|
449
458
|
}
|
|
450
459
|
|
|
451
460
|
template<typename T, typename C, typename S, typename A>
|
|
452
|
-
kll_sketch<T, C, S, A> kll_sketch<T, C, S, A>::deserialize(std::istream& is) {
|
|
461
|
+
kll_sketch<T, C, S, A> kll_sketch<T, C, S, A>::deserialize(std::istream& is, const A& allocator) {
|
|
453
462
|
uint8_t preamble_ints;
|
|
454
463
|
is.read((char*)&preamble_ints, sizeof(preamble_ints));
|
|
455
464
|
uint8_t serial_version;
|
|
@@ -472,7 +481,7 @@ kll_sketch<T, C, S, A> kll_sketch<T, C, S, A>::deserialize(std::istream& is) {
|
|
|
472
481
|
|
|
473
482
|
if (!is.good()) throw std::runtime_error("error reading from std::istream");
|
|
474
483
|
const bool is_empty(flags_byte & (1 << flags::IS_EMPTY));
|
|
475
|
-
if (is_empty) return kll_sketch(k);
|
|
484
|
+
if (is_empty) return kll_sketch(k, allocator);
|
|
476
485
|
|
|
477
486
|
uint64_t n;
|
|
478
487
|
uint16_t min_k;
|
|
@@ -488,7 +497,7 @@ kll_sketch<T, C, S, A> kll_sketch<T, C, S, A>::deserialize(std::istream& is) {
|
|
|
488
497
|
is.read((char*)&num_levels, sizeof(num_levels));
|
|
489
498
|
is.read((char*)&unused, sizeof(unused));
|
|
490
499
|
}
|
|
491
|
-
vector_u32<A> levels(num_levels + 1);
|
|
500
|
+
vector_u32<A> levels(num_levels + 1, 0, allocator);
|
|
492
501
|
const uint32_t capacity(kll_helper::compute_total_capacity(k, m, num_levels));
|
|
493
502
|
if (is_single_item) {
|
|
494
503
|
levels[0] = capacity - 1;
|
|
@@ -497,41 +506,43 @@ kll_sketch<T, C, S, A> kll_sketch<T, C, S, A>::deserialize(std::istream& is) {
|
|
|
497
506
|
is.read((char*)levels.data(), sizeof(levels[0]) * num_levels);
|
|
498
507
|
}
|
|
499
508
|
levels[num_levels] = capacity;
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
std::unique_ptr<T, decltype(item_buffer_deleter)>
|
|
503
|
-
std::unique_ptr<T,
|
|
504
|
-
std::unique_ptr<T, item_deleter>
|
|
509
|
+
A alloc(allocator);
|
|
510
|
+
auto item_buffer_deleter = [&alloc](T* ptr) { alloc.deallocate(ptr, 1); };
|
|
511
|
+
std::unique_ptr<T, decltype(item_buffer_deleter)> min_value_buffer(alloc.allocate(1), item_buffer_deleter);
|
|
512
|
+
std::unique_ptr<T, decltype(item_buffer_deleter)> max_value_buffer(alloc.allocate(1), item_buffer_deleter);
|
|
513
|
+
std::unique_ptr<T, item_deleter> min_value(nullptr, item_deleter(allocator));
|
|
514
|
+
std::unique_ptr<T, item_deleter> max_value(nullptr, item_deleter(allocator));
|
|
505
515
|
if (!is_single_item) {
|
|
506
516
|
S().deserialize(is, min_value_buffer.get(), 1);
|
|
507
517
|
// serde call did not throw, repackage with destrtuctor
|
|
508
|
-
min_value = std::unique_ptr<T, item_deleter>(min_value_buffer.release(), item_deleter());
|
|
518
|
+
min_value = std::unique_ptr<T, item_deleter>(min_value_buffer.release(), item_deleter(allocator));
|
|
509
519
|
S().deserialize(is, max_value_buffer.get(), 1);
|
|
510
520
|
// serde call did not throw, repackage with destrtuctor
|
|
511
|
-
max_value = std::unique_ptr<T, item_deleter>(max_value_buffer.release(), item_deleter());
|
|
521
|
+
max_value = std::unique_ptr<T, item_deleter>(max_value_buffer.release(), item_deleter(allocator));
|
|
512
522
|
}
|
|
513
|
-
auto items_buffer_deleter = [capacity](T* ptr) {
|
|
514
|
-
std::unique_ptr<T, decltype(items_buffer_deleter)> items_buffer(
|
|
523
|
+
auto items_buffer_deleter = [capacity, &alloc](T* ptr) { alloc.deallocate(ptr, capacity); };
|
|
524
|
+
std::unique_ptr<T, decltype(items_buffer_deleter)> items_buffer(alloc.allocate(capacity), items_buffer_deleter);
|
|
515
525
|
const auto num_items = levels[num_levels] - levels[0];
|
|
516
526
|
S().deserialize(is, &items_buffer.get()[levels[0]], num_items);
|
|
517
527
|
// serde call did not throw, repackage with destrtuctors
|
|
518
|
-
std::unique_ptr<T, items_deleter> items(items_buffer.release(), items_deleter(levels[0], capacity));
|
|
528
|
+
std::unique_ptr<T, items_deleter> items(items_buffer.release(), items_deleter(levels[0], capacity, allocator));
|
|
519
529
|
const bool is_level_zero_sorted = (flags_byte & (1 << flags::IS_LEVEL_ZERO_SORTED)) > 0;
|
|
520
530
|
if (is_single_item) {
|
|
521
531
|
new (min_value_buffer.get()) T(items.get()[levels[0]]);
|
|
522
532
|
// copy did not throw, repackage with destrtuctor
|
|
523
|
-
min_value = std::unique_ptr<T, item_deleter>(min_value_buffer.release(), item_deleter());
|
|
533
|
+
min_value = std::unique_ptr<T, item_deleter>(min_value_buffer.release(), item_deleter(allocator));
|
|
524
534
|
new (max_value_buffer.get()) T(items.get()[levels[0]]);
|
|
525
535
|
// copy did not throw, repackage with destrtuctor
|
|
526
|
-
max_value = std::unique_ptr<T, item_deleter>(max_value_buffer.release(), item_deleter());
|
|
536
|
+
max_value = std::unique_ptr<T, item_deleter>(max_value_buffer.release(), item_deleter(allocator));
|
|
527
537
|
}
|
|
528
|
-
if (!is.good())
|
|
538
|
+
if (!is.good())
|
|
539
|
+
throw std::runtime_error("error reading from std::istream");
|
|
529
540
|
return kll_sketch(k, min_k, n, num_levels, std::move(levels), std::move(items), capacity,
|
|
530
541
|
std::move(min_value), std::move(max_value), is_level_zero_sorted);
|
|
531
542
|
}
|
|
532
543
|
|
|
533
544
|
template<typename T, typename C, typename S, typename A>
|
|
534
|
-
kll_sketch<T, C, S, A> kll_sketch<T, C, S, A>::deserialize(const void* bytes, size_t size) {
|
|
545
|
+
kll_sketch<T, C, S, A> kll_sketch<T, C, S, A>::deserialize(const void* bytes, size_t size, const A& allocator) {
|
|
535
546
|
ensure_minimum_memory(size, 8);
|
|
536
547
|
const char* ptr = static_cast<const char*>(bytes);
|
|
537
548
|
uint8_t preamble_ints;
|
|
@@ -555,7 +566,7 @@ kll_sketch<T, C, S, A> kll_sketch<T, C, S, A>::deserialize(const void* bytes, si
|
|
|
555
566
|
ensure_minimum_memory(size, 1 << preamble_ints);
|
|
556
567
|
|
|
557
568
|
const bool is_empty(flags_byte & (1 << flags::IS_EMPTY));
|
|
558
|
-
if (is_empty) return kll_sketch<T, C, S, A>(k);
|
|
569
|
+
if (is_empty) return kll_sketch<T, C, S, A>(k, allocator);
|
|
559
570
|
|
|
560
571
|
uint64_t n;
|
|
561
572
|
uint16_t min_k;
|
|
@@ -572,7 +583,7 @@ kll_sketch<T, C, S, A> kll_sketch<T, C, S, A>::deserialize(const void* bytes, si
|
|
|
572
583
|
ptr += copy_from_mem(ptr, &num_levels, sizeof(num_levels));
|
|
573
584
|
ptr++; // skip unused byte
|
|
574
585
|
}
|
|
575
|
-
vector_u32<A> levels(num_levels + 1);
|
|
586
|
+
vector_u32<A> levels(num_levels + 1, 0, allocator);
|
|
576
587
|
const uint32_t capacity(kll_helper::compute_total_capacity(k, m, num_levels));
|
|
577
588
|
if (is_single_item) {
|
|
578
589
|
levels[0] = capacity - 1;
|
|
@@ -581,35 +592,36 @@ kll_sketch<T, C, S, A> kll_sketch<T, C, S, A>::deserialize(const void* bytes, si
|
|
|
581
592
|
ptr += copy_from_mem(ptr, levels.data(), sizeof(levels[0]) * num_levels);
|
|
582
593
|
}
|
|
583
594
|
levels[num_levels] = capacity;
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
std::unique_ptr<T, decltype(item_buffer_deleter)>
|
|
587
|
-
std::unique_ptr<T,
|
|
588
|
-
std::unique_ptr<T, item_deleter>
|
|
595
|
+
A alloc(allocator);
|
|
596
|
+
auto item_buffer_deleter = [&alloc](T* ptr) { alloc.deallocate(ptr, 1); };
|
|
597
|
+
std::unique_ptr<T, decltype(item_buffer_deleter)> min_value_buffer(alloc.allocate(1), item_buffer_deleter);
|
|
598
|
+
std::unique_ptr<T, decltype(item_buffer_deleter)> max_value_buffer(alloc.allocate(1), item_buffer_deleter);
|
|
599
|
+
std::unique_ptr<T, item_deleter> min_value(nullptr, item_deleter(allocator));
|
|
600
|
+
std::unique_ptr<T, item_deleter> max_value(nullptr, item_deleter(allocator));
|
|
589
601
|
if (!is_single_item) {
|
|
590
602
|
ptr += S().deserialize(ptr, end_ptr - ptr, min_value_buffer.get(), 1);
|
|
591
603
|
// serde call did not throw, repackage with destrtuctor
|
|
592
|
-
min_value = std::unique_ptr<T, item_deleter>(min_value_buffer.release(), item_deleter());
|
|
604
|
+
min_value = std::unique_ptr<T, item_deleter>(min_value_buffer.release(), item_deleter(allocator));
|
|
593
605
|
ptr += S().deserialize(ptr, end_ptr - ptr, max_value_buffer.get(), 1);
|
|
594
606
|
// serde call did not throw, repackage with destrtuctor
|
|
595
|
-
max_value = std::unique_ptr<T, item_deleter>(max_value_buffer.release(), item_deleter());
|
|
607
|
+
max_value = std::unique_ptr<T, item_deleter>(max_value_buffer.release(), item_deleter(allocator));
|
|
596
608
|
}
|
|
597
|
-
auto items_buffer_deleter = [capacity](T* ptr) {
|
|
598
|
-
std::unique_ptr<T, decltype(items_buffer_deleter)> items_buffer(
|
|
609
|
+
auto items_buffer_deleter = [capacity, &alloc](T* ptr) { alloc.deallocate(ptr, capacity); };
|
|
610
|
+
std::unique_ptr<T, decltype(items_buffer_deleter)> items_buffer(alloc.allocate(capacity), items_buffer_deleter);
|
|
599
611
|
const auto num_items = levels[num_levels] - levels[0];
|
|
600
612
|
ptr += S().deserialize(ptr, end_ptr - ptr, &items_buffer.get()[levels[0]], num_items);
|
|
601
613
|
// serde call did not throw, repackage with destrtuctors
|
|
602
|
-
std::unique_ptr<T, items_deleter> items(items_buffer.release(), items_deleter(levels[0], capacity));
|
|
614
|
+
std::unique_ptr<T, items_deleter> items(items_buffer.release(), items_deleter(levels[0], capacity, allocator));
|
|
603
615
|
const size_t delta = ptr - static_cast<const char*>(bytes);
|
|
604
616
|
if (delta != size) throw std::logic_error("deserialized size mismatch: " + std::to_string(delta) + " != " + std::to_string(size));
|
|
605
617
|
const bool is_level_zero_sorted = (flags_byte & (1 << flags::IS_LEVEL_ZERO_SORTED)) > 0;
|
|
606
618
|
if (is_single_item) {
|
|
607
619
|
new (min_value_buffer.get()) T(items.get()[levels[0]]);
|
|
608
620
|
// copy did not throw, repackage with destrtuctor
|
|
609
|
-
min_value = std::unique_ptr<T, item_deleter>(min_value_buffer.release(), item_deleter());
|
|
621
|
+
min_value = std::unique_ptr<T, item_deleter>(min_value_buffer.release(), item_deleter(allocator));
|
|
610
622
|
new (max_value_buffer.get()) T(items.get()[levels[0]]);
|
|
611
623
|
// copy did not throw, repackage with destrtuctor
|
|
612
|
-
max_value = std::unique_ptr<T, item_deleter>(max_value_buffer.release(), item_deleter());
|
|
624
|
+
max_value = std::unique_ptr<T, item_deleter>(max_value_buffer.release(), item_deleter(allocator));
|
|
613
625
|
}
|
|
614
626
|
return kll_sketch(k, min_k, n, num_levels, std::move(levels), std::move(items), capacity,
|
|
615
627
|
std::move(min_value), std::move(max_value), is_level_zero_sorted);
|
|
@@ -634,6 +646,7 @@ template<typename T, typename C, typename S, typename A>
|
|
|
634
646
|
kll_sketch<T, C, S, A>::kll_sketch(uint16_t k, uint16_t min_k, uint64_t n, uint8_t num_levels, vector_u32<A>&& levels,
|
|
635
647
|
std::unique_ptr<T, items_deleter> items, uint32_t items_size, std::unique_ptr<T, item_deleter> min_value,
|
|
636
648
|
std::unique_ptr<T, item_deleter> max_value, bool is_level_zero_sorted):
|
|
649
|
+
allocator_(levels.get_allocator()),
|
|
637
650
|
k_(k),
|
|
638
651
|
m_(DEFAULT_M),
|
|
639
652
|
min_k_(min_k),
|
|
@@ -735,9 +748,9 @@ void kll_sketch<T, C, S, A>::add_empty_top_level_to_completely_full_sketch() {
|
|
|
735
748
|
const uint32_t new_total_cap = cur_total_cap + delta_cap;
|
|
736
749
|
|
|
737
750
|
// move (and shift) the current data into the new buffer
|
|
738
|
-
T* new_buf =
|
|
751
|
+
T* new_buf = allocator_.allocate(new_total_cap);
|
|
739
752
|
kll_helper::move_construct<T>(items_, 0, cur_total_cap, new_buf, delta_cap, true);
|
|
740
|
-
|
|
753
|
+
allocator_.deallocate(items_, items_size_);
|
|
741
754
|
items_ = new_buf;
|
|
742
755
|
items_size_ = new_total_cap;
|
|
743
756
|
|
|
@@ -763,19 +776,20 @@ void kll_sketch<T, C, S, A>::sort_level_zero() {
|
|
|
763
776
|
template<typename T, typename C, typename S, typename A>
|
|
764
777
|
std::unique_ptr<kll_quantile_calculator<T, C, A>, std::function<void(kll_quantile_calculator<T, C, A>*)>> kll_sketch<T, C, S, A>::get_quantile_calculator() {
|
|
765
778
|
sort_level_zero();
|
|
766
|
-
|
|
779
|
+
using AllocCalc = typename std::allocator_traits<A>::template rebind_alloc<kll_quantile_calculator<T, C, A>>;
|
|
780
|
+
AllocCalc alloc(allocator_);
|
|
767
781
|
std::unique_ptr<kll_quantile_calculator<T, C, A>, std::function<void(kll_quantile_calculator<T, C, A>*)>> quantile_calculator(
|
|
768
|
-
new (
|
|
769
|
-
[](kll_quantile_calculator<T, C, A>* ptr){ ptr->~kll_quantile_calculator<T, C, A>();
|
|
782
|
+
new (alloc.allocate(1)) kll_quantile_calculator<T, C, A>(items_, levels_.data(), num_levels_, n_, allocator_),
|
|
783
|
+
[&alloc](kll_quantile_calculator<T, C, A>* ptr){ ptr->~kll_quantile_calculator<T, C, A>(); alloc.deallocate(ptr, 1); }
|
|
770
784
|
);
|
|
771
785
|
return quantile_calculator;
|
|
772
786
|
}
|
|
773
787
|
|
|
774
788
|
template<typename T, typename C, typename S, typename A>
|
|
775
789
|
vector_d<A> kll_sketch<T, C, S, A>::get_PMF_or_CDF(const T* split_points, uint32_t size, bool is_CDF) const {
|
|
776
|
-
if (is_empty()) return vector_d<A>();
|
|
790
|
+
if (is_empty()) return vector_d<A>(allocator_);
|
|
777
791
|
kll_helper::validate_values<T, C>(split_points, size);
|
|
778
|
-
vector_d<A> buckets(size + 1, 0);
|
|
792
|
+
vector_d<A> buckets(size + 1, 0, allocator_);
|
|
779
793
|
uint8_t level = 0;
|
|
780
794
|
uint64_t weight = 1;
|
|
781
795
|
while (level < num_levels_) {
|
|
@@ -845,12 +859,13 @@ template<typename T, typename C, typename S, typename A>
|
|
|
845
859
|
template<typename O>
|
|
846
860
|
void kll_sketch<T, C, S, A>::merge_higher_levels(O&& other, uint64_t final_n) {
|
|
847
861
|
const uint32_t tmp_num_items = get_num_retained() + other.get_num_retained_above_level_zero();
|
|
848
|
-
|
|
849
|
-
|
|
862
|
+
A alloc(allocator_);
|
|
863
|
+
auto tmp_items_deleter = [tmp_num_items, &alloc](T* ptr) { alloc.deallocate(ptr, tmp_num_items); }; // no destructor needed
|
|
864
|
+
const std::unique_ptr<T, decltype(tmp_items_deleter)> workbuf(allocator_.allocate(tmp_num_items), tmp_items_deleter);
|
|
850
865
|
const uint8_t ub = kll_helper::ub_on_num_levels(final_n);
|
|
851
866
|
const size_t work_levels_size = ub + 2; // ub+1 does not work
|
|
852
|
-
vector_u32<A> worklevels(work_levels_size);
|
|
853
|
-
vector_u32<A> outlevels(work_levels_size);
|
|
867
|
+
vector_u32<A> worklevels(work_levels_size, 0, allocator_);
|
|
868
|
+
vector_u32<A> outlevels(work_levels_size, 0, allocator_);
|
|
854
869
|
|
|
855
870
|
const uint8_t provisional_num_levels = std::max(num_levels_, other.num_levels_);
|
|
856
871
|
|
|
@@ -864,9 +879,9 @@ void kll_sketch<T, C, S, A>::merge_higher_levels(O&& other, uint64_t final_n) {
|
|
|
864
879
|
|
|
865
880
|
// now we need to transfer the results back into "this" sketch
|
|
866
881
|
if (result.final_capacity != items_size_) {
|
|
867
|
-
|
|
882
|
+
allocator_.deallocate(items_, items_size_);
|
|
868
883
|
items_size_ = result.final_capacity;
|
|
869
|
-
items_ =
|
|
884
|
+
items_ = allocator_.allocate(items_size_);
|
|
870
885
|
}
|
|
871
886
|
const uint32_t free_space_at_bottom = result.final_capacity - result.final_num_items;
|
|
872
887
|
kll_helper::move_construct<T>(workbuf.get(), outlevels[0], outlevels[0] + result.final_num_items, items_, free_space_at_bottom, true);
|
|
@@ -1101,29 +1116,32 @@ const std::pair<const T&, const uint64_t> kll_sketch<T, C, S, A>::const_iterator
|
|
|
1101
1116
|
template<typename T, typename C, typename S, typename A>
|
|
1102
1117
|
class kll_sketch<T, C, S, A>::item_deleter {
|
|
1103
1118
|
public:
|
|
1104
|
-
|
|
1119
|
+
item_deleter(const A& allocator): allocator_(allocator) {}
|
|
1120
|
+
void operator() (T* ptr) {
|
|
1105
1121
|
if (ptr != nullptr) {
|
|
1106
1122
|
ptr->~T();
|
|
1107
|
-
|
|
1123
|
+
allocator_.deallocate(ptr, 1);
|
|
1108
1124
|
}
|
|
1109
1125
|
}
|
|
1126
|
+
private:
|
|
1127
|
+
A allocator_;
|
|
1110
1128
|
};
|
|
1111
1129
|
|
|
1112
1130
|
template<typename T, typename C, typename S, typename A>
|
|
1113
1131
|
class kll_sketch<T, C, S, A>::items_deleter {
|
|
1114
1132
|
public:
|
|
1115
|
-
items_deleter(uint32_t start, uint32_t num
|
|
1116
|
-
|
|
1133
|
+
items_deleter(uint32_t start, uint32_t num, const A& allocator):
|
|
1134
|
+
allocator_(allocator), start_(start), num_(num) {}
|
|
1135
|
+
void operator() (T* ptr) {
|
|
1117
1136
|
if (ptr != nullptr) {
|
|
1118
|
-
for (uint32_t i =
|
|
1119
|
-
|
|
1120
|
-
}
|
|
1121
|
-
A().deallocate(ptr, num);
|
|
1137
|
+
for (uint32_t i = start_; i < num_; ++i) ptr[i].~T();
|
|
1138
|
+
allocator_.deallocate(ptr, num_);
|
|
1122
1139
|
}
|
|
1123
1140
|
}
|
|
1124
1141
|
private:
|
|
1125
|
-
|
|
1126
|
-
uint32_t
|
|
1142
|
+
A allocator_;
|
|
1143
|
+
uint32_t start_;
|
|
1144
|
+
uint32_t num_;
|
|
1127
1145
|
};
|
|
1128
1146
|
|
|
1129
1147
|
} /* namespace datasketches */
|