datasketches 0.5.1 → 0.5.3
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 +9 -0
- data/ext/datasketches/cpc_wrapper.cpp +8 -9
- data/ext/datasketches/fi_wrapper.cpp +4 -5
- data/ext/datasketches/hll_wrapper.cpp +9 -10
- data/ext/datasketches/kll_wrapper.cpp +13 -12
- data/ext/datasketches/theta_wrapper.cpp +11 -13
- data/ext/datasketches/vo_wrapper.cpp +1 -2
- data/lib/datasketches/version.rb +1 -1
- data/vendor/datasketches-cpp/CMakeLists.txt +5 -3
- data/vendor/datasketches-cpp/CODE_OF_CONDUCT.md +1 -1
- data/vendor/datasketches-cpp/LICENSE +14 -0
- data/vendor/datasketches-cpp/README.md +67 -73
- data/vendor/datasketches-cpp/benchmarks/CMakeLists.txt +52 -0
- data/vendor/datasketches-cpp/benchmarks/benchmark_count_min_sketch.cpp +153 -0
- data/vendor/datasketches-cpp/benchmarks/benchmark_count_min_sketch_serialization.cpp +161 -0
- data/vendor/datasketches-cpp/common/CMakeLists.txt +1 -0
- data/vendor/datasketches-cpp/common/include/binomial_bounds.hpp +2 -2
- data/vendor/datasketches-cpp/common/include/fdlibm_log.hpp +101 -0
- data/vendor/datasketches-cpp/common/include/serde.hpp +6 -0
- data/vendor/datasketches-cpp/common/test/CMakeLists.txt +44 -2
- data/vendor/datasketches-cpp/common/test/binomial_bounds_test.cpp +279 -0
- data/vendor/datasketches-cpp/common/test/deserialize_hardening_test.cpp +188 -0
- data/vendor/datasketches-cpp/count/include/count_min.hpp +17 -4
- data/vendor/datasketches-cpp/count/include/count_min_impl.hpp +65 -83
- data/vendor/datasketches-cpp/count/test/count_min_test.cpp +63 -7
- data/vendor/datasketches-cpp/cpc/include/compression_data.hpp +2 -0
- data/vendor/datasketches-cpp/cpc/include/cpc_compressor_impl.hpp +16 -7
- data/vendor/datasketches-cpp/cpc/include/cpc_sketch.hpp +1 -0
- data/vendor/datasketches-cpp/cpc/include/cpc_sketch_impl.hpp +54 -36
- data/vendor/datasketches-cpp/cpc/include/cpc_union_impl.hpp +27 -27
- data/vendor/datasketches-cpp/cpc/include/cpc_util.hpp +7 -7
- data/vendor/datasketches-cpp/cpc/include/icon_estimator.hpp +5 -5
- data/vendor/datasketches-cpp/cpc/include/u32_table_impl.hpp +16 -16
- data/vendor/datasketches-cpp/cpc/test/cpc_sketch_test.cpp +35 -0
- data/vendor/datasketches-cpp/fi/include/frequent_items_sketch.hpp +28 -3
- data/vendor/datasketches-cpp/fi/include/frequent_items_sketch_impl.hpp +41 -25
- data/vendor/datasketches-cpp/fi/include/reverse_purge_hash_map.hpp +3 -1
- data/vendor/datasketches-cpp/fi/include/reverse_purge_hash_map_impl.hpp +10 -5
- data/vendor/datasketches-cpp/fi/test/frequent_items_sketch_serialize_for_java.cpp +24 -0
- data/vendor/datasketches-cpp/fi/test/frequent_items_sketch_test.cpp +116 -0
- data/vendor/datasketches-cpp/filters/include/bloom_filter.hpp +1 -1
- data/vendor/datasketches-cpp/filters/include/bloom_filter_impl.hpp +32 -12
- data/vendor/datasketches-cpp/filters/test/bloom_filter_test.cpp +28 -1
- data/vendor/datasketches-cpp/hll/include/CouponHashSet-internal.hpp +1 -2
- data/vendor/datasketches-cpp/hll/include/CouponList-internal.hpp +19 -5
- data/vendor/datasketches-cpp/hll/include/CubicInterpolation-internal.hpp +4 -4
- data/vendor/datasketches-cpp/hll/include/HarmonicNumbers-internal.hpp +2 -1
- data/vendor/datasketches-cpp/hll/include/Hll4Array-internal.hpp +4 -4
- data/vendor/datasketches-cpp/hll/include/Hll4Array.hpp +1 -1
- data/vendor/datasketches-cpp/hll/include/Hll6Array-internal.hpp +3 -3
- data/vendor/datasketches-cpp/hll/include/Hll6Array.hpp +1 -1
- data/vendor/datasketches-cpp/hll/include/Hll8Array-internal.hpp +6 -3
- data/vendor/datasketches-cpp/hll/include/Hll8Array.hpp +1 -1
- data/vendor/datasketches-cpp/hll/include/HllArray-internal.hpp +35 -29
- data/vendor/datasketches-cpp/hll/include/HllArray.hpp +1 -1
- data/vendor/datasketches-cpp/hll/include/HllSketch-internal.hpp +3 -5
- data/vendor/datasketches-cpp/hll/include/HllSketchImpl-internal.hpp +5 -11
- data/vendor/datasketches-cpp/hll/include/HllSketchImpl.hpp +2 -4
- data/vendor/datasketches-cpp/hll/include/HllSketchImplFactory.hpp +11 -10
- data/vendor/datasketches-cpp/hll/include/HllUnion-internal.hpp +17 -8
- data/vendor/datasketches-cpp/hll/include/HllUtil.hpp +12 -3
- data/vendor/datasketches-cpp/hll/include/coupon_iterator-internal.hpp +2 -2
- data/vendor/datasketches-cpp/hll/include/coupon_iterator.hpp +3 -0
- data/vendor/datasketches-cpp/hll/include/hll.hpp +11 -4
- data/vendor/datasketches-cpp/hll/include/hll.private.hpp +19 -0
- data/vendor/datasketches-cpp/hll/test/CMakeLists.txt +2 -0
- data/vendor/datasketches-cpp/hll/test/CouponListTest.cpp +64 -0
- data/vendor/datasketches-cpp/hll/test/HllFullSizeTest.cpp +137 -0
- data/vendor/datasketches-cpp/hll/test/HllKxqRebuildTest.cpp +150 -0
- data/vendor/datasketches-cpp/hll/test/HllSketchTest.cpp +3 -3
- data/vendor/datasketches-cpp/hll/test/HllUnionTest.cpp +71 -1
- data/vendor/datasketches-cpp/kll/include/kll_helper_impl.hpp +10 -10
- data/vendor/datasketches-cpp/kll/include/kll_sketch.hpp +10 -1
- data/vendor/datasketches-cpp/kll/include/kll_sketch_impl.hpp +33 -24
- data/vendor/datasketches-cpp/kll/test/kll_sketch_deserialize_from_java_test.cpp +24 -0
- data/vendor/datasketches-cpp/kll/test/kll_sketch_serialize_for_java.cpp +10 -0
- data/vendor/datasketches-cpp/quantiles/include/quantiles_sketch.hpp +11 -2
- data/vendor/datasketches-cpp/quantiles/include/quantiles_sketch_impl.hpp +24 -15
- data/vendor/datasketches-cpp/req/include/req_sketch.hpp +9 -0
- data/vendor/datasketches-cpp/req/include/req_sketch_impl.hpp +24 -15
- data/vendor/datasketches-cpp/req/test/req_sketch_deserialize_from_java_test.cpp +46 -0
- data/vendor/datasketches-cpp/req/test/req_sketch_serialize_for_java.cpp +20 -0
- data/vendor/datasketches-cpp/req/test/req_sketch_test.cpp +70 -0
- data/vendor/datasketches-cpp/sampling/include/ebpps_sample_impl.hpp +17 -8
- data/vendor/datasketches-cpp/sampling/include/ebpps_sketch.hpp +13 -0
- data/vendor/datasketches-cpp/sampling/include/var_opt_sketch.hpp +10 -1
- data/vendor/datasketches-cpp/sampling/include/var_opt_sketch_impl.hpp +6 -7
- data/vendor/datasketches-cpp/sampling/include/var_opt_union.hpp +5 -1
- data/vendor/datasketches-cpp/sampling/include/var_opt_union_impl.hpp +2 -1
- data/vendor/datasketches-cpp/sampling/test/ebpps_allocation_test.cpp +1 -1
- data/vendor/datasketches-cpp/sampling/test/ebpps_sketch_test.cpp +2 -2
- data/vendor/datasketches-cpp/sampling/test/var_opt_allocation_test.cpp +1 -1
- data/vendor/datasketches-cpp/sampling/test/var_opt_sketch_test.cpp +10 -4
- data/vendor/datasketches-cpp/sampling/test/var_opt_union_test.cpp +12 -0
- data/vendor/datasketches-cpp/tdigest/include/tdigest.hpp +38 -2
- data/vendor/datasketches-cpp/tdigest/include/tdigest_impl.hpp +168 -9
- data/vendor/datasketches-cpp/tdigest/test/CMakeLists.txt +1 -0
- data/vendor/datasketches-cpp/tdigest/test/tdigest_iterator_test.cpp +274 -0
- data/vendor/datasketches-cpp/tdigest/test/tdigest_test.cpp +275 -0
- data/vendor/datasketches-cpp/theta/include/compact_theta_sketch_parser.hpp +2 -0
- data/vendor/datasketches-cpp/theta/include/compact_theta_sketch_parser_impl.hpp +24 -3
- data/vendor/datasketches-cpp/theta/include/theta_constants.hpp +4 -2
- data/vendor/datasketches-cpp/theta/include/theta_helpers.hpp +32 -0
- data/vendor/datasketches-cpp/theta/include/theta_set_difference_base_impl.hpp +4 -2
- data/vendor/datasketches-cpp/theta/include/theta_sketch.hpp +22 -4
- data/vendor/datasketches-cpp/theta/include/theta_sketch_impl.hpp +60 -38
- data/vendor/datasketches-cpp/theta/include/theta_union_base_impl.hpp +2 -6
- data/vendor/datasketches-cpp/theta/include/theta_update_sketch_base_impl.hpp +2 -2
- data/vendor/datasketches-cpp/theta/test/bit_packing_test.cpp +50 -0
- data/vendor/datasketches-cpp/theta/test/theta_a_not_b_test.cpp +22 -0
- data/vendor/datasketches-cpp/theta/test/theta_sketch_test.cpp +315 -0
- data/vendor/datasketches-cpp/tools/rat-check.sh +68 -0
- data/vendor/datasketches-cpp/tuple/include/array_tuple_sketch.hpp +35 -4
- data/vendor/datasketches-cpp/tuple/include/array_tuple_sketch_impl.hpp +2 -2
- data/vendor/datasketches-cpp/tuple/include/tuple_sketch.hpp +41 -0
- data/vendor/datasketches-cpp/tuple/include/tuple_sketch_impl.hpp +5 -4
- data/vendor/datasketches-cpp/tuple/test/tuple_sketch_test.cpp +59 -0
- data/vendor/datasketches-cpp/version.cfg.in +1 -1
- metadata +12 -2
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
#include <cmath>
|
|
29
29
|
#include <string>
|
|
30
30
|
#include <sstream>
|
|
31
|
+
#include <type_traits>
|
|
31
32
|
|
|
32
33
|
namespace datasketches {
|
|
33
34
|
|
|
@@ -365,11 +366,15 @@ std::pair<ebpps_sample<T, A>, size_t> ebpps_sample<T, A>::deserialize(const uint
|
|
|
365
366
|
|
|
366
367
|
optional<T> partial_item;
|
|
367
368
|
if (has_partial) {
|
|
368
|
-
|
|
369
|
-
|
|
369
|
+
// Space to deserialize.
|
|
370
|
+
// serde::deserialize expects allocated but not initialized storage.
|
|
371
|
+
typename std::aligned_storage<sizeof(T), alignof(T)>::type tmp_storage;
|
|
372
|
+
T* tmp = reinterpret_cast<T*>(&tmp_storage);
|
|
373
|
+
|
|
374
|
+
ptr += sd.deserialize(ptr, end_ptr - ptr, tmp, 1);
|
|
370
375
|
// serde did not throw so place item and clean up
|
|
371
|
-
partial_item.emplace(*tmp);
|
|
372
|
-
|
|
376
|
+
partial_item.emplace(std::move(*tmp));
|
|
377
|
+
tmp->~T();
|
|
373
378
|
}
|
|
374
379
|
|
|
375
380
|
return std::pair<ebpps_sample<T,A>, size_t>(
|
|
@@ -400,11 +405,15 @@ ebpps_sample<T, A> ebpps_sample<T, A>::deserialize(std::istream& is, const SerDe
|
|
|
400
405
|
|
|
401
406
|
optional<T> partial_item;
|
|
402
407
|
if (has_partial) {
|
|
403
|
-
|
|
404
|
-
|
|
408
|
+
// Space to deserialize.
|
|
409
|
+
// serde::deserialize expects allocated but not initialized storage.
|
|
410
|
+
typename std::aligned_storage<sizeof(T), alignof(T)>::type tmp_storage;
|
|
411
|
+
T* tmp = reinterpret_cast<T*>(&tmp_storage);
|
|
412
|
+
|
|
413
|
+
sd.deserialize(is, tmp, 1);
|
|
405
414
|
// serde did not throw so place item and clean up
|
|
406
|
-
partial_item.emplace(*tmp);
|
|
407
|
-
|
|
415
|
+
partial_item.emplace(std::move(*tmp));
|
|
416
|
+
tmp->~T();
|
|
408
417
|
}
|
|
409
418
|
|
|
410
419
|
if (!is.good()) throw std::runtime_error("error reading from std::istream");
|
|
@@ -50,6 +50,11 @@ namespace ebpps_constants {
|
|
|
50
50
|
* The sample may be smaller than k and the resulting size of the sample potentially includes
|
|
51
51
|
* a probabilistic component, meaning the resulting sample size is not always constant.
|
|
52
52
|
*
|
|
53
|
+
* Sketch that may retain string values.
|
|
54
|
+
* For sketches containing strings, cross-language portability depends on
|
|
55
|
+
* using compatible string encodings. This class does not by itself enforce
|
|
56
|
+
* UTF-8 validity for all string inputs.
|
|
57
|
+
*
|
|
53
58
|
* @author Jon Malkin
|
|
54
59
|
*/
|
|
55
60
|
template<
|
|
@@ -71,6 +76,8 @@ class ebpps_sketch {
|
|
|
71
76
|
/**
|
|
72
77
|
* Updates this sketch with the given data item with the given weight.
|
|
73
78
|
* This method takes an lvalue.
|
|
79
|
+
* If cross-language portability is required, callers should ensure that
|
|
80
|
+
* the input string uses a compatible encoding (valid UTF-8).
|
|
74
81
|
* @param item an item from a stream of items
|
|
75
82
|
* @param weight the weight of the item
|
|
76
83
|
*/
|
|
@@ -79,6 +86,8 @@ class ebpps_sketch {
|
|
|
79
86
|
/**
|
|
80
87
|
* Updates this sketch with the given data item with the given weight.
|
|
81
88
|
* This method takes an rvalue.
|
|
89
|
+
* If cross-language portability is required, callers should ensure that
|
|
90
|
+
* the input string uses a compatible encoding (valid UTF-8).
|
|
82
91
|
* @param item an item from a stream of items
|
|
83
92
|
* @param weight the weight of the item
|
|
84
93
|
*/
|
|
@@ -87,6 +96,8 @@ class ebpps_sketch {
|
|
|
87
96
|
/**
|
|
88
97
|
* Merges the provided sketch into the current one.
|
|
89
98
|
* This method takes an lvalue.
|
|
99
|
+
* If sketches contain strings, callers are responsible for ensuring that
|
|
100
|
+
* both sketches were built using compatible string encodings.
|
|
90
101
|
* @param sketch the sketch to merge into the current object
|
|
91
102
|
*/
|
|
92
103
|
void merge(const ebpps_sketch<T, A>& sketch);
|
|
@@ -94,6 +105,8 @@ class ebpps_sketch {
|
|
|
94
105
|
/**
|
|
95
106
|
* Merges the provided sketch into the current one.
|
|
96
107
|
* This method takes an rvalue.
|
|
108
|
+
* If sketches contain strings, callers are responsible for ensuring that
|
|
109
|
+
* both sketches were built using compatible string encodings.
|
|
97
110
|
* @param sketch the sketch to merge into the current object
|
|
98
111
|
*/
|
|
99
112
|
void merge(ebpps_sketch<T, A>&& sketch);
|
|
@@ -57,6 +57,11 @@ namespace var_opt_constants {
|
|
|
57
57
|
* optimal (varopt) sampling is related to reservoir sampling, with improved error bounds for
|
|
58
58
|
* subset sum estimation.
|
|
59
59
|
*
|
|
60
|
+
* Sketch that may retain string values.
|
|
61
|
+
* For sketches containing strings, cross-language portability depends on
|
|
62
|
+
* using compatible string encodings. This class does not by itself enforce
|
|
63
|
+
* UTF-8 validity for all string inputs.
|
|
64
|
+
*
|
|
60
65
|
* author Kevin Lang
|
|
61
66
|
* author Jon Malkin
|
|
62
67
|
*/
|
|
@@ -111,6 +116,8 @@ class var_opt_sketch {
|
|
|
111
116
|
/**
|
|
112
117
|
* Updates this sketch with the given data item with the given weight.
|
|
113
118
|
* This method takes an lvalue.
|
|
119
|
+
* If cross-language portability is required, callers should ensure that
|
|
120
|
+
* the input string uses a compatible encoding (valid UTF-8).
|
|
114
121
|
* @param item an item from a stream of items
|
|
115
122
|
* @param weight the weight of the item
|
|
116
123
|
*/
|
|
@@ -119,6 +126,8 @@ class var_opt_sketch {
|
|
|
119
126
|
/**
|
|
120
127
|
* Updates this sketch with the given data item with the given weight.
|
|
121
128
|
* This method takes an rvalue.
|
|
129
|
+
* If cross-language portability is required, callers should ensure that
|
|
130
|
+
* the input string uses a compatible encoding (valid UTF-8).
|
|
122
131
|
* @param item an item from a stream of items
|
|
123
132
|
* @param weight the weight of the item
|
|
124
133
|
*/
|
|
@@ -263,7 +272,7 @@ class var_opt_sketch {
|
|
|
263
272
|
typedef typename std::allocator_traits<A>::template rebind_alloc<double> AllocDouble;
|
|
264
273
|
typedef typename std::allocator_traits<A>::template rebind_alloc<bool> AllocBool;
|
|
265
274
|
|
|
266
|
-
static const uint32_t MIN_LG_ARR_ITEMS =
|
|
275
|
+
static const uint32_t MIN_LG_ARR_ITEMS = 4;
|
|
267
276
|
|
|
268
277
|
static const uint8_t PREAMBLE_LONGS_EMPTY = 1;
|
|
269
278
|
static const uint8_t PREAMBLE_LONGS_WARMUP = 3;
|
|
@@ -772,12 +772,11 @@ string<A> var_opt_sketch<T, A>::items_to_string(bool print_gap) const {
|
|
|
772
772
|
template<typename T, typename A>
|
|
773
773
|
template<typename O>
|
|
774
774
|
void var_opt_sketch<T, A>::update(O&& item, double weight, bool mark) {
|
|
775
|
-
if (weight
|
|
776
|
-
throw std::invalid_argument("Item weights must be
|
|
775
|
+
if (weight <= 0.0 || std::isnan(weight) || std::isinf(weight)) {
|
|
776
|
+
throw std::invalid_argument("Item weights must be positive and finite. Found: "
|
|
777
777
|
+ std::to_string(weight));
|
|
778
|
-
} else if (weight == 0.0) {
|
|
779
|
-
return;
|
|
780
778
|
}
|
|
779
|
+
|
|
781
780
|
++n_;
|
|
782
781
|
|
|
783
782
|
if (r_ == 0) {
|
|
@@ -1029,7 +1028,7 @@ void var_opt_sketch<T, A>::transition_from_warmup() {
|
|
|
1029
1028
|
total_wt_r_ = weights_[k_]; // only one item, known location
|
|
1030
1029
|
weights_[k_] = -1.0;
|
|
1031
1030
|
|
|
1032
|
-
// The two lightest items are
|
|
1031
|
+
// The two lightest items are necessarily downsample-able to one item,
|
|
1033
1032
|
// and are therefore a valid initial candidate set
|
|
1034
1033
|
grow_candidate_set(weights_[k_ - 1] + total_wt_r_, 2);
|
|
1035
1034
|
}
|
|
@@ -1065,7 +1064,7 @@ void var_opt_sketch<T, A>::restore_towards_leaves(uint32_t slot_in) {
|
|
|
1065
1064
|
while (child <= last_slot) {
|
|
1066
1065
|
uint32_t child2 = child + 1; // might also be invalid
|
|
1067
1066
|
if ((child2 <= last_slot) && (weights_[child2] < weights_[child])) {
|
|
1068
|
-
//
|
|
1067
|
+
// switch to other child if it's both valid and smaller
|
|
1069
1068
|
child = child2;
|
|
1070
1069
|
}
|
|
1071
1070
|
|
|
@@ -1221,7 +1220,7 @@ uint32_t var_opt_sketch<T, A>::choose_delete_slot(double wt_cands, uint32_t num_
|
|
|
1221
1220
|
if ((wt_cands * next_double_exclude_zero()) < ((num_cands - 1) * wt_m_cand)) {
|
|
1222
1221
|
return pick_random_slot_in_r(); // keep item in M
|
|
1223
1222
|
} else {
|
|
1224
|
-
return h_; //
|
|
1223
|
+
return h_; // index of item in M
|
|
1225
1224
|
}
|
|
1226
1225
|
} else {
|
|
1227
1226
|
// general case
|
|
@@ -65,13 +65,17 @@ public:
|
|
|
65
65
|
/**
|
|
66
66
|
* Updates this union with the given sketch
|
|
67
67
|
* This method takes an lvalue.
|
|
68
|
+
* If sketches contain strings, callers are responsible for ensuring that
|
|
69
|
+
* both sketches were built using compatible string encodings.
|
|
68
70
|
* @param sk a sketch to add to the union
|
|
69
71
|
*/
|
|
70
72
|
void update(const var_opt_sketch<T, A>& sk);
|
|
71
|
-
|
|
73
|
+
|
|
72
74
|
/**
|
|
73
75
|
* Updates this union with the given sketch
|
|
74
76
|
* This method takes an rvalue.
|
|
77
|
+
* If sketches contain strings, callers are responsible for ensuring that
|
|
78
|
+
* both sketches were built using compatible string encodings.
|
|
75
79
|
* @param sk a sketch to add to the union
|
|
76
80
|
*/
|
|
77
81
|
void update(var_opt_sketch<T, A>&& sk);
|
|
@@ -200,6 +200,7 @@ var_opt_union<T, A> var_opt_union<T, A>::deserialize(const void* bytes, size_t s
|
|
|
200
200
|
return var_opt_union(max_k);
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
+
ensure_minimum_memory(size, PREAMBLE_LONGS_NON_EMPTY << 3);
|
|
203
204
|
uint64_t items_seen;
|
|
204
205
|
ptr += copy_from_mem(ptr, items_seen);
|
|
205
206
|
double outer_tau_numer;
|
|
@@ -590,7 +591,7 @@ void var_opt_union<T, A>::migrate_marked_items_by_decreasing_k(var_opt_sketch<T,
|
|
|
590
591
|
|
|
591
592
|
// if non-full and pseudo-exact, change k so that gcopy is full
|
|
592
593
|
if ((r_count == 0) && (h_count < k)) {
|
|
593
|
-
gcopy.k_ = h_count; // may
|
|
594
|
+
gcopy.k_ = h_count; // may leave extra space allocated but that's ok
|
|
594
595
|
}
|
|
595
596
|
|
|
596
597
|
// Now k equals the number of samples, so reducing k will increase tau.
|
|
@@ -222,7 +222,7 @@ TEST_CASE("ebpps sketch: merge large into small", "[ebpps_sketch]") {
|
|
|
222
222
|
sk1 = create_unweighted_sketch(k / 2, 0);
|
|
223
223
|
sk1.update(-1, k / 4.0);
|
|
224
224
|
sk1.update(-2, k / 8.0);
|
|
225
|
-
// sk2 should have been
|
|
225
|
+
// sk2 should have been unchanged
|
|
226
226
|
REQUIRE(sk2.get_n() == k);
|
|
227
227
|
REQUIRE(sk2.get_c() == Approx(k).margin(EPS));
|
|
228
228
|
|
|
@@ -250,7 +250,7 @@ TEST_CASE("ebpps sketch: merge small into large", "[ebpps_sketch]") {
|
|
|
250
250
|
|
|
251
251
|
// rvalue merge
|
|
252
252
|
sk1 = create_unweighted_sketch(k, 3 * k / 2);
|
|
253
|
-
// sk2 should have been
|
|
253
|
+
// sk2 should have been unchanged
|
|
254
254
|
REQUIRE(sk2.get_n() == 1);
|
|
255
255
|
REQUIRE(sk2.get_c() == 1.0);
|
|
256
256
|
sk2.update(-2, k / 10.0);
|
|
@@ -67,7 +67,7 @@ TEST_CASE( "varopt union: move", "[var_opt_union][test_type]") {
|
|
|
67
67
|
var_opt_test_sketch sk1(k, var_opt_test_sketch::DEFAULT_RESIZE_FACTOR, 0);
|
|
68
68
|
var_opt_test_sketch sk2(k, var_opt_test_sketch::DEFAULT_RESIZE_FACTOR, 0);
|
|
69
69
|
|
|
70
|
-
// move
|
|
70
|
+
// move updates
|
|
71
71
|
for (int i = 0; i < (int) n; ++i) {
|
|
72
72
|
sk1.update(i);
|
|
73
73
|
sk2.update(-i);
|
|
@@ -178,11 +178,17 @@ TEST_CASE("varopt sketch: non-empty degenerate sketch", "[var_opt_sketch]") {
|
|
|
178
178
|
|
|
179
179
|
TEST_CASE("varopt sketch: invalid weight", "[var_opt_sketch]") {
|
|
180
180
|
var_opt_sketch<std::string> sk(100, resize_factor::X2);
|
|
181
|
-
REQUIRE_THROWS_AS(sk.update("invalid_weight", -1.0), std::invalid_argument);
|
|
182
181
|
|
|
183
|
-
//
|
|
184
|
-
sk.update("
|
|
185
|
-
|
|
182
|
+
// Negative
|
|
183
|
+
REQUIRE_THROWS_AS(sk.update("invalid_weight", -1.0), std::invalid_argument);
|
|
184
|
+
// Zero
|
|
185
|
+
REQUIRE_THROWS_AS(sk.update("zero_weight", 0.0), std::invalid_argument);
|
|
186
|
+
// NaN
|
|
187
|
+
REQUIRE_THROWS_AS(sk.update("NaN_weight", std::numeric_limits<double>::quiet_NaN()), std::invalid_argument);
|
|
188
|
+
// +Inf
|
|
189
|
+
REQUIRE_THROWS_AS(sk.update("positive_infinity", std::numeric_limits<double>::infinity()), std::invalid_argument);
|
|
190
|
+
// -Inf
|
|
191
|
+
REQUIRE_THROWS_AS(sk.update("negative_infinity", -std::numeric_limits<double>::infinity()), std::invalid_argument);
|
|
186
192
|
}
|
|
187
193
|
|
|
188
194
|
TEST_CASE("varopt sketch: corrupt serialized weight", "[var_opt_sketch]") {
|
|
@@ -305,4 +305,16 @@ TEST_CASE("varopt union: serialize sampling", "[var_opt_union]") {
|
|
|
305
305
|
compare_serialization_deserialization(u);
|
|
306
306
|
}
|
|
307
307
|
|
|
308
|
+
TEST_CASE("varopt union: deserialize truncated non-empty preamble", "[var_opt_union]") {
|
|
309
|
+
var_opt_sketch<int> sk(32);
|
|
310
|
+
sk.update(1);
|
|
311
|
+
var_opt_union<int> u(32);
|
|
312
|
+
u.update(sk);
|
|
313
|
+
auto bytes = u.serialize();
|
|
314
|
+
// a non-empty union needs 4 preamble longs
|
|
315
|
+
for (size_t size = 8; size < 32; ++size) {
|
|
316
|
+
REQUIRE_THROWS_AS(var_opt_union<int>::deserialize(bytes.data(), size), std::out_of_range);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
308
320
|
}
|
|
@@ -108,6 +108,7 @@ public:
|
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
110
|
* Update this t-Digest with the given value
|
|
111
|
+
* NaN and infinity values are ignored
|
|
111
112
|
* @param value to update the t-Digest with
|
|
112
113
|
*/
|
|
113
114
|
void update(T value);
|
|
@@ -153,6 +154,7 @@ public:
|
|
|
153
154
|
* Compute approximate normalized rank of the given value.
|
|
154
155
|
*
|
|
155
156
|
* <p>If the sketch is empty this throws std::runtime_error.
|
|
157
|
+
* <p>NaN value throw std::invalid_argument.
|
|
156
158
|
*
|
|
157
159
|
* @param value to be ranked
|
|
158
160
|
* @return normalized rank (from 0 to 1 inclusive)
|
|
@@ -257,16 +259,29 @@ public:
|
|
|
257
259
|
*/
|
|
258
260
|
static tdigest deserialize(const void* bytes, size_t size, const Allocator& allocator = Allocator());
|
|
259
261
|
|
|
262
|
+
class const_iterator;
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Iterator pointing to the first centroid in the sketch.
|
|
266
|
+
* If the sketch is empty, the returned iterator must not be dereferenced or incremented.
|
|
267
|
+
* @return iterator pointing to the first centroid in the sketch
|
|
268
|
+
*/
|
|
269
|
+
const_iterator begin() const;
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Iterator pointing to the past-the-end centroid in the sketch.
|
|
273
|
+
* It does not point to any centroid, and must not be dereferenced or incremented.
|
|
274
|
+
* @return iterator pointing to the past-the-end centroid in the sketch
|
|
275
|
+
*/
|
|
276
|
+
const_iterator end() const;
|
|
260
277
|
private:
|
|
261
278
|
bool reverse_merge_;
|
|
262
279
|
uint16_t k_;
|
|
263
|
-
uint16_t internal_k_;
|
|
264
280
|
T min_;
|
|
265
281
|
T max_;
|
|
266
282
|
size_t centroids_capacity_;
|
|
267
283
|
vector_centroid centroids_;
|
|
268
284
|
uint64_t centroids_weight_;
|
|
269
|
-
size_t buffer_capacity_;
|
|
270
285
|
vector_t buffer_;
|
|
271
286
|
|
|
272
287
|
static const size_t BUFFER_MULTIPLIER = 4;
|
|
@@ -297,6 +312,27 @@ private:
|
|
|
297
312
|
static inline void check_split_points(const T* values, uint32_t size);
|
|
298
313
|
};
|
|
299
314
|
|
|
315
|
+
template<typename T, typename A>
|
|
316
|
+
class tdigest<T, A>::const_iterator {
|
|
317
|
+
public:
|
|
318
|
+
using iterator_category = std::input_iterator_tag;
|
|
319
|
+
using value_type = std::pair<T, W>;
|
|
320
|
+
using difference_type = void;
|
|
321
|
+
using pointer = const return_value_holder<value_type>;
|
|
322
|
+
using reference = const value_type;
|
|
323
|
+
|
|
324
|
+
const_iterator& operator++();
|
|
325
|
+
const_iterator& operator++(int);
|
|
326
|
+
bool operator==(const const_iterator& other) const;
|
|
327
|
+
bool operator!=(const const_iterator& other) const;
|
|
328
|
+
reference operator*() const;
|
|
329
|
+
pointer operator->() const;
|
|
330
|
+
private:
|
|
331
|
+
friend class tdigest;
|
|
332
|
+
uint32_t index_;
|
|
333
|
+
vector_centroid centroids_;
|
|
334
|
+
const_iterator(const tdigest& tdigest_, bool is_end);
|
|
335
|
+
};
|
|
300
336
|
} /* namespace datasketches */
|
|
301
337
|
|
|
302
338
|
#include "tdigest_impl.hpp"
|