pub struct HllSketch { /* private fields */ }Expand description
A HyperLogLog sketch: estimates the number of distinct items added via
update_*, using bounded memory regardless of how many items are added.
lg_config_k (passed to HllSketch::new, valid range 4..=21) trades
memory for accuracy: higher values are more accurate but use more space.
Implementations§
Source§impl HllSketch
impl HllSketch
Sourcepub fn new(
lg_config_k: u8,
tgt_type: TargetHllType,
) -> Result<Self, SketchError>
pub fn new( lg_config_k: u8, tgt_type: TargetHllType, ) -> Result<Self, SketchError>
Creates a new, empty sketch with the given lg_config_k (4..=21)
and internal representation. Returns SketchError::InvalidConfig
if lg_config_k is out of range.
Examples found in repository?
7fn main() {
8 // A sketch estimates the number of distinct items seen, using bounded
9 // memory regardless of how many items are added. `lg_config_k` (4..=21)
10 // trades memory for accuracy: higher values are more accurate but use
11 // more space.
12 let mut sketch = HllSketch::new(12, TargetHllType::Hll4).expect("valid lg_config_k");
13
14 for i in 0..10_000u64 {
15 sketch.update_u64(i);
16 }
17 // Duplicates don't affect the distinct count.
18 for i in 0..5_000u64 {
19 sketch.update_u64(i);
20 }
21 sketch.update_str("some-key");
22 sketch.update_bytes(b"raw bytes work too");
23
24 println!("distinct count estimate: {:.1}", sketch.get_estimate());
25 println!(
26 "95% confidence interval: [{:.1}, {:.1}]",
27 sketch.get_lower_bound(2).unwrap(),
28 sketch.get_upper_bound(2).unwrap()
29 );
30
31 // Sketches can be serialized to bytes (e.g. to store or send over the
32 // network) and reconstructed later.
33 let bytes = sketch.serialize_compact();
34 let restored = HllSketch::deserialize(&bytes).expect("valid sketch bytes");
35 assert_eq!(sketch.get_estimate(), restored.get_estimate());
36 println!(
37 "serialized to {} bytes and restored successfully",
38 bytes.len()
39 );
40
41 // HllUnion merges multiple sketches into one, e.g. combining
42 // per-shard/per-day counts into a total distinct count.
43 let mut shard_a = HllSketch::new(12, TargetHllType::Hll4).unwrap();
44 for i in 0..10_000u64 {
45 shard_a.update_u64(i);
46 }
47 let mut shard_b = HllSketch::new(12, TargetHllType::Hll4).unwrap();
48 for i in 5_000..15_000u64 {
49 shard_b.update_u64(i);
50 }
51
52 let mut union = HllUnion::new(12).expect("valid lg_max_k");
53 union.update_sketch(&shard_a);
54 union.update_sketch(&shard_b);
55
56 let merged = union.get_result(TargetHllType::Hll4);
57 println!(
58 "merged distinct count across two overlapping shards (true count = 15000): {:.1}",
59 merged.get_estimate()
60 );
61}Sourcepub fn copy_as(&self, tgt_type: TargetHllType) -> Self
pub fn copy_as(&self, tgt_type: TargetHllType) -> Self
Returns a copy of this sketch converted to a different
TargetHllType, preserving its current state.
Sourcepub fn deserialize(bytes: &[u8]) -> Result<Self, SketchError>
pub fn deserialize(bytes: &[u8]) -> Result<Self, SketchError>
Reconstructs a sketch from bytes produced by
Self::serialize_compact or Self::serialize_updatable.
Examples found in repository?
7fn main() {
8 // A sketch estimates the number of distinct items seen, using bounded
9 // memory regardless of how many items are added. `lg_config_k` (4..=21)
10 // trades memory for accuracy: higher values are more accurate but use
11 // more space.
12 let mut sketch = HllSketch::new(12, TargetHllType::Hll4).expect("valid lg_config_k");
13
14 for i in 0..10_000u64 {
15 sketch.update_u64(i);
16 }
17 // Duplicates don't affect the distinct count.
18 for i in 0..5_000u64 {
19 sketch.update_u64(i);
20 }
21 sketch.update_str("some-key");
22 sketch.update_bytes(b"raw bytes work too");
23
24 println!("distinct count estimate: {:.1}", sketch.get_estimate());
25 println!(
26 "95% confidence interval: [{:.1}, {:.1}]",
27 sketch.get_lower_bound(2).unwrap(),
28 sketch.get_upper_bound(2).unwrap()
29 );
30
31 // Sketches can be serialized to bytes (e.g. to store or send over the
32 // network) and reconstructed later.
33 let bytes = sketch.serialize_compact();
34 let restored = HllSketch::deserialize(&bytes).expect("valid sketch bytes");
35 assert_eq!(sketch.get_estimate(), restored.get_estimate());
36 println!(
37 "serialized to {} bytes and restored successfully",
38 bytes.len()
39 );
40
41 // HllUnion merges multiple sketches into one, e.g. combining
42 // per-shard/per-day counts into a total distinct count.
43 let mut shard_a = HllSketch::new(12, TargetHllType::Hll4).unwrap();
44 for i in 0..10_000u64 {
45 shard_a.update_u64(i);
46 }
47 let mut shard_b = HllSketch::new(12, TargetHllType::Hll4).unwrap();
48 for i in 5_000..15_000u64 {
49 shard_b.update_u64(i);
50 }
51
52 let mut union = HllUnion::new(12).expect("valid lg_max_k");
53 union.update_sketch(&shard_a);
54 union.update_sketch(&shard_b);
55
56 let merged = union.get_result(TargetHllType::Hll4);
57 println!(
58 "merged distinct count across two overlapping shards (true count = 15000): {:.1}",
59 merged.get_estimate()
60 );
61}Sourcepub fn update_u64(&mut self, value: u64)
pub fn update_u64(&mut self, value: u64)
Adds a u64 value to the sketch.
Examples found in repository?
7fn main() {
8 // A sketch estimates the number of distinct items seen, using bounded
9 // memory regardless of how many items are added. `lg_config_k` (4..=21)
10 // trades memory for accuracy: higher values are more accurate but use
11 // more space.
12 let mut sketch = HllSketch::new(12, TargetHllType::Hll4).expect("valid lg_config_k");
13
14 for i in 0..10_000u64 {
15 sketch.update_u64(i);
16 }
17 // Duplicates don't affect the distinct count.
18 for i in 0..5_000u64 {
19 sketch.update_u64(i);
20 }
21 sketch.update_str("some-key");
22 sketch.update_bytes(b"raw bytes work too");
23
24 println!("distinct count estimate: {:.1}", sketch.get_estimate());
25 println!(
26 "95% confidence interval: [{:.1}, {:.1}]",
27 sketch.get_lower_bound(2).unwrap(),
28 sketch.get_upper_bound(2).unwrap()
29 );
30
31 // Sketches can be serialized to bytes (e.g. to store or send over the
32 // network) and reconstructed later.
33 let bytes = sketch.serialize_compact();
34 let restored = HllSketch::deserialize(&bytes).expect("valid sketch bytes");
35 assert_eq!(sketch.get_estimate(), restored.get_estimate());
36 println!(
37 "serialized to {} bytes and restored successfully",
38 bytes.len()
39 );
40
41 // HllUnion merges multiple sketches into one, e.g. combining
42 // per-shard/per-day counts into a total distinct count.
43 let mut shard_a = HllSketch::new(12, TargetHllType::Hll4).unwrap();
44 for i in 0..10_000u64 {
45 shard_a.update_u64(i);
46 }
47 let mut shard_b = HllSketch::new(12, TargetHllType::Hll4).unwrap();
48 for i in 5_000..15_000u64 {
49 shard_b.update_u64(i);
50 }
51
52 let mut union = HllUnion::new(12).expect("valid lg_max_k");
53 union.update_sketch(&shard_a);
54 union.update_sketch(&shard_b);
55
56 let merged = union.get_result(TargetHllType::Hll4);
57 println!(
58 "merged distinct count across two overlapping shards (true count = 15000): {:.1}",
59 merged.get_estimate()
60 );
61}Sourcepub fn update_i64(&mut self, value: i64)
pub fn update_i64(&mut self, value: i64)
Adds an i64 value to the sketch.
Sourcepub fn update_f64(&mut self, value: f64)
pub fn update_f64(&mut self, value: f64)
Adds an f64 value to the sketch.
Sourcepub fn update_str(&mut self, value: &str)
pub fn update_str(&mut self, value: &str)
Adds a string value to the sketch.
Examples found in repository?
7fn main() {
8 // A sketch estimates the number of distinct items seen, using bounded
9 // memory regardless of how many items are added. `lg_config_k` (4..=21)
10 // trades memory for accuracy: higher values are more accurate but use
11 // more space.
12 let mut sketch = HllSketch::new(12, TargetHllType::Hll4).expect("valid lg_config_k");
13
14 for i in 0..10_000u64 {
15 sketch.update_u64(i);
16 }
17 // Duplicates don't affect the distinct count.
18 for i in 0..5_000u64 {
19 sketch.update_u64(i);
20 }
21 sketch.update_str("some-key");
22 sketch.update_bytes(b"raw bytes work too");
23
24 println!("distinct count estimate: {:.1}", sketch.get_estimate());
25 println!(
26 "95% confidence interval: [{:.1}, {:.1}]",
27 sketch.get_lower_bound(2).unwrap(),
28 sketch.get_upper_bound(2).unwrap()
29 );
30
31 // Sketches can be serialized to bytes (e.g. to store or send over the
32 // network) and reconstructed later.
33 let bytes = sketch.serialize_compact();
34 let restored = HllSketch::deserialize(&bytes).expect("valid sketch bytes");
35 assert_eq!(sketch.get_estimate(), restored.get_estimate());
36 println!(
37 "serialized to {} bytes and restored successfully",
38 bytes.len()
39 );
40
41 // HllUnion merges multiple sketches into one, e.g. combining
42 // per-shard/per-day counts into a total distinct count.
43 let mut shard_a = HllSketch::new(12, TargetHllType::Hll4).unwrap();
44 for i in 0..10_000u64 {
45 shard_a.update_u64(i);
46 }
47 let mut shard_b = HllSketch::new(12, TargetHllType::Hll4).unwrap();
48 for i in 5_000..15_000u64 {
49 shard_b.update_u64(i);
50 }
51
52 let mut union = HllUnion::new(12).expect("valid lg_max_k");
53 union.update_sketch(&shard_a);
54 union.update_sketch(&shard_b);
55
56 let merged = union.get_result(TargetHllType::Hll4);
57 println!(
58 "merged distinct count across two overlapping shards (true count = 15000): {:.1}",
59 merged.get_estimate()
60 );
61}Sourcepub fn update_bytes(&mut self, value: &[u8])
pub fn update_bytes(&mut self, value: &[u8])
Adds an arbitrary byte slice to the sketch.
Examples found in repository?
7fn main() {
8 // A sketch estimates the number of distinct items seen, using bounded
9 // memory regardless of how many items are added. `lg_config_k` (4..=21)
10 // trades memory for accuracy: higher values are more accurate but use
11 // more space.
12 let mut sketch = HllSketch::new(12, TargetHllType::Hll4).expect("valid lg_config_k");
13
14 for i in 0..10_000u64 {
15 sketch.update_u64(i);
16 }
17 // Duplicates don't affect the distinct count.
18 for i in 0..5_000u64 {
19 sketch.update_u64(i);
20 }
21 sketch.update_str("some-key");
22 sketch.update_bytes(b"raw bytes work too");
23
24 println!("distinct count estimate: {:.1}", sketch.get_estimate());
25 println!(
26 "95% confidence interval: [{:.1}, {:.1}]",
27 sketch.get_lower_bound(2).unwrap(),
28 sketch.get_upper_bound(2).unwrap()
29 );
30
31 // Sketches can be serialized to bytes (e.g. to store or send over the
32 // network) and reconstructed later.
33 let bytes = sketch.serialize_compact();
34 let restored = HllSketch::deserialize(&bytes).expect("valid sketch bytes");
35 assert_eq!(sketch.get_estimate(), restored.get_estimate());
36 println!(
37 "serialized to {} bytes and restored successfully",
38 bytes.len()
39 );
40
41 // HllUnion merges multiple sketches into one, e.g. combining
42 // per-shard/per-day counts into a total distinct count.
43 let mut shard_a = HllSketch::new(12, TargetHllType::Hll4).unwrap();
44 for i in 0..10_000u64 {
45 shard_a.update_u64(i);
46 }
47 let mut shard_b = HllSketch::new(12, TargetHllType::Hll4).unwrap();
48 for i in 5_000..15_000u64 {
49 shard_b.update_u64(i);
50 }
51
52 let mut union = HllUnion::new(12).expect("valid lg_max_k");
53 union.update_sketch(&shard_a);
54 union.update_sketch(&shard_b);
55
56 let merged = union.get_result(TargetHllType::Hll4);
57 println!(
58 "merged distinct count across two overlapping shards (true count = 15000): {:.1}",
59 merged.get_estimate()
60 );
61}Sourcepub fn get_estimate(&self) -> f64
pub fn get_estimate(&self) -> f64
Returns the current estimate of the number of distinct items added.
Examples found in repository?
7fn main() {
8 // A sketch estimates the number of distinct items seen, using bounded
9 // memory regardless of how many items are added. `lg_config_k` (4..=21)
10 // trades memory for accuracy: higher values are more accurate but use
11 // more space.
12 let mut sketch = HllSketch::new(12, TargetHllType::Hll4).expect("valid lg_config_k");
13
14 for i in 0..10_000u64 {
15 sketch.update_u64(i);
16 }
17 // Duplicates don't affect the distinct count.
18 for i in 0..5_000u64 {
19 sketch.update_u64(i);
20 }
21 sketch.update_str("some-key");
22 sketch.update_bytes(b"raw bytes work too");
23
24 println!("distinct count estimate: {:.1}", sketch.get_estimate());
25 println!(
26 "95% confidence interval: [{:.1}, {:.1}]",
27 sketch.get_lower_bound(2).unwrap(),
28 sketch.get_upper_bound(2).unwrap()
29 );
30
31 // Sketches can be serialized to bytes (e.g. to store or send over the
32 // network) and reconstructed later.
33 let bytes = sketch.serialize_compact();
34 let restored = HllSketch::deserialize(&bytes).expect("valid sketch bytes");
35 assert_eq!(sketch.get_estimate(), restored.get_estimate());
36 println!(
37 "serialized to {} bytes and restored successfully",
38 bytes.len()
39 );
40
41 // HllUnion merges multiple sketches into one, e.g. combining
42 // per-shard/per-day counts into a total distinct count.
43 let mut shard_a = HllSketch::new(12, TargetHllType::Hll4).unwrap();
44 for i in 0..10_000u64 {
45 shard_a.update_u64(i);
46 }
47 let mut shard_b = HllSketch::new(12, TargetHllType::Hll4).unwrap();
48 for i in 5_000..15_000u64 {
49 shard_b.update_u64(i);
50 }
51
52 let mut union = HllUnion::new(12).expect("valid lg_max_k");
53 union.update_sketch(&shard_a);
54 union.update_sketch(&shard_b);
55
56 let merged = union.get_result(TargetHllType::Hll4);
57 println!(
58 "merged distinct count across two overlapping shards (true count = 15000): {:.1}",
59 merged.get_estimate()
60 );
61}Sourcepub fn get_lower_bound(&self, num_std_dev: u8) -> Result<f64, SketchError>
pub fn get_lower_bound(&self, num_std_dev: u8) -> Result<f64, SketchError>
Returns the lower bound of the confidence interval around
Self::get_estimate, for the given number of standard deviations
(1, 2, or 3, corresponding to roughly 67%, 95%, and 99%
confidence). Returns SketchError::InvalidConfig for any other
value.
Examples found in repository?
7fn main() {
8 // A sketch estimates the number of distinct items seen, using bounded
9 // memory regardless of how many items are added. `lg_config_k` (4..=21)
10 // trades memory for accuracy: higher values are more accurate but use
11 // more space.
12 let mut sketch = HllSketch::new(12, TargetHllType::Hll4).expect("valid lg_config_k");
13
14 for i in 0..10_000u64 {
15 sketch.update_u64(i);
16 }
17 // Duplicates don't affect the distinct count.
18 for i in 0..5_000u64 {
19 sketch.update_u64(i);
20 }
21 sketch.update_str("some-key");
22 sketch.update_bytes(b"raw bytes work too");
23
24 println!("distinct count estimate: {:.1}", sketch.get_estimate());
25 println!(
26 "95% confidence interval: [{:.1}, {:.1}]",
27 sketch.get_lower_bound(2).unwrap(),
28 sketch.get_upper_bound(2).unwrap()
29 );
30
31 // Sketches can be serialized to bytes (e.g. to store or send over the
32 // network) and reconstructed later.
33 let bytes = sketch.serialize_compact();
34 let restored = HllSketch::deserialize(&bytes).expect("valid sketch bytes");
35 assert_eq!(sketch.get_estimate(), restored.get_estimate());
36 println!(
37 "serialized to {} bytes and restored successfully",
38 bytes.len()
39 );
40
41 // HllUnion merges multiple sketches into one, e.g. combining
42 // per-shard/per-day counts into a total distinct count.
43 let mut shard_a = HllSketch::new(12, TargetHllType::Hll4).unwrap();
44 for i in 0..10_000u64 {
45 shard_a.update_u64(i);
46 }
47 let mut shard_b = HllSketch::new(12, TargetHllType::Hll4).unwrap();
48 for i in 5_000..15_000u64 {
49 shard_b.update_u64(i);
50 }
51
52 let mut union = HllUnion::new(12).expect("valid lg_max_k");
53 union.update_sketch(&shard_a);
54 union.update_sketch(&shard_b);
55
56 let merged = union.get_result(TargetHllType::Hll4);
57 println!(
58 "merged distinct count across two overlapping shards (true count = 15000): {:.1}",
59 merged.get_estimate()
60 );
61}Sourcepub fn get_upper_bound(&self, num_std_dev: u8) -> Result<f64, SketchError>
pub fn get_upper_bound(&self, num_std_dev: u8) -> Result<f64, SketchError>
Returns the upper bound of the confidence interval around
Self::get_estimate. See Self::get_lower_bound for the meaning
of num_std_dev.
Examples found in repository?
7fn main() {
8 // A sketch estimates the number of distinct items seen, using bounded
9 // memory regardless of how many items are added. `lg_config_k` (4..=21)
10 // trades memory for accuracy: higher values are more accurate but use
11 // more space.
12 let mut sketch = HllSketch::new(12, TargetHllType::Hll4).expect("valid lg_config_k");
13
14 for i in 0..10_000u64 {
15 sketch.update_u64(i);
16 }
17 // Duplicates don't affect the distinct count.
18 for i in 0..5_000u64 {
19 sketch.update_u64(i);
20 }
21 sketch.update_str("some-key");
22 sketch.update_bytes(b"raw bytes work too");
23
24 println!("distinct count estimate: {:.1}", sketch.get_estimate());
25 println!(
26 "95% confidence interval: [{:.1}, {:.1}]",
27 sketch.get_lower_bound(2).unwrap(),
28 sketch.get_upper_bound(2).unwrap()
29 );
30
31 // Sketches can be serialized to bytes (e.g. to store or send over the
32 // network) and reconstructed later.
33 let bytes = sketch.serialize_compact();
34 let restored = HllSketch::deserialize(&bytes).expect("valid sketch bytes");
35 assert_eq!(sketch.get_estimate(), restored.get_estimate());
36 println!(
37 "serialized to {} bytes and restored successfully",
38 bytes.len()
39 );
40
41 // HllUnion merges multiple sketches into one, e.g. combining
42 // per-shard/per-day counts into a total distinct count.
43 let mut shard_a = HllSketch::new(12, TargetHllType::Hll4).unwrap();
44 for i in 0..10_000u64 {
45 shard_a.update_u64(i);
46 }
47 let mut shard_b = HllSketch::new(12, TargetHllType::Hll4).unwrap();
48 for i in 5_000..15_000u64 {
49 shard_b.update_u64(i);
50 }
51
52 let mut union = HllUnion::new(12).expect("valid lg_max_k");
53 union.update_sketch(&shard_a);
54 union.update_sketch(&shard_b);
55
56 let merged = union.get_result(TargetHllType::Hll4);
57 println!(
58 "merged distinct count across two overlapping shards (true count = 15000): {:.1}",
59 merged.get_estimate()
60 );
61}Sourcepub fn get_lg_config_k(&self) -> u8
pub fn get_lg_config_k(&self) -> u8
Returns the lg_config_k this sketch was built with.
Sourcepub fn get_target_type(&self) -> TargetHllType
pub fn get_target_type(&self) -> TargetHllType
Returns the TargetHllType this sketch currently uses.
Sourcepub fn to_string_summary(&self) -> String
pub fn to_string_summary(&self) -> String
Returns a human-readable, multi-line summary of this sketch’s internal state — useful for debugging, not for parsing.
Sourcepub fn serialize_compact(&self) -> Vec<u8> ⓘ
pub fn serialize_compact(&self) -> Vec<u8> ⓘ
Serializes this sketch in compact form (read-only once
deserialized): smaller on the wire, but a
Self::deserialized sketch produced from these bytes cannot be
updated further. Use Self::serialize_updatable if you need to
resume adding items after deserializing.
Examples found in repository?
7fn main() {
8 // A sketch estimates the number of distinct items seen, using bounded
9 // memory regardless of how many items are added. `lg_config_k` (4..=21)
10 // trades memory for accuracy: higher values are more accurate but use
11 // more space.
12 let mut sketch = HllSketch::new(12, TargetHllType::Hll4).expect("valid lg_config_k");
13
14 for i in 0..10_000u64 {
15 sketch.update_u64(i);
16 }
17 // Duplicates don't affect the distinct count.
18 for i in 0..5_000u64 {
19 sketch.update_u64(i);
20 }
21 sketch.update_str("some-key");
22 sketch.update_bytes(b"raw bytes work too");
23
24 println!("distinct count estimate: {:.1}", sketch.get_estimate());
25 println!(
26 "95% confidence interval: [{:.1}, {:.1}]",
27 sketch.get_lower_bound(2).unwrap(),
28 sketch.get_upper_bound(2).unwrap()
29 );
30
31 // Sketches can be serialized to bytes (e.g. to store or send over the
32 // network) and reconstructed later.
33 let bytes = sketch.serialize_compact();
34 let restored = HllSketch::deserialize(&bytes).expect("valid sketch bytes");
35 assert_eq!(sketch.get_estimate(), restored.get_estimate());
36 println!(
37 "serialized to {} bytes and restored successfully",
38 bytes.len()
39 );
40
41 // HllUnion merges multiple sketches into one, e.g. combining
42 // per-shard/per-day counts into a total distinct count.
43 let mut shard_a = HllSketch::new(12, TargetHllType::Hll4).unwrap();
44 for i in 0..10_000u64 {
45 shard_a.update_u64(i);
46 }
47 let mut shard_b = HllSketch::new(12, TargetHllType::Hll4).unwrap();
48 for i in 5_000..15_000u64 {
49 shard_b.update_u64(i);
50 }
51
52 let mut union = HllUnion::new(12).expect("valid lg_max_k");
53 union.update_sketch(&shard_a);
54 union.update_sketch(&shard_b);
55
56 let merged = union.get_result(TargetHllType::Hll4);
57 println!(
58 "merged distinct count across two overlapping shards (true count = 15000): {:.1}",
59 merged.get_estimate()
60 );
61}Sourcepub fn serialize_updatable(&self) -> Vec<u8> ⓘ
pub fn serialize_updatable(&self) -> Vec<u8> ⓘ
Serializes this sketch in updatable form: larger on the wire than
Self::serialize_compact, but a deserialized sketch can have more
items added to it.