20 #ifndef THETA_A_SET_DIFFERENCE_BASE_IMPL_HPP_
21 #define THETA_A_SET_DIFFERENCE_BASE_IMPL_HPP_
26 #include "conditional_back_inserter.hpp"
27 #include "conditional_forward.hpp"
31 template<
typename EN,
typename EK,
typename CS,
typename A>
32 theta_set_difference_base<EN, EK, CS, A>::theta_set_difference_base(uint64_t seed,
const A& allocator):
33 allocator_(allocator),
34 seed_hash_(compute_seed_hash(seed))
37 template<
typename EN,
typename EK,
typename CS,
typename A>
38 template<
typename FwdSketch,
typename Sketch>
39 CS theta_set_difference_base<EN, EK, CS, A>::compute(FwdSketch&& a,
const Sketch& b,
bool ordered)
const {
40 if (a.is_empty() || (a.get_num_retained() > 0 && b.is_empty()))
return CS(a, ordered);
41 if (a.get_seed_hash() != seed_hash_)
throw std::invalid_argument(
"A seed hash mismatch");
42 if (b.get_seed_hash() != seed_hash_)
throw std::invalid_argument(
"B seed hash mismatch");
44 const uint64_t theta = std::min(a.get_theta64(), b.get_theta64());
45 std::vector<EN, A> entries(allocator_);
46 bool is_empty = a.is_empty();
48 if (b.get_num_retained() == 0) {
49 std::copy_if(forward_begin(std::forward<FwdSketch>(a)), forward_end(std::forward<FwdSketch>(a)), std::back_inserter(entries),
50 key_less_than<uint64_t, EN, EK>(theta));
52 if (a.is_ordered() && b.is_ordered()) {
53 std::set_difference(forward_begin(std::forward<FwdSketch>(a)), forward_end(std::forward<FwdSketch>(a)), b.begin(), b.end(),
54 conditional_back_inserter(entries, key_less_than<uint64_t, EN, EK>(theta)), comparator());
56 const uint8_t lg_size = lg_size_from_count(b.get_num_retained(), hash_table::REBUILD_THRESHOLD);
57 hash_table table(lg_size, lg_size, hash_table::resize_factor::X1, 1, 0, 0, allocator_);
58 for (
const auto& entry: b) {
59 const uint64_t hash = EK()(entry);
61 table.insert(table.find(hash).first, hash);
62 }
else if (b.is_ordered()) {
68 for (
auto&& entry: a) {
69 const uint64_t hash = EK()(entry);
71 auto result = table.find(hash);
72 if (!result.second) entries.push_back(conditional_forward<FwdSketch>(entry));
73 }
else if (a.is_ordered()) {
79 if (entries.empty() && theta == theta_constants::MAX_THETA) is_empty =
true;
80 if (ordered && !a.is_ordered()) std::sort(entries.begin(), entries.end(), comparator());
81 return CS(is_empty, a.is_ordered() || ordered, seed_hash_, theta, std::move(entries));
DataSketches namespace.
Definition: binomial_bounds.hpp:38