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 c7e745a feat: add diagnostic summaries for HLL and CPC (#232)
c7e745a is described below
commit c7e745affc08b95dfd601ae426043e7818bf8a60
Author: Xinyao Zhang <[email protected]>
AuthorDate: Sat Sep 26 09:15:24 2026 -0400
feat: add diagnostic summaries for HLL and CPC (#232)
Co-authored-by: tison <[email protected]>
---
CHANGELOG.md | 1 +
datasketches/src/cpc/sketch.rs | 19 ++++++++++++++++++-
datasketches/src/cpc/union.rs | 21 ++++++++++++++++++++-
datasketches/src/hll/sketch.rs | 36 +++++++++++++++++++++++++++++++++++-
4 files changed, 74 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ba590ae..e6614a7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@ All significant changes to this project will be documented in
this file.
### Improvements
+* Improve the readability of `Debug` output for HLL and CPC sketches and
unions.
* `BloomFilter::insert` is faster for integer and raw-byte inputs.
`BloomFilter::contains_and_insert` is also faster when checking already-present
integer values.
* `CountMinSketch` updates are faster for integer and raw-byte inputs.
* `CpcSketch` updates are faster for integer and raw-byte inputs.
diff --git a/datasketches/src/cpc/sketch.rs b/datasketches/src/cpc/sketch.rs
index 2cc4a7a..d946b1b 100644
--- a/datasketches/src/cpc/sketch.rs
+++ b/datasketches/src/cpc/sketch.rs
@@ -15,6 +15,7 @@
// specific language governing permissions and limitations
// under the License.
+use std::fmt;
use std::hash::Hash;
use crate::codec::SketchBytes;
@@ -59,7 +60,7 @@ use crate::hash::compute_seed_hash;
/// A Compressed Probabilistic Counting sketch.
///
/// See the [module level documentation](super) for more.
-#[derive(Debug, Clone)]
+#[derive(Clone)]
pub struct CpcSketch {
// immutable config variables
lg_k: u8,
@@ -471,6 +472,22 @@ impl CpcSketch {
}
}
+impl fmt::Debug for CpcSketch {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let estimator = if self.merge_flag { "ICON" } else { "HIP" };
+ f.debug_struct("CpcSketch")
+ .field("lg_k", &self.lg_k())
+ .field("seed", &self.seed)
+ .field("flavor", &self.flavor())
+ .field("is_empty", &self.is_empty())
+ .field("merged", &self.merge_flag)
+ .field("estimator", &estimator)
+ .field("num_coupons", &self.num_coupons)
+ .field("estimate", &self.estimate())
+ .finish()
+ }
+}
+
impl CpcSketch {
/// Serializes this `CpcSketch` to bytes.
pub fn serialize(&self) -> Vec<u8> {
diff --git a/datasketches/src/cpc/union.rs b/datasketches/src/cpc/union.rs
index 51742a3..67870f5 100644
--- a/datasketches/src/cpc/union.rs
+++ b/datasketches/src/cpc/union.rs
@@ -61,6 +61,8 @@
//! which requires doing some extra work to figure out the values of
num_coupons, offset,
//! first_interesting_column, and kxp.
+use std::fmt;
+
use crate::cpc::CpcSketch;
use crate::cpc::DEFAULT_LG_K;
use crate::cpc::Flavor;
@@ -71,7 +73,7 @@ use crate::error::Error;
use crate::hash::DEFAULT_UPDATE_SEED;
/// Union operator for CPC sketches.
-#[derive(Debug, Clone)]
+#[derive(Clone)]
pub struct CpcUnion {
// immutable config variables
lg_k: u8,
@@ -356,6 +358,23 @@ impl CpcUnion {
}
}
+impl fmt::Debug for CpcUnion {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let (state, num_coupons) = match &self.state {
+ UnionState::Accumulator(sketch) => ("Accumulator",
sketch.num_coupons),
+ UnionState::BitMatrix(matrix) => ("BitMatrix",
count_bits_set_in_matrix(matrix)),
+ };
+
+ f.debug_struct("CpcUnion")
+ .field("lg_k", &self.lg_k())
+ .field("seed", &self.seed)
+ .field("state", &state)
+ .field("is_empty", &(num_coupons == 0))
+ .field("num_coupons", &num_coupons)
+ .finish()
+ }
+}
+
fn or_window_into_matrix(
dst_matrix: &mut [u64],
dst_lg_k: u8,
diff --git a/datasketches/src/hll/sketch.rs b/datasketches/src/hll/sketch.rs
index a229b3b..bef4fbb 100644
--- a/datasketches/src/hll/sketch.rs
+++ b/datasketches/src/hll/sketch.rs
@@ -20,6 +20,7 @@
//! This module provides the main [`HllSketch`] struct, which is the primary
interface
//! for creating and using HLL sketches for cardinality estimation.
+use std::fmt;
use std::hash::Hash;
use crate::codec::SketchSlice;
@@ -60,7 +61,7 @@ use crate::hll::serialization::extract_tgt_hll_type;
/// A HyperLogLog sketch.
///
/// See the [module level documentation](super) for more.
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Clone, PartialEq)]
pub struct HllSketch {
lg_config_k: u8,
mode: Mode,
@@ -464,6 +465,39 @@ impl HllSketch {
}
}
+impl fmt::Debug for HllSketch {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let (mode, estimate_state) = match &self.mode {
+ Mode::List { .. } => ("List", None),
+ Mode::Set { .. } => ("Set", None),
+ Mode::Array4(array) => ("Hll", Some(array.estimate_state())),
+ Mode::Array6(array) => ("Hll", Some(array.estimate_state())),
+ Mode::Array8(array) => ("Hll", Some(array.estimate_state())),
+ };
+
+ let mut debug = f.debug_struct("HllSketch");
+ debug
+ .field("lg_config_k", &self.lg_config_k())
+ .field("target_type", &self.target_type())
+ .field("mode", &mode)
+ .field("is_empty", &self.is_empty());
+ if let Some(state) = estimate_state {
+ let estimator = match state {
+ EstimateState::Hip(_) => "HIP",
+ EstimateState::Composite => "Composite",
+ };
+ debug.field("estimator", &estimator);
+ }
+ debug
+ .field("estimate", &self.estimate())
+ .field(
+ "bounds",
+
&(self.lower_bound(NumStdDev::One)..=self.upper_bound(NumStdDev::One)),
+ )
+ .finish()
+ }
+}
+
fn promote_container_to_set(container: &Container, hll_type: HllType) -> Mode {
let mut set = HashSet::default();
for coupon in container.iter() {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]