You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by ti...@apache.org on 2026/08/19 16:44:22 UTC

(datasketches-rust) branch codex/hll-union-rebuild-regression-tests created (now bc6d1c6)

This is an automated email from the ASF dual-hosted git repository.

tisonkun pushed a change to branch codex/hll-union-rebuild-regression-tests
in repository https://gitbox.apache.org/repos/asf/datasketches-rust.git


      at bc6d1c6  test(hll): cover union rebuild regressions

This branch includes the following new commits:

     new bc6d1c6  test(hll): cover union rebuild regressions

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org


(datasketches-rust) 01/01: test(hll): cover union rebuild regressions

Posted by ti...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tisonkun pushed a commit to branch codex/hll-union-rebuild-regression-tests
in repository https://gitbox.apache.org/repos/asf/datasketches-rust.git

commit bc6d1c62f32746846d099de4d7f6712f412a4c40
Author: tison <wa...@gmail.com>
AuthorDate: Thu Aug 20 00:44:08 2026 +0800

    test(hll): cover union rebuild regressions
---
 datasketches/tests/hll_test/union.rs | 115 +++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/datasketches/tests/hll_test/union.rs b/datasketches/tests/hll_test/union.rs
index ef67b39..529ffc0 100644
--- a/datasketches/tests/hll_test/union.rs
+++ b/datasketches/tests/hll_test/union.rs
@@ -32,6 +32,47 @@ use datasketches::hll::HllSketch;
 use datasketches::hll::HllType;
 use datasketches::hll::HllUnion;
 
+const HLL_TYPES: [HllType; 3] = [HllType::Hll4, HllType::Hll6, HllType::Hll8];
+
+fn make_hll_sketch(hll_type: HllType, lg_config_k: u8, start: u64, end: u64) -> HllSketch {
+    let mut sketch = HllSketch::new(lg_config_k, hll_type);
+    for value in start..end {
+        sketch.update(value);
+    }
+    sketch
+}
+
+fn assert_estimate_within(estimate: f64, expected: f64, relative_error: f64) {
+    let actual_relative_error = (estimate - expected).abs() / expected;
+    assert!(
+        actual_relative_error <= relative_error,
+        "Expected estimate within {:.1}% of {}, got {} ({:.1}% error)",
+        relative_error * 100.0,
+        expected,
+        estimate,
+        actual_relative_error * 100.0,
+    );
+}
+
+fn serialize_flat_union(first: &HllSketch, second: &HllSketch, third: &HllSketch) -> Vec<u8> {
+    let mut union = HllUnion::new(8);
+    union.update(first);
+    union.update(second);
+    union.update(third);
+    union.to_sketch(HllType::Hll8).serialize()
+}
+
+fn serialize_nested_union(first: &HllSketch, second: &HllSketch, third: &HllSketch) -> Vec<u8> {
+    let mut prefix = HllUnion::new(8);
+    prefix.update(first);
+    prefix.update(second);
+
+    let mut union = HllUnion::new(8);
+    union.update(&prefix.to_sketch(HllType::Hll8));
+    union.update(third);
+    union.to_sketch(HllType::Hll8).serialize()
+}
+
 #[test]
 fn test_union_basic_operations() {
     let mut union = HllUnion::new(12);
@@ -287,6 +328,80 @@ fn test_union_lg_k_handling() {
     );
 }
 
+// Regression coverage for https://github.com/apache/datasketches-cpp/pull/512.
+#[test]
+fn test_union_downsampling_merge_is_not_empty() {
+    for hll_type in HLL_TYPES {
+        let sketch = make_hll_sketch(hll_type, 15, 0, 100_000);
+        let mut union = HllUnion::new(8);
+        union.update(&sketch);
+
+        assert!(!union.is_empty(), "{hll_type:?} union should not be empty");
+    }
+}
+
+#[test]
+fn test_union_mixed_lg_k_estimate_is_merge_order_independent() {
+    const N: u64 = 100_000;
+
+    for hll_type in HLL_TYPES {
+        let a = make_hll_sketch(hll_type, 15, 0, N);
+        let b = make_hll_sketch(hll_type, 8, N, 2 * N);
+        let expected = 2.0 * N as f64;
+
+        let mut larger_first = HllUnion::new(8);
+        larger_first.update(&a);
+        larger_first.update(&b);
+        let larger_first_estimate = larger_first.estimate();
+        assert_estimate_within(larger_first_estimate, expected, 0.1);
+
+        let mut smaller_first = HllUnion::new(8);
+        smaller_first.update(&b);
+        smaller_first.update(&a);
+        let smaller_first_estimate = smaller_first.estimate();
+        assert_estimate_within(smaller_first_estimate, expected, 0.1);
+        assert_eq!(
+            larger_first_estimate, smaller_first_estimate,
+            "{hll_type:?} estimate should be merge-order independent",
+        );
+    }
+}
+
+#[test]
+fn test_union_scalar_update_after_downsampling_merge() {
+    const N: u64 = 100_000;
+
+    for hll_type in HLL_TYPES {
+        let sketch = make_hll_sketch(hll_type, 15, 0, N);
+        let mut union = HllUnion::new(8);
+        union.update(&sketch);
+        for value in N..2 * N {
+            union.update_value(value);
+        }
+
+        assert_estimate_within(union.estimate(), 2.0 * N as f64, 0.1);
+    }
+}
+
+#[test]
+fn test_union_serialization_is_grouping_independent() {
+    const N: u64 = 100_000;
+
+    for hll_type in HLL_TYPES {
+        let a = make_hll_sketch(hll_type, 15, 0, N);
+        let b = make_hll_sketch(hll_type, 8, N, 2 * N);
+        let c = make_hll_sketch(hll_type, 11, N / 2, N + N / 2);
+
+        for (first, second, third) in [(&b, &c, &a), (&a, &c, &b), (&a, &b, &c)] {
+            assert_eq!(
+                serialize_nested_union(first, second, third),
+                serialize_flat_union(first, second, third),
+                "{hll_type:?} serialization should be grouping independent",
+            );
+        }
+    }
+}
+
 #[test]
 fn test_union_bounds() {
     let mut union = HllUnion::new(12);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org