20#ifndef _HLLUNION_INTERNAL_HPP_
21#define _HLLUNION_INTERNAL_HPP_
25#include "HllSketchImpl.hpp"
26#include "HllArray.hpp"
36 lg_max_k_(HllUtil<A>::checkLgK(lg_max_k)),
42 if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL) {
43 static_cast<HllArray<A>*
>(gadget_.sketch_impl)->check_rebuild_kxq_cur_min();
45 return hll_sketch_alloc<A>(gadget_, target_type);
50 if (sketch.is_empty()) {
return; }
51 union_impl(sketch, lg_max_k_);
56 if (sketch.is_empty()) {
return; }
58 if (gadget_.is_empty() && sketch.get_target_type() ==
HLL_8 && sketch.get_lg_config_k() <= lg_max_k_
59 && sketch.sketch_impl->getAllocator() == gadget_.sketch_impl->getAllocator()) {
60 if (sketch.get_current_mode() == HLL || sketch.get_lg_config_k() == lg_max_k_) {
61 gadget_ = std::move(sketch);
64 union_impl(sketch, lg_max_k_);
69 gadget_.update(datum);
74 gadget_.update(datum);
79 gadget_.update(datum);
84 gadget_.update(datum);
89 gadget_.update(datum);
94 gadget_.update(datum);
99 gadget_.update(datum);
104 gadget_.update(datum);
109 gadget_.update(datum);
114 gadget_.update(datum);
119 gadget_.update(datum);
124 gadget_.update(data, length_bytes);
128void hll_union_alloc<A>::coupon_update(uint32_t coupon) {
129 if (coupon == HllUtil<A>::EMPTY) {
return; }
130 HllSketchImpl<A>* result = gadget_.sketch_impl->coupon_update(coupon);
131 if (result != gadget_.sketch_impl) {
132 if (gadget_.sketch_impl !=
nullptr) { gadget_.sketch_impl->get_deleter()(gadget_.sketch_impl); }
133 gadget_.sketch_impl = result;
139 if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL) {
140 static_cast<HllArray<A>*
>(gadget_.sketch_impl)->check_rebuild_kxq_cur_min();
142 return gadget_.get_estimate();
147 if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL) {
148 static_cast<HllArray<A>*
>(gadget_.sketch_impl)->check_rebuild_kxq_cur_min();
150 return gadget_.get_composite_estimate();
155 if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL) {
156 static_cast<HllArray<A>*
>(gadget_.sketch_impl)->check_rebuild_kxq_cur_min();
158 return gadget_.get_lower_bound(num_std_dev);
163 if (gadget_.sketch_impl->getCurMode() == hll_mode::HLL) {
164 static_cast<HllArray<A>*
>(gadget_.sketch_impl)->check_rebuild_kxq_cur_min();
166 return gadget_.get_upper_bound(num_std_dev);
171 return gadget_.get_lg_config_k();
178 gadget_.reset(
false);
183 return gadget_.is_empty();
187bool hll_union_alloc<A>::is_out_of_order_flag()
const {
188 return gadget_.is_out_of_order_flag();
192hll_mode hll_union_alloc<A>::get_current_mode()
const {
193 return gadget_.get_current_mode();
197bool hll_union_alloc<A>::is_estimation_mode()
const {
198 return gadget_.is_estimation_mode();
208 uint8_t lg_config_k, uint8_t num_std_dev) {
209 return HllUtil<A>::getRelErr(upper_bound, unioned, lg_config_k, num_std_dev);
214 const A& allocator) {
215 if (src_impl->getCurMode() != HLL) {
216 throw std::logic_error(
"Attempt to downsample non-HLL sketch");
218 const HllArray<A>* src =
static_cast<const HllArray<A>*
>(src_impl);
219 const uint8_t src_lg_k = src->getLgConfigK();
221 if (src_lg_k <= tgt_lg_k && src->getAllocator() == allocator) {
222 return src->copyAs(
HLL_8);
224 typedef typename std::allocator_traits<A>::template rebind_alloc<Hll8Array<A>> hll8Alloc;
225 const uint8_t lg_k = std::min(src_lg_k, tgt_lg_k);
226 Hll8Array<A>* tgtHllArr =
new (hll8Alloc(allocator).allocate(1)) Hll8Array<A>(lg_k, allocator);
227 tgtHllArr->mergeHll(*src);
229 tgtHllArr->putHipAccum(src->getHipAccum());
230 tgtHllArr->putOutOfOrderFlag(src->isOutOfOrderFlag());
237 if (result != impl) {
238 impl->get_deleter()(impl);
244void hll_union_alloc<A>::union_impl(
const hll_sketch_alloc<A>& sketch, uint8_t lg_max_k) {
249 const A allocator = dst_impl->getAllocator();
250 if (src_impl->getCurMode() == LIST || src_impl->getCurMode() == SET) {
251 if (dst_impl->isEmpty() && src_impl->getLgConfigK() == dst_impl->getLgConfigK()
252 && src_impl->getAllocator() == allocator) {
253 dst_impl = src_impl->copyAs(
HLL_8);
254 gadget_.sketch_impl->get_deleter()(gadget_.sketch_impl);
256 const CouponList<A>* src =
static_cast<const CouponList<A>*
>(src_impl);
257 for (
auto coupon: *src) {
258 dst_impl = leak_free_coupon_update(dst_impl, coupon);
261 }
else if (!dst_impl->isEmpty()) {
262 if (dst_impl->getCurMode() == LIST || dst_impl->getCurMode() == SET) {
265 const CouponList<A>* src =
static_cast<const CouponList<A>*
>(dst_impl);
266 dst_impl = copy_or_downsample(src_impl, lg_max_k, allocator);
267 static_cast<Hll8Array<A>*
>(dst_impl)->mergeList(*src);
268 gadget_.sketch_impl->get_deleter()(gadget_.sketch_impl);
270 if (src_impl->getLgConfigK() < dst_impl->getLgConfigK()) {
271 dst_impl = copy_or_downsample(dst_impl, sketch.get_lg_config_k(), allocator);
272 gadget_.sketch_impl->get_deleter()(gadget_.sketch_impl);
274 const HllArray<A>* src =
static_cast<const HllArray<A>*
>(src_impl);
275 static_cast<Hll8Array<A>*
>(dst_impl)->mergeHll(*src);
276 dst_impl->putOutOfOrderFlag(
true);
277 static_cast<Hll8Array<A>*
>(dst_impl)->putHipAccum(0);
280 dst_impl = copy_or_downsample(src_impl, lg_max_k, allocator);
281 gadget_.sketch_impl->get_deleter()(gadget_.sketch_impl);
283 gadget_.sketch_impl = dst_impl;
This is a high performance implementation of Phillipe Flajolet's HLL sketch but with significantly im...
Definition HllSketchImpl.hpp:31
target_hll_type get_target_type() const
Returns the union's target HLL mode (from target_hll_type).
Definition HllUnion-internal.hpp:202
double get_composite_estimate() const
This is less accurate than the get_estimate() method and is automatically used when the union has gon...
Definition HllUnion-internal.hpp:146
double get_estimate() const
Returns the current cardinality estimate.
Definition HllUnion-internal.hpp:138
void update(const hll_sketch_alloc< A > &sketch)
Update this union operator with the given sketch.
Definition HllUnion-internal.hpp:49
hll_sketch_alloc< A > get_result(target_hll_type tgt_type=HLL_4) const
Returns the result of this union operator with the specified target_hll_type.
Definition HllUnion-internal.hpp:41
bool is_empty() const
Indicates if the union is currently empty.
Definition HllUnion-internal.hpp:182
uint8_t get_lg_config_k() const
Returns union's configured lg_k value.
Definition HllUnion-internal.hpp:170
double get_lower_bound(uint8_t num_std_dev) const
Returns the approximate lower error bound given the specified number of standard deviations.
Definition HllUnion-internal.hpp:154
hll_union_alloc(uint8_t lg_max_k, const A &allocator=A())
Construct an hll_union operator with the given maximum log2 of k.
Definition HllUnion-internal.hpp:35
void reset()
Resets the union to an empty state in coupon collection mode.
Definition HllUnion-internal.hpp:175
static double get_rel_err(bool upper_bound, bool unioned, uint8_t lg_config_k, uint8_t num_std_dev)
Gets the current (approximate) Relative Error (RE) asymptotic values given several parameters.
Definition HllUnion-internal.hpp:207
double get_upper_bound(uint8_t num_std_dev) const
Returns the approximate upper error bound given the specified number of standard deviations.
Definition HllUnion-internal.hpp:162
DataSketches namespace.
Definition binomial_bounds.hpp:38
target_hll_type
Specifies the target type of HLL sketch to be created.
Definition hll.hpp:72
@ HLL_8
8 bits per entry (fastest, fixed size)
Definition hll.hpp:75