Skip to content

Commit 034749f

Browse files
Merge pull request #357 from apache/theta_union_fix
theta union get_result() fix
2 parents febe15c + 9d3ba57 commit 034749f

3 files changed

Lines changed: 35 additions & 10 deletions

File tree

theta/include/theta_union_base_impl.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void theta_union_base<EN, EK, P, S, CS, A>::update(SS&& sketch) {
4141
if (sketch.is_empty()) return;
4242
if (sketch.get_seed_hash() != compute_seed_hash(table_.seed_)) throw std::invalid_argument("seed hash mismatch");
4343
table_.is_empty_ = false;
44-
if (sketch.get_theta64() < union_theta_) union_theta_ = sketch.get_theta64();
44+
union_theta_ = std::min(union_theta_, sketch.get_theta64());
4545
for (auto& entry: sketch) {
4646
const uint64_t hash = EK()(entry);
4747
if (hash < union_theta_ && hash < table_.theta_) {
@@ -55,7 +55,7 @@ void theta_union_base<EN, EK, P, S, CS, A>::update(SS&& sketch) {
5555
if (sketch.is_ordered()) break; // early stop
5656
}
5757
}
58-
if (table_.theta_ < union_theta_) union_theta_ = table_.theta_;
58+
union_theta_ = std::min(union_theta_, table_.theta_);
5959
}
6060

6161
template<typename EN, typename EK, typename P, typename S, typename CS, typename A>
@@ -65,16 +65,16 @@ CS theta_union_base<EN, EK, P, S, CS, A>::get_result(bool ordered) const {
6565
entries.reserve(table_.num_entries_);
6666
uint64_t theta = std::min(union_theta_, table_.theta_);
6767
const uint32_t nominal_num = 1 << table_.lg_nom_size_;
68-
if (union_theta_ >= theta && table_.num_entries_ <= nominal_num) {
68+
if (union_theta_ >= table_.theta_) {
6969
std::copy_if(table_.begin(), table_.end(), std::back_inserter(entries), key_not_zero<EN, EK>());
7070
} else {
7171
std::copy_if(table_.begin(), table_.end(), std::back_inserter(entries), key_not_zero_less_than<uint64_t, EN, EK>(theta));
72-
if (entries.size() > nominal_num) {
73-
std::nth_element(entries.begin(), entries.begin() + nominal_num, entries.end(), comparator());
74-
theta = EK()(entries[nominal_num]);
75-
entries.erase(entries.begin() + nominal_num, entries.end());
76-
entries.shrink_to_fit();
77-
}
72+
}
73+
if (entries.size() > nominal_num) {
74+
std::nth_element(entries.begin(), entries.begin() + nominal_num, entries.end(), comparator());
75+
theta = EK()(entries[nominal_num]);
76+
entries.erase(entries.begin() + nominal_num, entries.end());
77+
entries.shrink_to_fit();
7878
}
7979
if (ordered) std::sort(entries.begin(), entries.end(), comparator());
8080
return CS(table_.is_empty_, ordered, compute_seed_hash(table_.seed_), theta, std::move(entries));

theta/include/theta_update_sketch_base_impl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ auto theta_update_sketch_base<EN, EK, A>::begin() const -> iterator {
188188

189189
template<typename EN, typename EK, typename A>
190190
auto theta_update_sketch_base<EN, EK, A>::end() const -> iterator {
191-
return &entries_[1ULL << lg_cur_size_];
191+
return entries_ + (1ULL << lg_cur_size_);
192192
}
193193

194194
template<typename EN, typename EK, typename A>

theta/test/theta_union_test.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,29 @@ TEST_CASE("theta union: seed mismatch", "[theta_union]") {
128128
REQUIRE_THROWS_AS(u.update(sketch), std::invalid_argument);
129129
}
130130

131+
TEST_CASE("theta union: larger K", "[theta_union]") {
132+
auto update_sketch1 = datasketches::update_theta_sketch::builder().set_lg_k(14).build();
133+
for(int i = 0; i < 16384; ++i) update_sketch1.update(i);
134+
135+
auto update_sketch2 = datasketches::update_theta_sketch::builder().set_lg_k(14).build();
136+
for(int i = 0; i < 26384; ++i) update_sketch2.update(i);
137+
138+
auto update_sketch3 = datasketches::update_theta_sketch::builder().set_lg_k(14).build();
139+
for(int i = 0; i < 86384; ++i) update_sketch3.update(i);
140+
141+
auto union1 = datasketches::theta_union::builder().set_lg_k(16).build();
142+
union1.update(update_sketch2);
143+
union1.update(update_sketch1);
144+
union1.update(update_sketch3);
145+
auto result1 = union1.get_result();
146+
REQUIRE(result1.get_estimate() == update_sketch3.get_estimate());
147+
148+
auto union2 = datasketches::theta_union::builder().set_lg_k(16).build();
149+
union2.update(update_sketch1);
150+
union2.update(update_sketch3);
151+
union2.update(update_sketch2);
152+
auto result2 = union2.get_result();
153+
REQUIRE(result2.get_estimate() == update_sketch3.get_estimate());
154+
}
155+
131156
} /* namespace datasketches */

0 commit comments

Comments
 (0)