### Get Raw Floating-Point Cardinality Estimate Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Retrieve the unrounded cardinality estimate as a floating-point number using `raw_count()`. This is useful for detailed statistical analysis or when the precise unrounded value is needed. ```Rust use hyperloglockless::HyperLogLog; let mut hll = HyperLogLog::new(16); hll.extend(0..50000); // Get rounded count let count = hll.count(); // Get raw floating-point estimate let raw = hll.raw_count(); println!("Rounded count: {}", count); // e.g., 49876 println!("Raw estimate: {:.2}", raw); // e.g., 49876.42 println!("Difference: {:.2}", raw - count as f64); ``` -------------------------------- ### HyperLogLogPlus Sparse to Dense Transition Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Demonstrates the automatic transition of HyperLogLogPlus from a memory-efficient sparse representation to a dense representation as more elements are added. This provides better accuracy for small cardinalities. ```rust use hyperloglockless::HyperLogLogPlus; let mut hll = HyperLogLogPlus::new(14); // Initially sparse (memory-efficient) assert!(hll.is_sparse()); println!("Initial precision: {}", hll.precision()); // Insert small number of elements hll.extend(0..1000); println!("Count (sparse): {}", hll.count()); // ~1000 println!("Still sparse: {}", hll.is_sparse()); // true // Insert many more elements - will switch to dense hll.extend(1000..100000); println!("Count (dense): {}", hll.count()); // ~100000 println!("Now sparse: {}", hll.is_sparse()); // false ``` -------------------------------- ### Initialize and use HyperLogLogPlus for sparse representation Source: https://github.com/tomtomwombat/hyperloglockless/blob/main/README.md Create a HyperLogLogPlus instance, which uses a sparse representation that automatically switches to a classic HLL when memory usage becomes comparable. This offers improved accuracy and speed. ```rust use hyperloglockless::HyperLogLogPlus; let mut hll = HyperLogLogPlus::new(14); hll.insert(&'🦀'); hll.extend('a'..='z'); ``` -------------------------------- ### Create HyperLogLog with Default Settings Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Initializes a new HyperLogLog with a specified precision using the default hasher and a random seed. Precision controls memory usage and error rate. ```rust use hyperloglockless::HyperLogLog; // Create a HyperLogLog with precision 14 (16384 registers, ~1% error) let mut hll = HyperLogLog::new(14); // Insert individual elements hll.insert(&"hello"); hll.insert(&"world"); hll.insert(&42u64); hll.insert(&'🦀'); // Get approximate count of distinct elements let count = hll.count(); println!("Approximate distinct elements: {}", count); // ~4 // Check memory usage (number of registers) println!("Memory: {} bytes", hll.len()); // 16384 ``` -------------------------------- ### Create HyperLogLog with Custom Hasher Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Initializes a HyperLogLog using a custom hasher implementation, allowing integration with various hashing algorithms for specific needs. ```rust use hyperloglockless::HyperLogLog; use foldhash::fast::RandomState; // Create HyperLogLog with foldhash let mut hll = HyperLogLog::with_hasher(14, RandomState::default()); hll.insert(&"custom-hash-example"); hll.insert(&vec![1, 2, 3, 4, 5]); let count = hll.count(); println!("Distinct elements: {}", count); // ~2 ``` -------------------------------- ### Initialize HyperLogLog with a custom hasher Source: https://github.com/tomtomwombat/hyperloglockless/blob/main/README.md Create a HyperLogLog instance using a specific hasher, such as RandomState from the foldhash crate, for custom hashing needs. ```rust use hyperloglockless::HyperLogLog; use foldhash::fast::RandomState; let hll = HyperLogLog::with_hasher(14, RandomState::default()); ``` -------------------------------- ### Serialize and Deserialize HyperLogLog with Serde Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Demonstrates how to serialize and deserialize HyperLogLog instances using the `serde` feature. This allows for persistence and network transmission of HLL state. ```rust use hyperloglockless::HyperLogLog; use serde::{Serialize, Deserialize}; // Note: Requires `serde` feature enabled in Cargo.toml // [dependencies] // hyperloglockless = { version = "0.5.0", features = ["serde"] } let mut original = HyperLogLog::seeded(14, 42); original.extend(0..10000); // Serialize to bytes (using serde_cbor as example) // let bytes = serde_cbor::to_vec(&original).unwrap(); // Deserialize back // let restored: HyperLogLog = serde_cbor::from_slice(&bytes).unwrap(); // Both produce identical counts // assert_eq!(original.count(), restored.count()); // assert_eq!(original, restored); println!("Original count: {}", original.count()); ``` -------------------------------- ### Initialize HyperLogLog and insert elements Source: https://github.com/tomtomwombat/hyperloglockless/blob/main/README.md Calculate the required precision for a desired error rate and initialize a HyperLogLog. Elements can be inserted individually or using extend with an iterator. ```rust use hyperloglockless::HyperLogLog; let precision = hyperloglockless::precision_for_error(0.01); // 1% error assert_eq!(precision, 14); let mut hll = HyperLogLog::new(precision); hll.insert(&'🦀'); hll.extend('a'..='z'); let count = hll.count(); // ~27 assert_eq!(hll.len(), 1 << precision); // 16384 bytes ``` -------------------------------- ### Create Seeded HyperLogLog for Reproducible Results Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Creates a HyperLogLog instance with a specific seed value to ensure reproducible cardinality counts across different runs or instances. Useful for testing and consistent behavior. ```rust use hyperloglockless::HyperLogLog; // Create two HyperLogLogs with the same seed let mut hll1 = HyperLogLog::seeded(12, 42); let mut hll2 = HyperLogLog::seeded(12, 42); // Insert same data into both for i in 0..1000 { hll1.insert(&i); hll2.insert(&i); } // Both will produce identical counts assert_eq!(hll1.count(), hll2.count()); assert_eq!(hll1, hll2); ``` -------------------------------- ### Bulk Insert with extend() Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Demonstrates efficient bulk insertion of multiple elements into a HyperLogLog using the `Extend` trait implementation, which accepts any iterator. ```rust use hyperloglockless::HyperLogLog; let mut hll = HyperLogLog::new(14); // Insert a range of integers hll.extend(1..=10000); // Insert from a vector let strings = vec!["apple", "banana", "cherry", "apple", "date"]; hll.extend(strings.iter()); // Insert characters hll.extend('a'..='z'); let count = hll.count(); println!("Approximate unique elements: {}", count); // ~10026 ``` -------------------------------- ### Create Reproducible HyperLogLogPlus with Seeded Hasher Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Initialize HyperLogLogPlus with a specific seed value to ensure reproducible results. This is useful for testing and comparing HLL instances. ```rust use hyperloglockless::HyperLogLogPlus; // Reproducible sparse HLL let mut hll1 = HyperLogLogPlus::seeded(16, 12345); let mut hll2 = HyperLogLogPlus::seeded(16, 12345); hll1.extend(0..5000); hll2.extend(0..5000); assert_eq!(hll1.count(), hll2.count()); assert_eq!(hll1, hll2); println!("Reproducible count: {}", hll1.count()); ``` -------------------------------- ### Add hyperloglockless to Cargo.toml Source: https://github.com/tomtomwombat/hyperloglockless/blob/main/README.md Add this line to your Cargo.toml file to include the hyperloglockless crate in your project. ```toml [dependencies] hyperloglockless = "0.5.0" ``` -------------------------------- ### Create Thread-Safe AtomicHyperLogLog with Custom Hasher Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Use AtomicHyperLogLog::with_hasher to create a thread-safe HyperLogLog instance with a specific hash function. This is useful for ensuring consistent hashing across distributed systems. ```rust use hyperloglockless::AtomicHyperLogLog; use foldhash::fast::RandomState; use std::sync::Arc; use std::thread; let hll = Arc::new(AtomicHyperLogLog::with_hasher(14, RandomState::default())); // Concurrent inserts with custom hasher let hll_clone = Arc::clone(&hll); let handle = thread::spawn(move || { hll_clone.extend(0..5000); }); hll.extend(5000..10000); handle.join().unwrap(); println!("Count with custom hasher: {}", hll.count()); // ~10000 ``` -------------------------------- ### Access and Reconstruct HyperLogLog Parts Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Use the parts API to extract internal state for custom serialization or reconstruction. ```rust use hyperloglockless::HyperLogLog; let mut original = HyperLogLog::seeded(16, 42); original.extend(1000..=2000); // Extract internal parts let (registers, hasher, zeros, sum, updated_count) = original.parts(); // Reconstruct from parts let reconstructed = HyperLogLog::from_parts( registers.into(), hasher.clone(), zeros, sum, updated_count ); assert_eq!(original, reconstructed); println!("Original: {}, Reconstructed: {}", original.count(), reconstructed.count()); ``` -------------------------------- ### Merge HyperLogLogPlus Instances (Union Operations) Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Perform union operations on HyperLogLogPlus instances. The library automatically handles merging between sparse and dense representations. ```rust use hyperloglockless::HyperLogLogPlus; let mut sparse1 = HyperLogLogPlus::seeded(12, 42); let mut sparse2 = HyperLogLogPlus::seeded(12, 42); sparse1.extend(0..500); // Stays sparse sparse2.extend(400..900); // Stays sparse // Merge sparse into sparse sparse1.union(&sparse2).expect("Same precision"); println!("Merged sparse count: {}", sparse1.count()); // ~900 // Create dense HLL let mut dense = HyperLogLogPlus::seeded(12, 42); dense.extend(0..50000); // Converts to dense // Merge sparse into dense (sparse1 converts to dense) sparse1.union(&dense).expect("Same precision"); println!("Final count: {}", sparse1.count()); // ~50000 ``` -------------------------------- ### Concurrent Insertions with AtomicHyperLogLog Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Use `AtomicHyperLogLog` for thread-safe cardinality estimation. Its methods accept `&self`, enabling concurrent insertions and reads from multiple threads without explicit locking mechanisms. ```Rust use hyperloglockless::AtomicHyperLogLog; use std::sync::Arc; use std::thread; // Create atomic HLL wrapped in Arc for sharing let hll = Arc::new(AtomicHyperLogLog::new(14)); // Spawn multiple threads to insert concurrently let handles: Vec<_> = (0..4) .map(|thread_id| { let hll_clone = Arc::clone(&hll); thread::spawn(move || { let start = thread_id * 10000; let end = start + 10000; for i in start..end { hll_clone.insert(&i); } }) }) .collect(); // Wait for all threads for handle in handles { handle.join().unwrap(); } // Get count (thread-safe) let count = hll.count(); println!("Concurrent insert count: {}", count); // ~40000 ``` -------------------------------- ### Merge Two HyperLogLogs with Union Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Combine two `HyperLogLog` instances into one using the `union` method. Ensure both instances have the same precision and ideally the same hasher for accurate results. This operation is efficient, maintaining O(1) count queries. ```Rust use hyperloglockless::HyperLogLog; // Create two HyperLogLogs with same precision and seed let mut hll1 = HyperLogLog::seeded(14, 42); let mut hll2 = HyperLogLog::seeded(14, 42); // Insert different data hll1.extend(0..5000); // Elements 0-4999 hll2.extend(3000..8000); // Elements 3000-7999 println!("HLL1 count: {}", hll1.count()); // ~5000 println!("HLL2 count: {}", hll2.count()); // ~5000 // Merge hll2 into hll1 hll1.union(&hll2).expect("Same precision required"); // Union contains distinct elements from both (0-7999 = 8000 unique) println!("Union count: {}", hll1.count()); // ~8000 ``` -------------------------------- ### Use AtomicHyperLogLog for concurrent access Source: https://github.com/tomtomwombat/hyperloglockless/blob/main/README.md Initialize and use AtomicHyperLogLog for thread-safe operations. Its methods accept `&self`, allowing it to be wrapped in an `Arc` for concurrent updates without needing mutable references. ```rust use hyperloglockless::AtomicHyperLogLog; let hll = AtomicHyperLogLog::new(14); hll.insert(&'🦀'); ``` -------------------------------- ### Precision and Error Rate Utilities Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Provides utility functions to calculate the required precision for a target error rate and to determine the expected error rate for a given precision. ```rust use hyperloglockless::{precision_for_error, error_for_precision}; // Find precision needed for 1% error rate let precision = precision_for_error(0.01); assert_eq!(precision, 14); // Calculate expected error for precision 12 let error = error_for_precision(12); println!("Expected error at precision 12: {:.2}%", error * 100.0); // ~1.62% // Memory usage at each precision for p in 4..=18 { let memory = 1usize << p; let err = error_for_precision(p); println!("Precision {}: {} bytes, {:.2}% error", p, memory, err * 100.0); } ``` -------------------------------- ### Insert Pre-computed Hashes Directly Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Use `insert_hash` when you have already computed hash values for your data. This is useful for integrating with external hashing mechanisms or when receiving pre-hashed data. ```Rust use hyperloglockless::HyperLogLog; use std::hash::{Hash, Hasher}; use std::collections::hash_map::DefaultHasher; let mut hll = HyperLogLog::new(14); // Compute hash externally fn compute_hash(value: &T) -> u64 { let mut hasher = DefaultHasher::new(); value.hash(&mut hasher); hasher.finish() } // Insert using pre-computed hash let hash = compute_hash(&"my-value"); hll.insert_hash(hash); // Useful for streaming scenarios where hashes are computed elsewhere let hashes: Vec = vec![0x123, 0x456, 0x789, 0xABC]; for h in hashes { hll.insert_hash(h); } println!("Count: {}", hll.count()); ``` -------------------------------- ### Handle HyperLogLog Union Errors Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Manage potential failures during union operations, specifically when precisions are incompatible. ```rust use hyperloglockless::{HyperLogLog, Error}; let mut hll_p12 = HyperLogLog::new(12); let hll_p14 = HyperLogLog::new(14); hll_p12.extend(0..1000); // Attempt to union incompatible HLLs match hll_p12.union(&hll_p14) { Ok(()) => println!("Union successful"), Err(Error::IncompatibleLength) => { println!("Cannot union HLLs with different precisions!"); println!("HLL1 registers: {}", hll_p12.len()); // 4096 println!("HLL2 registers: {}", hll_p14.len()); // 16384 } } ``` -------------------------------- ### Iterate Over HyperLogLog Registers Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Access internal register values for debugging or analysis by collecting them into a vector. ```rust use hyperloglockless::HyperLogLog; let mut hll = HyperLogLog::new(8); // Small precision for demonstration hll.extend(0..100); // Iterate over all register values let registers: Vec = hll.iter().collect(); println!("Number of registers: {}", registers.len()); // 256 // Count non-zero registers let non_zero = registers.iter().filter(|&&x| x > 0).count(); println!("Non-zero registers: {}", non_zero); // Find max register value let max_val = registers.iter().max().unwrap(); println!("Max register value: {}", max_val); ``` -------------------------------- ### High-Throughput Lazy Inserts with AtomicHyperLogLog Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Utilize insert_lazy for high-throughput scenarios where immediate count accuracy is not critical. This method defers the actual insertion processing. ```rust use hyperloglockless::AtomicHyperLogLog; use std::sync::Arc; use std::thread; let hll = Arc::new(AtomicHyperLogLog::seeded(12, 42)); // High-throughput concurrent lazy inserts let handles: Vec<_> = (0..8) .map(|t| { let h = Arc::clone(&hll); thread::spawn(move || { for i in (t * 50000)..((t + 1) * 50000) { h.insert_lazy(&i); } }) }) .collect(); for handle in handles { handle.join().unwrap(); } // Single count scan at the end let count = hll.count(); println!("High-throughput count: {}", count); // ~400000 ``` -------------------------------- ### Lazy Insertion for Insert-Heavy Workloads Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Utilizes `insert_lazy` for faster inserts in workloads with frequent insertions and infrequent count queries. The count is recomputed only when `count()` is called. ```rust use hyperloglockless::HyperLogLog; let mut hll = HyperLogLog::new(12); // Fast inserts without count maintenance for i in 0..100_000 { hll.insert_lazy(&i); } // Count will scan all registers (slower, but only once) let count = hll.count(); println!("Count after lazy inserts: {}", count); // ~100000 // insert_hash_lazy for pre-computed hashes let hash = 0xDEADBEEF_u64; hll.insert_hash_lazy(hash); ``` -------------------------------- ### Perform Lazy Union for Batch Merging Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt Utilize `union_lazy` for efficient batch merging of multiple `HyperLogLog` structures. This method defers the count computation until explicitly requested, optimizing performance when performing many unions sequentially. ```Rust use hyperloglockless::HyperLogLog; let mut main_hll = HyperLogLog::seeded(12, 42); // Create multiple HLLs to merge let hlls: Vec = (0..10) .map(|i| { let mut h = HyperLogLog::seeded(12, 42); h.extend((i * 1000)..((i + 1) * 1000)); h }) .collect(); // Merge all using lazy union (faster for multiple merges) for hll in &hlls { main_hll.union_lazy(hll).expect("Same precision"); } // Single count computation at the end let total = main_hll.count(); println!("Total distinct across all HLLs: {}", total); // ~10000 ``` -------------------------------- ### Count Elements from Iterator in One Operation Source: https://context7.com/tomtomwombat/hyperloglockless/llms.txt The `count_once` method efficiently inserts all elements from an iterator and returns the final cardinality estimate in a single call. It optimizes for large iterators using lazy inserts. ```Rust use hyperloglockless::HyperLogLog; let mut hll = HyperLogLog::new(14); // Insert existing elements hll.extend(1..=1000); // Count after adding more elements in one call let data = vec![500, 1001, 1002, 1003, 1004]; let count = hll.count_once(data.iter()); println!("Total distinct after adding more: {}", count); // ~1004 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.