Skip to main content

CpcSketch

Struct CpcSketch 

Source
pub struct CpcSketch { /* private fields */ }
Expand description

A CPC (Compressed Probabilistic Counting) sketch: estimates the number of distinct items added via update_*. Unlike Theta’s ThetaSketch, there is no separate compact/wrapped variant — this single type is both the mutable/update type and the serializable type, since CPC’s serialized form is always compressed by construction. Build one with CpcSketchBuilder.

Implementations§

Source§

impl CpcSketch

Source

pub fn deserialize(bytes: &[u8]) -> Result<Self, SketchError>

Reconstructs a sketch from bytes produced by Self::serialize.

Examples found in repository?
examples/cpc.rs (line 59)
8fn main() {
9    // A sketch estimates the number of distinct items seen, using bounded
10    // memory regardless of how many items are added. `lg_k` (4..=26)
11    // trades memory for accuracy: higher values are more accurate but use
12    // more space.
13    let mut visitors_day1 = CpcSketchBuilder::new()
14        .lg_k(11)
15        .build()
16        .expect("valid lg_k");
17    for id in 0..10_000u64 {
18        visitors_day1.update_u64(id);
19    }
20
21    let mut visitors_day2 = CpcSketchBuilder::new()
22        .lg_k(11)
23        .build()
24        .expect("valid lg_k");
25    for id in 5_000..15_000u64 {
26        visitors_day2.update_u64(id);
27    }
28
29    println!(
30        "Day 1 unique visitors (estimate): {:.0}",
31        visitors_day1.get_estimate()
32    );
33    println!(
34        "Day 2 unique visitors (estimate): {:.0}",
35        visitors_day2.get_estimate()
36    );
37    println!(
38        "Day 1, 95% confidence interval: [{:.0}, {:.0}]",
39        visitors_day1.get_lower_bound(2).unwrap(),
40        visitors_day1.get_upper_bound(2).unwrap()
41    );
42
43    // CpcUnion merges multiple sketches into one, e.g. combining per-day
44    // counts into a total distinct count across both days.
45    let mut union = CpcUnionBuilder::new().lg_k(11).build().expect("valid lg_k");
46    union.update(&visitors_day1);
47    union.update(&visitors_day2);
48    let total_unique = union.get_result();
49    println!(
50        "Total unique visitors across both days (true count = 15000): {:.0}",
51        total_unique.get_estimate()
52    );
53
54    // Sketches can be serialized to bytes (e.g. to store or send over the
55    // network) and reconstructed later. CPC's serialized form is always
56    // compressed, so there's a single serialize()/deserialize() pair
57    // (unlike Theta, which has separate compressed/uncompressed formats).
58    let bytes = visitors_day1.serialize();
59    let restored = CpcSketch::deserialize(&bytes).expect("valid sketch bytes");
60    println!(
61        "serialized day-1 sketch to {} bytes and restored successfully (estimate {:.0})",
62        bytes.len(),
63        restored.get_estimate()
64    );
65}
Source

pub fn update_u64(&mut self, value: u64)

Adds a u64 value to the sketch.

