From f9bf211fc7fab1bd2c0362815045e54c6c45dbf8 Mon Sep 17 00:00:00 2001 From: tison Date: Tue, 11 Aug 2026 09:59:16 +0800 Subject: [PATCH 1/2] docs: correct public sketch semantics --- datasketches/src/bloom/mod.rs | 4 ++-- datasketches/src/bloom/sketch.rs | 4 ++-- datasketches/src/codec/decode.rs | 8 ++++---- datasketches/src/frequencies/mod.rs | 13 +++++++++---- datasketches/src/hll/mod.rs | 19 ++++++++++++------- datasketches/src/hll/union.rs | 8 +++++++- .../thetafamily/theta/jaccard_similarity.rs | 5 +++-- .../thetafamily/tuple/jaccard_similarity.rs | 5 +++-- 8 files changed, 42 insertions(+), 24 deletions(-) diff --git a/datasketches/src/bloom/mod.rs b/datasketches/src/bloom/mod.rs index 3ee0df1e..b6f64378 100644 --- a/datasketches/src/bloom/mod.rs +++ b/datasketches/src/bloom/mod.rs @@ -43,8 +43,8 @@ //! filter.insert(42_u64); //! //! // Check membership -//! assert!(filter.contains(&"apple")); // true - definitely inserted -//! assert!(!filter.contains(&"grape")); // false - never inserted (probably) +//! assert!(filter.contains(&"apple")); // true - possibly present (and known to be inserted here) +//! assert!(!filter.contains(&"grape")); // false - definitely not present //! //! // Get statistics //! println!("Capacity: {} bits", filter.capacity()); diff --git a/datasketches/src/bloom/sketch.rs b/datasketches/src/bloom/sketch.rs index 64af2e5d..8b0543f7 100644 --- a/datasketches/src/bloom/sketch.rs +++ b/datasketches/src/bloom/sketch.rs @@ -66,8 +66,8 @@ impl BloomFilter { /// let mut filter = BloomFilterBuilder::with_accuracy(100, 0.01).build(); /// filter.insert("apple"); /// - /// assert!(filter.contains(&"apple")); // true - was inserted (probably) - /// assert!(!filter.contains(&"grape")); // false - never inserted + /// assert!(filter.contains(&"apple")); // true - possibly present (and known to be inserted here) + /// assert!(!filter.contains(&"grape")); // false - definitely not present /// ``` pub fn contains(&self, item: &T) -> bool { if self.is_empty() { diff --git a/datasketches/src/codec/decode.rs b/datasketches/src/codec/decode.rs index d2f23644..bce6e0b8 100644 --- a/datasketches/src/codec/decode.rs +++ b/datasketches/src/codec/decode.rs @@ -123,28 +123,28 @@ impl SketchSlice<'_> { Ok(i32::from_be_bytes(buf)) } - /// Reads a 16-bit unsigned integer from the slice in little-endian byte order. + /// Reads a 64-bit unsigned integer from the slice in little-endian byte order. pub fn read_u64_le(&mut self) -> io::Result { let mut buf = [0u8; 8]; self.read_exact(&mut buf)?; Ok(u64::from_le_bytes(buf)) } - /// Reads a 16-bit unsigned integer from the slice in big-endian byte order. + /// Reads a 64-bit unsigned integer from the slice in big-endian byte order. pub fn read_u64_be(&mut self) -> io::Result { let mut buf = [0u8; 8]; self.read_exact(&mut buf)?; Ok(u64::from_be_bytes(buf)) } - /// Reads a 16-bit signed integer from the slice in little-endian byte order. + /// Reads a 64-bit signed integer from the slice in little-endian byte order. pub fn read_i64_le(&mut self) -> io::Result { let mut buf = [0u8; 8]; self.read_exact(&mut buf)?; Ok(i64::from_le_bytes(buf)) } - /// Reads a 16-bit signed integer from the slice in big-endian byte order. + /// Reads a 64-bit signed integer from the slice in big-endian byte order. pub fn read_i64_be(&mut self) -> io::Result { let mut buf = [0u8; 8]; self.read_exact(&mut buf)?; diff --git a/datasketches/src/frequencies/mod.rs b/datasketches/src/frequencies/mod.rs index 8ed7dcd2..1c994655 100644 --- a/datasketches/src/frequencies/mod.rs +++ b/datasketches/src/frequencies/mod.rs @@ -23,10 +23,11 @@ //! in Data Streams"](https://arxiv.org/abs/1705.07001) by Daniel Anderson, Pryce Bevan, Kevin Lang, //! Edo Liberty, Lee Rhodes, and Justin Thaler. //! -//! This sketch is useful for tracking approximate frequencies of items of type `T` that implements -//! [`FrequentItemValue`], with optional associated counts (`T` item, `u64` count) that are members -//! of a multiset of such items. The true frequency of an item is defined to be the sum of -//! associated counts. +//! This sketch tracks approximate frequencies of items of type `T` that implement [`Eq`] and +//! [`Hash`](std::hash::Hash), with optional associated counts (`T` item, `u64` count) that are +//! members of a multiset. The true frequency of an item is the sum of its associated counts. Core +//! updates and queries do not require [`FrequentItemValue`]; that trait is required only by the +//! built-in serialization and deserialization methods. //! //! This implementation provides the following capabilities: //! * Estimate the frequency of an item. @@ -89,6 +90,10 @@ //! //! # Serialization //! +//! The built-in serialization methods are available when the item type implements +//! [`FrequentItemValue`]. Sketches whose items implement only [`Eq`] and [`Hash`](std::hash::Hash) +//! can still use all core update and query operations. +//! //! ``` //! use datasketches::frequencies::FrequentItemsSketch; //! diff --git a/datasketches/src/hll/mod.rs b/datasketches/src/hll/mod.rs index b6fece07..262cccb1 100644 --- a/datasketches/src/hll/mod.rs +++ b/datasketches/src/hll/mod.rs @@ -42,11 +42,14 @@ //! //! # HLL Types //! -//! Three target HLL types are supported, trading precision for memory: +//! The three target HLL types are isomorphic representations of the same registers. Given the +//! same `lg_k` and input, they produce identical estimates and error distributions; they trade +//! memory layout and update performance, not statistical precision: //! -//! * [`HllType::Hll4`]: 4 bits per bucket (most compact) -//! * [`HllType::Hll6`]: 6 bits per bucket (balanced) -//! * [`HllType::Hll8`]: 8 bits per bucket (highest precision) +//! * [`HllType::Hll4`]: 4 bits per bucket plus an auxiliary table for rare exceptions (most +//! compact) +//! * [`HllType::Hll6`]: 6 bits per bucket (fixed-size middle ground) +//! * [`HllType::Hll8`]: 8 bits per bucket (largest and simplest representation) //! //! # Union Operations //! @@ -54,12 +57,14 @@ //! It maintains an internal "gadget" sketch that accumulates the union of all input sketches //! and automatically handles: //! -//! * Sketches with different `lg_k` precision levels (resizes/downsamples as needed) +//! * Sketches with different `lg_k` configurations (resizes/downsamples as needed) //! * Sketches in different modes (List, Set, or Array) //! * Sketches with different target HLL types //! -//! The union operation preserves cardinality estimation accuracy while enabling distributed -//! computation patterns where sketches are built independently and merged later. +//! The result's accuracy is determined by its final effective `lg_k`. Coupon-mode inputs are +//! replayed without forcing a reduction, but an array-mode input with a smaller `lg_k` causes the +//! union to downsample to that value. Downsampling reduces the number of registers and therefore +//! widens the error distribution; converting among HLL target types does not change accuracy. //! //! # Serialization //! diff --git a/datasketches/src/hll/union.rs b/datasketches/src/hll/union.rs index 87da53ed..725cb815 100644 --- a/datasketches/src/hll/union.rs +++ b/datasketches/src/hll/union.rs @@ -45,6 +45,12 @@ use crate::hll::mode::Mode; /// the union of all input sketches. It automatically handles sketches with /// different configurations and modes. /// +/// Coupon-mode inputs are replayed into the current gadget without reducing its `lg_k`. An +/// array-mode input with a smaller `lg_k` reduces the gadget to that value; larger array inputs are +/// downsampled to the gadget's current configuration. Once reduced, the effective `lg_k` remains +/// lower until [`reset`](Self::reset), so estimates and bounds reflect the reduced register count. +/// The requested [`HllType`] changes only the result representation, not its statistical accuracy. +/// /// See the [module level documentation](super) for more. #[derive(Debug, Clone)] pub struct HllUnion { @@ -114,7 +120,7 @@ impl HllUnion { /// Update the union with another sketch /// /// Merges the input sketch into the union's internal gadget, handling: - /// * Sketches with different lg_k values (resizes/downsamples as needed) + /// * Sketches with different `lg_k` values (resizes/downsamples as needed) /// * Sketches in different modes (List, Set, Array4/6/8) /// * Sketches with different target HLL types /// diff --git a/datasketches/src/thetafamily/theta/jaccard_similarity.rs b/datasketches/src/thetafamily/theta/jaccard_similarity.rs index 0a88a9e6..b556f86f 100644 --- a/datasketches/src/thetafamily/theta/jaccard_similarity.rs +++ b/datasketches/src/thetafamily/theta/jaccard_similarity.rs @@ -63,8 +63,9 @@ impl ThetaJaccardSimilarity { /// /// # Errors /// - /// Returns an error if either non-empty sketch was built with a seed different from this - /// operator's configured seed. + /// Returns an error if both sketches are logically non-empty and either was built with a seed + /// different from this operator's configured seed. Empty-input fast paths return an exact + /// result without checking seed compatibility. pub fn compute<'a, 'b>( &self, sketch_a: impl Into>, diff --git a/datasketches/src/thetafamily/tuple/jaccard_similarity.rs b/datasketches/src/thetafamily/tuple/jaccard_similarity.rs index e4cd7530..e65becbb 100644 --- a/datasketches/src/thetafamily/tuple/jaccard_similarity.rs +++ b/datasketches/src/thetafamily/tuple/jaccard_similarity.rs @@ -68,8 +68,9 @@ impl TupleJaccardSimilarity { /// /// # Errors /// - /// Returns an error if either non-empty sketch was built with a seed different from this - /// operator's configured seed. + /// Returns an error if both sketches are logically non-empty and either was built with a seed + /// different from this operator's configured seed. Empty-input fast paths return an exact + /// result without checking seed compatibility. pub fn compute<'a, 'b, S, T>( &self, sketch_a: impl Into>, From 02fbdff927857afb2ef869d24b3b93a755c85e0e Mon Sep 17 00:00:00 2001 From: tison Date: Tue, 11 Aug 2026 10:27:52 +0800 Subject: [PATCH 2/2] docs: address review feedback --- datasketches/src/frequencies/mod.rs | 7 ++----- datasketches/src/hll/mod.rs | 15 ++++++--------- datasketches/src/hll/union.rs | 14 ++++++-------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/datasketches/src/frequencies/mod.rs b/datasketches/src/frequencies/mod.rs index 1c994655..7dc15ec7 100644 --- a/datasketches/src/frequencies/mod.rs +++ b/datasketches/src/frequencies/mod.rs @@ -25,9 +25,7 @@ //! //! This sketch tracks approximate frequencies of items of type `T` that implement [`Eq`] and //! [`Hash`](std::hash::Hash), with optional associated counts (`T` item, `u64` count) that are -//! members of a multiset. The true frequency of an item is the sum of its associated counts. Core -//! updates and queries do not require [`FrequentItemValue`]; that trait is required only by the -//! built-in serialization and deserialization methods. +//! members of a multiset. The true frequency of an item is the sum of its associated counts. //! //! This implementation provides the following capabilities: //! * Estimate the frequency of an item. @@ -91,8 +89,7 @@ //! # Serialization //! //! The built-in serialization methods are available when the item type implements -//! [`FrequentItemValue`]. Sketches whose items implement only [`Eq`] and [`Hash`](std::hash::Hash) -//! can still use all core update and query operations. +//! [`FrequentItemValue`]. //! //! ``` //! use datasketches::frequencies::FrequentItemsSketch; diff --git a/datasketches/src/hll/mod.rs b/datasketches/src/hll/mod.rs index 262cccb1..90d0465c 100644 --- a/datasketches/src/hll/mod.rs +++ b/datasketches/src/hll/mod.rs @@ -46,25 +46,22 @@ //! same `lg_k` and input, they produce identical estimates and error distributions; they trade //! memory layout and update performance, not statistical precision: //! -//! * [`HllType::Hll4`]: 4 bits per bucket plus an auxiliary table for rare exceptions (most -//! compact) +//! * [`HllType::Hll4`]: 4 bits per bucket (most compact) //! * [`HllType::Hll6`]: 6 bits per bucket (fixed-size middle ground) //! * [`HllType::Hll8`]: 8 bits per bucket (largest and simplest representation) //! //! # Union Operations //! //! The [`HllUnion`] type enables combining multiple HLL sketches into a unified estimate. -//! It maintains an internal "gadget" sketch that accumulates the union of all input sketches -//! and automatically handles: +//! It accumulates the distinct values represented by all input sketches and automatically handles: //! //! * Sketches with different `lg_k` configurations (resizes/downsamples as needed) -//! * Sketches in different modes (List, Set, or Array) //! * Sketches with different target HLL types //! -//! The result's accuracy is determined by its final effective `lg_k`. Coupon-mode inputs are -//! replayed without forcing a reduction, but an array-mode input with a smaller `lg_k` causes the -//! union to downsample to that value. Downsampling reduces the number of registers and therefore -//! widens the error distribution; converting among HLL target types does not change accuracy. +//! The result's accuracy is determined by its final effective `lg_k`. Merging sketches with +//! different configurations may reduce this value. Once reduced, it remains lower until the union +//! is reset. A lower effective `lg_k` widens the error distribution; converting among HLL target +//! types does not change accuracy. //! //! # Serialization //! diff --git a/datasketches/src/hll/union.rs b/datasketches/src/hll/union.rs index 725cb815..a710fd9b 100644 --- a/datasketches/src/hll/union.rs +++ b/datasketches/src/hll/union.rs @@ -41,15 +41,13 @@ use crate::hll::mode::Mode; /// An HLL Union for combining multiple HLL sketches. /// -/// The union maintains an internal sketch (the "gadget") that accumulates -/// the union of all input sketches. It automatically handles sketches with -/// different configurations and modes. +/// The union accumulates the distinct values represented by all input sketches and automatically +/// handles sketches with different configurations. /// -/// Coupon-mode inputs are replayed into the current gadget without reducing its `lg_k`. An -/// array-mode input with a smaller `lg_k` reduces the gadget to that value; larger array inputs are -/// downsampled to the gadget's current configuration. Once reduced, the effective `lg_k` remains -/// lower until [`reset`](Self::reset), so estimates and bounds reflect the reduced register count. -/// The requested [`HllType`] changes only the result representation, not its statistical accuracy. +/// Merging sketches with different configurations may reduce the union's effective `lg_k`. Once +/// reduced, it remains lower until [`reset`](Self::reset), so estimates and bounds reflect the +/// reduced register count. The requested [`HllType`] changes only the result representation, not +/// its statistical accuracy. /// /// See the [module level documentation](super) for more. #[derive(Debug, Clone)]