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]