Examples found in repository?
examples/cpc.rs (line 18)
8fn main() {
9    // A sketch estimates the number of distinct items seen, using bounded
10    // memory regardless of how many items are added. `lg_k` (4..=26)
11    // trades memory for accuracy: higher values are more accurate but use
12    // more space.
13    let mut visitors_day1 = CpcSketchBuilder::new()
14        .lg_k(11)
15        .build()
16        .expect("valid lg_k");
17    for id in 0..10_000u64 {
18        visitors_day1.update_u64(id);
19    }
20
21    let mut visitors_day2 = CpcSketchBuilder::new()
22        .lg_k(11)
23        .build()
24        .expect("valid lg_k");
25    for id in 5_000..15_000u64 {
26        visitors_day2.update_u64(id);
27    }
28
29    println!(
30        "Day 1 unique visitors (estimate): {:.0}",
31        visitors_day1.get_estimate()
32    );
33    println!(
34        "Day 2 unique visitors (estimate): {:.0}",
35        visitors_day2.get_estimate()
36    );
37    println!(
38        "Day 1, 95% confidence interval: [{:.0}, {:.0}]",
39        visitors_day1.get_lower_bound(2).unwrap(),
40        visitors_day1.get_upper_bound(2).unwrap()
41    );
42
43    // CpcUnion merges multiple sketches into one, e.g. combining per-day
44    // counts into a total distinct count across both days.
45    let mut union = CpcUnionBuilder::new().lg_k(11).build().expect("valid lg_k");
46    union.update(&visitors_day1);
47    union.update(&visitors_day2);
48    let total_unique = union.get_result();
49    println!(
50        "Total unique visitors across both days (true count = 15000): {:.0}",
51        total_unique.get_estimate()
52    );
53
54    // Sketches can be serialized to bytes (e.g. to store or send over the
55    // network) and reconstructed later. CPC's serialized form is always
56    // compressed, so there's a single serialize()/deserialize() pair
57    // (unlike Theta, which has separate compressed/uncompressed formats).
58    let bytes = visitors_day1.serialize();
59    let restored = CpcSketch::deserialize(&bytes).expect("valid sketch bytes");
60    println!(
61        "serialized day-1 sketch to {} bytes and restored successfully (estimate {:.0})",
62        bytes.len(),
63        restored.get_estimate()
64    );
65}
Source

pub fn update_i64(&mut self, value: i64)

Adds an i64 value to the sketch.

Source

pub fn update_u32(&mut self, value: u32)

Adds a u32 value to the sketch.

Source

pub fn update_i32(&mut self, value: i32)

Adds an i32 value to the sketch.

Source

pub fn update_u16(&mut self, value: u16)

Adds a u16 value to the sketch.

Source

pub fn update_i16(&mut self, value: i16)

Adds an i16 value to the sketch.

Source

pub fn update_u8(&mut self, value: u8)

Adds a u8 value to the sketch.

Source

pub fn update_i8(&mut self, value: i8)

Adds an i8 value to the sketch.

Source

pub fn update_f64(&mut self, value: f64)

Adds an f64 value to the sketch.

Source

pub fn update_f32(&mut self, value: f32)

Adds an f32 value to the sketch.

Source

pub fn update_str(&mut self, value: &str)

Adds a string value to the sketch.

Source

pub fn update_bytes(&mut self, value: &[u8])

Adds an arbitrary byte slice to the sketch.

Source

pub fn is_empty(&self) -> bool

Returns true if no items have been added to this sketch.

Source

pub fn get_estimate(&self) -> f64

Returns the current estimate of the number of distinct items added.

Examples found in repository?
examples/cpc.rs (line 31)
8fn main() {
9    // A sketch estimates the number of distinct items seen, using bounded
10    // memory regardless of how many items are added. `lg_k` (4..=26)
11    // trades memory for accuracy: higher values are more accurate but use
12    // more space.
13    let mut visitors_day1 = CpcSketchBuilder::new()
14        .lg_k(11)
15        .build()
16        .expect("valid lg_k");
17    for id in 0..10_000u64 {
18        visitors_day1.update_u64(id);
19    }
20
21    let mut visitors_day2 = CpcSketchBuilder::new()
22        .lg_k(11)
23        .build()
24        .expect("valid lg_k");
25    for id in 5_000..15_000u64 {
26        visitors_day2.update_u64(id);
27    }
28
29    println!(
30        "Day 1 unique visitors (estimate): {:.0}",
31        visitors_day1.get_estimate()
32    );
33    println!(
34        "Day 2 unique visitors (estimate): {:.0}",
35        visitors_day2.get_estimate()
36    );
37    println!(
38        "Day 1, 95% confidence interval: [{:.0}, {:.0}]",
39        visitors_day1.get_lower_bound(2).unwrap(),
40        visitors_day1.get_upper_bound(2).unwrap()
41    );
42
43    // CpcUnion merges multiple sketches into one, e.g. combining per-day
44    // counts into a total distinct count across both days.
45    let mut union = CpcUnionBuilder::new().lg_k(11).build().expect("valid lg_k");
46    union.update(&visitors_day1);
47    union.update(&visitors_day2);
48    let total_unique = union.get_result();
49    println!(
50        "Total unique visitors across both days (true count = 15000): {:.0}",
51        total_unique.get_estimate()
52    );
53
54    // Sketches can be serialized to bytes (e.g. to store or send over the
55    // network) and reconstructed later. CPC's serialized form is always
56    // compressed, so there's a single serialize()/deserialize() pair
57    // (unlike Theta, which has separate compressed/uncompressed formats).
58    let bytes = visitors_day1.serialize();
59    let restored = CpcSketch::deserialize(&bytes).expect("valid sketch bytes");
60    println!(
61        "serialized day-1 sketch to {} bytes and restored successfully (estimate {:.0})",
62        bytes.len(),
63        restored.get_estimate()
64    );
65}
Source

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 — upstream calls this parameter kappa). Returns SketchError::InvalidConfig for any other value.

