20 #ifndef REQ_SKETCH_IMPL_HPP_
21 #define REQ_SKETCH_IMPL_HPP_
28 template<
typename T,
typename C,
typename A>
29 req_sketch<T, C, A>::req_sketch(uint16_t k,
bool hra,
const C& comparator,
const A& allocator):
30 comparator_(comparator),
31 allocator_(allocator),
32 k_(std::max<uint8_t>(static_cast<int>(k) & -2, static_cast<int>(req_constants::
MIN_K))),
37 compactors_(allocator),
45 template<
typename T,
typename C,
typename A>
46 req_sketch<T, C, A>::~req_sketch() {
50 template<
typename T,
typename C,
typename A>
52 comparator_(other.comparator_),
53 allocator_(other.allocator_),
56 max_nom_size_(other.max_nom_size_),
57 num_retained_(other.num_retained_),
59 compactors_(other.compactors_),
60 min_item_(other.min_item_),
61 max_item_(other.max_item_),
65 template<
typename T,
typename C,
typename A>
67 comparator_(std::move(other.comparator_)),
68 allocator_(std::move(other.allocator_)),
71 max_nom_size_(other.max_nom_size_),
72 num_retained_(other.num_retained_),
74 compactors_(std::move(other.compactors_)),
75 min_item_(std::move(other.min_item_)),
76 max_item_(std::move(other.max_item_)),
80 template<
typename T,
typename C,
typename A>
83 std::swap(comparator_, copy.comparator_);
84 std::swap(allocator_, copy.allocator_);
85 std::swap(k_, copy.k_);
86 std::swap(hra_, copy.hra_);
87 std::swap(max_nom_size_, copy.max_nom_size_);
88 std::swap(num_retained_, copy.num_retained_);
89 std::swap(n_, copy.n_);
90 std::swap(compactors_, copy.compactors_);
91 std::swap(min_item_, copy.min_item_);
92 std::swap(max_item_, copy.max_item_);
97 template<
typename T,
typename C,
typename A>
99 std::swap(comparator_, other.comparator_);
100 std::swap(allocator_, other.allocator_);
101 std::swap(k_, other.k_);
102 std::swap(hra_, other.hra_);
103 std::swap(max_nom_size_, other.max_nom_size_);
104 std::swap(num_retained_, other.num_retained_);
105 std::swap(n_, other.n_);
106 std::swap(compactors_, other.compactors_);
107 std::swap(min_item_, other.min_item_);
108 std::swap(max_item_, other.max_item_);
113 template<
typename T,
typename C,
typename A>
114 template<
typename TT,
typename CC,
typename AA>
116 comparator_(comparator),
117 allocator_(allocator),
120 max_nom_size_(other.max_nom_size_),
121 num_retained_(other.num_retained_),
123 compactors_(allocator),
124 min_item_(other.min_item_),
125 max_item_(other.max_item_),
126 sorted_view_(nullptr)
129 std::is_constructible<T, TT>::value,
130 "Type converting constructor requires new type to be constructible from existing type"
132 compactors_.reserve(other.compactors_.size());
133 for (
const auto& compactor: other.compactors_) {
134 compactors_.push_back(req_compactor<T, C, A>(compactor, comparator_, allocator_));
138 template<
typename T,
typename C,
typename A>
143 template<
typename T,
typename C,
typename A>
148 template<
typename T,
typename C,
typename A>
153 template<
typename T,
typename C,
typename A>
158 template<
typename T,
typename C,
typename A>
160 return num_retained_;
163 template<
typename T,
typename C,
typename A>
165 return compactors_.size() > 1;
168 template<
typename T,
typename C,
typename A>
169 template<
typename FwdT>
171 if (!check_update_item(item)) {
return; }
173 min_item_.emplace(item);
174 max_item_.emplace(item);
176 if (comparator_(item, *min_item_)) *min_item_ = item;
177 if (comparator_(*max_item_, item)) *max_item_ = item;
179 compactors_[0].append(std::forward<FwdT>(item));
182 if (num_retained_ == max_nom_size_) compress();
186 template<
typename T,
typename C,
typename A>
187 template<
typename FwdSk>
189 if (is_HRA() != other.
is_HRA())
throw std::invalid_argument(
"merging HRA and LRA is not valid");
192 min_item_.emplace(conditional_forward<FwdSk>(*other.min_item_));
193 max_item_.emplace(conditional_forward<FwdSk>(*other.max_item_));
195 if (comparator_(*other.min_item_, *min_item_)) *min_item_ = conditional_forward<FwdSk>(*other.min_item_);
196 if (comparator_(*max_item_, *other.max_item_)) *max_item_ = conditional_forward<FwdSk>(*other.max_item_);
199 while (get_num_levels() < other.get_num_levels()) grow();
201 for (
size_t i = 0; i < other.get_num_levels(); ++i) {
202 compactors_[i].merge(conditional_forward<FwdSk>(other.compactors_[i]));
205 update_max_nom_size();
206 update_num_retained();
207 if (num_retained_ >= max_nom_size_) compress();
211 template<
typename T,
typename C,
typename A>
213 if (is_empty())
throw std::runtime_error(
"operation is undefined for an empty sketch");
217 template<
typename T,
typename C,
typename A>
219 if (is_empty())
throw std::runtime_error(
"operation is undefined for an empty sketch");
223 template<
typename T,
typename C,
typename A>
228 template<
typename T,
typename C,
typename A>
233 template<
typename T,
typename C,
typename A>
235 if (is_empty())
throw std::runtime_error(
"operation is undefined for an empty sketch");
237 for (
const auto& compactor: compactors_) {
238 weight += compactor.compute_weight(item, inclusive);
240 return static_cast<double>(weight) / n_;
243 template<
typename T,
typename C,
typename A>
245 if (is_empty())
throw std::runtime_error(
"operation is undefined for an empty sketch");
247 return sorted_view_->get_PMF(split_points, size, inclusive);
250 template<
typename T,
typename C,
typename A>
252 if (is_empty())
throw std::runtime_error(
"operation is undefined for an empty sketch");
254 return sorted_view_->get_CDF(split_points, size, inclusive);
257 template<
typename T,
typename C,
typename A>
259 if (is_empty())
throw std::runtime_error(
"operation is undefined for an empty sketch");
260 if ((rank < 0.0) || (rank > 1.0)) {
261 throw std::invalid_argument(
"Normalized rank cannot be less than 0 or greater than 1");
265 return sorted_view_->get_quantile(rank, inclusive);
268 template<
typename T,
typename C,
typename A>
270 if (!compactors_[0].is_sorted()) {
271 const_cast<Compactor&
>(compactors_[0]).sort();
275 for (
auto& compactor: compactors_) {
276 view.add(compactor.begin(), compactor.end(), 1ULL << compactor.get_lg_weight());
279 view.convert_to_cummulative();
283 template<
typename T,
typename C,
typename A>
285 return get_rank_lb(get_k(), get_num_levels(), rank, num_std_dev, get_n(), hra_);
288 template<
typename T,
typename C,
typename A>
290 return get_rank_ub(get_k(), get_num_levels(), rank, num_std_dev, get_n(), hra_);
293 template<
typename T,
typename C,
typename A>
295 return get_rank_lb(k, 2, rank, 1, n, hra);
298 template<
typename T,
typename C,
typename A>
300 if (is_exact_rank(k, num_levels, rank, n, hra))
return rank;
301 const double relative = relative_rse_factor() / k * (hra ? 1.0 - rank : rank);
302 const double fixed = FIXED_RSE_FACTOR / k;
303 const double lb_rel = rank - num_std_dev * relative;
304 const double lb_fix = rank - num_std_dev * fixed;
305 return std::max(lb_rel, lb_fix);
308 template<
typename T,
typename C,
typename A>
309 double req_sketch<T, C, A>::get_rank_ub(uint16_t k, uint8_t num_levels,
double rank, uint8_t num_std_dev, uint64_t n,
bool hra) {
310 if (is_exact_rank(k, num_levels, rank, n, hra))
return rank;
311 const double relative = relative_rse_factor() / k * (hra ? 1.0 - rank : rank);
312 const double fixed = FIXED_RSE_FACTOR / k;
313 const double ub_rel = rank + num_std_dev * relative;
314 const double ub_fix = rank + num_std_dev * fixed;
315 return std::min(ub_rel, ub_fix);
318 template<
typename T,
typename C,
typename A>
319 bool req_sketch<T, C, A>::is_exact_rank(uint16_t k, uint8_t num_levels,
double rank, uint64_t n,
bool hra) {
321 if (num_levels == 1 || n <= base_cap)
return true;
322 const double exact_rank_thresh =
static_cast<double>(base_cap) / n;
323 return (hra && rank >= 1.0 - exact_rank_thresh) || (!hra && rank <= exact_rank_thresh);
326 template<
typename T,
typename C,
typename A>
327 double req_sketch<T, C, A>::relative_rse_factor() {
332 template<
typename T,
typename C,
typename A>
333 template<typename TT, typename SerDe, typename std::enable_if<std::is_arithmetic<TT>::value,
int>::type>
335 size_t size = PREAMBLE_SIZE_BYTES;
336 if (is_empty())
return size;
337 if (is_estimation_mode()) {
338 size +=
sizeof(n_) +
sizeof(TT) * 2;
343 for (
const auto& compactor: compactors_) size += compactor.get_serialized_size_bytes(sd);
349 template<
typename T,
typename C,
typename A>
350 template<typename TT, typename SerDe, typename std::enable_if<!std::is_arithmetic<TT>::value,
int>::type>
352 size_t size = PREAMBLE_SIZE_BYTES;
353 if (is_empty())
return size;
354 if (is_estimation_mode()) {
356 size += sd.size_of_item(*min_item_);
357 size += sd.size_of_item(*max_item_);
360 size += sd.size_of_item(*compactors_[0].begin());
362 for (
const auto& compactor: compactors_) size += compactor.get_serialized_size_bytes(sd);
367 template<
typename T,
typename C,
typename A>
368 template<
typename SerDe>
370 const uint8_t preamble_ints = is_estimation_mode() ? 4 : 2;
371 write(os, preamble_ints);
372 const uint8_t serial_version = SERIAL_VERSION;
373 write(os, serial_version);
374 const uint8_t family = FAMILY;
377 const uint8_t flags_byte(
378 (is_empty() ? 1 << flags::IS_EMPTY : 0)
379 | (hra_ ? 1 << flags::IS_HIGH_RANK : 0)
380 | (raw_items ? 1 << flags::RAW_ITEMS : 0)
381 | (compactors_[0].is_sorted() ? 1 << flags::IS_LEVEL_ZERO_SORTED : 0)
383 write(os, flags_byte);
385 const uint8_t num_levels = is_empty() ? 0 : get_num_levels();
386 write(os, num_levels);
387 const uint8_t num_raw_items = raw_items ?
static_cast<uint8_t
>(n_) : 0;
388 write(os, num_raw_items);
389 if (is_empty())
return;
390 if (is_estimation_mode()) {
392 sd.serialize(os, &*min_item_, 1);
393 sd.serialize(os, &*max_item_, 1);
396 sd.serialize(os, compactors_[0].begin(), num_raw_items);
398 for (
const auto& compactor: compactors_) compactor.serialize(os, sd);
402 template<
typename T,
typename C,
typename A>
403 template<
typename SerDe>
405 const size_t size = header_size_bytes + get_serialized_size_bytes(sd);
406 vector_bytes bytes(size, 0, allocator_);
407 uint8_t* ptr = bytes.data() + header_size_bytes;
408 const uint8_t* end_ptr = ptr + size;
410 const uint8_t preamble_ints = is_estimation_mode() ? 4 : 2;
411 ptr += copy_to_mem(preamble_ints, ptr);
412 const uint8_t serial_version = SERIAL_VERSION;
413 ptr += copy_to_mem(serial_version, ptr);
414 const uint8_t family = FAMILY;
415 ptr += copy_to_mem(family, ptr);
417 const uint8_t flags_byte(
418 (is_empty() ? 1 << flags::IS_EMPTY : 0)
419 | (hra_ ? 1 << flags::IS_HIGH_RANK : 0)
420 | (raw_items ? 1 << flags::RAW_ITEMS : 0)
421 | (compactors_[0].is_sorted() ? 1 << flags::IS_LEVEL_ZERO_SORTED : 0)
423 ptr += copy_to_mem(flags_byte, ptr);
424 ptr += copy_to_mem(k_, ptr);
425 const uint8_t num_levels = is_empty() ? 0 : get_num_levels();
426 ptr += copy_to_mem(num_levels, ptr);
427 const uint8_t num_raw_items = raw_items ?
static_cast<uint8_t
>(n_) : 0;
428 ptr += copy_to_mem(num_raw_items, ptr);
430 if (is_estimation_mode()) {
431 ptr += copy_to_mem(n_, ptr);
432 ptr += sd.serialize(ptr, end_ptr - ptr, &*min_item_, 1);
433 ptr += sd.serialize(ptr, end_ptr - ptr, &*max_item_, 1);
436 ptr += sd.serialize(ptr, end_ptr - ptr, compactors_[0].begin(), num_raw_items);
438 for (
const auto& compactor: compactors_) ptr += compactor.serialize(ptr, end_ptr - ptr, sd);
444 template<
typename T,
typename C,
typename A>
445 template<
typename SerDe>
447 const auto preamble_ints = read<uint8_t>(is);
448 const auto serial_version = read<uint8_t>(is);
449 const auto family_id = read<uint8_t>(is);
450 const auto flags_byte = read<uint8_t>(is);
451 const auto k = read<uint16_t>(is);
452 const auto num_levels = read<uint8_t>(is);
453 const auto num_raw_items = read<uint8_t>(is);
455 check_preamble_ints(preamble_ints, num_levels);
456 check_serial_version(serial_version);
457 check_family_id(family_id);
459 if (!is.good())
throw std::runtime_error(
"error reading from std::istream");
460 const bool is_empty = flags_byte & (1 << flags::IS_EMPTY);
461 const bool hra = flags_byte & (1 << flags::IS_HIGH_RANK);
462 if (is_empty)
return req_sketch(k, hra, comparator, allocator);
465 optional<T> min_item;
466 optional<T> max_item;
468 const bool raw_items = flags_byte & (1 << flags::RAW_ITEMS);
469 const bool is_level_0_sorted = flags_byte & (1 << flags::IS_LEVEL_ZERO_SORTED);
470 std::vector<Compactor, AllocCompactor> compactors(allocator);
473 if (num_levels > 1) {
474 n = read<uint64_t>(is);
475 sd.deserialize(is, &*tmp, 1);
477 min_item.emplace(*tmp);
479 sd.deserialize(is, &*tmp, 1);
481 max_item.emplace(*tmp);
486 compactors.push_back(Compactor::deserialize(is, sd, comparator, allocator, is_level_0_sorted, k, num_raw_items, hra));
488 for (
size_t i = 0; i < num_levels; ++i) {
489 compactors.push_back(Compactor::deserialize(is, sd, comparator, allocator, i == 0 ? is_level_0_sorted :
true, hra));
492 if (num_levels == 1) {
493 const auto begin = compactors[0].begin();
494 const auto end = compactors[0].end();
495 n = compactors[0].get_num_items();
498 for (
auto it = begin; it != end; ++it) {
499 if (comparator(*it, *min_it)) min_it = it;
500 if (comparator(*max_it, *it)) max_it = it;
502 min_item.emplace(*min_it);
503 max_item.emplace(*max_it);
506 if (!is.good())
throw std::runtime_error(
"error reading from std::istream");
507 return req_sketch(k, hra, n, std::move(min_item), std::move(max_item), std::move(compactors), comparator);
510 template<
typename T,
typename C,
typename A>
511 template<
typename SerDe>
513 ensure_minimum_memory(size, 8);
514 const char* ptr =
static_cast<const char*
>(bytes);
515 const char* end_ptr =
static_cast<const char*
>(bytes) + size;
517 uint8_t preamble_ints;
518 ptr += copy_from_mem(ptr, preamble_ints);
519 uint8_t serial_version;
520 ptr += copy_from_mem(ptr, serial_version);
522 ptr += copy_from_mem(ptr, family_id);
524 ptr += copy_from_mem(ptr, flags_byte);
526 ptr += copy_from_mem(ptr, k);
528 ptr += copy_from_mem(ptr, num_levels);
529 uint8_t num_raw_items;
530 ptr += copy_from_mem(ptr, num_raw_items);
532 check_preamble_ints(preamble_ints, num_levels);
533 check_serial_version(serial_version);
534 check_family_id(family_id);
536 const bool is_empty = flags_byte & (1 << flags::IS_EMPTY);
537 const bool hra = flags_byte & (1 << flags::IS_HIGH_RANK);
538 if (is_empty)
return req_sketch(k, hra, comparator, allocator);
541 optional<T> min_item;
542 optional<T> max_item;
544 const bool raw_items = flags_byte & (1 << flags::RAW_ITEMS);
545 const bool is_level_0_sorted = flags_byte & (1 << flags::IS_LEVEL_ZERO_SORTED);
546 std::vector<Compactor, AllocCompactor> compactors(allocator);
549 if (num_levels > 1) {
550 ensure_minimum_memory(end_ptr - ptr,
sizeof(n));
551 ptr += copy_from_mem(ptr, n);
552 ptr += sd.deserialize(ptr, end_ptr - ptr, &*tmp, 1);
554 min_item.emplace(*tmp);
556 ptr += sd.deserialize(ptr, end_ptr - ptr, &*tmp, 1);
558 max_item.emplace(*tmp);
563 auto pair = Compactor::deserialize(ptr, end_ptr - ptr, sd, comparator, allocator, is_level_0_sorted, k, num_raw_items, hra);
564 compactors.push_back(std::move(pair.first));
567 for (
size_t i = 0; i < num_levels; ++i) {
568 auto pair = Compactor::deserialize(ptr, end_ptr - ptr, sd, comparator, allocator, i == 0 ? is_level_0_sorted :
true, hra);
569 compactors.push_back(std::move(pair.first));
573 if (num_levels == 1) {
574 const auto begin = compactors[0].begin();
575 const auto end = compactors[0].end();
576 n = compactors[0].get_num_items();
579 for (
auto it = begin; it != end; ++it) {
580 if (comparator(*it, *min_it)) min_it = it;
581 if (comparator(*max_it, *it)) max_it = it;
583 min_item.emplace(*min_it);
584 max_item.emplace(*max_it);
587 return req_sketch(k, hra, n, std::move(min_item), std::move(max_item), std::move(compactors), comparator);
590 template<
typename T,
typename C,
typename A>
591 void req_sketch<T, C, A>::grow() {
592 const uint8_t lg_weight = get_num_levels();
593 compactors_.push_back(Compactor(hra_, lg_weight, k_, comparator_, allocator_));
594 update_max_nom_size();
597 template<
typename T,
typename C,
typename A>
598 uint8_t req_sketch<T, C, A>::get_num_levels()
const {
599 return static_cast<uint8_t
>(compactors_.size());
602 template<
typename T,
typename C,
typename A>
603 void req_sketch<T, C, A>::update_max_nom_size() {
605 for (
const auto& compactor: compactors_) max_nom_size_ += compactor.get_nom_capacity();
608 template<
typename T,
typename C,
typename A>
609 void req_sketch<T, C, A>::update_num_retained() {
611 for (
const auto& compactor: compactors_) num_retained_ += compactor.get_num_items();
614 template<
typename T,
typename C,
typename A>
615 void req_sketch<T, C, A>::compress() {
616 for (
size_t h = 0; h < compactors_.size(); ++h) {
617 if (compactors_[h].get_num_items() >= compactors_[h].get_nom_capacity()) {
618 if (h == 0) compactors_[0].sort();
619 if (h + 1 >= get_num_levels()) {
622 auto pair = compactors_[h].compact(compactors_[h + 1]);
623 num_retained_ -= pair.first;
624 max_nom_size_ += pair.second;
625 if (LAZY_COMPRESSION && num_retained_ < max_nom_size_)
break;
630 template<
typename T,
typename C,
typename A>
634 std::ostringstream os;
635 os <<
"### REQ sketch summary:" << std::endl;
636 os <<
" K : " << k_ << std::endl;
637 os <<
" High Rank Acc : " << (hra_ ?
"true" :
"false") << std::endl;
638 os <<
" Empty : " << (is_empty() ?
"true" :
"false") << std::endl;
639 os <<
" Estimation mode: " << (is_estimation_mode() ?
"true" :
"false") << std::endl;
640 os <<
" Sorted : " << (compactors_[0].is_sorted() ?
"true" :
"false") << std::endl;
641 os <<
" N : " << n_ << std::endl;
642 os <<
" Levels : " << compactors_.size() << std::endl;
643 os <<
" Retained items : " << num_retained_ << std::endl;
644 os <<
" Capacity items : " << max_nom_size_ << std::endl;
646 os <<
" Min item : " << *min_item_ << std::endl;
647 os <<
" Max item : " << *max_item_ << std::endl;
649 os <<
"### End sketch summary" << std::endl;
652 os <<
"### REQ sketch levels:" << std::endl;
653 os <<
" index: nominal capacity, actual size" << std::endl;
654 for (uint8_t i = 0; i < compactors_.size(); i++) {
655 os <<
" " << (
unsigned int) i <<
": "
656 << compactors_[i].get_nom_capacity() <<
", "
657 << compactors_[i].get_num_items() << std::endl;
659 os <<
"### End sketch levels" << std::endl;
663 os <<
"### REQ sketch data:" << std::endl;
665 for (
const auto& compactor: compactors_) {
666 os <<
" level " << level <<
": " << std::endl;
667 for (
auto it = compactor.begin(); it != compactor.end(); ++it) {
668 os <<
" " << *it << std::endl;
672 os <<
"### End sketch data" << std::endl;
674 return string<A>(os.str().c_str(), allocator_);
677 template<
typename T,
typename C,
typename A>
679 optional<T>&& min_item, optional<T>&& max_item,
680 std::vector<Compactor, AllocCompactor>&& compactors,
const C& comparator):
681 comparator_(comparator),
682 allocator_(compactors.get_allocator()),
688 compactors_(std::move(compactors)),
689 min_item_(std::move(min_item)),
690 max_item_(std::move(max_item)),
691 sorted_view_(nullptr)
693 update_max_nom_size();
694 update_num_retained();
697 template<
typename T,
typename C,
typename A>
698 void req_sketch<T, C, A>::check_preamble_ints(uint8_t preamble_ints, uint8_t num_levels) {
699 const uint8_t expected_preamble_ints = num_levels > 1 ? 4 : 2;
700 if (preamble_ints != expected_preamble_ints) {
701 throw std::invalid_argument(
"Possible corruption: preamble ints must be "
702 + std::to_string(expected_preamble_ints) +
", got " + std::to_string(preamble_ints));
706 template<
typename T,
typename C,
typename A>
707 void req_sketch<T, C, A>::check_serial_version(uint8_t serial_version) {
708 if (serial_version != SERIAL_VERSION) {
709 throw std::invalid_argument(
"Possible corruption: serial version mismatch: expected "
710 + std::to_string(SERIAL_VERSION)
711 +
", got " + std::to_string(serial_version));
715 template<
typename T,
typename C,
typename A>
716 void req_sketch<T, C, A>::check_family_id(uint8_t family_id) {
717 if (family_id != FAMILY) {
718 throw std::invalid_argument(
"Possible corruption: family mismatch: expected "
719 + std::to_string(FAMILY) +
", got " + std::to_string(family_id));
723 template<
typename T,
typename C,
typename A>
725 return const_iterator(compactors_.begin(), compactors_.end());
728 template<
typename T,
typename C,
typename A>
730 return const_iterator(compactors_.end(), compactors_.end());
733 template<
typename T,
typename C,
typename A>
735 if (sorted_view_ ==
nullptr) {
736 using AllocSortedView =
typename std::allocator_traits<A>::template rebind_alloc<quantiles_sorted_view<T, C, A>>;
741 template<
typename T,
typename C,
typename A>
742 void req_sketch<T, C, A>::reset_sorted_view() {
743 if (sorted_view_ !=
nullptr) {
744 sorted_view_->~quantiles_sorted_view();
745 using AllocSortedView =
typename std::allocator_traits<A>::template rebind_alloc<quantiles_sorted_view<T, C, A>>;
746 AllocSortedView(allocator_).deallocate(sorted_view_, 1);
747 sorted_view_ =
nullptr;
753 template<
typename T,
typename C,
typename A>
754 req_sketch<T, C, A>::const_iterator::const_iterator(LevelsIterator begin, LevelsIterator end):
757 compactor_it_(begin == end ? nullptr : (*levels_it_).begin())
760 template<
typename T,
typename C,
typename A>
761 auto req_sketch<T, C, A>::const_iterator::operator++() -> const_iterator& {
763 if (compactor_it_ == (*levels_it_).end()) {
765 if (levels_it_ != levels_end_) compactor_it_ = (*levels_it_).begin();
770 template<
typename T,
typename C,
typename A>
771 auto req_sketch<T, C, A>::const_iterator::operator++(
int) -> const_iterator& {
772 const_iterator tmp(*
this);
777 template<
typename T,
typename C,
typename A>
778 bool req_sketch<T, C, A>::const_iterator::operator==(
const const_iterator& other)
const {
779 if (levels_it_ != other.levels_it_)
return false;
780 if (levels_it_ == levels_end_)
return true;
781 return compactor_it_ == other.compactor_it_;
784 template<
typename T,
typename C,
typename A>
785 bool req_sketch<T, C, A>::const_iterator::operator!=(
const const_iterator& other)
const {
786 return !operator==(other);
789 template<
typename T,
typename C,
typename A>
790 auto req_sketch<T, C, A>::const_iterator::operator*() const -> reference {
791 return value_type(*compactor_it_, 1ULL << (*levels_it_).get_lg_weight());
794 template<
typename T,
typename C,
typename A>
795 auto req_sketch<T, C, A>::const_iterator::operator->() const -> pointer {
Relative Error Quantiles Sketch.
Definition: req_sketch.hpp:79
Comparator get_comparator() const
Returns an instance of the comparator for this sketch.
Definition: req_sketch_impl.hpp:224
quantiles_sorted_view< T, Comparator, Allocator > get_sorted_view() const
Gets the sorted view of this sketch.
Definition: req_sketch_impl.hpp:269
static req_sketch deserialize(std::istream &is, const SerDe &sd=SerDe(), const Comparator &comparator=Comparator(), const Allocator &allocator=Allocator())
This method deserializes a sketch from a given stream.
vector_double get_CDF(const T *split_points, uint32_t size, bool inclusive=true) const
Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analo...
Definition: req_sketch_impl.hpp:251
uint32_t get_num_retained() const
Returns the number of retained items in the sketch.
Definition: req_sketch_impl.hpp:159
vector_double get_PMF(const T *split_points, uint32_t size, bool inclusive=true) const
Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of sp...
Definition: req_sketch_impl.hpp:244
void merge(FwdSk &&other)
Merges another sketch into this one.
Definition: req_sketch_impl.hpp:188
typename quantiles_sorted_view< T, Comparator, Allocator >::quantile_return_type quantile_return_type
Quantile return type.
Definition: req_sketch.hpp:92
void update(FwdT &&item)
Updates this sketch with the given data item.
Definition: req_sketch_impl.hpp:170
void serialize(std::ostream &os, const SerDe &sd=SerDe()) const
This method serializes the sketch into a given stream in a binary form.
Definition: req_sketch_impl.hpp:369
string< Allocator > to_string(bool print_levels=false, bool print_items=false) const
Prints a summary of the sketch.
Definition: req_sketch_impl.hpp:631
uint16_t get_k() const
Returns configured parameter K.
Definition: req_sketch_impl.hpp:139
bool is_empty() const
Returns true if this sketch is empty.
Definition: req_sketch_impl.hpp:149
const T & get_max_item() const
Returns the max item of the stream.
Definition: req_sketch_impl.hpp:218
double get_rank_upper_bound(double rank, uint8_t num_std_dev) const
Returns an approximate upper bound of the given normalized rank.
Definition: req_sketch_impl.hpp:289
double get_rank(const T &item, bool inclusive=true) const
Returns an approximation to the normalized rank of the given item from 0 to 1 inclusive.
Definition: req_sketch_impl.hpp:234
static double get_RSE(uint16_t k, double rank, bool hra, uint64_t n)
Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,...
Definition: req_sketch_impl.hpp:294
double get_rank_lower_bound(double rank, uint8_t num_std_dev) const
Returns an approximate lower bound of the given normalized rank.
Definition: req_sketch_impl.hpp:284
Allocator get_allocator() const
Returns an instance of the allocator for this sketch.
Definition: req_sketch_impl.hpp:229
req_sketch & operator=(const req_sketch &other)
Copy assignment.
Definition: req_sketch_impl.hpp:81
quantile_return_type get_quantile(double rank, bool inclusive=true) const
Returns an approximate quantile of the given normalized rank.
Definition: req_sketch_impl.hpp:258
const_iterator begin() const
Iterator pointing to the first item in the sketch.
Definition: req_sketch_impl.hpp:724
size_t get_serialized_size_bytes(const SerDe &sd=SerDe()) const
Computes size needed to serialize the current state of the sketch.
Definition: req_sketch_impl.hpp:334
const_iterator end() const
Iterator pointing to the past-the-end item in the sketch.
Definition: req_sketch_impl.hpp:729
bool is_estimation_mode() const
Returns true if this sketch is in estimation mode.
Definition: req_sketch_impl.hpp:164
const T & get_min_item() const
Returns the min item of the stream.
Definition: req_sketch_impl.hpp:212
bool is_HRA() const
Returns configured parameter High Rank Accuracy.
Definition: req_sketch_impl.hpp:144
uint64_t get_n() const
Returns the length of the input stream.
Definition: req_sketch_impl.hpp:154
const uint16_t MIN_K
min value of parameter K
Definition: kll_sketch.hpp:39
const uint8_t INIT_NUM_SECTIONS
initial number of sections
Definition: req_common.hpp:35
const uint16_t MIN_K
minimum value of parameter K
Definition: req_common.hpp:33
DataSketches namespace.
Definition: binomial_bounds.hpp:38