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