Examples found in repository?
examples/cpc.rs (line 39)
8fn main() {
9    // A sketch estimates the number of distinct items seen, using bounded
10    // memory regardless of how many items are added. `lg_k` (4..=26)
11    // trades memory for accuracy: higher values are more accurate but use
12    // more space.
13    let mut visitors_day1 = CpcSketchBuilder::new()
14        .lg_k(11)
15        .build()
16        .expect("valid lg_k");
17    for id in 0..10_000u64 {
18        visitors_day1.update_u64(id);
19    }
20
21    let mut visitors_day2 = CpcSketchBuilder::new()
22        .lg_k(11)
23        .build()
24        .expect("valid lg_k");
25    for id in 5_000..15_000u64 {
26        visitors_day2.update_u64(id);
27    }
28
29    println!(
30        "Day 1 unique visitors (estimate): {:.0}",
31        visitors_day1.get_estimate()
32    );
33    println!(
34        "Day 2 unique visitors (estimate): {:.0}",
35        visitors_day2.get_estimate()
36    );
37    println!(
38        "Day 1, 95% confidence interval: [{:.0}, {:.0}]",
39        visitors_day1.get_lower_bound(2).unwrap(),
40        visitors_day1.get_upper_bound(2).unwrap()
41    );
42
43    // CpcUnion merges multiple sketches into one, e.g. combining per-day
44    // counts into a total distinct count across both days.
45    let mut union = CpcUnionBuilder::new().lg_k(11).build().expect("valid lg_k");
46    union.update(&visitors_day1);
47    union.update(&visitors_day2);
48    let total_unique = union.get_result();
49    println!(
50        "Total unique visitors across both days (true count = 15000): {:.0}",
51        total_unique.get_estimate()
52    );
53
54    // Sketches can be serialized to bytes (e.g. to store or send over the
55    // network) and reconstructed later. CPC's serialized form is always
56    // compressed, so there's a single serialize()/deserialize() pair
57    // (unlike Theta, which has separate compressed/uncompressed formats).
58    let bytes = visitors_day1.serialize();
59    let restored = CpcSketch::deserialize(&bytes).expect("valid sketch bytes");
60    println!(
61        "serialized day-1 sketch to {} bytes and restored successfully (estimate {:.0})",
62        bytes.len(),
63        restored.get_estimate()
64    );
65}
Source

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?
examples/cpc.rs (line 40)
8fn main() {
9    // A sketch estimates the number of distinct items seen, using bounded
10    // memory regardless of how many items are added. `lg_k` (4..=26)
11    // trades memory for accuracy: higher values are more accurate but use
12    // more space.
13    let mut visitors_day1 = CpcSketchBuilder::new()
14        .lg_k(11)
15        .build()
16        .expect("valid lg_k");
17    for id in 0..10_000u64 {
18        visitors_day1.update_u64(id);
19    }
20
21    let mut visitors_day2 = CpcSketchBuilder::new()
22        .lg_k(11)
23        .build()
24        .expect("valid lg_k");
25    for id in 5_000..15_000u64 {
26        visitors_day2.update_u64(id);
27    }
28
29    println!(
30        "Day 1 unique visitors (estimate): {:.0}",
31        visitors_day1.get_estimate()
32    );
33    println!(
34        "Day 2 unique visitors (estimate): {:.0}",
35        visitors_day2.get_estimate()
36    );
37    println!(
38        "Day 1, 95% confidence interval: [{:.0}, {:.0}]",
39        visitors_day1.get_lower_bound(2).unwrap(),
40        visitors_day1.get_upper_bound(2).unwrap()
41    );
42
43    // CpcUnion merges multiple sketches into one, e.g. combining per-day
44    // counts into a total distinct count across both days.
45    let mut union = CpcUnionBuilder::new().lg_k(11).build().expect("valid lg_k");
46    union.update(&visitors_day1);
47    union.update(&visitors_day2);
48    let total_unique = union.get_result();
49    println!(
50        "Total unique visitors across both days (true count = 15000): {:.0}",
51        total_unique.get_estimate()
52    );
53
54    // Sketches can be serialized to bytes (e.g. to store or send over the
55    // network) and reconstructed later. CPC's serialized form is always
56    // compressed, so there's a single serialize()/deserialize() pair
57    // (unlike Theta, which has separate compressed/uncompressed formats).
58    let bytes = visitors_day1.serialize();
59    let restored = CpcSketch::deserialize(&bytes).expect("valid sketch bytes");
60    println!(
61        "serialized day-1 sketch to {} bytes and restored successfully (estimate {:.0})",
62        bytes.len(),
63        restored.get_estimate()
64    );
65}
Source

