20#ifndef _HLLSKETCH_INTERNAL_HPP_
21#define _HLLSKETCH_INTERNAL_HPP_
25#include "HllSketchImplFactory.hpp"
26#include "CouponList.hpp"
27#include "HllArray.hpp"
28#include "common_defs.hpp"
45hll_sketch_alloc<A>::hll_sketch_alloc(uint8_t lg_config_k,
target_hll_type tgt_type,
bool start_full_size,
const A& allocator) {
46 HllUtil<A>::checkLgK(lg_config_k);
47 if (start_full_size) {
48 sketch_impl = HllSketchImplFactory<A>::newHll(lg_config_k, tgt_type, allocator);
50 typedef typename std::allocator_traits<A>::template rebind_alloc<CouponList<A>> clAlloc;
51 sketch_impl =
new (clAlloc(allocator).allocate(1)) CouponList<A>(lg_config_k, tgt_type, hll_mode::LIST, allocator);
56hll_sketch_alloc<A> hll_sketch_alloc<A>::deserialize(std::istream& is,
const A& allocator) {
57 HllSketchImpl<A>* impl = HllSketchImplFactory<A>::deserialize(is, allocator);
58 return hll_sketch_alloc<A>(impl);
62hll_sketch_alloc<A> hll_sketch_alloc<A>::deserialize(
const void* bytes,
size_t len,
const A& allocator) {
63 HllSketchImpl<A>* impl = HllSketchImplFactory<A>::deserialize(bytes, len, allocator);
64 return hll_sketch_alloc<A>(impl);
68hll_sketch_alloc<A>::~hll_sketch_alloc() {
69 if (sketch_impl !=
nullptr) {
70 sketch_impl->get_deleter()(sketch_impl);
75hll_sketch_alloc<A>::hll_sketch_alloc(
const hll_sketch_alloc<A>& that) :
76 sketch_impl(that.sketch_impl->copy())
80hll_sketch_alloc<A>::hll_sketch_alloc(
const hll_sketch_alloc<A>& that, target_hll_type tgt_type) :
81 sketch_impl(that.sketch_impl->copyAs(tgt_type))
85hll_sketch_alloc<A>::hll_sketch_alloc(hll_sketch_alloc<A>&& that) noexcept :
88 std::swap(sketch_impl, that.sketch_impl);
92hll_sketch_alloc<A>::hll_sketch_alloc(HllSketchImpl<A>* that) :
97hll_sketch_alloc<A>& hll_sketch_alloc<A>::operator=(
const hll_sketch_alloc<A>& other) {
98 sketch_impl->get_deleter()(sketch_impl);
99 sketch_impl = other.sketch_impl->copy();
104hll_sketch_alloc<A>& hll_sketch_alloc<A>::operator=(hll_sketch_alloc<A>&& other) {
105 std::swap(sketch_impl, other.sketch_impl);
110void hll_sketch_alloc<A>::reset(
bool full_size) {
111 sketch_impl = sketch_impl->reset(full_size);
115void hll_sketch_alloc<A>::update(
const std::string& datum) {
116 if (datum.empty()) {
return; }
117 HashState hashResult;
118 HllUtil<A>::hash(datum.c_str(), datum.length(), DEFAULT_SEED, hashResult);
119 coupon_update(HllUtil<A>::coupon(hashResult));
123void hll_sketch_alloc<A>::update(uint64_t datum) {
125 HashState hashResult;
126 HllUtil<A>::hash(&datum,
sizeof(uint64_t), DEFAULT_SEED, hashResult);
127 coupon_update(HllUtil<A>::coupon(hashResult));
131void hll_sketch_alloc<A>::update(uint32_t datum) {
132 update(
static_cast<int32_t
>(datum));
136void hll_sketch_alloc<A>::update(uint16_t datum) {
137 update(
static_cast<int16_t
>(datum));
141void hll_sketch_alloc<A>::update(uint8_t datum) {
142 update(
static_cast<int8_t
>(datum));
146void hll_sketch_alloc<A>::update(int64_t datum) {
147 HashState hashResult;
148 HllUtil<A>::hash(&datum,
sizeof(int64_t), DEFAULT_SEED, hashResult);
149 coupon_update(HllUtil<A>::coupon(hashResult));
153void hll_sketch_alloc<A>::update(int32_t datum) {
154 const int64_t val =
static_cast<int64_t
>(datum);
155 HashState hashResult;
156 HllUtil<A>::hash(&val,
sizeof(int64_t), DEFAULT_SEED, hashResult);
157 coupon_update(HllUtil<A>::coupon(hashResult));
161void hll_sketch_alloc<A>::update(int16_t datum) {
162 const int64_t val =
static_cast<int64_t
>(datum);
163 HashState hashResult;
164 HllUtil<A>::hash(&val,
sizeof(int64_t), DEFAULT_SEED, hashResult);
165 coupon_update(HllUtil<A>::coupon(hashResult));
169void hll_sketch_alloc<A>::update(int8_t datum) {
170 const int64_t val =
static_cast<int64_t
>(datum);
171 HashState hashResult;
172 HllUtil<A>::hash(&val,
sizeof(int64_t), DEFAULT_SEED, hashResult);
173 coupon_update(HllUtil<A>::coupon(hashResult));
177void hll_sketch_alloc<A>::update(
double datum) {
179 d.doubleBytes =
static_cast<double>(datum);
182 }
else if (std::isnan(d.doubleBytes)) {
183 d.longBytes = 0x7ff8000000000000L;
185 HashState hashResult;
186 HllUtil<A>::hash(&d,
sizeof(
double), DEFAULT_SEED, hashResult);
187 coupon_update(HllUtil<A>::coupon(hashResult));
191void hll_sketch_alloc<A>::update(
float datum) {
193 d.doubleBytes =
static_cast<double>(datum);
196 }
else if (std::isnan(d.doubleBytes)) {
197 d.longBytes = 0x7ff8000000000000L;
199 HashState hashResult;
200 HllUtil<A>::hash(&d,
sizeof(
double), DEFAULT_SEED, hashResult);
201 coupon_update(HllUtil<A>::coupon(hashResult));
205void hll_sketch_alloc<A>::update(
const void* data,
size_t lengthBytes) {
206 if (data ==
nullptr) {
return; }
207 HashState hashResult;
208 HllUtil<A>::hash(data, lengthBytes, DEFAULT_SEED, hashResult);
209 coupon_update(HllUtil<A>::coupon(hashResult));
213void hll_sketch_alloc<A>::coupon_update(uint32_t coupon) {
214 if (coupon == hll_constants::EMPTY) {
return; }
215 HllSketchImpl<A>* result = this->sketch_impl->couponUpdate(coupon);
216 if (result != this->sketch_impl) {
217 this->sketch_impl->get_deleter()(this->sketch_impl);
218 this->sketch_impl = result;
223void hll_sketch_alloc<A>::serialize_compact(std::ostream& os)
const {
224 return sketch_impl->serialize(os,
true);
228void hll_sketch_alloc<A>::serialize_updatable(std::ostream& os)
const {
229 return sketch_impl->serialize(os,
false);
233auto hll_sketch_alloc<A>::serialize_compact(
unsigned header_size_bytes)
const -> vector_bytes {
234 return sketch_impl->serialize(
true, header_size_bytes);
238auto hll_sketch_alloc<A>::serialize_updatable() const -> vector_bytes {
239 return sketch_impl->serialize(
false, 0);
243string<A> hll_sketch_alloc<A>::to_string(
const bool summary,
245 const bool aux_detail,
246 const bool all)
const {
249 std::stringstream os;
251 os <<
"### HLL sketch summary:" << std::endl
252 <<
" Log Config K : " << std::to_string(get_lg_config_k()) << std::endl
253 <<
" Hll Target : " << type_as_string() << std::endl
254 <<
" Current Mode : " << mode_as_string() << std::endl
255 <<
" LB : " << get_lower_bound(1) << std::endl
256 <<
" Estimate : " << get_estimate() << std::endl
257 <<
" UB : " << get_upper_bound(1) << std::endl
258 <<
" OutOfOrder flag: " << (is_out_of_order_flag() ?
"true" :
"false") << std::endl;
259 if (get_current_mode() == HLL) {
260 HllArray<A>* hllArray = (HllArray<A>*) sketch_impl;
261 os <<
" CurMin : " << std::to_string(hllArray->getCurMin()) << std::endl
262 <<
" NumAtCurMin : " << hllArray->getNumAtCurMin() << std::endl
263 <<
" HipAccum : " << hllArray->getHipAccum() << std::endl
264 <<
" KxQ0 : " << hllArray->getKxQ0() << std::endl
265 <<
" KxQ1 : " << hllArray->getKxQ1() << std::endl;
266 if (get_target_type() == HLL_4) {
267 const Hll4Array<A>* hll4_ptr =
static_cast<const Hll4Array<A>*
>(sketch_impl);
268 os <<
" Aux table? : " << (hll4_ptr->getAuxHashMap() !=
nullptr ?
"true" :
"false") << std::endl;
271 os <<
" Coupon count : "
272 << std::to_string(((CouponList<A>*) sketch_impl)->getCouponCount()) << std::endl;
274 os <<
"### End HLL sketch summary" << std::endl;
278 os <<
"### HLL sketch data detail:" << std::endl;
279 if (get_current_mode() == HLL) {
280 const HllArray<A>* hll_ptr =
static_cast<const HllArray<A>*
>(sketch_impl);
281 os << std::left << std::setw(10) <<
"Slot" << std::setw(6) <<
"Value" << std::endl;
282 auto it = hll_ptr->begin(all);
283 while (it != hll_ptr->end()) {
284 os << std::setw(10) << HllUtil<A>::getLow26(*it);
285 os << std::setw(6) << HllUtil<A>::getValue(*it);
290 const CouponList<A>* list_ptr =
static_cast<const CouponList<A>*
>(sketch_impl);
292 os << std::setw(10) <<
"Index";
293 os << std::setw(10) <<
"Key";
294 os << std::setw(10) <<
"Slot";
295 os << std::setw(6) <<
"Value";
297 auto it = list_ptr->begin(all);
299 int mask = (1 << get_lg_config_k()) - 1;
300 while (it != list_ptr->end()) {
301 os << std::setw(10) << i;
302 os << std::setw(10) << HllUtil<A>::getLow26(*it);
303 os << std::setw(10) << (HllUtil<A>::getLow26(*it) & mask);
304 os << std::setw(6) << HllUtil<A>::getValue(*it);
310 os <<
"### End HLL sketch data detail" << std::endl;
313 if ((get_current_mode() == HLL) && (get_target_type() == HLL_4)) {
314 const Hll4Array<A>* hll4_ptr =
static_cast<const Hll4Array<A>*
>(sketch_impl);
315 const AuxHashMap<A>* aux_ptr = hll4_ptr->getAuxHashMap();
316 if (aux_ptr !=
nullptr) {
317 os <<
"### HLL sketch aux detail:" << std::endl;
319 os << std::setw(10) <<
"Index";
320 os << std::setw(10) <<
"Key";
321 os << std::setw(10) <<
"Slot";
322 os << std::setw(6) <<
"Value";
324 auto it = aux_ptr->begin(all);
326 int mask = (1 << get_lg_config_k()) - 1;
327 while (it != aux_ptr->end()) {
328 os << std::setw(10) << i;
329 os << std::setw(10) << HllUtil<A>::getLow26(*it);
330 os << std::setw(10) << (HllUtil<A>::getLow26(*it) & mask);
331 os << std::setw(6) << HllUtil<A>::getValue(*it);
336 os <<
"### End HLL sketch aux detail" << std::endl;
341 return string<A>(os.str().c_str(), sketch_impl->getAllocator());
345double hll_sketch_alloc<A>::get_estimate()
const {
346 return sketch_impl->getEstimate();
350double hll_sketch_alloc<A>::get_composite_estimate()
const {
351 return sketch_impl->getCompositeEstimate();
355double hll_sketch_alloc<A>::get_lower_bound(uint8_t numStdDev)
const {
356 return sketch_impl->getLowerBound(numStdDev);
360double hll_sketch_alloc<A>::get_upper_bound(uint8_t numStdDev)
const {
361 return sketch_impl->getUpperBound(numStdDev);
365hll_mode hll_sketch_alloc<A>::get_current_mode()
const {
366 return sketch_impl->getCurMode();
370uint8_t hll_sketch_alloc<A>::get_lg_config_k()
const {
371 return sketch_impl->getLgConfigK();
376 return sketch_impl->getTgtHllType();
380bool hll_sketch_alloc<A>::is_out_of_order_flag()
const {
381 return sketch_impl->isOutOfOrderFlag();
385bool hll_sketch_alloc<A>::is_estimation_mode()
const {
390uint32_t hll_sketch_alloc<A>::get_updatable_serialization_bytes()
const {
391 return sketch_impl->getUpdatableSerializationBytes();
395uint32_t hll_sketch_alloc<A>::get_compact_serialization_bytes()
const {
396 return sketch_impl->getCompactSerializationBytes();
400bool hll_sketch_alloc<A>::is_compact()
const {
401 return sketch_impl->isCompact();
405bool hll_sketch_alloc<A>::is_empty()
const {
406 return sketch_impl->isEmpty();
410std::string hll_sketch_alloc<A>::type_as_string()
const {
411 switch (sketch_impl->getTgtHllType()) {
412 case target_hll_type::HLL_4:
413 return std::string(
"HLL_4");
414 case target_hll_type::HLL_6:
415 return std::string(
"HLL_6");
416 case target_hll_type::HLL_8:
417 return std::string(
"HLL_8");
419 throw std::runtime_error(
"Sketch state error: Invalid target_hll_type");
424std::string hll_sketch_alloc<A>::mode_as_string()
const {
425 switch (sketch_impl->getCurMode()) {
427 return std::string(
"LIST");
429 return std::string(
"SET");
431 return std::string(
"HLL");
433 throw std::runtime_error(
"Sketch state error: Invalid hll_mode");
438uint32_t hll_sketch_alloc<A>::get_max_updatable_serialization_bytes(uint8_t lg_config_k,
439 const target_hll_type tgtHllType) {
441 if (tgtHllType == target_hll_type::HLL_4) {
442 const uint32_t auxBytes = 4 << hll_constants::LG_AUX_ARR_INTS[lg_config_k];
443 arrBytes = HllArray<A>::hll4ArrBytes(lg_config_k) + auxBytes;
444 }
else if (tgtHllType == target_hll_type::HLL_6) {
445 arrBytes = HllArray<A>::hll6ArrBytes(lg_config_k);
447 arrBytes = HllArray<A>::hll8ArrBytes(lg_config_k);
449 return hll_constants::HLL_BYTE_ARR_START + arrBytes;
453double hll_sketch_alloc<A>::get_rel_err(
bool upperBound,
bool unioned,
454 uint8_t lg_config_k, uint8_t numStdDev) {
455 return HllUtil<A>::getRelErr(upperBound, unioned, lg_config_k, numStdDev);
DataSketches namespace.
Definition binomial_bounds.hpp:38
target_hll_type
Specifies the target type of HLL sketch to be created.
Definition hll.hpp:72