20 #ifndef _HLLSKETCH_INTERNAL_HPP_
21 #define _HLLSKETCH_INTERNAL_HPP_
24 #include "HllUtil.hpp"
25 #include "HllSketchImplFactory.hpp"
26 #include "CouponList.hpp"
27 #include "HllArray.hpp"
28 #include "common_defs.hpp"
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 HllUtil<A>::checkLgK(lg_config_k);
47 if (start_full_size) {
48 sketch_impl = HllSketchImplFactory<A>::newHll(lg_config_k, tgt_type, start_full_size, 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);
56 hll_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);
62 hll_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);
68 hll_sketch_alloc<A>::~hll_sketch_alloc() {
69 if (sketch_impl !=
nullptr) {
70 sketch_impl->get_deleter()(sketch_impl);
75 hll_sketch_alloc<A>::hll_sketch_alloc(
const hll_sketch_alloc<A>& that) :
76 sketch_impl(that.sketch_impl->copy())
80 hll_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))
85 hll_sketch_alloc<A>::hll_sketch_alloc(hll_sketch_alloc<A>&& that) noexcept :
88 std::swap(sketch_impl, that.sketch_impl);
92 hll_sketch_alloc<A>::hll_sketch_alloc(HllSketchImpl<A>* that) :
97 hll_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();
104 hll_sketch_alloc<A>& hll_sketch_alloc<A>::operator=(hll_sketch_alloc<A>&& other) {
105 std::swap(sketch_impl, other.sketch_impl);
110 void hll_sketch_alloc<A>::reset() {
113 sketch_impl = sketch_impl->reset();
117 void hll_sketch_alloc<A>::update(
const std::string& datum) {
118 if (datum.empty()) {
return; }
119 HashState hashResult;
120 HllUtil<A>::hash(datum.c_str(), datum.length(), DEFAULT_SEED, hashResult);
121 coupon_update(HllUtil<A>::coupon(hashResult));
125 void hll_sketch_alloc<A>::update(uint64_t datum) {
127 HashState hashResult;
128 HllUtil<A>::hash(&datum,
sizeof(uint64_t), DEFAULT_SEED, hashResult);
129 coupon_update(HllUtil<A>::coupon(hashResult));
133 void hll_sketch_alloc<A>::update(uint32_t datum) {
134 update(
static_cast<int32_t
>(datum));
138 void hll_sketch_alloc<A>::update(uint16_t datum) {
139 update(
static_cast<int16_t
>(datum));
143 void hll_sketch_alloc<A>::update(uint8_t datum) {
144 update(
static_cast<int8_t
>(datum));
148 void hll_sketch_alloc<A>::update(int64_t datum) {
149 HashState hashResult;
150 HllUtil<A>::hash(&datum,
sizeof(int64_t), DEFAULT_SEED, hashResult);
151 coupon_update(HllUtil<A>::coupon(hashResult));
155 void hll_sketch_alloc<A>::update(int32_t datum) {
156 const int64_t val =
static_cast<int64_t
>(datum);
157 HashState hashResult;
158 HllUtil<A>::hash(&val,
sizeof(int64_t), DEFAULT_SEED, hashResult);
159 coupon_update(HllUtil<A>::coupon(hashResult));
163 void hll_sketch_alloc<A>::update(int16_t datum) {
164 const int64_t val =
static_cast<int64_t
>(datum);
165 HashState hashResult;
166 HllUtil<A>::hash(&val,
sizeof(int64_t), DEFAULT_SEED, hashResult);
167 coupon_update(HllUtil<A>::coupon(hashResult));
171 void hll_sketch_alloc<A>::update(int8_t datum) {
172 const int64_t val =
static_cast<int64_t
>(datum);
173 HashState hashResult;
174 HllUtil<A>::hash(&val,
sizeof(int64_t), DEFAULT_SEED, hashResult);
175 coupon_update(HllUtil<A>::coupon(hashResult));
179 void hll_sketch_alloc<A>::update(
double datum) {
181 d.doubleBytes =
static_cast<double>(datum);
184 }
else if (std::isnan(d.doubleBytes)) {
185 d.longBytes = 0x7ff8000000000000L;
187 HashState hashResult;
188 HllUtil<A>::hash(&d,
sizeof(
double), DEFAULT_SEED, hashResult);
189 coupon_update(HllUtil<A>::coupon(hashResult));
193 void hll_sketch_alloc<A>::update(
float datum) {
195 d.doubleBytes =
static_cast<double>(datum);
198 }
else if (std::isnan(d.doubleBytes)) {
199 d.longBytes = 0x7ff8000000000000L;
201 HashState hashResult;
202 HllUtil<A>::hash(&d,
sizeof(
double), DEFAULT_SEED, hashResult);
203 coupon_update(HllUtil<A>::coupon(hashResult));
207 void hll_sketch_alloc<A>::update(
const void* data,
size_t lengthBytes) {
208 if (data ==
nullptr) {
return; }
209 HashState hashResult;
210 HllUtil<A>::hash(data, lengthBytes, DEFAULT_SEED, hashResult);
211 coupon_update(HllUtil<A>::coupon(hashResult));
215 void hll_sketch_alloc<A>::coupon_update(uint32_t coupon) {
216 if (coupon == hll_constants::EMPTY) {
return; }
217 HllSketchImpl<A>* result = this->sketch_impl->couponUpdate(coupon);
218 if (result != this->sketch_impl) {
219 this->sketch_impl->get_deleter()(this->sketch_impl);
220 this->sketch_impl = result;
225 void hll_sketch_alloc<A>::serialize_compact(std::ostream& os)
const {
226 return sketch_impl->serialize(os,
true);
230 void hll_sketch_alloc<A>::serialize_updatable(std::ostream& os)
const {
231 return sketch_impl->serialize(os,
false);
235 auto hll_sketch_alloc<A>::serialize_compact(
unsigned header_size_bytes)
const -> vector_bytes {
236 return sketch_impl->serialize(
true, header_size_bytes);
240 auto hll_sketch_alloc<A>::serialize_updatable() const -> vector_bytes {
241 return sketch_impl->serialize(
false, 0);
245 string<A> hll_sketch_alloc<A>::to_string(
const bool summary,
247 const bool aux_detail,
248 const bool all)
const {
251 std::stringstream os;
253 os <<
"### HLL sketch summary:" << std::endl
254 <<
" Log Config K : " << std::to_string(get_lg_config_k()) << std::endl
255 <<
" Hll Target : " << type_as_string() << std::endl
256 <<
" Current Mode : " << mode_as_string() << std::endl
257 <<
" LB : " << get_lower_bound(1) << std::endl
258 <<
" Estimate : " << get_estimate() << std::endl
259 <<
" UB : " << get_upper_bound(1) << std::endl
260 <<
" OutOfOrder flag: " << (is_out_of_order_flag() ?
"true" :
"false") << std::endl;
261 if (get_current_mode() == HLL) {
262 HllArray<A>* hllArray = (HllArray<A>*) sketch_impl;
263 os <<
" CurMin : " << std::to_string(hllArray->getCurMin()) << std::endl
264 <<
" NumAtCurMin : " << hllArray->getNumAtCurMin() << std::endl
265 <<
" HipAccum : " << hllArray->getHipAccum() << std::endl
266 <<
" KxQ0 : " << hllArray->getKxQ0() << std::endl
267 <<
" KxQ1 : " << hllArray->getKxQ1() << std::endl;
268 if (get_target_type() == HLL_4) {
269 const Hll4Array<A>* hll4_ptr =
static_cast<const Hll4Array<A>*
>(sketch_impl);
270 os <<
" Aux table? : " << (hll4_ptr->getAuxHashMap() !=
nullptr ?
"true" :
"false") << std::endl;
273 os <<
" Coupon count : "
274 << std::to_string(((CouponList<A>*) sketch_impl)->getCouponCount()) << std::endl;
276 os <<
"### End HLL sketch summary" << std::endl;
280 os <<
"### HLL sketch data detail:" << std::endl;
281 if (get_current_mode() == HLL) {
282 const HllArray<A>* hll_ptr =
static_cast<const HllArray<A>*
>(sketch_impl);
283 os << std::left << std::setw(10) <<
"Slot" << std::setw(6) <<
"Value" << std::endl;
284 auto it = hll_ptr->begin(all);
285 while (it != hll_ptr->end()) {
286 os << std::setw(10) << HllUtil<A>::getLow26(*it);
287 os << std::setw(6) << HllUtil<A>::getValue(*it);
292 const CouponList<A>* list_ptr =
static_cast<const CouponList<A>*
>(sketch_impl);
294 os << std::setw(10) <<
"Index";
295 os << std::setw(10) <<
"Key";
296 os << std::setw(10) <<
"Slot";
297 os << std::setw(6) <<
"Value";
299 auto it = list_ptr->begin(all);
301 int mask = (1 << get_lg_config_k()) - 1;
302 while (it != list_ptr->end()) {
303 os << std::setw(10) << i;
304 os << std::setw(10) << HllUtil<A>::getLow26(*it);
305 os << std::setw(10) << (HllUtil<A>::getLow26(*it) & mask);
306 os << std::setw(6) << HllUtil<A>::getValue(*it);
312 os <<
"### End HLL sketch data detail" << std::endl;
315 if ((get_current_mode() == HLL) && (get_target_type() == HLL_4)) {
316 const Hll4Array<A>* hll4_ptr =
static_cast<const Hll4Array<A>*
>(sketch_impl);
317 const AuxHashMap<A>* aux_ptr = hll4_ptr->getAuxHashMap();
318 if (aux_ptr !=
nullptr) {
319 os <<
"### HLL sketch aux detail:" << std::endl;
321 os << std::setw(10) <<
"Index";
322 os << std::setw(10) <<
"Key";
323 os << std::setw(10) <<
"Slot";
324 os << std::setw(6) <<
"Value";
326 auto it = aux_ptr->begin(all);
328 int mask = (1 << get_lg_config_k()) - 1;
329 while (it != aux_ptr->end()) {
330 os << std::setw(10) << i;
331 os << std::setw(10) << HllUtil<A>::getLow26(*it);
332 os << std::setw(10) << (HllUtil<A>::getLow26(*it) & mask);
333 os << std::setw(6) << HllUtil<A>::getValue(*it);
338 os <<
"### End HLL sketch aux detail" << std::endl;
343 return string<A>(os.str().c_str(), sketch_impl->getAllocator());
347 double hll_sketch_alloc<A>::get_estimate()
const {
348 return sketch_impl->getEstimate();
352 double hll_sketch_alloc<A>::get_composite_estimate()
const {
353 return sketch_impl->getCompositeEstimate();
357 double hll_sketch_alloc<A>::get_lower_bound(uint8_t numStdDev)
const {
358 return sketch_impl->getLowerBound(numStdDev);
362 double hll_sketch_alloc<A>::get_upper_bound(uint8_t numStdDev)
const {
363 return sketch_impl->getUpperBound(numStdDev);
367 hll_mode hll_sketch_alloc<A>::get_current_mode()
const {
368 return sketch_impl->getCurMode();
372 uint8_t hll_sketch_alloc<A>::get_lg_config_k()
const {
373 return sketch_impl->getLgConfigK();
378 return sketch_impl->getTgtHllType();
382 bool hll_sketch_alloc<A>::is_out_of_order_flag()
const {
383 return sketch_impl->isOutOfOrderFlag();
387 bool hll_sketch_alloc<A>::is_estimation_mode()
const {
392 uint32_t hll_sketch_alloc<A>::get_updatable_serialization_bytes()
const {
393 return sketch_impl->getUpdatableSerializationBytes();
397 uint32_t hll_sketch_alloc<A>::get_compact_serialization_bytes()
const {
398 return sketch_impl->getCompactSerializationBytes();
402 bool hll_sketch_alloc<A>::is_compact()
const {
403 return sketch_impl->isCompact();
407 bool hll_sketch_alloc<A>::is_empty()
const {
408 return sketch_impl->isEmpty();
412 std::string hll_sketch_alloc<A>::type_as_string()
const {
413 switch (sketch_impl->getTgtHllType()) {
414 case target_hll_type::HLL_4:
415 return std::string(
"HLL_4");
416 case target_hll_type::HLL_6:
417 return std::string(
"HLL_6");
418 case target_hll_type::HLL_8:
419 return std::string(
"HLL_8");
421 throw std::runtime_error(
"Sketch state error: Invalid target_hll_type");
426 std::string hll_sketch_alloc<A>::mode_as_string()
const {
427 switch (sketch_impl->getCurMode()) {
429 return std::string(
"LIST");
431 return std::string(
"SET");
433 return std::string(
"HLL");
435 throw std::runtime_error(
"Sketch state error: Invalid hll_mode");
440 uint32_t hll_sketch_alloc<A>::get_max_updatable_serialization_bytes(uint8_t lg_config_k,
441 const target_hll_type tgtHllType) {
443 if (tgtHllType == target_hll_type::HLL_4) {
444 const uint32_t auxBytes = 4 << hll_constants::LG_AUX_ARR_INTS[lg_config_k];
445 arrBytes = HllArray<A>::hll4ArrBytes(lg_config_k) + auxBytes;
446 }
else if (tgtHllType == target_hll_type::HLL_6) {
447 arrBytes = HllArray<A>::hll6ArrBytes(lg_config_k);
449 arrBytes = HllArray<A>::hll8ArrBytes(lg_config_k);
451 return hll_constants::HLL_BYTE_ARR_START + arrBytes;
455 double hll_sketch_alloc<A>::get_rel_err(
bool upperBound,
bool unioned,
456 uint8_t lg_config_k, uint8_t numStdDev) {
457 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