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
|
@@ -33,7 +33,7 @@ namespace datasketches {
|
|
|
33
33
|
|
|
34
34
|
template<typename A>
|
|
35
35
|
CouponList<A>::CouponList(uint8_t lgConfigK, target_hll_type tgtHllType, hll_mode mode, const A& allocator):
|
|
36
|
-
HllSketchImpl<A>(lgConfigK, tgtHllType, mode
|
|
36
|
+
HllSketchImpl<A>(lgConfigK, tgtHllType, mode),
|
|
37
37
|
couponCount_(0),
|
|
38
38
|
oooFlag_(false),
|
|
39
39
|
coupons_(1ULL << (mode == hll_mode::LIST ? hll_constants::LG_INIT_LIST_SIZE : hll_constants::LG_INIT_SET_SIZE), 0, allocator)
|
|
@@ -41,7 +41,7 @@ coupons_(1ULL << (mode == hll_mode::LIST ? hll_constants::LG_INIT_LIST_SIZE : hl
|
|
|
41
41
|
|
|
42
42
|
template<typename A>
|
|
43
43
|
CouponList<A>::CouponList(const CouponList& that, const target_hll_type tgtHllType):
|
|
44
|
-
HllSketchImpl<A>(that.lgConfigK_, tgtHllType, that.mode_
|
|
44
|
+
HllSketchImpl<A>(that.lgConfigK_, tgtHllType, that.mode_),
|
|
45
45
|
couponCount_(that.couponCount_),
|
|
46
46
|
oooFlag_(that.oooFlag_),
|
|
47
47
|
coupons_(that.coupons_)
|
|
@@ -99,6 +99,13 @@ CouponList<A>* CouponList<A>::newList(const void* bytes, size_t len, const A& al
|
|
|
99
99
|
const bool emptyFlag = ((data[hll_constants::FLAGS_BYTE] & hll_constants::EMPTY_FLAG_MASK) ? true : false);
|
|
100
100
|
|
|
101
101
|
const uint32_t couponCount = data[hll_constants::LIST_COUNT_BYTE];
|
|
102
|
+
// Reject LIST counts at or above the fixed LIST capacity.
|
|
103
|
+
const uint32_t listCapacity = 1u << hll_constants::LG_INIT_LIST_SIZE;
|
|
104
|
+
if (couponCount >= listCapacity) {
|
|
105
|
+
throw std::invalid_argument("Attempt to deserialize invalid CouponList with couponCount >= capacity. Found couponCount: "
|
|
106
|
+
+ std::to_string(couponCount)
|
|
107
|
+
+ ", capacity: " + std::to_string(listCapacity));
|
|
108
|
+
}
|
|
102
109
|
const uint32_t couponsInArray = (compact ? couponCount : (1 << HllUtil<A>::computeLgArrInts(LIST, couponCount, lgK)));
|
|
103
110
|
const size_t expectedLength = hll_constants::LIST_INT_ARR_START + (couponsInArray * sizeof(uint32_t));
|
|
104
111
|
if (len < expectedLength) {
|
|
@@ -146,11 +153,19 @@ CouponList<A>* CouponList<A>::newList(std::istream& is, const A& allocator) {
|
|
|
146
153
|
const bool oooFlag = ((listHeader[hll_constants::FLAGS_BYTE] & hll_constants::OUT_OF_ORDER_FLAG_MASK) ? true : false);
|
|
147
154
|
const bool emptyFlag = ((listHeader[hll_constants::FLAGS_BYTE] & hll_constants::EMPTY_FLAG_MASK) ? true : false);
|
|
148
155
|
|
|
156
|
+
const uint32_t couponCount = listHeader[hll_constants::LIST_COUNT_BYTE];
|
|
157
|
+
// Reject LIST counts at or above the fixed LIST capacity.
|
|
158
|
+
const uint32_t listCapacity = 1u << hll_constants::LG_INIT_LIST_SIZE;
|
|
159
|
+
if (couponCount >= listCapacity) {
|
|
160
|
+
throw std::invalid_argument("Attempt to deserialize invalid CouponList with couponCount >= capacity. Found couponCount: "
|
|
161
|
+
+ std::to_string(couponCount)
|
|
162
|
+
+ ", capacity: " + std::to_string(listCapacity));
|
|
163
|
+
}
|
|
164
|
+
|
|
149
165
|
ClAlloc cla(allocator);
|
|
150
166
|
CouponList<A>* sketch = new (cla.allocate(1)) CouponList<A>(lgK, tgtHllType, mode, allocator);
|
|
151
167
|
using coupon_list_ptr = std::unique_ptr<CouponList<A>, std::function<void(HllSketchImpl<A>*)>>;
|
|
152
168
|
coupon_list_ptr ptr(sketch, sketch->get_deleter());
|
|
153
|
-
const uint32_t couponCount = listHeader[hll_constants::LIST_COUNT_BYTE];
|
|
154
169
|
sketch->couponCount_ = couponCount;
|
|
155
170
|
sketch->putOutOfOrderFlag(oooFlag); // should always be false for LIST
|
|
156
171
|
|
|
@@ -162,8 +177,7 @@ CouponList<A>* CouponList<A>::newList(std::istream& is, const A& allocator) {
|
|
|
162
177
|
read(is, sketch->coupons_.data(), numToRead * sizeof(uint32_t));
|
|
163
178
|
}
|
|
164
179
|
|
|
165
|
-
if (!is.good())
|
|
166
|
-
throw std::runtime_error("error reading from std::istream");
|
|
180
|
+
if (!is.good()) { throw std::runtime_error("error reading from std::istream"); }
|
|
167
181
|
|
|
168
182
|
return ptr.release();
|
|
169
183
|
}
|
|
@@ -165,10 +165,10 @@ static int recursiveFindStraddle(const double xArr[], const int l, const int r,
|
|
|
165
165
|
throw std::logic_error("target value invariant violated in search");
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
if (l+1 == r) return (l);
|
|
168
|
+
if (l+1 == r) { return (l); }
|
|
169
169
|
m = l + ((r-l)/2);
|
|
170
|
-
if (xArr[m] <= x) return (recursiveFindStraddle<A>(xArr, m, r, x));
|
|
171
|
-
else return (recursiveFindStraddle<A>(xArr, l, m, x));
|
|
170
|
+
if (xArr[m] <= x) { return (recursiveFindStraddle<A>(xArr, m, r, x)); }
|
|
171
|
+
else { return (recursiveFindStraddle<A>(xArr, l, m, x)); }
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
|
|
@@ -191,7 +191,7 @@ double CubicInterpolation<A>::usingXArrAndYStride(const double xArr[], const int
|
|
|
191
191
|
const int xArrLenM1 = xArrLen - 1;
|
|
192
192
|
|
|
193
193
|
if ((xArrLen < 4) || (x < xArr[0]) || (x > xArr[xArrLenM1])) {
|
|
194
|
-
throw std::logic_error("impossible values during
|
|
194
|
+
throw std::logic_error("impossible values during interpolation");
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
if (x == xArr[xArrLenM1]) { /* corner case */
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
#define _HARMONICNUMBERS_INTERNAL_HPP_
|
|
22
22
|
|
|
23
23
|
#include "HarmonicNumbers.hpp"
|
|
24
|
+
#include "fdlibm_log.hpp"
|
|
24
25
|
|
|
25
26
|
#include <cmath>
|
|
26
27
|
|
|
@@ -70,7 +71,7 @@ double HarmonicNumbers<A>::harmonicNumber(const uint64_t x_i) {
|
|
|
70
71
|
} else {
|
|
71
72
|
double x = static_cast<double>(x_i);
|
|
72
73
|
double invSq = 1.0 / (x * x);
|
|
73
|
-
double sum = log(x) + EULER_MASCHERONI_CONSTANT + (1.0 / (2.0 * x));
|
|
74
|
+
double sum = fdlibm::log(x) + EULER_MASCHERONI_CONSTANT + (1.0 / (2.0 * x));
|
|
74
75
|
/* note: the number of terms included from this series expansion is appropriate
|
|
75
76
|
for the size of the exact table (25) and the precision of doubles */
|
|
76
77
|
double pow = invSq; // now n^-2
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
namespace datasketches {
|
|
31
31
|
|
|
32
32
|
template<typename A>
|
|
33
|
-
Hll4Array<A>::Hll4Array(uint8_t lgConfigK,
|
|
34
|
-
HllArray<A>(lgConfigK, target_hll_type::HLL_4,
|
|
33
|
+
Hll4Array<A>::Hll4Array(uint8_t lgConfigK, const A& allocator):
|
|
34
|
+
HllArray<A>(lgConfigK, target_hll_type::HLL_4, allocator),
|
|
35
35
|
auxHashMap_(nullptr)
|
|
36
36
|
{
|
|
37
37
|
const uint32_t numBytes = this->hll4ArrBytes(lgConfigK);
|
|
@@ -53,7 +53,7 @@ Hll4Array<A>::Hll4Array(const Hll4Array<A>& that) :
|
|
|
53
53
|
|
|
54
54
|
template<typename A>
|
|
55
55
|
Hll4Array<A>::Hll4Array(const HllArray<A>& other) :
|
|
56
|
-
HllArray<A>(other.getLgConfigK(), target_hll_type::HLL_4, other.
|
|
56
|
+
HllArray<A>(other.getLgConfigK(), target_hll_type::HLL_4, other.getAllocator()),
|
|
57
57
|
auxHashMap_(nullptr)
|
|
58
58
|
{
|
|
59
59
|
const int numBytes = this->hll4ArrBytes(this->lgConfigK_);
|
|
@@ -131,7 +131,7 @@ uint8_t Hll4Array<A>::getSlot(uint32_t slotNo) const {
|
|
|
131
131
|
|
|
132
132
|
template<typename A>
|
|
133
133
|
uint8_t Hll4Array<A>::adjustRawValue(uint32_t slot, uint8_t value) const {
|
|
134
|
-
if (value != hll_constants::AUX_TOKEN) return value + this->curMin_;
|
|
134
|
+
if (value != hll_constants::AUX_TOKEN) { return value + this->curMin_; }
|
|
135
135
|
return auxHashMap_->mustFindValueFor(slot);
|
|
136
136
|
}
|
|
137
137
|
|
|
@@ -28,7 +28,7 @@ namespace datasketches {
|
|
|
28
28
|
template<typename A>
|
|
29
29
|
class Hll4Array final : public HllArray<A> {
|
|
30
30
|
public:
|
|
31
|
-
explicit Hll4Array(uint8_t lgConfigK,
|
|
31
|
+
explicit Hll4Array(uint8_t lgConfigK, const A& allocator);
|
|
32
32
|
explicit Hll4Array(const Hll4Array<A>& that);
|
|
33
33
|
explicit Hll4Array(const HllArray<A>& that);
|
|
34
34
|
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
namespace datasketches {
|
|
28
28
|
|
|
29
29
|
template<typename A>
|
|
30
|
-
Hll6Array<A>::Hll6Array(uint8_t lgConfigK,
|
|
31
|
-
HllArray<A>(lgConfigK, target_hll_type::HLL_6,
|
|
30
|
+
Hll6Array<A>::Hll6Array(uint8_t lgConfigK, const A& allocator):
|
|
31
|
+
HllArray<A>(lgConfigK, target_hll_type::HLL_6, allocator)
|
|
32
32
|
{
|
|
33
33
|
const int numBytes = this->hll6ArrBytes(lgConfigK);
|
|
34
34
|
this->hllByteArr_.resize(numBytes, 0);
|
|
@@ -36,7 +36,7 @@ HllArray<A>(lgConfigK, target_hll_type::HLL_6, startFullSize, allocator)
|
|
|
36
36
|
|
|
37
37
|
template<typename A>
|
|
38
38
|
Hll6Array<A>::Hll6Array(const HllArray<A>& other) :
|
|
39
|
-
HllArray<A>(other.getLgConfigK(), target_hll_type::HLL_6, other.
|
|
39
|
+
HllArray<A>(other.getLgConfigK(), target_hll_type::HLL_6, other.getAllocator())
|
|
40
40
|
{
|
|
41
41
|
const int numBytes = this->hll6ArrBytes(this->lgConfigK_);
|
|
42
42
|
this->hllByteArr_.resize(numBytes, 0);
|
|
@@ -30,7 +30,7 @@ class Hll6Iterator;
|
|
|
30
30
|
template<typename A>
|
|
31
31
|
class Hll6Array final : public HllArray<A> {
|
|
32
32
|
public:
|
|
33
|
-
Hll6Array(uint8_t lgConfigK,
|
|
33
|
+
Hll6Array(uint8_t lgConfigK, const A& allocator);
|
|
34
34
|
explicit Hll6Array(const HllArray<A>& that);
|
|
35
35
|
|
|
36
36
|
virtual ~Hll6Array() = default;
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
namespace datasketches {
|
|
26
26
|
|
|
27
27
|
template<typename A>
|
|
28
|
-
Hll8Array<A>::Hll8Array(uint8_t lgConfigK,
|
|
29
|
-
HllArray<A>(lgConfigK, target_hll_type::HLL_8,
|
|
28
|
+
Hll8Array<A>::Hll8Array(uint8_t lgConfigK, const A& allocator):
|
|
29
|
+
HllArray<A>(lgConfigK, target_hll_type::HLL_8, allocator)
|
|
30
30
|
{
|
|
31
31
|
const int numBytes = this->hll8ArrBytes(lgConfigK);
|
|
32
32
|
this->hllByteArr_.resize(numBytes, 0);
|
|
@@ -34,7 +34,7 @@ HllArray<A>(lgConfigK, target_hll_type::HLL_8, startFullSize, allocator)
|
|
|
34
34
|
|
|
35
35
|
template<typename A>
|
|
36
36
|
Hll8Array<A>::Hll8Array(const HllArray<A>& other):
|
|
37
|
-
HllArray<A>(other.getLgConfigK(), target_hll_type::HLL_8, other.
|
|
37
|
+
HllArray<A>(other.getLgConfigK(), target_hll_type::HLL_8, other.getAllocator())
|
|
38
38
|
{
|
|
39
39
|
const int numBytes = this->hll8ArrBytes(this->lgConfigK_);
|
|
40
40
|
this->hllByteArr_.resize(numBytes, 0);
|
|
@@ -98,6 +98,9 @@ void Hll8Array<A>::internalCouponUpdate(uint32_t coupon) {
|
|
|
98
98
|
|
|
99
99
|
const uint8_t curVal = this->hllByteArr_[slotNo];
|
|
100
100
|
if (newVal > curVal) {
|
|
101
|
+
// A prior HLL merge may have left the estimator state stale. Rebuild it before applying
|
|
102
|
+
// an incremental update for a changed register.
|
|
103
|
+
this->check_rebuild_kxq_cur_min();
|
|
101
104
|
this->hllByteArr_[slotNo] = newVal;
|
|
102
105
|
this->hipAndKxQIncrementalUpdate(curVal, newVal);
|
|
103
106
|
this->numAtCurMin_ -= curVal == 0; // interpret numAtCurMin as num zeros
|
|
@@ -30,7 +30,7 @@ class Hll8Iterator;
|
|
|
30
30
|
template<typename A>
|
|
31
31
|
class Hll8Array final : public HllArray<A> {
|
|
32
32
|
public:
|
|
33
|
-
Hll8Array(uint8_t lgConfigK,
|
|
33
|
+
Hll8Array(uint8_t lgConfigK, const A& allocator);
|
|
34
34
|
explicit Hll8Array(const HllArray<A>& that);
|
|
35
35
|
|
|
36
36
|
virtual ~Hll8Array() = default;
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
#define _HLLARRAY_INTERNAL_HPP_
|
|
22
22
|
|
|
23
23
|
#include "HllArray.hpp"
|
|
24
|
+
#include "fdlibm_log.hpp"
|
|
24
25
|
#include "HllUtil.hpp"
|
|
25
26
|
#include "HarmonicNumbers.hpp"
|
|
26
27
|
#include "CubicInterpolation.hpp"
|
|
@@ -35,8 +36,8 @@
|
|
|
35
36
|
namespace datasketches {
|
|
36
37
|
|
|
37
38
|
template<typename A>
|
|
38
|
-
HllArray<A>::HllArray(uint8_t lgConfigK, target_hll_type tgtHllType,
|
|
39
|
-
HllSketchImpl<A>(lgConfigK, tgtHllType, hll_mode::HLL
|
|
39
|
+
HllArray<A>::HllArray(uint8_t lgConfigK, target_hll_type tgtHllType, const A& allocator):
|
|
40
|
+
HllSketchImpl<A>(lgConfigK, tgtHllType, hll_mode::HLL),
|
|
40
41
|
hipAccum_(0.0),
|
|
41
42
|
kxq0_(1 << lgConfigK),
|
|
42
43
|
kxq1_(0.0),
|
|
@@ -49,7 +50,7 @@ rebuild_kxq_curmin_(false)
|
|
|
49
50
|
|
|
50
51
|
template<typename A>
|
|
51
52
|
HllArray<A>::HllArray(const HllArray& other, target_hll_type tgtHllType) :
|
|
52
|
-
HllSketchImpl<A>(other.getLgConfigK(), tgtHllType, hll_mode::HLL
|
|
53
|
+
HllSketchImpl<A>(other.getLgConfigK(), tgtHllType, hll_mode::HLL),
|
|
53
54
|
// remaining fields are initialized to empty sketch defaults
|
|
54
55
|
// and left to subclass constructor to populate
|
|
55
56
|
hipAccum_(0.0),
|
|
@@ -109,7 +110,6 @@ HllArray<A>* HllArray<A>::newHll(const void* bytes, size_t len, const A& allocat
|
|
|
109
110
|
const target_hll_type tgtHllType = HllSketchImpl<A>::extractTgtHllType(data[hll_constants::MODE_BYTE]);
|
|
110
111
|
const bool oooFlag = ((data[hll_constants::FLAGS_BYTE] & hll_constants::OUT_OF_ORDER_FLAG_MASK) ? true : false);
|
|
111
112
|
const bool comapctFlag = ((data[hll_constants::FLAGS_BYTE] & hll_constants::COMPACT_FLAG_MASK) ? true : false);
|
|
112
|
-
const bool startFullSizeFlag = ((data[hll_constants::FLAGS_BYTE] & hll_constants::FULL_SIZE_FLAG_MASK) ? true : false);
|
|
113
113
|
|
|
114
114
|
const uint8_t lgK = data[hll_constants::LG_K_BYTE];
|
|
115
115
|
const uint8_t curMin = data[hll_constants::HLL_CUR_MIN_BYTE];
|
|
@@ -139,18 +139,19 @@ HllArray<A>* HllArray<A>::newHll(const void* bytes, size_t len, const A& allocat
|
|
|
139
139
|
aux_ptr = aux_hash_map_ptr(auxHashMap, auxHashMap->make_deleter());
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
HllArray<A>* sketch = HllSketchImplFactory<A>::newHll(lgK, tgtHllType,
|
|
142
|
+
HllArray<A>* sketch = HllSketchImplFactory<A>::newHll(lgK, tgtHllType, allocator);
|
|
143
143
|
sketch->putCurMin(curMin);
|
|
144
144
|
sketch->putOutOfOrderFlag(oooFlag);
|
|
145
|
-
if (!oooFlag) sketch->putHipAccum(hip);
|
|
145
|
+
if (!oooFlag) { sketch->putHipAccum(hip); }
|
|
146
146
|
sketch->putKxQ0(kxq0);
|
|
147
147
|
sketch->putKxQ1(kxq1);
|
|
148
148
|
sketch->putNumAtCurMin(numAtCurMin);
|
|
149
149
|
|
|
150
150
|
std::memcpy(sketch->hllByteArr_.data(), data + hll_constants::HLL_BYTE_ARR_START, arrayBytes);
|
|
151
151
|
|
|
152
|
-
if (auxHashMap != nullptr)
|
|
152
|
+
if (auxHashMap != nullptr) {
|
|
153
153
|
((Hll4Array<A>*)sketch)->putAuxHashMap(auxHashMap);
|
|
154
|
+
}
|
|
154
155
|
|
|
155
156
|
aux_ptr.release();
|
|
156
157
|
return sketch;
|
|
@@ -173,18 +174,17 @@ HllArray<A>* HllArray<A>::newHll(std::istream& is, const A& allocator) {
|
|
|
173
174
|
|
|
174
175
|
hll_mode mode = HllSketchImpl<A>::extractCurMode(listHeader[hll_constants::MODE_BYTE]);
|
|
175
176
|
if (mode != HLL) {
|
|
176
|
-
throw std::invalid_argument("Calling HLL
|
|
177
|
+
throw std::invalid_argument("Calling HLL constructor with non-HLL mode data");
|
|
177
178
|
}
|
|
178
179
|
|
|
179
180
|
const target_hll_type tgtHllType = HllSketchImpl<A>::extractTgtHllType(listHeader[hll_constants::MODE_BYTE]);
|
|
180
181
|
const bool oooFlag = ((listHeader[hll_constants::FLAGS_BYTE] & hll_constants::OUT_OF_ORDER_FLAG_MASK) ? true : false);
|
|
181
182
|
const bool comapctFlag = ((listHeader[hll_constants::FLAGS_BYTE] & hll_constants::COMPACT_FLAG_MASK) ? true : false);
|
|
182
|
-
const bool startFullSizeFlag = ((listHeader[hll_constants::FLAGS_BYTE] & hll_constants::FULL_SIZE_FLAG_MASK) ? true : false);
|
|
183
183
|
|
|
184
184
|
const uint8_t lgK = listHeader[hll_constants::LG_K_BYTE];
|
|
185
185
|
const uint8_t curMin = listHeader[hll_constants::HLL_CUR_MIN_BYTE];
|
|
186
186
|
|
|
187
|
-
HllArray* sketch = HllSketchImplFactory<A>::newHll(lgK, tgtHllType,
|
|
187
|
+
HllArray* sketch = HllSketchImplFactory<A>::newHll(lgK, tgtHllType, allocator);
|
|
188
188
|
typedef std::unique_ptr<HllArray<A>, std::function<void(HllSketchImpl<A>*)>> hll_array_ptr;
|
|
189
189
|
hll_array_ptr sketch_ptr(sketch, sketch->get_deleter());
|
|
190
190
|
sketch->putCurMin(curMin);
|
|
@@ -193,7 +193,7 @@ HllArray<A>* HllArray<A>::newHll(std::istream& is, const A& allocator) {
|
|
|
193
193
|
const auto hip = read<double>(is);
|
|
194
194
|
const auto kxq0 = read<double>(is);
|
|
195
195
|
const auto kxq1 = read<double>(is);
|
|
196
|
-
if (!oooFlag) sketch->putHipAccum(hip);
|
|
196
|
+
if (!oooFlag) { sketch->putHipAccum(hip); }
|
|
197
197
|
sketch->putKxQ0(kxq0);
|
|
198
198
|
sketch->putKxQ1(kxq1);
|
|
199
199
|
|
|
@@ -209,8 +209,7 @@ HllArray<A>* HllArray<A>::newHll(std::istream& is, const A& allocator) {
|
|
|
209
209
|
((Hll4Array<A>*)sketch)->putAuxHashMap(auxHashMap);
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
if (!is.good())
|
|
213
|
-
throw std::runtime_error("error reading from std::istream");
|
|
212
|
+
if (!is.good()) { throw std::runtime_error("error reading from std::istream"); }
|
|
214
213
|
|
|
215
214
|
return sketch_ptr.release();
|
|
216
215
|
}
|
|
@@ -465,6 +464,10 @@ bool HllArray<A>::isCompact() const {
|
|
|
465
464
|
|
|
466
465
|
template<typename A>
|
|
467
466
|
bool HllArray<A>::isEmpty() const {
|
|
467
|
+
// mergeHll() is only called with non-empty sketches and sets this flag after updating the
|
|
468
|
+
// register array. The cached curMin_/numAtCurMin_ may still have their empty-sketch values,
|
|
469
|
+
// but a pending rebuild therefore proves that this array is not empty.
|
|
470
|
+
if (rebuild_kxq_curmin_) return false;
|
|
468
471
|
const uint32_t configK = 1 << this->lgConfigK_;
|
|
469
472
|
return (curMin_ == 0) && (numAtCurMin_ == configK);
|
|
470
473
|
}
|
|
@@ -545,7 +548,7 @@ template<typename A>
|
|
|
545
548
|
void HllArray<A>::hipAndKxQIncrementalUpdate(uint8_t oldValue, uint8_t newValue) {
|
|
546
549
|
const uint32_t configK = 1 << this->getLgConfigK();
|
|
547
550
|
// update hip BEFORE updating kxq
|
|
548
|
-
if (!oooFlag_) hipAccum_ += configK / (kxq0_ + kxq1_);
|
|
551
|
+
if (!oooFlag_) { hipAccum_ += configK / (kxq0_ + kxq1_); }
|
|
549
552
|
// update kxq0 and kxq1; subtract first, then add
|
|
550
553
|
if (oldValue < 32) { kxq0_ -= INVERSE_POWERS_OF_2[oldValue]; }
|
|
551
554
|
else { kxq1_ -= INVERSE_POWERS_OF_2[oldValue]; }
|
|
@@ -566,7 +569,7 @@ double HllArray<A>::getHllBitMapEstimate() const {
|
|
|
566
569
|
|
|
567
570
|
//This will eventually go away.
|
|
568
571
|
if (numUnhitBuckets == 0) {
|
|
569
|
-
return configK * log(configK / 0.5);
|
|
572
|
+
return configK * fdlibm::log(configK / 0.5);
|
|
570
573
|
}
|
|
571
574
|
|
|
572
575
|
const uint32_t numHitBuckets = configK - numUnhitBuckets;
|
|
@@ -599,34 +602,37 @@ bool HllArray<A>::isRebuildKxqCurminFlag() const {
|
|
|
599
602
|
template<typename A>
|
|
600
603
|
void HllArray<A>::check_rebuild_kxq_cur_min() {
|
|
601
604
|
if (!rebuild_kxq_curmin_) { return; }
|
|
605
|
+
// the deferred rebuild is only ever set on an HLL_8 union gadget. Guarding here also keeps
|
|
606
|
+
// this from ever rewriting curMin_ on an HLL_4 array, whose nibbles are stored relative to it.
|
|
607
|
+
if (this->getCurMode() != hll_mode::HLL || this->getTgtHllType() != target_hll_type::HLL_8) {
|
|
608
|
+
rebuild_kxq_curmin_ = false;
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
602
611
|
|
|
603
|
-
|
|
604
|
-
uint32_t num_at_cur_min = 0;
|
|
612
|
+
uint32_t num_zeros = 0;
|
|
605
613
|
double kxq0 = 1 << this->lgConfigK_;
|
|
606
614
|
double kxq1 = 0;
|
|
607
615
|
|
|
608
|
-
auto it = this->begin(true); // want all
|
|
616
|
+
auto it = this->begin(true); // want all slots, including the empty ones
|
|
609
617
|
const auto end = this->end();
|
|
610
618
|
while (it != end) {
|
|
611
619
|
uint8_t v = HllUtil<A>::getValue(*it);
|
|
612
620
|
if (v > 0) {
|
|
613
621
|
if (v < 32) { kxq0 += INVERSE_POWERS_OF_2[v] - 1.0; }
|
|
614
622
|
else { kxq1 += INVERSE_POWERS_OF_2[v] - 1.0; }
|
|
615
|
-
}
|
|
616
|
-
if (v > cur_min) { ++it; continue; }
|
|
617
|
-
if (v < cur_min) {
|
|
618
|
-
cur_min = v;
|
|
619
|
-
num_at_cur_min = 1;
|
|
620
623
|
} else {
|
|
621
|
-
++
|
|
622
|
-
}
|
|
624
|
+
++num_zeros;
|
|
625
|
+
}
|
|
623
626
|
++it;
|
|
624
627
|
}
|
|
625
628
|
|
|
626
629
|
kxq0_ = kxq0;
|
|
627
630
|
kxq1_ = kxq1;
|
|
628
|
-
|
|
629
|
-
|
|
631
|
+
// HLL_8 convention: curMin is always 0 and numAtCurMin is the number of zero registers.
|
|
632
|
+
// That is the representation the incremental update path maintains, so the rebuilt state is
|
|
633
|
+
// indistinguishable from it and the timing of this rebuild is not observable in the image.
|
|
634
|
+
curMin_ = 0;
|
|
635
|
+
numAtCurMin_ = num_zeros;
|
|
630
636
|
rebuild_kxq_curmin_ = false;
|
|
631
637
|
// HipAccum is not affected
|
|
632
638
|
|
|
@@ -648,7 +654,7 @@ array_(array), array_size_(array_size), index_(index), hll_type_(hll_type), exce
|
|
|
648
654
|
{
|
|
649
655
|
while (index_ < array_size_) {
|
|
650
656
|
value_ = get_value(array_, index_, hll_type_, exceptions_, offset_);
|
|
651
|
-
if (all_ || value_ != hll_constants::EMPTY) break;
|
|
657
|
+
if (all_ || value_ != hll_constants::EMPTY) { break; }
|
|
652
658
|
++index_;
|
|
653
659
|
}
|
|
654
660
|
}
|
|
@@ -657,7 +663,7 @@ template<typename A>
|
|
|
657
663
|
typename HllArray<A>::const_iterator& HllArray<A>::const_iterator::operator++() {
|
|
658
664
|
while (++index_ < array_size_) {
|
|
659
665
|
value_ = get_value(array_, index_, hll_type_, exceptions_, offset_);
|
|
660
|
-
if (all_ || value_ != hll_constants::EMPTY) break;
|
|
666
|
+
if (all_ || value_ != hll_constants::EMPTY) { break; }
|
|
661
667
|
}
|
|
662
668
|
return *this;
|
|
663
669
|
}
|
|
@@ -33,7 +33,7 @@ class HllArray : public HllSketchImpl<A> {
|
|
|
33
33
|
public:
|
|
34
34
|
using vector_bytes = std::vector<uint8_t, typename std::allocator_traits<A>::template rebind_alloc<uint8_t>>;
|
|
35
35
|
|
|
36
|
-
HllArray(uint8_t lgConfigK, target_hll_type tgtHllType,
|
|
36
|
+
HllArray(uint8_t lgConfigK, target_hll_type tgtHllType, const A& allocator);
|
|
37
37
|
explicit HllArray(const HllArray& other, target_hll_type tgtHllType);
|
|
38
38
|
|
|
39
39
|
static HllArray* newHll(const void* bytes, size_t len, const A& allocator);
|
|
@@ -45,7 +45,7 @@ template<typename A>
|
|
|
45
45
|
hll_sketch_alloc<A>::hll_sketch_alloc(uint8_t lg_config_k, target_hll_type tgt_type, bool start_full_size, const A& allocator) {
|
|
46
46
|
HllUtil<A>::checkLgK(lg_config_k);
|
|
47
47
|
if (start_full_size) {
|
|
48
|
-
sketch_impl = HllSketchImplFactory<A>::newHll(lg_config_k, tgt_type,
|
|
48
|
+
sketch_impl = HllSketchImplFactory<A>::newHll(lg_config_k, tgt_type, allocator);
|
|
49
49
|
} else {
|
|
50
50
|
typedef typename std::allocator_traits<A>::template rebind_alloc<CouponList<A>> clAlloc;
|
|
51
51
|
sketch_impl = new (clAlloc(allocator).allocate(1)) CouponList<A>(lg_config_k, tgt_type, hll_mode::LIST, allocator);
|
|
@@ -107,10 +107,8 @@ hll_sketch_alloc<A>& hll_sketch_alloc<A>::operator=(hll_sketch_alloc<A>&& other)
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
template<typename A>
|
|
110
|
-
void hll_sketch_alloc<A>::reset() {
|
|
111
|
-
|
|
112
|
-
// (either here or in other implementation)
|
|
113
|
-
sketch_impl = sketch_impl->reset();
|
|
110
|
+
void hll_sketch_alloc<A>::reset(bool full_size) {
|
|
111
|
+
sketch_impl = sketch_impl->reset(full_size);
|
|
114
112
|
}
|
|
115
113
|
|
|
116
114
|
template<typename A>
|
|
@@ -29,11 +29,10 @@ namespace datasketches {
|
|
|
29
29
|
|
|
30
30
|
template<typename A>
|
|
31
31
|
HllSketchImpl<A>::HllSketchImpl(uint8_t lgConfigK, target_hll_type tgtHllType,
|
|
32
|
-
hll_mode mode
|
|
32
|
+
hll_mode mode)
|
|
33
33
|
: lgConfigK_(lgConfigK),
|
|
34
34
|
tgtHllType_(tgtHllType),
|
|
35
|
-
mode_(mode)
|
|
36
|
-
startFullSize_(startFullSize)
|
|
35
|
+
mode_(mode)
|
|
37
36
|
{
|
|
38
37
|
}
|
|
39
38
|
|
|
@@ -75,7 +74,7 @@ uint8_t HllSketchImpl<A>::makeFlagsByte(bool compact) const {
|
|
|
75
74
|
flags |= (isEmpty() ? hll_constants::EMPTY_FLAG_MASK : 0);
|
|
76
75
|
flags |= (compact ? hll_constants::COMPACT_FLAG_MASK : 0);
|
|
77
76
|
flags |= (isOutOfOrderFlag() ? hll_constants::OUT_OF_ORDER_FLAG_MASK : 0);
|
|
78
|
-
|
|
77
|
+
// bit 32 is reserved: see RESERVED_FLAG_MASK_32 in HllUtil.hpp
|
|
79
78
|
return flags;
|
|
80
79
|
}
|
|
81
80
|
|
|
@@ -122,8 +121,8 @@ uint8_t HllSketchImpl<A>::makeModeByte() const {
|
|
|
122
121
|
}
|
|
123
122
|
|
|
124
123
|
template<typename A>
|
|
125
|
-
HllSketchImpl<A>* HllSketchImpl<A>::reset() {
|
|
126
|
-
return HllSketchImplFactory<A>::reset(this,
|
|
124
|
+
HllSketchImpl<A>* HllSketchImpl<A>::reset(bool full_size) {
|
|
125
|
+
return HllSketchImplFactory<A>::reset(this, full_size);
|
|
127
126
|
}
|
|
128
127
|
|
|
129
128
|
template<typename A>
|
|
@@ -141,11 +140,6 @@ hll_mode HllSketchImpl<A>::getCurMode() const {
|
|
|
141
140
|
return mode_;
|
|
142
141
|
}
|
|
143
142
|
|
|
144
|
-
template<typename A>
|
|
145
|
-
bool HllSketchImpl<A>::isStartFullSize() const {
|
|
146
|
-
return startFullSize_;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
143
|
}
|
|
150
144
|
|
|
151
145
|
#endif // _HLLSKETCHIMPL_INTERNAL_HPP_
|
|
@@ -32,7 +32,7 @@ class HllSketchImpl {
|
|
|
32
32
|
public:
|
|
33
33
|
using vector_bytes = std::vector<uint8_t, typename std::allocator_traits<A>::template rebind_alloc<uint8_t>>;
|
|
34
34
|
|
|
35
|
-
HllSketchImpl(uint8_t lgConfigK, target_hll_type tgtHllType, hll_mode mode
|
|
35
|
+
HllSketchImpl(uint8_t lgConfigK, target_hll_type tgtHllType, hll_mode mode);
|
|
36
36
|
virtual ~HllSketchImpl();
|
|
37
37
|
|
|
38
38
|
virtual void serialize(std::ostream& os, bool compact) const = 0;
|
|
@@ -40,7 +40,7 @@ class HllSketchImpl {
|
|
|
40
40
|
|
|
41
41
|
virtual HllSketchImpl* copy() const = 0;
|
|
42
42
|
virtual HllSketchImpl* copyAs(target_hll_type tgtHllType) const = 0;
|
|
43
|
-
HllSketchImpl<A>* reset();
|
|
43
|
+
HllSketchImpl<A>* reset(bool full_size);
|
|
44
44
|
|
|
45
45
|
virtual std::function<void(HllSketchImpl<A>*)> get_deleter() const = 0;
|
|
46
46
|
|
|
@@ -69,7 +69,6 @@ class HllSketchImpl {
|
|
|
69
69
|
virtual bool isOutOfOrderFlag() const = 0;
|
|
70
70
|
virtual void putOutOfOrderFlag(bool oooFlag) = 0;
|
|
71
71
|
virtual A getAllocator() const = 0;
|
|
72
|
-
bool isStartFullSize() const;
|
|
73
72
|
|
|
74
73
|
protected:
|
|
75
74
|
static target_hll_type extractTgtHllType(uint8_t modeByte);
|
|
@@ -80,7 +79,6 @@ class HllSketchImpl {
|
|
|
80
79
|
const uint8_t lgConfigK_;
|
|
81
80
|
const target_hll_type tgtHllType_;
|
|
82
81
|
const hll_mode mode_;
|
|
83
|
-
const bool startFullSize_;
|
|
84
82
|
};
|
|
85
83
|
|
|
86
84
|
}
|
|
@@ -41,10 +41,11 @@ public:
|
|
|
41
41
|
|
|
42
42
|
static CouponHashSet<A>* promoteListToSet(const CouponList<A>& list);
|
|
43
43
|
static HllArray<A>* promoteListOrSetToHll(const CouponList<A>& list);
|
|
44
|
-
static HllArray<A>* newHll(uint8_t lgConfigK, target_hll_type tgtHllType,
|
|
44
|
+
static HllArray<A>* newHll(uint8_t lgConfigK, target_hll_type tgtHllType, const A& allocator);
|
|
45
45
|
|
|
46
46
|
// resets the input impl, deleting the input pointer and returning a new pointer
|
|
47
|
-
|
|
47
|
+
// full_size selects the state to reset to: an empty HLL array, or LIST (coupon) mode
|
|
48
|
+
static HllSketchImpl<A>* reset(HllSketchImpl<A>* impl, bool full_size);
|
|
48
49
|
|
|
49
50
|
static Hll4Array<A>* convertToHll4(const HllArray<A>& srcHllArr);
|
|
50
51
|
static Hll6Array<A>* convertToHll6(const HllArray<A>& srcHllArr);
|
|
@@ -63,7 +64,7 @@ CouponHashSet<A>* HllSketchImplFactory<A>::promoteListToSet(const CouponList<A>&
|
|
|
63
64
|
|
|
64
65
|
template<typename A>
|
|
65
66
|
HllArray<A>* HllSketchImplFactory<A>::promoteListOrSetToHll(const CouponList<A>& src) {
|
|
66
|
-
HllArray<A>* tgtHllArr = HllSketchImplFactory<A>::newHll(src.getLgConfigK(), src.getTgtHllType(),
|
|
67
|
+
HllArray<A>* tgtHllArr = HllSketchImplFactory<A>::newHll(src.getLgConfigK(), src.getTgtHllType(), src.getAllocator());
|
|
67
68
|
tgtHllArr->putKxQ0(1 << src.getLgConfigK());
|
|
68
69
|
for (const auto coupon: src) {
|
|
69
70
|
tgtHllArr->couponUpdate(coupon);
|
|
@@ -105,25 +106,25 @@ HllSketchImpl<A>* HllSketchImplFactory<A>::deserialize(const void* bytes, size_t
|
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
template<typename A>
|
|
108
|
-
HllArray<A>* HllSketchImplFactory<A>::newHll(uint8_t lgConfigK, target_hll_type tgtHllType,
|
|
109
|
+
HllArray<A>* HllSketchImplFactory<A>::newHll(uint8_t lgConfigK, target_hll_type tgtHllType, const A& allocator) {
|
|
109
110
|
switch (tgtHllType) {
|
|
110
111
|
case HLL_8:
|
|
111
112
|
using Hll8Alloc = typename std::allocator_traits<A>::template rebind_alloc<Hll8Array<A>>;
|
|
112
|
-
return new (Hll8Alloc(allocator).allocate(1)) Hll8Array<A>(lgConfigK,
|
|
113
|
+
return new (Hll8Alloc(allocator).allocate(1)) Hll8Array<A>(lgConfigK, allocator);
|
|
113
114
|
case HLL_6:
|
|
114
115
|
using Hll6Alloc = typename std::allocator_traits<A>::template rebind_alloc<Hll6Array<A>>;
|
|
115
|
-
return new (Hll6Alloc(allocator).allocate(1)) Hll6Array<A>(lgConfigK,
|
|
116
|
+
return new (Hll6Alloc(allocator).allocate(1)) Hll6Array<A>(lgConfigK, allocator);
|
|
116
117
|
case HLL_4:
|
|
117
118
|
using Hll4Alloc = typename std::allocator_traits<A>::template rebind_alloc<Hll4Array<A>>;
|
|
118
|
-
return new (Hll4Alloc(allocator).allocate(1)) Hll4Array<A>(lgConfigK,
|
|
119
|
+
return new (Hll4Alloc(allocator).allocate(1)) Hll4Array<A>(lgConfigK, allocator);
|
|
119
120
|
}
|
|
120
121
|
throw std::logic_error("Invalid target_hll_type");
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
template<typename A>
|
|
124
|
-
HllSketchImpl<A>* HllSketchImplFactory<A>::reset(HllSketchImpl<A>* impl, bool
|
|
125
|
-
if (
|
|
126
|
-
HllArray<A>* hll = newHll(impl->getLgConfigK(), impl->getTgtHllType(),
|
|
125
|
+
HllSketchImpl<A>* HllSketchImplFactory<A>::reset(HllSketchImpl<A>* impl, bool full_size) {
|
|
126
|
+
if (full_size) {
|
|
127
|
+
HllArray<A>* hll = newHll(impl->getLgConfigK(), impl->getTgtHllType(), impl->getAllocator());
|
|
127
128
|
impl->get_deleter()(impl);
|
|
128
129
|
return hll;
|
|
129
130
|
} else {
|
|
@@ -39,18 +39,21 @@ hll_union_alloc<A>::hll_union_alloc(uint8_t lg_max_k, const A& allocator):
|
|
|
39
39
|
|
|
40
40
|
template<typename A>
|
|
41
41
|
hll_sketch_alloc<A> hll_union_alloc<A>::get_result(target_hll_type target_type) const {
|
|
42
|
+
if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL) {
|
|
43
|
+
static_cast<HllArray<A>*>(gadget_.sketch_impl)->check_rebuild_kxq_cur_min();
|
|
44
|
+
}
|
|
42
45
|
return hll_sketch_alloc<A>(gadget_, target_type);
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
template<typename A>
|
|
46
49
|
void hll_union_alloc<A>::update(const hll_sketch_alloc<A>& sketch) {
|
|
47
|
-
if (sketch.is_empty()) return;
|
|
50
|
+
if (sketch.is_empty()) { return; }
|
|
48
51
|
union_impl(sketch, lg_max_k_);
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
template<typename A>
|
|
52
55
|
void hll_union_alloc<A>::update(hll_sketch_alloc<A>&& sketch) {
|
|
53
|
-
if (sketch.is_empty()) return;
|
|
56
|
+
if (sketch.is_empty()) { return; }
|
|
54
57
|
if (gadget_.is_empty() && sketch.get_target_type() == HLL_8 && sketch.get_lg_config_k() <= lg_max_k_) {
|
|
55
58
|
if (sketch.get_current_mode() == HLL || sketch.get_lg_config_k() == lg_max_k_) {
|
|
56
59
|
gadget_ = std::move(sketch);
|
|
@@ -131,29 +134,33 @@ void hll_union_alloc<A>::coupon_update(uint32_t coupon) {
|
|
|
131
134
|
|
|
132
135
|
template<typename A>
|
|
133
136
|
double hll_union_alloc<A>::get_estimate() const {
|
|
134
|
-
if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL)
|
|
137
|
+
if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL) {
|
|
135
138
|
static_cast<HllArray<A>*>(gadget_.sketch_impl)->check_rebuild_kxq_cur_min();
|
|
139
|
+
}
|
|
136
140
|
return gadget_.get_estimate();
|
|
137
141
|
}
|
|
138
142
|
|
|
139
143
|
template<typename A>
|
|
140
144
|
double hll_union_alloc<A>::get_composite_estimate() const {
|
|
141
|
-
if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL)
|
|
145
|
+
if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL) {
|
|
142
146
|
static_cast<HllArray<A>*>(gadget_.sketch_impl)->check_rebuild_kxq_cur_min();
|
|
147
|
+
}
|
|
143
148
|
return gadget_.get_composite_estimate();
|
|
144
149
|
}
|
|
145
150
|
|
|
146
151
|
template<typename A>
|
|
147
152
|
double hll_union_alloc<A>::get_lower_bound(uint8_t num_std_dev) const {
|
|
148
|
-
if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL)
|
|
153
|
+
if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL) {
|
|
149
154
|
static_cast<HllArray<A>*>(gadget_.sketch_impl)->check_rebuild_kxq_cur_min();
|
|
155
|
+
}
|
|
150
156
|
return gadget_.get_lower_bound(num_std_dev);
|
|
151
157
|
}
|
|
152
158
|
|
|
153
159
|
template<typename A>
|
|
154
160
|
double hll_union_alloc<A>::get_upper_bound(uint8_t num_std_dev) const {
|
|
155
|
-
if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL)
|
|
161
|
+
if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL) {
|
|
156
162
|
static_cast<HllArray<A>*>(gadget_.sketch_impl)->check_rebuild_kxq_cur_min();
|
|
163
|
+
}
|
|
157
164
|
return gadget_.get_upper_bound(num_std_dev);
|
|
158
165
|
}
|
|
159
166
|
|
|
@@ -164,7 +171,9 @@ uint8_t hll_union_alloc<A>::get_lg_config_k() const {
|
|
|
164
171
|
|
|
165
172
|
template<typename A>
|
|
166
173
|
void hll_union_alloc<A>::reset() {
|
|
167
|
-
|
|
174
|
+
// always coupon collection mode: the gadget is an internal detail and must not
|
|
175
|
+
// inherit a full-size state from whatever sketches happen to have been unioned in
|
|
176
|
+
gadget_.reset(false);
|
|
168
177
|
}
|
|
169
178
|
|
|
170
179
|
template<typename A>
|
|
@@ -209,7 +218,7 @@ HllSketchImpl<A>* hll_union_alloc<A>::copy_or_downsample(const HllSketchImpl<A>*
|
|
|
209
218
|
return src->copyAs(HLL_8);
|
|
210
219
|
}
|
|
211
220
|
typedef typename std::allocator_traits<A>::template rebind_alloc<Hll8Array<A>> hll8Alloc;
|
|
212
|
-
Hll8Array<A>* tgtHllArr = new (hll8Alloc(src->getAllocator()).allocate(1)) Hll8Array<A>(tgt_lg_k,
|
|
221
|
+
Hll8Array<A>* tgtHllArr = new (hll8Alloc(src->getAllocator()).allocate(1)) Hll8Array<A>(tgt_lg_k, src->getAllocator());
|
|
213
222
|
tgtHllArr->mergeHll(*src);
|
|
214
223
|
//both of these are required for isomorphism
|
|
215
224
|
tgtHllArr->putHipAccum(src->getHipAccum());
|