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

tisonkun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datasketches-rust.git


The following commit(s) were added to refs/heads/main by this push:
     new 771e618  fix(req): compactor merge (#220)
771e618 is described below

commit 771e6183eb5a2af293c5de5bf35a0131c1ea8d38
Author: Jeff Chung <[email protected]>
AuthorDate: Tue Aug 25 17:19:13 2026 +0800

    fix(req): compactor merge (#220)
---
 datasketches/src/req/compactor.rs     |  8 ++++++--
 datasketches/tests/serde_tests/req.rs | 25 +++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/datasketches/src/req/compactor.rs 
b/datasketches/src/req/compactor.rs
index 746e614..7d371f6 100644
--- a/datasketches/src/req/compactor.rs
+++ b/datasketches/src/req/compactor.rs
@@ -118,10 +118,14 @@ where
 
     /// Merges items from another compactor into this one.
     pub(super) fn merge(&mut self, other: &Self) {
+        debug_assert_eq!(self.lg_weight, other.lg_weight);
         self.state |= other.state;
-        self.items.extend_from_slice(&other.items);
         if !other.items.is_empty() {
-            self.is_sorted = false;
+            // make sure both items are sorted.
+            self.sort();
+            let mut other_items = other.items.clone();
+            other_items.sort_unstable_by(|a, b| a.total_cmp(b));
+            self.merge_sorted(&other_items);
         }
         // OR-ing the schedule counters can advance state past several doubling
         // thresholds at once. Loop until no more doublings are needed (C++:
diff --git a/datasketches/tests/serde_tests/req.rs 
b/datasketches/tests/serde_tests/req.rs
index 8a68fa3..8539819 100644
--- a/datasketches/tests/serde_tests/req.rs
+++ b/datasketches/tests/serde_tests/req.rs
@@ -231,6 +231,31 @@ fn deserialize_truncated_raw_items() {
     assert_that!(result, err(anything()));
 }
 
+#[test]
+fn merge_preserves_order_across_serde_round_trip() {
+    let mut high = ReqSketch::<f64>::new();
+    let mut low = ReqSketch::<f64>::new();
+
+    for value in 1000..=1072 {
+        high.update(value as f64);
+    }
+    for value in 0..=72 {
+        low.update(value as f64);
+    }
+
+    high.merge(&low).unwrap();
+    let restored = ReqSketch::<f64>::deserialize(&high.serialize()).unwrap();
+    let view = restored.sorted_view();
+
+    for value in 0..=1072 {
+        let value = value as f64;
+        assert_eq!(
+            restored.rank(&value, SearchCriteria::Inclusive).unwrap(),
+            view.rank(&value, SearchCriteria::Inclusive).unwrap(),
+        );
+    }
+}
+
 // ---------- Deserialize hardening: malformed compactor fields ----------
 //
 // A non-empty, non-raw, single-level sketch carries a full 20-byte compactor


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to