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/02 19:54:12 UTC
(datasketches-rust) branch main updated: refactor: simplify hash and theta module layout (#179)
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 ea5ec01 refactor: simplify hash and theta module layout (#179)
ea5ec01 is described below
commit ea5ec018befa416767df9b98910b312a36164942
Author: tison <wa...@gmail.com>
AuthorDate: Mon Aug 3 03:54:02 2026 +0800
refactor: simplify hash and theta module layout (#179)
Signed-off-by: tison <wa...@gmail.com>
---
.gitignore | 2 +-
CHANGELOG.md | 1 +
datasketches/src/bloom/builder.rs | 18 +-
datasketches/src/bloom/mod.rs | 9 +-
datasketches/src/bloom/sketch.rs | 29 +++-
datasketches/src/common/resize.rs | 3 +-
datasketches/src/countmin/mod.rs | 6 +-
datasketches/src/countmin/sketch.rs | 49 +++---
datasketches/src/cpc/sketch.rs | 12 +-
datasketches/src/cpc/union.rs | 4 +-
datasketches/src/error.rs | 5 +-
datasketches/src/frequencies/mod.rs | 8 +-
datasketches/src/frequencies/sketch.rs | 67 +++++---
datasketches/src/hash/mod.rs | 4 +
datasketches/src/hash/murmurhash.rs | 13 +-
.../{hash_value => hash/value}/canonical_float.rs | 14 +-
datasketches/src/{hash_value => hash/value}/mod.rs | 97 ++++++++++-
.../{hash_value => hash/value}/natural_extend.rs | 34 ++--
.../src/{hash_value => hash/value}/raw_bytes.rs | 28 +--
.../src/{hash_value => hash/value}/sign_extend.rs | 40 +++--
datasketches/src/hash/xxhash.rs | 14 +-
datasketches/src/hash_value/value.rs | 116 -------------
datasketches/src/hll/mod.rs | 23 ++-
datasketches/src/hll/sketch.rs | 50 +++---
datasketches/src/hll/union.rs | 22 ++-
datasketches/src/lib.rs | 13 +-
datasketches/src/tdigest/mod.rs | 3 +-
datasketches/src/tdigest/sketch.rs | 130 +++++++-------
.../common/bounds_binomial_proportions.rs | 188 ---------------------
.../common/a_not_b.rs | 0
.../common/binomial_bounds.rs | 165 ++++++++++++++++++
.../common/constants.rs | 0
.../common/hash_table.rs | 0
.../common/intersection.rs | 0
.../common/jaccard_similarity.rs | 6 +-
.../{theta_family => thetafamily}/common/mod.rs | 1 -
.../{theta_family => thetafamily}/common/union.rs | 0
.../src/{theta_family => thetafamily}/mod.rs | 0
.../{theta_family => thetafamily}/theta/a_not_b.rs | 4 +-
.../theta/bit_pack.rs | 0
.../theta/hash_table.rs | 0
.../theta/intersection.rs | 0
.../theta/jaccard_similarity.rs | 4 +-
.../src/{theta_family => thetafamily}/theta/mod.rs | 3 +-
.../theta/serialization.rs | 0
.../{theta_family => thetafamily}/theta/sketch.rs | 37 ++--
.../{theta_family => thetafamily}/theta/union.rs | 12 +-
.../{theta_family => thetafamily}/tuple/a_not_b.rs | 5 +-
.../tuple/hash_table.rs | 0
.../tuple/intersection.rs | 0
.../tuple/jaccard_similarity.rs | 5 +-
.../src/{theta_family => thetafamily}/tuple/mod.rs | 4 +-
.../{theta_family => thetafamily}/tuple/policy.rs | 0
.../tuple/serialization.rs | 0
.../{theta_family => thetafamily}/tuple/sketch.rs | 16 +-
.../{theta_family => thetafamily}/tuple/union.rs | 6 +-
datasketches/tests/serde_tests/hll.rs | 2 +-
datasketches/tests/theta_test/sketch.rs | 18 +-
datasketches/tests/tuple_test/sketch.rs | 6 +-
59 files changed, 703 insertions(+), 593 deletions(-)
diff --git a/.gitignore b/.gitignore
index f03006e..fa8608c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,4 +38,4 @@
**/target
# Generated files
-*.sk
\ No newline at end of file
+*.sk
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4b618ef..997607e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ All significant changes to this project will be documented in this file.
### Breaking changes
+* Move the `hash_value` module to `hash::value`.
* Remove `ThetaSketch::builder`, `ThetaUnion::builder`, and `TupleSketch::builder`. Construct `ThetaSketchBuilder`, `ThetaUnionBuilder`, and `TupleSketchBuilder` with `Default::default` instead.
* Standardize Theta and Tuple set-operation constructors. Zero-configuration operators use
`Default::default()`, `TupleIntersection::new(policy)` uses the default seed, and `with_seed`
diff --git a/datasketches/src/bloom/builder.rs b/datasketches/src/bloom/builder.rs
index 7622160..67f62b2 100644
--- a/datasketches/src/bloom/builder.rs
+++ b/datasketches/src/bloom/builder.rs
@@ -62,7 +62,8 @@ impl BloomFilterBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// // Optimal for 10,000 items with 1% FPP
/// let filter = BloomFilterBuilder::with_accuracy(10_000, 0.01)
/// .seed(42)
@@ -107,7 +108,8 @@ impl BloomFilterBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let filter = BloomFilterBuilder::with_size(10_000, 7).build();
/// ```
pub fn with_size(num_bits: u64, num_hashes: u16) -> Self {
@@ -140,7 +142,8 @@ impl BloomFilterBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let filter = BloomFilterBuilder::with_accuracy(100, 0.01)
/// .seed(12345)
/// .build();
@@ -176,7 +179,8 @@ impl BloomFilterBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let bits = BloomFilterBuilder::suggest_num_bits(1000, 0.01);
/// assert!(bits > 9000 && bits < 10000); // ~9585 bits
/// ```
@@ -198,7 +202,8 @@ impl BloomFilterBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let hashes = BloomFilterBuilder::suggest_num_hashes_from_accuracy(1000, 10000);
/// assert_eq!(hashes, 7); // Optimal k ≈ 6.93
/// ```
@@ -222,7 +227,8 @@ impl BloomFilterBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let hashes = BloomFilterBuilder::suggest_num_hashes_from_fpp(0.01);
/// assert_eq!(hashes, 7); // -log2(0.01) ≈ 6.64
/// ```
diff --git a/datasketches/src/bloom/mod.rs b/datasketches/src/bloom/mod.rs
index 3638ee2..3ee0df1 100644
--- a/datasketches/src/bloom/mod.rs
+++ b/datasketches/src/bloom/mod.rs
@@ -61,7 +61,8 @@
//! Automatically calculates optimal size and hash functions:
//!
//! ```
-//! # use datasketches::bloom::BloomFilterBuilder;
+//! use datasketches::bloom::BloomFilterBuilder;
+//!
//! let filter = BloomFilterBuilder::with_accuracy(
//! 10_000, // Expected max items
//! 0.01, // Target false positive probability (1%)
@@ -75,7 +76,8 @@
//! Specify requested bit count and hash functions (rounded up to a multiple of 64 bits):
//!
//! ```
-//! # use datasketches::bloom::BloomFilterBuilder;
+//! use datasketches::bloom::BloomFilterBuilder;
+//!
//! let filter = BloomFilterBuilder::with_size(
//! 95_851, // Number of bits
//! 7, // Number of hash functions
@@ -88,7 +90,8 @@
//! Bloom filters support efficient set operations:
//!
//! ```
-//! # use datasketches::bloom::BloomFilterBuilder;
+//! use datasketches::bloom::BloomFilterBuilder;
+//!
//! let mut filter1 = BloomFilterBuilder::with_accuracy(100, 0.01).build();
//! let mut filter2 = BloomFilterBuilder::with_accuracy(100, 0.01).build();
//!
diff --git a/datasketches/src/bloom/sketch.rs b/datasketches/src/bloom/sketch.rs
index ee17cff..081f6d4 100644
--- a/datasketches/src/bloom/sketch.rs
+++ b/datasketches/src/bloom/sketch.rs
@@ -61,7 +61,8 @@ impl BloomFilter {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let mut filter = BloomFilterBuilder::with_accuracy(100, 0.01).build();
/// filter.insert("apple");
///
@@ -85,7 +86,8 @@ impl BloomFilter {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let mut filter = BloomFilterBuilder::with_accuracy(100, 0.01).build();
///
/// let was_present = filter.contains_and_insert(&"apple");
@@ -108,7 +110,8 @@ impl BloomFilter {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let mut filter = BloomFilterBuilder::with_accuracy(100, 0.01).build();
///
/// filter.insert("apple");
@@ -129,7 +132,8 @@ impl BloomFilter {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let mut filter = BloomFilterBuilder::with_accuracy(100, 0.01).build();
/// filter.insert("apple");
/// assert!(!filter.is_empty());
@@ -156,7 +160,8 @@ impl BloomFilter {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let mut f1 = BloomFilterBuilder::with_accuracy(100, 0.01)
/// .seed(123)
/// .build();
@@ -198,7 +203,8 @@ impl BloomFilter {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let mut f1 = BloomFilterBuilder::with_accuracy(100, 0.01)
/// .seed(123)
/// .build();
@@ -238,7 +244,8 @@ impl BloomFilter {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::BloomFilterBuilder;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let mut filter = BloomFilterBuilder::with_accuracy(100, 0.01).build();
/// filter.insert("apple");
///
@@ -324,7 +331,9 @@ impl BloomFilter {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::{BloomFilter, BloomFilterBuilder};
+ /// use datasketches::bloom::BloomFilter;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let mut filter = BloomFilterBuilder::with_accuracy(100, 0.01).build();
/// filter.insert("test");
///
@@ -387,7 +396,9 @@ impl BloomFilter {
/// # Examples
///
/// ```
- /// # use datasketches::bloom::{BloomFilter, BloomFilterBuilder};
+ /// use datasketches::bloom::BloomFilter;
+ /// use datasketches::bloom::BloomFilterBuilder;
+ ///
/// let original = BloomFilterBuilder::with_accuracy(100, 0.01).build();
/// let bytes = original.serialize();
///
diff --git a/datasketches/src/common/resize.rs b/datasketches/src/common/resize.rs
index 0dbb1d5..5fa4742 100644
--- a/datasketches/src/common/resize.rs
+++ b/datasketches/src/common/resize.rs
@@ -36,7 +36,8 @@
/// # Examples
///
/// ```
-/// # use datasketches::common::ResizeFactor;
+/// use datasketches::common::ResizeFactor;
+///
/// let factor = ResizeFactor::X4;
/// assert_eq!(factor.value(), 4);
/// assert_eq!(factor.lg_value(), 2);
diff --git a/datasketches/src/countmin/mod.rs b/datasketches/src/countmin/mod.rs
index 4331c20..9572f11 100644
--- a/datasketches/src/countmin/mod.rs
+++ b/datasketches/src/countmin/mod.rs
@@ -23,7 +23,8 @@
//! # Usage
//!
//! ```
-//! # use datasketches::countmin::CountMinSketch;
+//! use datasketches::countmin::CountMinSketch;
+//!
//! let mut sketch = CountMinSketch::<i64>::new(5, 256);
//! sketch.update("apple");
//! sketch.update_with_weight("banana", 3);
@@ -33,7 +34,8 @@
//! # Configuration Helpers
//!
//! ```
-//! # use datasketches::countmin::CountMinSketch;
+//! use datasketches::countmin::CountMinSketch;
+//!
//! let buckets = CountMinSketch::<i64>::suggest_num_buckets(0.01);
//! let hashes = CountMinSketch::<i64>::suggest_num_hashes(0.99);
//! let sketch = CountMinSketch::<i64>::new(hashes, buckets);
diff --git a/datasketches/src/countmin/sketch.rs b/datasketches/src/countmin/sketch.rs
index 96c8bd8..a2dcb58 100644
--- a/datasketches/src/countmin/sketch.rs
+++ b/datasketches/src/countmin/sketch.rs
@@ -63,7 +63,8 @@ impl<T: CountMinValue> CountMinSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::countmin::CountMinSketch;
+ /// use datasketches::countmin::CountMinSketch;
+ ///
/// let sketch = CountMinSketch::<i64>::new(4, 128);
/// assert_eq!(sketch.num_buckets(), 128);
/// ```
@@ -84,7 +85,8 @@ impl<T: CountMinValue> CountMinSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::countmin::CountMinSketch;
+ /// use datasketches::countmin::CountMinSketch;
+ ///
/// let sketch = CountMinSketch::<i64>::with_seed(4, 64, 42);
/// assert_eq!(sketch.seed(), 42);
/// ```
@@ -155,7 +157,8 @@ impl<T: CountMinValue> CountMinSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::countmin::CountMinSketch;
+ /// use datasketches::countmin::CountMinSketch;
+ ///
/// let mut sketch = CountMinSketch::<i64>::new(4, 128);
/// sketch.update("apple");
/// assert!(sketch.estimate("apple") >= 1);
@@ -169,7 +172,8 @@ impl<T: CountMinValue> CountMinSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::countmin::CountMinSketch;
+ /// use datasketches::countmin::CountMinSketch;
+ ///
/// let mut sketch = CountMinSketch::<i64>::new(4, 128);
/// sketch.update_with_weight("banana", 3);
/// assert!(sketch.estimate("banana") >= 3);
@@ -193,7 +197,8 @@ impl<T: CountMinValue> CountMinSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::countmin::CountMinSketch;
+ /// use datasketches::countmin::CountMinSketch;
+ ///
/// let mut sketch = CountMinSketch::<i64>::new(4, 128);
/// sketch.update_with_weight("pear", 2);
/// assert!(sketch.estimate("pear") >= 2);
@@ -233,7 +238,8 @@ impl<T: CountMinValue> CountMinSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::countmin::CountMinSketch;
+ /// use datasketches::countmin::CountMinSketch;
+ ///
/// let mut left = CountMinSketch::<i64>::new(4, 128);
/// let mut right = CountMinSketch::<i64>::new(4, 128);
///
@@ -263,9 +269,10 @@ impl<T: CountMinValue> CountMinSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::countmin::CountMinSketch;
- /// # let mut sketch = CountMinSketch::<i64>::new(4, 128);
- /// # sketch.update("apple");
+ /// use datasketches::countmin::CountMinSketch;
+ ///
+ /// let mut sketch = CountMinSketch::<i64>::new(4, 128);
+ /// sketch.update("apple");
/// let bytes = sketch.serialize();
/// let decoded = CountMinSketch::<i64>::deserialize(&bytes).unwrap();
/// assert!(decoded.estimate("apple") >= 1);
@@ -308,10 +315,11 @@ impl<T: CountMinValue> CountMinSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::countmin::CountMinSketch;
- /// # let mut sketch = CountMinSketch::<i64>::new(4, 64);
- /// # sketch.update("apple");
- /// # let bytes = sketch.serialize();
+ /// use datasketches::countmin::CountMinSketch;
+ ///
+ /// let mut sketch = CountMinSketch::<i64>::new(4, 64);
+ /// sketch.update("apple");
+ /// let bytes = sketch.serialize();
/// let decoded = CountMinSketch::<i64>::deserialize(&bytes).unwrap();
/// assert!(decoded.estimate("apple") >= 1);
/// ```
@@ -324,10 +332,11 @@ impl<T: CountMinValue> CountMinSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::countmin::CountMinSketch;
- /// # let mut sketch = CountMinSketch::<i64>::with_seed(4, 64, 7);
- /// # sketch.update("apple");
- /// # let bytes = sketch.serialize();
+ /// use datasketches::countmin::CountMinSketch;
+ ///
+ /// let mut sketch = CountMinSketch::<i64>::with_seed(4, 64, 7);
+ /// sketch.update("apple");
+ /// let bytes = sketch.serialize();
/// let decoded = CountMinSketch::<i64>::deserialize_with_seed(&bytes, 7).unwrap();
/// assert!(decoded.estimate("apple") >= 1);
/// ```
@@ -425,7 +434,8 @@ impl<T: UnsignedCountMinValue> CountMinSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::countmin::CountMinSketch;
+ /// use datasketches::countmin::CountMinSketch;
+ ///
/// let mut sketch = CountMinSketch::<u64>::new(4, 128);
/// sketch.update_with_weight("apple", 3);
/// sketch.halve();
@@ -446,7 +456,8 @@ impl<T: UnsignedCountMinValue> CountMinSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::countmin::CountMinSketch;
+ /// use datasketches::countmin::CountMinSketch;
+ ///
/// let mut sketch = CountMinSketch::<u64>::new(4, 128);
/// sketch.update_with_weight("apple", 3);
/// sketch.decay(0.5);
diff --git a/datasketches/src/cpc/sketch.rs b/datasketches/src/cpc/sketch.rs
index 9b61fa9..61f6c9b 100644
--- a/datasketches/src/cpc/sketch.rs
+++ b/datasketches/src/cpc/sketch.rs
@@ -171,14 +171,14 @@ impl CpcSketch {
/// Update the sketch with a hashable value.
///
- /// You may use [`hash_value`](crate::hash_value) wrappers when matching other datasketches
- /// implementations require a specific value hashing strategy.
+ /// You may use [`hash::value`](crate::hash::value) wrappers when another DataSketches
+ /// implementation requires a specific value hashing strategy.
///
/// # Examples
///
/// ```rust
/// use datasketches::cpc::CpcSketch;
- /// use datasketches::hash_value;
+ /// use datasketches::hash::value::canonical_float;
///
/// let mut sketch = CpcSketch::with_seed(11, 123);
/// sketch.update(1);
@@ -186,9 +186,9 @@ impl CpcSketch {
/// sketch.update(3);
///
/// let mut sketch = CpcSketch::with_seed(11, 123);
- /// sketch.update(hash_value::canonical_float::from_f64(1.5));
- /// sketch.update(hash_value::canonical_float::from_f64(2.5));
- /// sketch.update(hash_value::canonical_float::from_f64(3.5));
+ /// sketch.update(canonical_float::from_f64(1.5));
+ /// sketch.update(canonical_float::from_f64(2.5));
+ /// sketch.update(canonical_float::from_f64(3.5));
/// ```
pub fn update<T: Hash>(&mut self, value: T) {
let mut hasher = MurmurHash3X64128::with_seed(self.seed);
diff --git a/datasketches/src/cpc/union.rs b/datasketches/src/cpc/union.rs
index a983630..9dc2a6c 100644
--- a/datasketches/src/cpc/union.rs
+++ b/datasketches/src/cpc/union.rs
@@ -121,8 +121,8 @@ impl CpcUnion {
/// # Examples
///
/// ```
- /// # use datasketches::cpc::CpcUnion;
- /// # use datasketches::cpc::CpcSketch;
+ /// use datasketches::cpc::CpcSketch;
+ /// use datasketches::cpc::CpcUnion;
///
/// let mut s1 = CpcSketch::new(12);
/// s1.update(&"apple");
diff --git a/datasketches/src/error.rs b/datasketches/src/error.rs
index 6e614ee..a4fe5b9 100644
--- a/datasketches/src/error.rs
+++ b/datasketches/src/error.rs
@@ -50,8 +50,9 @@ impl fmt::Display for ErrorKind {
/// # Examples
///
/// ```
-/// # use datasketches::error::Error;
-/// # use datasketches::error::ErrorKind;
+/// use datasketches::error::Error;
+/// use datasketches::error::ErrorKind;
+///
/// let err = Error::new(ErrorKind::InvalidArgument, "bad input");
/// assert_eq!(err.kind(), ErrorKind::InvalidArgument);
/// assert_eq!(err.message(), "bad input");
diff --git a/datasketches/src/frequencies/mod.rs b/datasketches/src/frequencies/mod.rs
index d5e7cf0..8ed7dcd 100644
--- a/datasketches/src/frequencies/mod.rs
+++ b/datasketches/src/frequencies/mod.rs
@@ -77,8 +77,9 @@
//! # Examples
//!
//! ```
-//! # use datasketches::frequencies::ErrorType;
-//! # use datasketches::frequencies::FrequentItemsSketch;
+//! use datasketches::frequencies::ErrorType;
+//! use datasketches::frequencies::FrequentItemsSketch;
+//!
//! let mut sketch = FrequentItemsSketch::<i64>::new(64);
//! sketch.update_with_count(1, 3);
//! sketch.update(2);
@@ -89,7 +90,8 @@
//! # Serialization
//!
//! ```
-//! # use datasketches::frequencies::FrequentItemsSketch;
+//! use datasketches::frequencies::FrequentItemsSketch;
+//!
//! let mut sketch = FrequentItemsSketch::<i64>::new(64);
//! sketch.update_with_count(42, 2);
//!
diff --git a/datasketches/src/frequencies/sketch.rs b/datasketches/src/frequencies/sketch.rs
index bb0a88f..4f4374d 100644
--- a/datasketches/src/frequencies/sketch.rs
+++ b/datasketches/src/frequencies/sketch.rs
@@ -115,7 +115,8 @@ impl<T: Eq + Hash> FrequentItemsSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::frequencies::FrequentItemsSketch;
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
/// let mut sketch = FrequentItemsSketch::<i64>::new(64);
/// sketch.update(1);
/// sketch.update(2);
@@ -154,7 +155,8 @@ impl<T: Eq + Hash> FrequentItemsSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::frequencies::FrequentItemsSketch;
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
/// let mut sketch = FrequentItemsSketch::<i64>::new(64);
/// sketch.update_with_count(10, 2);
/// assert!(sketch.estimate(&10) >= 2);
@@ -250,7 +252,8 @@ impl<T: Eq + Hash> FrequentItemsSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::frequencies::FrequentItemsSketch;
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
/// let mut sketch = FrequentItemsSketch::<i64>::new(64);
/// sketch.update(42);
/// assert!(sketch.estimate(&42) >= 1);
@@ -266,7 +269,8 @@ impl<T: Eq + Hash> FrequentItemsSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::frequencies::FrequentItemsSketch;
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
/// let mut sketch = FrequentItemsSketch::<i64>::new(64);
/// sketch.update_with_count(10, 3);
/// assert!(sketch.estimate(&10) >= 3);
@@ -290,7 +294,8 @@ impl<T: Eq + Hash> FrequentItemsSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::frequencies::FrequentItemsSketch;
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
/// let mut sketch = FrequentItemsSketch::<String>::new(64);
/// sketch.update_ref("nginx");
/// sketch.update_ref("nginx"); // no allocation on the second hit
@@ -313,7 +318,8 @@ impl<T: Eq + Hash> FrequentItemsSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::frequencies::FrequentItemsSketch;
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
/// let mut sketch = FrequentItemsSketch::<String>::new(64);
/// sketch.update_with_count_ref("gzip", 3);
/// assert!(sketch.estimate("gzip") >= 3);
@@ -340,7 +346,8 @@ impl<T: Eq + Hash> FrequentItemsSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::frequencies::FrequentItemsSketch;
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
/// let mut left = FrequentItemsSketch::<i64>::new(64);
/// let mut right = FrequentItemsSketch::<i64>::new(64);
/// left.update(1);
@@ -375,8 +382,9 @@ impl<T: Eq + Hash> FrequentItemsSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::frequencies::ErrorType;
- /// # use datasketches::frequencies::FrequentItemsSketch;
+ /// use datasketches::frequencies::ErrorType;
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
/// let mut sketch = FrequentItemsSketch::<i64>::new(64);
/// sketch.update_with_count(1, 5);
/// sketch.update(2);
@@ -400,8 +408,9 @@ impl<T: Eq + Hash> FrequentItemsSketch<T> {
/// # Examples
///
/// ```
- /// # use datasketches::frequencies::ErrorType;
- /// # use datasketches::frequencies::FrequentItemsSketch;
+ /// use datasketches::frequencies::ErrorType;
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
/// let mut sketch = FrequentItemsSketch::<i64>::new(64);
/// sketch.update_with_count(1, 5);
/// sketch.update(2);
@@ -607,9 +616,10 @@ impl<T: FrequentItemValue> FrequentItemsSketch<T> {
/// Built-in support for `i64`:
///
/// ```
- /// # use datasketches::frequencies::FrequentItemsSketch;
- /// # let mut sketch = FrequentItemsSketch::<i64>::new(64);
- /// # sketch.update_with_count(7, 2);
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
+ /// let mut sketch = FrequentItemsSketch::<i64>::new(64);
+ /// sketch.update_with_count(7, 2);
/// let bytes = sketch.serialize();
/// let decoded = FrequentItemsSketch::<i64>::deserialize(&bytes).unwrap();
/// assert!(decoded.estimate(&7) >= 2);
@@ -618,10 +628,11 @@ impl<T: FrequentItemValue> FrequentItemsSketch<T> {
/// Built-in support for `String`:
///
/// ```
- /// # use datasketches::frequencies::FrequentItemsSketch;
- /// # let mut sketch = FrequentItemsSketch::<String>::new(64);
- /// # let apple = "apple".to_string();
- /// # sketch.update_with_count(apple.clone(), 2);
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
+ /// let mut sketch = FrequentItemsSketch::<String>::new(64);
+ /// let apple = "apple".to_string();
+ /// sketch.update_with_count(apple.clone(), 2);
/// let bytes = sketch.serialize();
/// let decoded = FrequentItemsSketch::<String>::deserialize(&bytes).unwrap();
/// assert!(decoded.estimate(&apple) >= 2);
@@ -637,10 +648,11 @@ impl<T: FrequentItemValue> FrequentItemsSketch<T> {
/// Built-in support for `i64`:
///
/// ```
- /// # use datasketches::frequencies::FrequentItemsSketch;
- /// # let mut sketch = FrequentItemsSketch::<i64>::new(64);
- /// # sketch.update_with_count(7, 2);
- /// # let bytes = sketch.serialize();
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
+ /// let mut sketch = FrequentItemsSketch::<i64>::new(64);
+ /// sketch.update_with_count(7, 2);
+ /// let bytes = sketch.serialize();
/// let decoded = FrequentItemsSketch::<i64>::deserialize(&bytes).unwrap();
/// assert!(decoded.estimate(&7) >= 2);
/// ```
@@ -648,11 +660,12 @@ impl<T: FrequentItemValue> FrequentItemsSketch<T> {
/// Built-in support for `String`:
///
/// ```
- /// # use datasketches::frequencies::FrequentItemsSketch;
- /// # let mut sketch = FrequentItemsSketch::<String>::new(64);
- /// # let apple = "apple".to_string();
- /// # sketch.update_with_count(apple.clone(), 2);
- /// # let bytes = sketch.serialize();
+ /// use datasketches::frequencies::FrequentItemsSketch;
+ ///
+ /// let mut sketch = FrequentItemsSketch::<String>::new(64);
+ /// let apple = "apple".to_string();
+ /// sketch.update_with_count(apple.clone(), 2);
+ /// let bytes = sketch.serialize();
/// let decoded = FrequentItemsSketch::<String>::deserialize(&bytes).unwrap();
/// assert!(decoded.estimate(&apple) >= 2);
/// ```
diff --git a/datasketches/src/hash/mod.rs b/datasketches/src/hash/mod.rs
index ef4d745..41d879c 100644
--- a/datasketches/src/hash/mod.rs
+++ b/datasketches/src/hash/mod.rs
@@ -15,6 +15,10 @@
// specific language governing permissions and limitations
// under the License.
+//! Hashing support for sketches.
+
+pub mod value;
+
#[cfg(any(
feature = "countmin",
feature = "cpc",
diff --git a/datasketches/src/hash/murmurhash.rs b/datasketches/src/hash/murmurhash.rs
index 03345f2..1e0a383 100644
--- a/datasketches/src/hash/murmurhash.rs
+++ b/datasketches/src/hash/murmurhash.rs
@@ -18,6 +18,7 @@
use std::hash::Hasher;
use crate::hash::DEFAULT_UPDATE_SEED;
+use crate::hash::read_u64_le;
const C1: u64 = 0x87c37b91114253d5;
const C2: u64 = 0x4cf5ad432745937f;
@@ -55,7 +56,7 @@ impl MurmurHash3X64128 {
if rem > 0 {
if rem > 8 {
// read k2 little endian
- let mut k2 = super::read_u64_le(&self.buf[8..rem]);
+ let mut k2 = read_u64_le(&self.buf[8..rem]);
// mix k2
k2 = k2.wrapping_mul(C2);
k2 = k2.rotate_left(33);
@@ -65,7 +66,7 @@ impl MurmurHash3X64128 {
// read k1 little endian
let k1_len = rem.min(8);
- let mut k1 = super::read_u64_le(&self.buf[..k1_len]);
+ let mut k1 = read_u64_le(&self.buf[..k1_len]);
// mix k1
k1 = k1.wrapping_mul(C1);
k1 = k1.rotate_left(31);
@@ -135,8 +136,8 @@ impl Hasher for MurmurHash3X64128 {
let wanted = 16 - self.buf_len;
self.buf[self.buf_len..].copy_from_slice(&bytes[..wanted]);
- let k1 = super::read_u64_le(&self.buf[0..8]);
- let k2 = super::read_u64_le(&self.buf[8..16]);
+ let k1 = read_u64_le(&self.buf[0..8]);
+ let k2 = read_u64_le(&self.buf[8..16]);
self.update(k1, k2);
bytes = &bytes[wanted..];
@@ -152,8 +153,8 @@ impl Hasher for MurmurHash3X64128 {
let lo = i << 4;
let mi = lo + 8;
let hi = mi + 8;
- let k1 = super::read_u64_le(&bytes[lo..mi]);
- let k2 = super::read_u64_le(&bytes[mi..hi]);
+ let k1 = read_u64_le(&bytes[lo..mi]);
+ let k2 = read_u64_le(&bytes[mi..hi]);
self.update(k1, k2);
}
diff --git a/datasketches/src/hash_value/canonical_float.rs b/datasketches/src/hash/value/canonical_float.rs
similarity index 93%
rename from datasketches/src/hash_value/canonical_float.rs
rename to datasketches/src/hash/value/canonical_float.rs
index 354cffd..6ed9387 100644
--- a/datasketches/src/hash_value/canonical_float.rs
+++ b/datasketches/src/hash/value/canonical_float.rs
@@ -26,8 +26,8 @@
use std::hash::Hash;
use std::hash::Hasher;
-use super::value::HashStrategy;
-use super::value::Value;
+use super::HashStrategy;
+use super::Value;
/// A floating-point value wrapper that uses canonical floating-point hashing.
///
@@ -47,8 +47,9 @@ pub struct CanonicalFloatStrategy;
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::canonical_float;
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::canonical_float;
+///
/// assert_eq!(
/// calculate_hash(canonical_float::from_f32(0.0)),
/// calculate_hash(canonical_float::from_f32(-0.0))
@@ -74,8 +75,9 @@ pub fn from_f32(v: f32) -> CanonicalFloat<f32> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::canonical_float;
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::canonical_float;
+///
/// assert_eq!(
/// calculate_hash(canonical_float::from_f64(0.0)),
/// calculate_hash(canonical_float::from_f64(-0.0))
diff --git a/datasketches/src/hash_value/mod.rs b/datasketches/src/hash/value/mod.rs
similarity index 62%
rename from datasketches/src/hash_value/mod.rs
rename to datasketches/src/hash/value/mod.rs
index 61e6024..2455965 100644
--- a/datasketches/src/hash_value/mod.rs
+++ b/datasketches/src/hash/value/mod.rs
@@ -76,10 +76,105 @@ pub mod canonical_float;
pub mod natural_extend;
pub mod raw_bytes;
pub mod sign_extend;
-pub mod value;
+use std::cmp::Ordering;
+use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;
+use std::marker::PhantomData;
+use std::ops::Deref;
+use std::ops::DerefMut;
+
+/// A value wrapper that hashes its inner value with strategy `S`.
+///
+/// Most users should prefer the strategy-specific constructors.
+#[doc(hidden)]
+pub struct Value<T, S> {
+ value: T,
+ strategy: PhantomData<fn() -> S>,
+}
+
+impl<T, S> Value<T, S> {
+ /// Create a value wrapper.
+ #[inline(always)]
+ pub fn new(value: T) -> Self {
+ Self {
+ value,
+ strategy: PhantomData,
+ }
+ }
+
+ /// Get the value out.
+ #[inline(always)]
+ pub fn into_inner(self) -> T {
+ self.value
+ }
+}
+
+impl<T, S> Deref for Value<T, S> {
+ type Target = T;
+
+ fn deref(&self) -> &Self::Target {
+ &self.value
+ }
+}
+
+impl<T, S> DerefMut for Value<T, S> {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.value
+ }
+}
+
+impl<T: Clone, S> Clone for Value<T, S> {
+ fn clone(&self) -> Self {
+ Self::new(self.value.clone())
+ }
+}
+
+impl<T: Copy, S> Copy for Value<T, S> {}
+
+impl<T: PartialEq, S> PartialEq for Value<T, S> {
+ fn eq(&self, other: &Self) -> bool {
+ self.value == other.value
+ }
+}
+
+impl<T: Eq, S> Eq for Value<T, S> {}
+
+impl<T: PartialOrd, S> PartialOrd for Value<T, S> {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ self.value.partial_cmp(&other.value)
+ }
+}
+
+impl<T: Ord, S> Ord for Value<T, S> {
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.value.cmp(&other.value)
+ }
+}
+
+impl<T: fmt::Debug, S> fmt::Debug for Value<T, S> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Debug::fmt(&self.value, f)
+ }
+}
+
+impl<T: fmt::Display, S> fmt::Display for Value<T, S> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Display::fmt(&self.value, f)
+ }
+}
+
+impl<T, S: HashStrategy<T>> Hash for Value<T, S> {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ S::hash(&self.value, state);
+ }
+}
+
+#[doc(hidden)]
+pub trait HashStrategy<T> {
+ fn hash<H: Hasher>(value: &T, state: &mut H);
+}
#[doc(hidden)] // for doctest
pub fn calculate_hash<T: Hash>(t: T) -> u64 {
diff --git a/datasketches/src/hash_value/natural_extend.rs b/datasketches/src/hash/value/natural_extend.rs
similarity index 84%
rename from datasketches/src/hash_value/natural_extend.rs
rename to datasketches/src/hash/value/natural_extend.rs
index 0717b50..375fcad 100644
--- a/datasketches/src/hash_value/natural_extend.rs
+++ b/datasketches/src/hash/value/natural_extend.rs
@@ -25,8 +25,8 @@
use std::hash::Hash;
use std::hash::Hasher;
-use super::value::HashStrategy;
-use super::value::Value;
+use super::HashStrategy;
+use super::Value;
/// An integer value wrapper that uses Rust's natural integer widening before hashing.
///
@@ -42,8 +42,9 @@ pub struct NaturalExtendStrategy;
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::natural_extend::from_i8;
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::natural_extend::from_i8;
+///
/// assert_eq!(calculate_hash(from_i8(-1)), calculate_hash(-1i64));
/// assert_eq!(calculate_hash(from_i8(42)), calculate_hash(42i64));
/// ```
@@ -56,8 +57,9 @@ pub fn from_i8(v: i8) -> NaturalExtend<i8> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::natural_extend::from_u8;
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::natural_extend::from_u8;
+///
/// assert_eq!(calculate_hash(from_u8(255)), calculate_hash(255u64));
/// assert_eq!(calculate_hash(from_u8(42)), calculate_hash(42u64));
/// ```
@@ -70,8 +72,9 @@ pub fn from_u8(v: u8) -> NaturalExtend<u8> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::natural_extend::from_i16;
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::natural_extend::from_i16;
+///
/// assert_eq!(calculate_hash(from_i16(-1)), calculate_hash(-1i64));
/// assert_eq!(calculate_hash(from_i16(42)), calculate_hash(42i64));
/// ```
@@ -84,8 +87,9 @@ pub fn from_i16(v: i16) -> NaturalExtend<i16> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::natural_extend::from_u16;
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::natural_extend::from_u16;
+///
/// assert_eq!(calculate_hash(from_u16(65535)), calculate_hash(65535u64));
/// assert_eq!(calculate_hash(from_u16(42)), calculate_hash(42u64));
/// ```
@@ -98,8 +102,9 @@ pub fn from_u16(v: u16) -> NaturalExtend<u16> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::natural_extend::from_i32;
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::natural_extend::from_i32;
+///
/// assert_eq!(calculate_hash(from_i32(-1)), calculate_hash(-1i64));
/// assert_eq!(calculate_hash(from_i32(42)), calculate_hash(42i64));
/// ```
@@ -112,8 +117,9 @@ pub fn from_i32(v: i32) -> NaturalExtend<i32> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::natural_extend::from_u32;
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::natural_extend::from_u32;
+///
/// assert_eq!(
/// calculate_hash(from_u32(4294967295)),
/// calculate_hash(4294967295u64)
diff --git a/datasketches/src/hash_value/raw_bytes.rs b/datasketches/src/hash/value/raw_bytes.rs
similarity index 83%
rename from datasketches/src/hash_value/raw_bytes.rs
rename to datasketches/src/hash/value/raw_bytes.rs
index 4d9cfc1..1847711 100644
--- a/datasketches/src/hash_value/raw_bytes.rs
+++ b/datasketches/src/hash/value/raw_bytes.rs
@@ -26,8 +26,8 @@
use std::hash::Hasher;
-use super::value::HashStrategy;
-use super::value::Value;
+use super::HashStrategy;
+use super::Value;
/// A byte or string value wrapper that hashes raw bytes.
///
@@ -45,8 +45,10 @@ pub struct RawBytesStrategy;
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::raw_bytes::{from_slice, from_vec};
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::raw_bytes::from_slice;
+/// use datasketches::hash::value::raw_bytes::from_vec;
+///
/// assert_eq!(
/// calculate_hash(from_vec(b"abc".to_vec())),
/// calculate_hash(from_slice(b"abc"))
@@ -65,8 +67,10 @@ pub fn from_vec(v: Vec<u8>) -> RawBytes<Vec<u8>> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::raw_bytes::{from_str, from_string};
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::raw_bytes::from_str;
+/// use datasketches::hash::value::raw_bytes::from_string;
+///
/// assert_eq!(
/// calculate_hash(from_string("abc".to_owned())),
/// calculate_hash(from_str("abc"))
@@ -85,8 +89,10 @@ pub fn from_string(v: String) -> RawBytes<String> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::raw_bytes::{from_slice, from_vec};
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::raw_bytes::from_slice;
+/// use datasketches::hash::value::raw_bytes::from_vec;
+///
/// assert_eq!(
/// calculate_hash(from_slice(b"abc")),
/// calculate_hash(from_vec(b"abc".to_vec()))
@@ -105,8 +111,10 @@ pub fn from_slice(v: &[u8]) -> RawBytes<&[u8]> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::raw_bytes::{from_str, from_string};
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::raw_bytes::from_str;
+/// use datasketches::hash::value::raw_bytes::from_string;
+///
/// assert_eq!(
/// calculate_hash(from_str("abc")),
/// calculate_hash(from_string("abc".to_owned()))
diff --git a/datasketches/src/hash_value/sign_extend.rs b/datasketches/src/hash/value/sign_extend.rs
similarity index 81%
rename from datasketches/src/hash_value/sign_extend.rs
rename to datasketches/src/hash/value/sign_extend.rs
index c1ec518..0672f93 100644
--- a/datasketches/src/hash_value/sign_extend.rs
+++ b/datasketches/src/hash/value/sign_extend.rs
@@ -25,8 +25,8 @@
use std::hash::Hash;
use std::hash::Hasher;
-use super::value::HashStrategy;
-use super::value::Value;
+use super::HashStrategy;
+use super::Value;
/// An integer value wrapper that sign-extends the value before hashing.
///
@@ -42,8 +42,10 @@ pub struct SignExtendStrategy;
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::sign_extend::{from_i8, from_u8};
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::sign_extend::from_i8;
+/// use datasketches::hash::value::sign_extend::from_u8;
+///
/// assert_eq!(calculate_hash(from_i8(-1)), calculate_hash(from_u8(255)));
/// assert_eq!(calculate_hash(from_i8(-1)), calculate_hash(-1i64));
/// assert_eq!(calculate_hash(from_i8(42)), calculate_hash(42i64));
@@ -59,8 +61,10 @@ pub fn from_i8(v: i8) -> SignExtend<i8> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::sign_extend::{from_i8, from_u8};
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::sign_extend::from_i8;
+/// use datasketches::hash::value::sign_extend::from_u8;
+///
/// assert_eq!(calculate_hash(from_u8(255)), calculate_hash(from_i8(-1)));
/// assert_eq!(calculate_hash(from_u8(255)), calculate_hash(-1i64));
/// assert_eq!(calculate_hash(from_u8(1)), calculate_hash(1i64));
@@ -74,8 +78,10 @@ pub fn from_u8(v: u8) -> SignExtend<u8> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::sign_extend::{from_i16, from_u16};
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::sign_extend::from_i16;
+/// use datasketches::hash::value::sign_extend::from_u16;
+///
/// assert_eq!(
/// calculate_hash(from_i16(-1)),
/// calculate_hash(from_u16(65535))
@@ -94,8 +100,10 @@ pub fn from_i16(v: i16) -> SignExtend<i16> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::sign_extend::{from_i16, from_u16};
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::sign_extend::from_i16;
+/// use datasketches::hash::value::sign_extend::from_u16;
+///
/// assert_eq!(
/// calculate_hash(from_u16(65535)),
/// calculate_hash(from_i16(-1))
@@ -112,8 +120,10 @@ pub fn from_u16(v: u16) -> SignExtend<u16> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::sign_extend::{from_i32, from_u32};
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::sign_extend::from_i32;
+/// use datasketches::hash::value::sign_extend::from_u32;
+///
/// assert_eq!(
/// calculate_hash(from_i32(-1)),
/// calculate_hash(from_u32(4294967295))
@@ -132,8 +142,10 @@ pub fn from_i32(v: i32) -> SignExtend<i32> {
/// # Examples
///
/// ```
-/// # use datasketches::hash_value::calculate_hash;
-/// # use datasketches::hash_value::sign_extend::{from_i32, from_u32};
+/// use datasketches::hash::value::calculate_hash;
+/// use datasketches::hash::value::sign_extend::from_i32;
+/// use datasketches::hash::value::sign_extend::from_u32;
+///
/// assert_eq!(
/// calculate_hash(from_u32(4294967295)),
/// calculate_hash(from_i32(-1))
diff --git a/datasketches/src/hash/xxhash.rs b/datasketches/src/hash/xxhash.rs
index 25852ea..04c3e47 100644
--- a/datasketches/src/hash/xxhash.rs
+++ b/datasketches/src/hash/xxhash.rs
@@ -17,6 +17,8 @@
use std::hash::Hasher;
+use crate::hash::read_u64_le;
+
const DEFAULT_SEED: u64 = 0;
// Unsigned 64-bit primes from xxhash64.
@@ -76,7 +78,7 @@ impl XxHash64 {
let mut idx = 0;
let buf = &self.buffer[..self.buffer_len];
while idx + 8 <= buf.len() {
- let mut k1 = super::read_u64_le(&buf[idx..idx + 8]);
+ let mut k1 = read_u64_le(&buf[idx..idx + 8]);
k1 = k1.wrapping_mul(P2);
k1 = k1.rotate_left(31);
k1 = k1.wrapping_mul(P1);
@@ -86,7 +88,7 @@ impl XxHash64 {
}
if idx + 4 <= buf.len() {
- let k1 = super::read_u64_le(&buf[idx..idx + 4]);
+ let k1 = read_u64_le(&buf[idx..idx + 4]);
hash ^= k1.wrapping_mul(P1);
hash = hash.rotate_left(23).wrapping_mul(P2).wrapping_add(P3);
idx += 4;
@@ -116,10 +118,10 @@ impl XxHash64 {
#[inline]
fn update(&mut self, chunk: &[u8]) {
- self.v1 = round(self.v1, super::read_u64_le(&chunk[0..8]));
- self.v2 = round(self.v2, super::read_u64_le(&chunk[8..16]));
- self.v3 = round(self.v3, super::read_u64_le(&chunk[16..24]));
- self.v4 = round(self.v4, super::read_u64_le(&chunk[24..32]));
+ self.v1 = round(self.v1, read_u64_le(&chunk[0..8]));
+ self.v2 = round(self.v2, read_u64_le(&chunk[8..16]));
+ self.v3 = round(self.v3, read_u64_le(&chunk[16..24]));
+ self.v4 = round(self.v4, read_u64_le(&chunk[24..32]));
}
}
diff --git a/datasketches/src/hash_value/value.rs b/datasketches/src/hash_value/value.rs
deleted file mode 100644
index be857b0..0000000
--- a/datasketches/src/hash_value/value.rs
+++ /dev/null
@@ -1,116 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-//! Shared value wrapper and hashing strategy support.
-
-use std::cmp::Ordering;
-use std::fmt;
-use std::hash::Hash;
-use std::hash::Hasher;
-use std::marker::PhantomData;
-use std::ops::Deref;
-use std::ops::DerefMut;
-
-/// A value wrapper that hashes its inner value with strategy `S`.
-///
-/// Most users should prefer the strategy-specific constructors.
-pub struct Value<T, S> {
- value: T,
- strategy: PhantomData<fn() -> S>,
-}
-
-impl<T, S> Value<T, S> {
- /// Create a value wrapper.
- #[inline(always)]
- pub fn new(value: T) -> Self {
- Self {
- value,
- strategy: PhantomData,
- }
- }
-
- /// Get the value out.
- #[inline(always)]
- pub fn into_inner(self) -> T {
- self.value
- }
-}
-
-impl<T, S> Deref for Value<T, S> {
- type Target = T;
-
- fn deref(&self) -> &Self::Target {
- &self.value
- }
-}
-
-impl<T, S> DerefMut for Value<T, S> {
- fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.value
- }
-}
-
-impl<T: Clone, S> Clone for Value<T, S> {
- fn clone(&self) -> Self {
- Self::new(self.value.clone())
- }
-}
-
-impl<T: Copy, S> Copy for Value<T, S> {}
-
-impl<T: PartialEq, S> PartialEq for Value<T, S> {
- fn eq(&self, other: &Self) -> bool {
- self.value == other.value
- }
-}
-
-impl<T: Eq, S> Eq for Value<T, S> {}
-
-impl<T: PartialOrd, S> PartialOrd for Value<T, S> {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- self.value.partial_cmp(&other.value)
- }
-}
-
-impl<T: Ord, S> Ord for Value<T, S> {
- fn cmp(&self, other: &Self) -> Ordering {
- self.value.cmp(&other.value)
- }
-}
-
-impl<T: fmt::Debug, S> fmt::Debug for Value<T, S> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Debug::fmt(&self.value, f)
- }
-}
-
-impl<T: fmt::Display, S> fmt::Display for Value<T, S> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Display::fmt(&self.value, f)
- }
-}
-
-impl<T, S: HashStrategy<T>> Hash for Value<T, S> {
- fn hash<H: Hasher>(&self, state: &mut H) {
- S::hash(&self.value, state);
- }
-}
-
-#[doc(hidden)]
-pub trait HashStrategy<T> {
- fn hash<H: Hasher>(value: &T, state: &mut H);
-}
diff --git a/datasketches/src/hll/mod.rs b/datasketches/src/hll/mod.rs
index ec300a8..b6fece0 100644
--- a/datasketches/src/hll/mod.rs
+++ b/datasketches/src/hll/mod.rs
@@ -75,9 +75,10 @@
//! # Usage
//!
//! ```
-//! # use datasketches::hll::HllSketch;
-//! # use datasketches::hll::HllType;
-//! # use datasketches::common::NumStdDev;
+//! use datasketches::common::NumStdDev;
+//! use datasketches::hll::HllSketch;
+//! use datasketches::hll::HllType;
+//!
//! let mut sketch = HllSketch::new(12, HllType::Hll8);
//! sketch.update("apple");
//! let upper = sketch.upper_bound(NumStdDev::Two);
@@ -87,9 +88,10 @@
//! # Union
//!
//! ```
-//! # use datasketches::hll::HllSketch;
-//! # use datasketches::hll::HllType;
-//! # use datasketches::hll::HllUnion;
+//! use datasketches::hll::HllSketch;
+//! use datasketches::hll::HllType;
+//! use datasketches::hll::HllUnion;
+//!
//! let mut left = HllSketch::new(10, HllType::Hll8);
//! let mut right = HllSketch::new(10, HllType::Hll8);
//! left.update("apple");
@@ -174,7 +176,10 @@ const RESIZE_DENOMINATOR: u32 = 4;
/// # Examples
///
/// ```
-/// # use datasketches::hll::{HllSketch, HllType, Coupon};
+/// use datasketches::hll::Coupon;
+/// use datasketches::hll::HllSketch;
+/// use datasketches::hll::HllType;
+///
/// let c = Coupon::from_value("hello");
///
/// let mut sketch1 = HllSketch::new(10, HllType::Hll8);
@@ -206,8 +211,8 @@ impl Coupon {
/// Compute the HLL coupon for a hashable value.
///
- /// You may use [`hash_value`](crate::hash_value) wrappers when matching other datasketches
- /// implementations require a specific value hashing strategy.
+ /// You may use [`hash::value`](crate::hash::value) wrappers when another DataSketches
+ /// implementation requires a specific value hashing strategy.
///
/// Hashes `value` using MurmurHash3 128-bit and packs the result into a coupon:
/// the low 26 bits of the low hash word become the slot index, and the
diff --git a/datasketches/src/hll/sketch.rs b/datasketches/src/hll/sketch.rs
index 41e838e..9efd6ff 100644
--- a/datasketches/src/hll/sketch.rs
+++ b/datasketches/src/hll/sketch.rs
@@ -82,8 +82,9 @@ impl HllSketch {
/// # Examples
///
/// ```
- /// # use datasketches::hll::HllSketch;
- /// # use datasketches::hll::HllType;
+ /// use datasketches::hll::HllSketch;
+ /// use datasketches::hll::HllType;
+ ///
/// let sketch = HllSketch::new(12, HllType::Hll8);
/// assert_eq!(sketch.lg_config_k(), 12);
/// ```
@@ -161,8 +162,8 @@ impl HllSketch {
/// Accepts any type that implements [`Hash`]. The value is hashed and converted to
/// an internal coupon, which is then inserted into the sketch.
///
- /// You may use [`hash_value`](crate::hash_value) wrappers when matching other datasketches
- /// implementations require a specific value hashing strategy.
+ /// You may use [`hash::value`](crate::hash::value) wrappers when another DataSketches
+ /// implementation requires a specific value hashing strategy.
///
/// If you need to insert the same logical value into multiple sketches, consider
/// pre-computing the coupon with [`Coupon::from_value`] and calling
@@ -172,15 +173,16 @@ impl HllSketch {
/// # Examples
///
/// ```
- /// # use datasketches::hll::HllSketch;
- /// # use datasketches::hll::HllType;
- /// # use datasketches::hash_value;
+ /// use datasketches::hash::value::raw_bytes;
+ /// use datasketches::hll::HllSketch;
+ /// use datasketches::hll::HllType;
+ ///
/// let mut sketch = HllSketch::new(10, HllType::Hll8);
/// sketch.update("apple");
/// assert!(sketch.estimate() >= 1.0);
///
/// let mut sketch = HllSketch::new(10, HllType::Hll8);
- /// sketch.update(hash_value::raw_bytes::from_str("apple"));
+ /// sketch.update(raw_bytes::from_str("apple"));
/// assert!(sketch.estimate() >= 1.0);
/// ```
pub fn update<T: Hash>(&mut self, value: T) {
@@ -200,7 +202,10 @@ impl HllSketch {
/// # Examples
///
/// ```
- /// # use datasketches::hll::{HllSketch, HllType, Coupon};
+ /// use datasketches::hll::Coupon;
+ /// use datasketches::hll::HllSketch;
+ /// use datasketches::hll::HllType;
+ ///
/// let c = Coupon::from_value("apple");
/// let mut sketch = HllSketch::new(10, HllType::Hll8);
/// sketch.update_with_coupon(c);
@@ -242,8 +247,9 @@ impl HllSketch {
/// # Examples
///
/// ```
- /// # use datasketches::hll::HllSketch;
- /// # use datasketches::hll::HllType;
+ /// use datasketches::hll::HllSketch;
+ /// use datasketches::hll::HllType;
+ ///
/// let mut sketch = HllSketch::new(10, HllType::Hll8);
/// sketch.update("apple");
/// assert!(sketch.estimate() >= 1.0);
@@ -291,11 +297,13 @@ impl HllSketch {
/// # Examples
///
/// ```
- /// # use datasketches::hll::HllSketch;
- /// # use datasketches::hll::HllType;
- /// # let mut sketch = HllSketch::new(10, HllType::Hll8);
- /// # sketch.update("apple");
- /// # let bytes = sketch.serialize();
+ /// use datasketches::hll::HllSketch;
+ /// use datasketches::hll::HllType;
+ ///
+ /// let mut sketch = HllSketch::new(10, HllType::Hll8);
+ /// sketch.update("apple");
+ ///
+ /// let bytes = sketch.serialize();
/// let decoded = HllSketch::deserialize(&bytes).unwrap();
/// assert!(decoded.estimate() >= 1.0);
/// ```
@@ -406,10 +414,12 @@ impl HllSketch {
/// # Examples
///
/// ```
- /// # use datasketches::hll::HllSketch;
- /// # use datasketches::hll::HllType;
- /// # let mut sketch = HllSketch::new(10, HllType::Hll8);
- /// # sketch.update("apple");
+ /// use datasketches::hll::HllSketch;
+ /// use datasketches::hll::HllType;
+ ///
+ /// let mut sketch = HllSketch::new(10, HllType::Hll8);
+ /// sketch.update("apple");
+ ///
/// let bytes = sketch.serialize();
/// let decoded = HllSketch::deserialize(&bytes).unwrap();
/// assert!(decoded.estimate() >= 1.0);
diff --git a/datasketches/src/hll/union.rs b/datasketches/src/hll/union.rs
index df995f6..4de24d9 100644
--- a/datasketches/src/hll/union.rs
+++ b/datasketches/src/hll/union.rs
@@ -70,8 +70,9 @@ impl HllUnion {
/// # Examples
///
/// ```
- /// # use datasketches::hll::HllType;
- /// # use datasketches::hll::HllUnion;
+ /// use datasketches::hll::HllType;
+ /// use datasketches::hll::HllUnion;
+ ///
/// let mut union = HllUnion::new(10);
/// union.update_value("apple");
/// let result = union.to_sketch(HllType::Hll8);
@@ -98,8 +99,9 @@ impl HllUnion {
/// # Examples
///
/// ```
- /// # use datasketches::hll::HllType;
- /// # use datasketches::hll::HllUnion;
+ /// use datasketches::hll::HllType;
+ /// use datasketches::hll::HllUnion;
+ ///
/// let mut union = HllUnion::new(10);
/// union.update_value("apple");
/// let result = union.to_sketch(HllType::Hll8);
@@ -119,9 +121,10 @@ impl HllUnion {
/// # Examples
///
/// ```
- /// # use datasketches::hll::HllSketch;
- /// # use datasketches::hll::HllType;
- /// # use datasketches::hll::HllUnion;
+ /// use datasketches::hll::HllSketch;
+ /// use datasketches::hll::HllType;
+ /// use datasketches::hll::HllUnion;
+ ///
/// let mut left = HllSketch::new(10, HllType::Hll8);
/// let mut right = HllSketch::new(10, HllType::Hll8);
/// left.update("apple");
@@ -251,8 +254,9 @@ impl HllUnion {
/// # Examples
///
/// ```
- /// # use datasketches::hll::HllType;
- /// # use datasketches::hll::HllUnion;
+ /// use datasketches::hll::HllType;
+ /// use datasketches::hll::HllUnion;
+ ///
/// let mut union = HllUnion::new(10);
/// union.update_value("apple");
/// let result = union.to_sketch(HllType::Hll6);
diff --git a/datasketches/src/lib.rs b/datasketches/src/lib.rs
index 47cd37e..e169c4c 100644
--- a/datasketches/src/lib.rs
+++ b/datasketches/src/lib.rs
@@ -44,19 +44,16 @@ pub mod hll;
#[cfg(feature = "tdigest")]
pub mod tdigest;
#[cfg(any(feature = "theta", feature = "tuple"))]
-mod theta_family;
+mod thetafamily;
#[cfg(any(feature = "theta", feature = "tuple"))]
-pub use self::theta_family::common as thetacommon;
+pub use self::thetafamily::common as thetacommon;
#[cfg(feature = "theta")]
-pub use self::theta_family::theta;
+pub use self::thetafamily::theta;
#[cfg(feature = "tuple")]
-pub use self::theta_family::tuple;
+pub use self::thetafamily::tuple;
// common modules
pub mod codec;
pub mod common;
pub mod error;
-pub mod hash_value;
-
-// private internal modules
-mod hash;
+pub mod hash;
diff --git a/datasketches/src/tdigest/mod.rs b/datasketches/src/tdigest/mod.rs
index b3bcf00..5590c75 100644
--- a/datasketches/src/tdigest/mod.rs
+++ b/datasketches/src/tdigest/mod.rs
@@ -51,7 +51,8 @@
//! # Usage
//!
//! ```
-//! # use datasketches::tdigest::TDigestMut;
+//! use datasketches::tdigest::TDigestMut;
+//!
//! let mut sketch = TDigestMut::new(100);
//! sketch.update(1.0);
//! sketch.update(2.0);
diff --git a/datasketches/src/tdigest/sketch.rs b/datasketches/src/tdigest/sketch.rs
index 45c9222..3f26b00 100644
--- a/datasketches/src/tdigest/sketch.rs
+++ b/datasketches/src/tdigest/sketch.rs
@@ -77,7 +77,8 @@ impl TDigestMut {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
+ /// use datasketches::tdigest::TDigestMut;
+ ///
/// let sketch = TDigestMut::new(100);
/// assert_eq!(sketch.k(), 100);
/// ```
@@ -104,7 +105,8 @@ impl TDigestMut {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
+ /// use datasketches::tdigest::TDigestMut;
+ ///
/// let sketch = TDigestMut::try_new(20).unwrap();
/// assert_eq!(sketch.k(), 20);
/// ```
@@ -163,7 +165,8 @@ impl TDigestMut {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
+ /// use datasketches::tdigest::TDigestMut;
+ ///
/// let mut sketch = TDigestMut::new(100);
/// sketch.update(1.0);
/// assert!(sketch.total_weight() >= 1);
@@ -220,7 +223,8 @@ impl TDigestMut {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
+ /// use datasketches::tdigest::TDigestMut;
+ ///
/// let mut left = TDigestMut::new(100);
/// let mut right = TDigestMut::new(100);
/// left.update(1.0);
@@ -259,7 +263,8 @@ impl TDigestMut {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
+ /// use datasketches::tdigest::TDigestMut;
+ ///
/// let mut sketch = TDigestMut::new(100);
/// sketch.update(1.0);
/// let frozen = sketch.freeze();
@@ -292,11 +297,12 @@ impl TDigestMut {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
- /// # let mut sketch = TDigestMut::new(100);
- /// # for value in [1.0, 2.0, 3.0] {
- /// # sketch.update(value);
- /// # }
+ /// use datasketches::tdigest::TDigestMut;
+ ///
+ /// let mut sketch = TDigestMut::new(100);
+ /// for value in [1.0, 2.0, 3.0] {
+ /// sketch.update(value);
+ /// }
/// let cdf = sketch.cdf(&[1.5]).unwrap();
/// assert_eq!(cdf.len(), 2);
/// ```
@@ -315,11 +321,12 @@ impl TDigestMut {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
- /// # let mut sketch = TDigestMut::new(100);
- /// # for value in [1.0, 2.0, 3.0] {
- /// # sketch.update(value);
- /// # }
+ /// use datasketches::tdigest::TDigestMut;
+ ///
+ /// let mut sketch = TDigestMut::new(100);
+ /// for value in [1.0, 2.0, 3.0] {
+ /// sketch.update(value);
+ /// }
/// let pmf = sketch.pmf(&[1.5]).unwrap();
/// assert_eq!(pmf.len(), 2);
/// ```
@@ -338,11 +345,12 @@ impl TDigestMut {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
- /// # let mut sketch = TDigestMut::new(100);
- /// # for value in [1.0, 2.0, 3.0] {
- /// # sketch.update(value);
- /// # }
+ /// use datasketches::tdigest::TDigestMut;
+ ///
+ /// let mut sketch = TDigestMut::new(100);
+ /// for value in [1.0, 2.0, 3.0] {
+ /// sketch.update(value);
+ /// }
/// let rank = sketch.rank(2.0).unwrap();
/// assert!((0.0..=1.0).contains(&rank));
/// ```
@@ -371,11 +379,12 @@ impl TDigestMut {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
- /// # let mut sketch = TDigestMut::new(100);
- /// # for value in [1.0, 2.0, 3.0] {
- /// # sketch.update(value);
- /// # }
+ /// use datasketches::tdigest::TDigestMut;
+ ///
+ /// let mut sketch = TDigestMut::new(100);
+ /// for value in [1.0, 2.0, 3.0] {
+ /// sketch.update(value);
+ /// }
/// let median = sketch.quantile(0.5).unwrap();
/// assert!((1.0..=3.0).contains(&median));
/// ```
@@ -394,9 +403,10 @@ impl TDigestMut {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
- /// # let mut sketch = TDigestMut::new(100);
- /// # sketch.update(1.0);
+ /// use datasketches::tdigest::TDigestMut;
+ ///
+ /// let mut sketch = TDigestMut::new(100);
+ /// sketch.update(1.0);
/// let bytes = sketch.serialize();
/// let decoded = TDigestMut::deserialize(&bytes, false).unwrap();
/// assert_eq!(decoded.max_value(), Some(1.0));
@@ -486,11 +496,12 @@ impl TDigestMut {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
- /// # let mut sketch = TDigestMut::new(100);
- /// # sketch.update(1.0);
- /// # sketch.update(2.0);
- /// # let bytes = sketch.serialize();
+ /// use datasketches::tdigest::TDigestMut;
+ ///
+ /// let mut sketch = TDigestMut::new(100);
+ /// sketch.update(1.0);
+ /// sketch.update(2.0);
+ /// let bytes = sketch.serialize();
/// let decoded = TDigestMut::deserialize(&bytes, false).unwrap();
/// assert_eq!(decoded.max_value(), Some(2.0));
/// ```
@@ -894,11 +905,12 @@ impl TDigest {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
- /// # let mut sketch = TDigestMut::new(100);
- /// # for value in [1.0, 2.0, 3.0] {
- /// # sketch.update(value);
- /// # }
+ /// use datasketches::tdigest::TDigestMut;
+ ///
+ /// let mut sketch = TDigestMut::new(100);
+ /// for value in [1.0, 2.0, 3.0] {
+ /// sketch.update(value);
+ /// }
/// let digest = sketch.freeze();
/// let cdf = digest.cdf(&[1.5]).unwrap();
/// assert_eq!(cdf.len(), 2);
@@ -930,11 +942,12 @@ impl TDigest {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
- /// # let mut sketch = TDigestMut::new(100);
- /// # for value in [1.0, 2.0, 3.0] {
- /// # sketch.update(value);
- /// # }
+ /// use datasketches::tdigest::TDigestMut;
+ ///
+ /// let mut sketch = TDigestMut::new(100);
+ /// for value in [1.0, 2.0, 3.0] {
+ /// sketch.update(value);
+ /// }
/// let digest = sketch.freeze();
/// let pmf = digest.pmf(&[1.5]).unwrap();
/// assert_eq!(pmf.len(), 2);
@@ -954,11 +967,12 @@ impl TDigest {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
- /// # let mut sketch = TDigestMut::new(100);
- /// # for value in [1.0, 2.0, 3.0] {
- /// # sketch.update(value);
- /// # }
+ /// use datasketches::tdigest::TDigestMut;
+ ///
+ /// let mut sketch = TDigestMut::new(100);
+ /// for value in [1.0, 2.0, 3.0] {
+ /// sketch.update(value);
+ /// }
/// let digest = sketch.freeze();
/// let rank = digest.rank(2.0).unwrap();
/// assert!((0.0..=1.0).contains(&rank));
@@ -979,11 +993,12 @@ impl TDigest {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
- /// # let mut sketch = TDigestMut::new(100);
- /// # for value in [1.0, 2.0, 3.0] {
- /// # sketch.update(value);
- /// # }
+ /// use datasketches::tdigest::TDigestMut;
+ ///
+ /// let mut sketch = TDigestMut::new(100);
+ /// for value in [1.0, 2.0, 3.0] {
+ /// sketch.update(value);
+ /// }
/// let digest = sketch.freeze();
/// let q = digest.quantile(0.5).unwrap();
/// assert!((1.0..=3.0).contains(&q));
@@ -998,10 +1013,11 @@ impl TDigest {
/// # Examples
///
/// ```
- /// # use datasketches::tdigest::TDigestMut;
- /// # let mut sketch = TDigestMut::new(100);
- /// # sketch.update(1.0);
- /// # let digest = sketch.freeze();
+ /// use datasketches::tdigest::TDigestMut;
+ ///
+ /// let mut sketch = TDigestMut::new(100);
+ /// sketch.update(1.0);
+ /// let digest = sketch.freeze();
/// let mut mutable = digest.unfreeze();
/// mutable.update(2.0);
/// assert_eq!(mutable.total_weight(), 2);
diff --git a/datasketches/src/theta_family/common/bounds_binomial_proportions.rs b/datasketches/src/theta_family/common/bounds_binomial_proportions.rs
deleted file mode 100644
index b075833..0000000
--- a/datasketches/src/theta_family/common/bounds_binomial_proportions.rs
+++ /dev/null
@@ -1,188 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use crate::error::Error;
-
-/// Computes an approximate lower bound for an unknown binomial proportion.
-pub(crate) fn approximate_lower_bound_on_p(
- n: u64,
- k: u64,
- num_std_devs: f64,
-) -> Result<f64, Error> {
- check_inputs(n, k)?;
- if n == 0 || k == 0 {
- Ok(0.0)
- } else if k == 1 {
- Ok(exact_lower_bound_on_p_k_eq_1(
- n,
- delta_of_num_stdevs(num_std_devs),
- ))
- } else if k == n {
- Ok(exact_lower_bound_on_p_k_eq_n(
- n,
- delta_of_num_stdevs(num_std_devs),
- ))
- } else {
- let x = abramowitz_stegun_formula_26p5p22((n - k) as f64 + 1.0, k as f64, -num_std_devs);
- Ok(1.0 - x)
- }
-}
-
-/// Computes an approximate upper bound for an unknown binomial proportion.
-pub(crate) fn approximate_upper_bound_on_p(
- n: u64,
- k: u64,
- num_std_devs: f64,
-) -> Result<f64, Error> {
- check_inputs(n, k)?;
- if n == 0 || k == n {
- Ok(1.0)
- } else if k == n - 1 {
- Ok(exact_upper_bound_on_p_k_eq_minusone(
- n,
- delta_of_num_stdevs(num_std_devs),
- ))
- } else if k == 0 {
- Ok(exact_upper_bound_on_p_k_eq_zero(
- n,
- delta_of_num_stdevs(num_std_devs),
- ))
- } else {
- let x = abramowitz_stegun_formula_26p5p22((n - k) as f64, k as f64 + 1.0, num_std_devs);
- Ok(1.0 - x)
- }
-}
-
-fn check_inputs(n: u64, k: u64) -> Result<(), Error> {
- if k > n {
- return Err(Error::invalid_argument(format!(
- "k cannot exceed n: k={k}, n={n}"
- )));
- }
- Ok(())
-}
-
-fn delta_of_num_stdevs(kappa: f64) -> f64 {
- normal_cdf(-kappa)
-}
-
-fn normal_cdf(x: f64) -> f64 {
- 0.5 * (1.0 + erf(x / 2.0_f64.sqrt()))
-}
-
-fn erf(x: f64) -> f64 {
- if x < 0.0 {
- -erf_of_nonneg(-x)
- } else {
- erf_of_nonneg(x)
- }
-}
-
-fn erf_of_nonneg(x: f64) -> f64 {
- let a1 = 0.0705230784;
- let a2 = 0.0422820123;
- let a3 = 0.0092705272;
- let a4 = 0.0001520143;
- let a5 = 0.0002765672;
- let a6 = 0.0000430638;
- let x2 = x * x;
- let x3 = x2 * x;
- let x4 = x2 * x2;
- let x5 = x2 * x3;
- let x6 = x3 * x3;
- let sum = 1.0 + (a1 * x) + (a2 * x2) + (a3 * x3) + (a4 * x4) + (a5 * x5) + (a6 * x6);
- let sum2 = sum * sum;
- let sum4 = sum2 * sum2;
- let sum8 = sum4 * sum4;
- let sum16 = sum8 * sum8;
- 1.0 - (1.0 / sum16)
-}
-
-fn abramowitz_stegun_formula_26p5p22(a: f64, b: f64, yp: f64) -> f64 {
- let b2m1 = (2.0 * b) - 1.0;
- let a2m1 = (2.0 * a) - 1.0;
- let lambda = ((yp * yp) - 3.0) / 6.0;
- let reciprocal_sum = (1.0 / a2m1) + (1.0 / b2m1);
- let h = 2.0 / reciprocal_sum;
- let term1 = (yp * (h + lambda).sqrt()) / h;
- let term2 = (1.0 / b2m1) - (1.0 / a2m1);
- let term3 = (lambda + (5.0 / 6.0)) - (2.0 / (3.0 * h));
- let w = term1 - (term2 * term3);
- a / (a + (b * (2.0 * w).exp()))
-}
-
-fn exact_upper_bound_on_p_k_eq_zero(n: u64, delta: f64) -> f64 {
- 1.0 - delta.powf(1.0 / n as f64)
-}
-
-fn exact_lower_bound_on_p_k_eq_n(n: u64, delta: f64) -> f64 {
- delta.powf(1.0 / n as f64)
-}
-
-fn exact_lower_bound_on_p_k_eq_1(n: u64, delta: f64) -> f64 {
- 1.0 - (1.0 - delta).powf(1.0 / n as f64)
-}
-
-fn exact_upper_bound_on_p_k_eq_minusone(n: u64, delta: f64) -> f64 {
- (1.0 - delta).powf(1.0 / n as f64)
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn rejects_invalid_counts() {
- assert!(approximate_lower_bound_on_p(1, 2, 2.0).is_err());
- assert!(approximate_upper_bound_on_p(1, 2, 2.0).is_err());
- }
-
- #[test]
- fn computes_exact_edge_cases() {
- assert_eq!(approximate_lower_bound_on_p(0, 0, 2.0).unwrap(), 0.0);
- assert_eq!(approximate_upper_bound_on_p(0, 0, 2.0).unwrap(), 1.0);
- assert_eq!(approximate_lower_bound_on_p(10, 0, 2.0).unwrap(), 0.0);
- assert_eq!(approximate_upper_bound_on_p(10, 10, 2.0).unwrap(), 1.0);
- }
-
- #[test]
- fn matches_cross_language_reference_vectors() {
- const LOWER: [f64; 6] = [
- 0.0,
- 0.004592032688529923,
- 0.04725537386564205,
- 0.1396230607626959,
- 0.2735831034867167,
- 0.4692424353373485,
- ];
- const UPPER: [f64; 6] = [
- 0.5307575646626514,
- 0.7264168965132833,
- 0.860376939237304,
- 0.952744626134358,
- 0.9954079673114701,
- 1.0,
- ];
-
- for k in 0..=5 {
- let lower = approximate_lower_bound_on_p(5, k, 2.0).unwrap();
- let upper = approximate_upper_bound_on_p(5, k, 2.0).unwrap();
- assert!((lower - LOWER[k as usize]).abs() < 1e-14);
- assert!((upper - UPPER[k as usize]).abs() < 1e-14);
- }
- }
-}
diff --git a/datasketches/src/theta_family/common/a_not_b.rs b/datasketches/src/thetafamily/common/a_not_b.rs
similarity index 100%
rename from datasketches/src/theta_family/common/a_not_b.rs
rename to datasketches/src/thetafamily/common/a_not_b.rs
diff --git a/datasketches/src/theta_family/common/binomial_bounds.rs b/datasketches/src/thetafamily/common/binomial_bounds.rs
similarity index 88%
rename from datasketches/src/theta_family/common/binomial_bounds.rs
rename to datasketches/src/thetafamily/common/binomial_bounds.rs
index 2950d1d..d3a3dde 100644
--- a/datasketches/src/theta_family/common/binomial_bounds.rs
+++ b/datasketches/src/thetafamily/common/binomial_bounds.rs
@@ -341,6 +341,130 @@ pub(crate) fn upper_bound(
Ok(estimate.max(ub))
}
+/// Computes an approximate lower bound for an unknown binomial proportion.
+pub(crate) fn approximate_lower_bound_on_p(
+ n: u64,
+ k: u64,
+ num_std_devs: f64,
+) -> Result<f64, Error> {
+ check_proportion_inputs(n, k)?;
+ if n == 0 || k == 0 {
+ Ok(0.0)
+ } else if k == 1 {
+ Ok(exact_lower_bound_on_p_k_eq_1(
+ n,
+ delta_of_num_stdevs(num_std_devs),
+ ))
+ } else if k == n {
+ Ok(exact_lower_bound_on_p_k_eq_n(
+ n,
+ delta_of_num_stdevs(num_std_devs),
+ ))
+ } else {
+ let x = abramowitz_stegun_formula_26p5p22((n - k) as f64 + 1.0, k as f64, -num_std_devs);
+ Ok(1.0 - x)
+ }
+}
+
+/// Computes an approximate upper bound for an unknown binomial proportion.
+pub(crate) fn approximate_upper_bound_on_p(
+ n: u64,
+ k: u64,
+ num_std_devs: f64,
+) -> Result<f64, Error> {
+ check_proportion_inputs(n, k)?;
+ if n == 0 || k == n {
+ Ok(1.0)
+ } else if k == n - 1 {
+ Ok(exact_upper_bound_on_p_k_eq_minusone(
+ n,
+ delta_of_num_stdevs(num_std_devs),
+ ))
+ } else if k == 0 {
+ Ok(exact_upper_bound_on_p_k_eq_zero(
+ n,
+ delta_of_num_stdevs(num_std_devs),
+ ))
+ } else {
+ let x = abramowitz_stegun_formula_26p5p22((n - k) as f64, k as f64 + 1.0, num_std_devs);
+ Ok(1.0 - x)
+ }
+}
+
+fn check_proportion_inputs(n: u64, k: u64) -> Result<(), Error> {
+ if k > n {
+ return Err(Error::invalid_argument(format!(
+ "k cannot exceed n: k={k}, n={n}"
+ )));
+ }
+ Ok(())
+}
+
+fn delta_of_num_stdevs(kappa: f64) -> f64 {
+ normal_cdf(-kappa)
+}
+
+fn normal_cdf(x: f64) -> f64 {
+ 0.5 * (1.0 + erf(x / 2.0_f64.sqrt()))
+}
+
+fn erf(x: f64) -> f64 {
+ if x < 0.0 {
+ -erf_of_nonneg(-x)
+ } else {
+ erf_of_nonneg(x)
+ }
+}
+
+fn erf_of_nonneg(x: f64) -> f64 {
+ let a1 = 0.0705230784;
+ let a2 = 0.0422820123;
+ let a3 = 0.0092705272;
+ let a4 = 0.0001520143;
+ let a5 = 0.0002765672;
+ let a6 = 0.0000430638;
+ let x2 = x * x;
+ let x3 = x2 * x;
+ let x4 = x2 * x2;
+ let x5 = x2 * x3;
+ let x6 = x3 * x3;
+ let sum = 1.0 + (a1 * x) + (a2 * x2) + (a3 * x3) + (a4 * x4) + (a5 * x5) + (a6 * x6);
+ let sum2 = sum * sum;
+ let sum4 = sum2 * sum2;
+ let sum8 = sum4 * sum4;
+ let sum16 = sum8 * sum8;
+ 1.0 - (1.0 / sum16)
+}
+
+fn abramowitz_stegun_formula_26p5p22(a: f64, b: f64, yp: f64) -> f64 {
+ let b2m1 = (2.0 * b) - 1.0;
+ let a2m1 = (2.0 * a) - 1.0;
+ let lambda = ((yp * yp) - 3.0) / 6.0;
+ let reciprocal_sum = (1.0 / a2m1) + (1.0 / b2m1);
+ let h = 2.0 / reciprocal_sum;
+ let term1 = (yp * (h + lambda).sqrt()) / h;
+ let term2 = (1.0 / b2m1) - (1.0 / a2m1);
+ let term3 = (lambda + (5.0 / 6.0)) - (2.0 / (3.0 * h));
+ let w = term1 - (term2 * term3);
+ a / (a + (b * (2.0 * w).exp()))
+}
+
+fn exact_upper_bound_on_p_k_eq_zero(n: u64, delta: f64) -> f64 {
+ 1.0 - delta.powf(1.0 / n as f64)
+}
+
+fn exact_lower_bound_on_p_k_eq_n(n: u64, delta: f64) -> f64 {
+ delta.powf(1.0 / n as f64)
+}
+
+fn exact_lower_bound_on_p_k_eq_1(n: u64, delta: f64) -> f64 {
+ 1.0 - (1.0 - delta).powf(1.0 / n as f64)
+}
+
+fn exact_upper_bound_on_p_k_eq_minusone(n: u64, delta: f64) -> f64 {
+ (1.0 - delta).powf(1.0 / n as f64)
+}
+
/// Computes the lower bound using a Gaussian approximation with continuity correction.
fn cont_classic_lb(num_samples: u64, theta: f64, num_std_devs: f64) -> f64 {
let n_hat = (num_samples as f64 - 0.5) / theta;
@@ -746,4 +870,45 @@ mod tests {
let result = upper_bound(0, 0.5, NumStdDev::One, false).unwrap();
assert!(result > 0.0); // Upper bound should exist
}
+
+ #[test]
+ fn rejects_invalid_proportion_counts() {
+ assert!(approximate_lower_bound_on_p(1, 2, 2.0).is_err());
+ assert!(approximate_upper_bound_on_p(1, 2, 2.0).is_err());
+ }
+
+ #[test]
+ fn computes_exact_proportion_edge_cases() {
+ assert_eq!(approximate_lower_bound_on_p(0, 0, 2.0).unwrap(), 0.0);
+ assert_eq!(approximate_upper_bound_on_p(0, 0, 2.0).unwrap(), 1.0);
+ assert_eq!(approximate_lower_bound_on_p(10, 0, 2.0).unwrap(), 0.0);
+ assert_eq!(approximate_upper_bound_on_p(10, 10, 2.0).unwrap(), 1.0);
+ }
+
+ #[test]
+ fn matches_cross_language_proportion_reference_vectors() {
+ const LOWER: [f64; 6] = [
+ 0.0,
+ 0.004592032688529923,
+ 0.04725537386564205,
+ 0.1396230607626959,
+ 0.2735831034867167,
+ 0.4692424353373485,
+ ];
+ const UPPER: [f64; 6] = [
+ 0.5307575646626514,
+ 0.7264168965132833,
+ 0.860376939237304,
+ 0.952744626134358,
+ 0.9954079673114701,
+ 1.0,
+ ];
+
+ for k in 0..=5 {
+ let lower = approximate_lower_bound_on_p(5, k, 2.0).unwrap();
+ let upper = approximate_upper_bound_on_p(5, k, 2.0).unwrap();
+ assert!((lower - LOWER[k as usize]).abs() < 1e-14);
+ assert!((upper - UPPER[k as usize]).abs() < 1e-14);
+ }
+ }
}
diff --git a/datasketches/src/theta_family/common/constants.rs b/datasketches/src/thetafamily/common/constants.rs
similarity index 100%
rename from datasketches/src/theta_family/common/constants.rs
rename to datasketches/src/thetafamily/common/constants.rs
diff --git a/datasketches/src/theta_family/common/hash_table.rs b/datasketches/src/thetafamily/common/hash_table.rs
similarity index 100%
rename from datasketches/src/theta_family/common/hash_table.rs
rename to datasketches/src/thetafamily/common/hash_table.rs
diff --git a/datasketches/src/theta_family/common/intersection.rs b/datasketches/src/thetafamily/common/intersection.rs
similarity index 100%
rename from datasketches/src/theta_family/common/intersection.rs
rename to datasketches/src/thetafamily/common/intersection.rs
diff --git a/datasketches/src/theta_family/common/jaccard_similarity.rs b/datasketches/src/thetafamily/common/jaccard_similarity.rs
similarity index 97%
rename from datasketches/src/theta_family/common/jaccard_similarity.rs
rename to datasketches/src/thetafamily/common/jaccard_similarity.rs
index d2a1704..4e97b30 100644
--- a/datasketches/src/theta_family/common/jaccard_similarity.rs
+++ b/datasketches/src/thetafamily/common/jaccard_similarity.rs
@@ -21,7 +21,7 @@ use crate::hash::compute_seed_hash;
use crate::thetacommon::RetainedEntry;
use crate::thetacommon::ThetaFamilySketchView;
use crate::thetacommon::ThetaKeySketchView;
-use crate::thetacommon::bounds_binomial_proportions;
+use crate::thetacommon::binomial_bounds;
use crate::thetacommon::constants::MAX_LG_K;
use crate::thetacommon::constants::MAX_THETA;
use crate::thetacommon::constants::MIN_LG_K;
@@ -92,13 +92,13 @@ impl JaccardSimilarity {
let adjustment = NUM_STD_DEVS * sampling_adjuster(sampling_probability);
Ok(Self {
- lower_bound: bounds_binomial_proportions::approximate_lower_bound_on_p(
+ lower_bound: binomial_bounds::approximate_lower_bound_on_p(
union_count,
intersection_count,
adjustment,
)?,
estimate: intersection_count as f64 / union_count as f64,
- upper_bound: bounds_binomial_proportions::approximate_upper_bound_on_p(
+ upper_bound: binomial_bounds::approximate_upper_bound_on_p(
union_count,
intersection_count,
adjustment,
diff --git a/datasketches/src/theta_family/common/mod.rs b/datasketches/src/thetafamily/common/mod.rs
similarity index 98%
rename from datasketches/src/theta_family/common/mod.rs
rename to datasketches/src/thetafamily/common/mod.rs
index 4314158..199e5cc 100644
--- a/datasketches/src/theta_family/common/mod.rs
+++ b/datasketches/src/thetafamily/common/mod.rs
@@ -19,7 +19,6 @@
pub(crate) mod a_not_b;
pub(crate) mod binomial_bounds;
-pub(crate) mod bounds_binomial_proportions;
pub(crate) mod constants;
pub(crate) mod hash_table;
pub(crate) mod intersection;
diff --git a/datasketches/src/theta_family/common/union.rs b/datasketches/src/thetafamily/common/union.rs
similarity index 100%
rename from datasketches/src/theta_family/common/union.rs
rename to datasketches/src/thetafamily/common/union.rs
diff --git a/datasketches/src/theta_family/mod.rs b/datasketches/src/thetafamily/mod.rs
similarity index 100%
rename from datasketches/src/theta_family/mod.rs
rename to datasketches/src/thetafamily/mod.rs
diff --git a/datasketches/src/theta_family/theta/a_not_b.rs b/datasketches/src/thetafamily/theta/a_not_b.rs
similarity index 97%
rename from datasketches/src/theta_family/theta/a_not_b.rs
rename to datasketches/src/thetafamily/theta/a_not_b.rs
index bef222c..7def6e9 100644
--- a/datasketches/src/theta_family/theta/a_not_b.rs
+++ b/datasketches/src/thetafamily/theta/a_not_b.rs
@@ -35,7 +35,9 @@ use crate::thetacommon::a_not_b::ANotBOperator;
/// # Examples
///
/// ```
-/// # use datasketches::theta::{ThetaANotB, ThetaSketchBuilder};
+/// use datasketches::theta::ThetaANotB;
+/// use datasketches::theta::ThetaSketchBuilder;
+///
/// let mut a = ThetaSketchBuilder::default().build();
/// a.update("apple");
/// a.update("banana");
diff --git a/datasketches/src/theta_family/theta/bit_pack.rs b/datasketches/src/thetafamily/theta/bit_pack.rs
similarity index 100%
rename from datasketches/src/theta_family/theta/bit_pack.rs
rename to datasketches/src/thetafamily/theta/bit_pack.rs
diff --git a/datasketches/src/theta_family/theta/hash_table.rs b/datasketches/src/thetafamily/theta/hash_table.rs
similarity index 100%
rename from datasketches/src/theta_family/theta/hash_table.rs
rename to datasketches/src/thetafamily/theta/hash_table.rs
diff --git a/datasketches/src/theta_family/theta/intersection.rs b/datasketches/src/thetafamily/theta/intersection.rs
similarity index 100%
rename from datasketches/src/theta_family/theta/intersection.rs
rename to datasketches/src/thetafamily/theta/intersection.rs
diff --git a/datasketches/src/theta_family/theta/jaccard_similarity.rs b/datasketches/src/thetafamily/theta/jaccard_similarity.rs
similarity index 95%
rename from datasketches/src/theta_family/theta/jaccard_similarity.rs
rename to datasketches/src/thetafamily/theta/jaccard_similarity.rs
index 0c1937f..83beff0 100644
--- a/datasketches/src/theta_family/theta/jaccard_similarity.rs
+++ b/datasketches/src/thetafamily/theta/jaccard_similarity.rs
@@ -31,7 +31,9 @@ use crate::thetacommon::jaccard_similarity::JaccardSimilarityOperator;
/// # Examples
///
/// ```
-/// # use datasketches::theta::{ThetaJaccardSimilarity, ThetaSketchBuilder};
+/// use datasketches::theta::ThetaJaccardSimilarity;
+/// use datasketches::theta::ThetaSketchBuilder;
+///
/// let mut a = ThetaSketchBuilder::default().build();
/// let mut b = ThetaSketchBuilder::default().build();
/// a.update("apple");
diff --git a/datasketches/src/theta_family/theta/mod.rs b/datasketches/src/thetafamily/theta/mod.rs
similarity index 97%
rename from datasketches/src/theta_family/theta/mod.rs
rename to datasketches/src/thetafamily/theta/mod.rs
index 87f21fe..e63fffe 100644
--- a/datasketches/src/theta_family/theta/mod.rs
+++ b/datasketches/src/thetafamily/theta/mod.rs
@@ -33,7 +33,8 @@
//! # Usage
//!
//! ```
-//! # use datasketches::theta::ThetaSketchBuilder;
+//! use datasketches::theta::ThetaSketchBuilder;
+//!
//! let mut sketch = ThetaSketchBuilder::default().build();
//! sketch.update("apple");
//! assert!(sketch.estimate() >= 1.0);
diff --git a/datasketches/src/theta_family/theta/serialization.rs b/datasketches/src/thetafamily/theta/serialization.rs
similarity index 100%
rename from datasketches/src/theta_family/theta/serialization.rs
rename to datasketches/src/thetafamily/theta/serialization.rs
diff --git a/datasketches/src/theta_family/theta/sketch.rs b/datasketches/src/thetafamily/theta/sketch.rs
similarity index 97%
rename from datasketches/src/theta_family/theta/sketch.rs
rename to datasketches/src/thetafamily/theta/sketch.rs
index 3be2441..5c1f761 100644
--- a/datasketches/src/theta_family/theta/sketch.rs
+++ b/datasketches/src/thetafamily/theta/sketch.rs
@@ -106,13 +106,13 @@ pub struct ThetaSketch {
impl ThetaSketch {
/// Update the sketch with a hashable value.
///
- /// You may use [`hash_value`](crate::hash_value) wrappers when matching other datasketches
- /// implementations require a specific value hashing strategy.
+ /// You may use [`hash::value`](crate::hash::value) wrappers when another DataSketches
+ /// implementation requires a specific value hashing strategy.
///
/// # Examples
///
/// ```
- /// use datasketches::hash_value;
+ /// use datasketches::hash::value::raw_bytes;
/// use datasketches::theta::ThetaSketchBuilder;
///
/// let mut sketch = ThetaSketchBuilder::default().build();
@@ -120,7 +120,7 @@ impl ThetaSketch {
/// assert!(sketch.estimate() >= 1.0);
///
/// let mut sketch = ThetaSketchBuilder::default().build();
- /// sketch.update(hash_value::raw_bytes::from_str("apple"));
+ /// sketch.update(raw_bytes::from_str("apple"));
/// assert!(sketch.estimate() >= 1.0);
/// ```
pub fn update<T: Hash>(&mut self, value: T) {
@@ -132,9 +132,10 @@ impl ThetaSketch {
/// # Examples
///
/// ```
- /// # use datasketches::theta::ThetaSketchBuilder;
- /// # let mut sketch = ThetaSketchBuilder::default().build();
- /// # sketch.update("apple");
+ /// use datasketches::theta::ThetaSketchBuilder;
+ ///
+ /// let mut sketch = ThetaSketchBuilder::default().build();
+ /// sketch.update("apple");
/// assert!(sketch.estimate() >= 1.0);
/// ```
pub fn estimate(&self) -> f64 {
@@ -196,9 +197,10 @@ impl ThetaSketch {
/// # Examples
///
/// ```
- /// # use datasketches::theta::ThetaSketchBuilder;
- /// # let mut sketch = ThetaSketchBuilder::default().build();
- /// # sketch.update("apple");
+ /// use datasketches::theta::ThetaSketchBuilder;
+ ///
+ /// let mut sketch = ThetaSketchBuilder::default().build();
+ /// sketch.update("apple");
/// let mut iter = sketch.iter();
/// assert!(iter.next().is_some());
/// ```
@@ -213,7 +215,8 @@ impl ThetaSketch {
/// # Examples
///
/// ```
- /// # use datasketches::theta::ThetaSketchBuilder;
+ /// use datasketches::theta::ThetaSketchBuilder;
+ ///
/// let mut sketch = ThetaSketchBuilder::default().build();
/// sketch.update("apple");
/// let compact = sketch.compact(true);
@@ -935,7 +938,8 @@ impl ThetaSketchBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::theta::ThetaSketchBuilder;
+ /// use datasketches::theta::ThetaSketchBuilder;
+ ///
/// let sketch = ThetaSketchBuilder::default().lg_k(12).build();
/// assert_eq!(sketch.lg_k(), 12);
/// ```
@@ -969,7 +973,8 @@ impl ThetaSketchBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::theta::ThetaSketchBuilder;
+ /// use datasketches::theta::ThetaSketchBuilder;
+ ///
/// ThetaSketchBuilder::default()
/// .sampling_probability(0.5)
/// .build();
@@ -988,7 +993,8 @@ impl ThetaSketchBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::theta::ThetaSketchBuilder;
+ /// use datasketches::theta::ThetaSketchBuilder;
+ ///
/// ThetaSketchBuilder::default().seed(7).build();
/// ```
pub fn seed(mut self, seed: u64) -> Self {
@@ -1001,7 +1007,8 @@ impl ThetaSketchBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::theta::ThetaSketchBuilder;
+ /// use datasketches::theta::ThetaSketchBuilder;
+ ///
/// ThetaSketchBuilder::default().lg_k(10).build();
/// ```
pub fn build(self) -> ThetaSketch {
diff --git a/datasketches/src/theta_family/theta/union.rs b/datasketches/src/thetafamily/theta/union.rs
similarity index 95%
rename from datasketches/src/theta_family/theta/union.rs
rename to datasketches/src/thetafamily/theta/union.rs
index 94a974f..d521612 100644
--- a/datasketches/src/theta_family/theta/union.rs
+++ b/datasketches/src/thetafamily/theta/union.rs
@@ -98,7 +98,8 @@ impl ThetaUnionBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::theta::ThetaUnionBuilder;
+ /// use datasketches::theta::ThetaUnionBuilder;
+ ///
/// ThetaUnionBuilder::default().lg_k(12).build();
/// ```
pub fn lg_k(mut self, lg_k: u8) -> Self {
@@ -125,7 +126,8 @@ impl ThetaUnionBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::theta::ThetaUnionBuilder;
+ /// use datasketches::theta::ThetaUnionBuilder;
+ ///
/// ThetaUnionBuilder::default()
/// .sampling_probability(0.5)
/// .build();
@@ -144,7 +146,8 @@ impl ThetaUnionBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::theta::ThetaUnionBuilder;
+ /// use datasketches::theta::ThetaUnionBuilder;
+ ///
/// ThetaUnionBuilder::default().seed(7).build();
/// ```
pub fn seed(mut self, seed: u64) -> Self {
@@ -157,7 +160,8 @@ impl ThetaUnionBuilder {
/// # Examples
///
/// ```
- /// # use datasketches::theta::ThetaUnionBuilder;
+ /// use datasketches::theta::ThetaUnionBuilder;
+ ///
/// ThetaUnionBuilder::default().lg_k(10).build();
/// ```
pub fn build(self) -> ThetaUnion {
diff --git a/datasketches/src/theta_family/tuple/a_not_b.rs b/datasketches/src/thetafamily/tuple/a_not_b.rs
similarity index 96%
rename from datasketches/src/theta_family/tuple/a_not_b.rs
rename to datasketches/src/thetafamily/tuple/a_not_b.rs
index 5584b9d..b79430f 100644
--- a/datasketches/src/theta_family/tuple/a_not_b.rs
+++ b/datasketches/src/thetafamily/tuple/a_not_b.rs
@@ -38,7 +38,10 @@ use crate::tuple::sketch::TupleSketchView;
/// # Examples
///
/// ```
-/// # use datasketches::tuple::{DefaultUpdatePolicy, TupleANotB, TupleSketchBuilder};
+/// use datasketches::tuple::DefaultUpdatePolicy;
+/// use datasketches::tuple::TupleANotB;
+/// use datasketches::tuple::TupleSketchBuilder;
+///
/// let update_policy = DefaultUpdatePolicy::<u64>::default();
/// let mut a = TupleSketchBuilder::new(update_policy).build();
/// a.update("apple", 1);
diff --git a/datasketches/src/theta_family/tuple/hash_table.rs b/datasketches/src/thetafamily/tuple/hash_table.rs
similarity index 100%
rename from datasketches/src/theta_family/tuple/hash_table.rs
rename to datasketches/src/thetafamily/tuple/hash_table.rs
diff --git a/datasketches/src/theta_family/tuple/intersection.rs b/datasketches/src/thetafamily/tuple/intersection.rs
similarity index 100%
rename from datasketches/src/theta_family/tuple/intersection.rs
rename to datasketches/src/thetafamily/tuple/intersection.rs
diff --git a/datasketches/src/theta_family/tuple/jaccard_similarity.rs b/datasketches/src/thetafamily/tuple/jaccard_similarity.rs
similarity index 94%
rename from datasketches/src/theta_family/tuple/jaccard_similarity.rs
rename to datasketches/src/thetafamily/tuple/jaccard_similarity.rs
index d262714..6ad3835 100644
--- a/datasketches/src/theta_family/tuple/jaccard_similarity.rs
+++ b/datasketches/src/thetafamily/tuple/jaccard_similarity.rs
@@ -32,7 +32,10 @@ use crate::tuple::TupleKeySketchView;
/// # Examples
///
/// ```
-/// # use datasketches::tuple::{DefaultUpdatePolicy, TupleJaccardSimilarity, TupleSketchBuilder};
+/// use datasketches::tuple::DefaultUpdatePolicy;
+/// use datasketches::tuple::TupleJaccardSimilarity;
+/// use datasketches::tuple::TupleSketchBuilder;
+///
/// let policy = DefaultUpdatePolicy::<u64>::default();
/// let mut a = TupleSketchBuilder::new(policy).build();
/// let mut b = TupleSketchBuilder::new(policy).build();
diff --git a/datasketches/src/theta_family/tuple/mod.rs b/datasketches/src/thetafamily/tuple/mod.rs
similarity index 96%
rename from datasketches/src/theta_family/tuple/mod.rs
rename to datasketches/src/thetafamily/tuple/mod.rs
index e77f5d4..a8dfcba 100644
--- a/datasketches/src/theta_family/tuple/mod.rs
+++ b/datasketches/src/thetafamily/tuple/mod.rs
@@ -31,7 +31,9 @@
//! # Usage
//!
//! ```
-//! # use datasketches::tuple::{DefaultUpdatePolicy, TupleSketchBuilder};
+//! use datasketches::tuple::DefaultUpdatePolicy;
+//! use datasketches::tuple::TupleSketchBuilder;
+//!
//! let policy = DefaultUpdatePolicy::<u64>::default();
//! let mut sketch = TupleSketchBuilder::new(policy).build();
//! sketch.update("apple", 1_u64);
diff --git a/datasketches/src/theta_family/tuple/policy.rs b/datasketches/src/thetafamily/tuple/policy.rs
similarity index 100%
rename from datasketches/src/theta_family/tuple/policy.rs
rename to datasketches/src/thetafamily/tuple/policy.rs
diff --git a/datasketches/src/theta_family/tuple/serialization.rs b/datasketches/src/thetafamily/tuple/serialization.rs
similarity index 100%
rename from datasketches/src/theta_family/tuple/serialization.rs
rename to datasketches/src/thetafamily/tuple/serialization.rs
diff --git a/datasketches/src/theta_family/tuple/sketch.rs b/datasketches/src/thetafamily/tuple/sketch.rs
similarity index 98%
rename from datasketches/src/theta_family/tuple/sketch.rs
rename to datasketches/src/thetafamily/tuple/sketch.rs
index 67080d8..bd48322 100644
--- a/datasketches/src/theta_family/tuple/sketch.rs
+++ b/datasketches/src/thetafamily/tuple/sketch.rs
@@ -88,7 +88,9 @@ impl<S, T> TupleSketchView<S> for T where
/// # Examples
///
/// ```
-/// # use datasketches::tuple::{DefaultUpdatePolicy, TupleSketchBuilder};
+/// use datasketches::tuple::DefaultUpdatePolicy;
+/// use datasketches::tuple::TupleSketchBuilder;
+///
/// let policy = DefaultUpdatePolicy::<u64>::default();
/// let mut sketch = TupleSketchBuilder::new(policy).build();
/// sketch.update("apple", 1);
@@ -118,7 +120,9 @@ where
/// # Examples
///
/// ```
- /// # use datasketches::tuple::{DefaultUpdatePolicy, TupleSketchBuilder};
+ /// use datasketches::tuple::DefaultUpdatePolicy;
+ /// use datasketches::tuple::TupleSketchBuilder;
+ ///
/// let policy = DefaultUpdatePolicy::<u64>::default();
/// let mut sketch = TupleSketchBuilder::new(policy).build();
/// sketch.update(42, 5);
@@ -242,7 +246,9 @@ where
/// # Examples
///
/// ```
- /// # use datasketches::tuple::{DefaultUpdatePolicy, TupleSketchBuilder};
+ /// use datasketches::tuple::DefaultUpdatePolicy;
+ /// use datasketches::tuple::TupleSketchBuilder;
+ ///
/// let policy = DefaultUpdatePolicy::<u64>::default();
/// let mut sketch = TupleSketchBuilder::new(policy).build();
/// sketch.update("apple", 1);
@@ -439,7 +445,9 @@ impl<S> CompactTupleSketch<S> {
/// # Examples
///
/// ```
- /// # use datasketches::tuple::{DefaultUpdatePolicy, TupleSketchBuilder};
+ /// use datasketches::tuple::DefaultUpdatePolicy;
+ /// use datasketches::tuple::TupleSketchBuilder;
+ ///
/// let policy = DefaultUpdatePolicy::<u64>::default();
/// let mut sketch = TupleSketchBuilder::new(policy).build();
/// sketch.update("apple", 1);
diff --git a/datasketches/src/theta_family/tuple/union.rs b/datasketches/src/thetafamily/tuple/union.rs
similarity index 96%
rename from datasketches/src/theta_family/tuple/union.rs
rename to datasketches/src/thetafamily/tuple/union.rs
index 4fdf5e4..c64bbcd 100644
--- a/datasketches/src/theta_family/tuple/union.rs
+++ b/datasketches/src/thetafamily/tuple/union.rs
@@ -43,7 +43,11 @@ use crate::tuple::sketch::TupleSketchView;
/// # Examples
///
/// ```
-/// # use datasketches::tuple::{DefaultUnionPolicy, DefaultUpdatePolicy, TupleSketchBuilder, TupleUnionBuilder};
+/// use datasketches::tuple::DefaultUnionPolicy;
+/// use datasketches::tuple::DefaultUpdatePolicy;
+/// use datasketches::tuple::TupleSketchBuilder;
+/// use datasketches::tuple::TupleUnionBuilder;
+///
/// let update_policy = DefaultUpdatePolicy::<u64>::default();
/// let mut a = TupleSketchBuilder::new(update_policy).build();
/// a.update("apple", 1);
diff --git a/datasketches/tests/serde_tests/hll.rs b/datasketches/tests/serde_tests/hll.rs
index 3447c78..4501b1f 100644
--- a/datasketches/tests/serde_tests/hll.rs
+++ b/datasketches/tests/serde_tests/hll.rs
@@ -18,7 +18,7 @@
use std::fs;
use std::path::PathBuf;
-use datasketches::hash_value::natural_extend;
+use datasketches::hash::value::natural_extend;
use datasketches::hll::HllSketch;
use datasketches::hll::HllType;
diff --git a/datasketches/tests/theta_test/sketch.rs b/datasketches/tests/theta_test/sketch.rs
index 3ce86f0..2ed07db 100644
--- a/datasketches/tests/theta_test/sketch.rs
+++ b/datasketches/tests/theta_test/sketch.rs
@@ -16,7 +16,7 @@
// under the License.
use datasketches::common::NumStdDev;
-use datasketches::hash_value;
+use datasketches::hash::value::canonical_float;
use datasketches::theta::ThetaSketchBuilder;
#[test]
@@ -41,10 +41,10 @@ fn test_update_various_types() {
sketch.update(42i64);
sketch.update(42u64);
// where floating-point numbers have different representations
- sketch.update(hash_value::canonical_float::from_f64(3.15));
- sketch.update(hash_value::canonical_float::from_f64(3.15));
- sketch.update(hash_value::canonical_float::from_f32(3.15));
- sketch.update(hash_value::canonical_float::from_f32(3.15));
+ sketch.update(canonical_float::from_f64(3.15));
+ sketch.update(canonical_float::from_f64(3.15));
+ sketch.update(canonical_float::from_f32(3.15));
+ sketch.update(canonical_float::from_f32(3.15));
sketch.update([1u8, 2, 3]);
assert!(!sketch.is_empty());
@@ -56,10 +56,10 @@ fn test_update_various_types() {
sketch.update(42i64);
sketch.update(42u64);
// where floating-point numbers have the same representation
- sketch.update(hash_value::canonical_float::from_f64(5.0));
- sketch.update(hash_value::canonical_float::from_f64(5.0));
- sketch.update(hash_value::canonical_float::from_f32(5.0));
- sketch.update(hash_value::canonical_float::from_f32(5.0));
+ sketch.update(canonical_float::from_f64(5.0));
+ sketch.update(canonical_float::from_f64(5.0));
+ sketch.update(canonical_float::from_f32(5.0));
+ sketch.update(canonical_float::from_f32(5.0));
sketch.update([1u8, 2, 3]);
assert!(!sketch.is_empty());
diff --git a/datasketches/tests/tuple_test/sketch.rs b/datasketches/tests/tuple_test/sketch.rs
index a13d36a..34110e7 100644
--- a/datasketches/tests/tuple_test/sketch.rs
+++ b/datasketches/tests/tuple_test/sketch.rs
@@ -16,7 +16,7 @@
// under the License.
use datasketches::common::NumStdDev;
-use datasketches::hash_value;
+use datasketches::hash::value;
use datasketches::tuple::CompactTupleSketch;
use datasketches::tuple::DefaultUpdatePolicy;
use datasketches::tuple::SummaryPolicy;
@@ -47,8 +47,8 @@ fn accepts_supported_hash_representations() {
sketch.update("string", 1u64);
sketch.update(42i64, 1u64);
sketch.update(42u64, 1u64);
- sketch.update(hash_value::canonical_float::from_f64(5.0), 1u64);
- sketch.update(hash_value::canonical_float::from_f32(5.0), 1u64);
+ sketch.update(value::canonical_float::from_f64(5.0), 1u64);
+ sketch.update(value::canonical_float::from_f32(5.0), 1u64);
sketch.update([1u8, 2, 3], 1u64);
assert_eq!(sketch.estimate(), 4.0);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org