pub fn get_lg_k(&self) -> u8

Returns the lg_k this sketch was built with.

Source

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.

Source

pub fn serialize(&self) -> Vec<u8>

Serializes this sketch to bytes. CPC’s on-wire format is always compressed, so there is only this one serialization method (unlike Theta’s separate compressed/uncompressed formats).

Examples found in repository?
examples/cpc.rs (line 58)
8fn main() {
9    // A sketch estimates the number of distinct items seen, using bounded
10    // memory regardless of how many items are added. `lg_k` (4..=26)
11    // trades memory for accuracy: higher values are more accurate but use
12    // more space.
13    let mut visitors_day1 = CpcSketchBuilder::new()
14        .lg_k(11)
15        .build()
16        .expect("valid lg_k");
17    for id in 0..10_000u64 {
18        visitors_day1.update_u64(id);
19    }
20
21    let mut visitors_day2 = CpcSketchBuilder::new()
22        .lg_k(11)
23        .build()
24        .expect("valid lg_k");
25    for id in 5_000..15_000u64 {
26        visitors_day2.update_u64(id);
27    }
28
29    println!(
30        "Day 1 unique visitors (estimate): {:.0}",
31        visitors_day1.get_estimate()
32    );
33    println!(
34        "Day 2 unique visitors (estimate): {:.0}",
35        visitors_day2.get_estimate()
36    );
37    println!(
38        "Day 1, 95% confidence interval: [{:.0}, {:.0}]",
39        visitors_day1.get_lower_bound(2).unwrap(),
40        visitors_day1.get_upper_bound(2).unwrap()
41    );
42
43    // CpcUnion merges multiple sketches into one, e.g. combining per-day
44    // counts into a total distinct count across both days.
45    let mut union = CpcUnionBuilder::new().lg_k(11).build().expect("valid lg_k");
46    union.update(&visitors_day1);
47    union.update(&visitors_day2);
48    let total_unique = union.get_result();
49    println!(
50        "Total unique visitors across both days (true count = 15000): {:.0}",
51        total_unique.get_estimate()
52    );
53
54    // Sketches can be serialized to bytes (e.g. to store or send over the
55    // network) and reconstructed later. CPC's serialized form is always
56    // compressed, so there's a single serialize()/deserialize() pair
57    // (unlike Theta, which has separate compressed/uncompressed formats).
58    let bytes = visitors_day1.serialize();
59    let restored = CpcSketch::deserialize(&bytes).expect("valid sketch bytes");
60    println!(
61        "serialized day-1 sketch to {} bytes and restored successfully (estimate {:.0})",
62        bytes.len(),
63        restored.get_estimate()
64    );
65}

Trait Implementations§

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.