1use apache_datasketches::theta::{
8 jaccard_similarity, ThetaAnotB, ThetaIntersection, ThetaSketchBuilder, ThetaUnionBuilder,
9};
10
11fn main() {
12 let mut visitors_day1 = ThetaSketchBuilder::new().lg_k(12).build().unwrap();
14 for id in 0..10_000u64 {
15 visitors_day1.update_u64(id);
16 }
17
18 let mut visitors_day2 = ThetaSketchBuilder::new().lg_k(12).build().unwrap();
19 for id in 5_000..15_000u64 {
20 visitors_day2.update_u64(id);
21 }
22
23 println!(
24 "Day 1 unique visitors (estimate): {:.0}",
25 visitors_day1.get_estimate()
26 );
27 println!(
28 "Day 2 unique visitors (estimate): {:.0}",
29 visitors_day2.get_estimate()
30 );
31
32 let mut union = ThetaUnionBuilder::new().lg_k(12).build().unwrap();
34 union.update(&visitors_day1);
35 union.update(&visitors_day2);
36 let total_unique = union.get_result(true);
37 println!(
38 "Total unique visitors (union estimate): {:.0}",
39 total_unique.get_estimate()
40 );
41
42 let mut intersection = ThetaIntersection::new();
44 intersection.update(&visitors_day1);
45 intersection.update(&visitors_day2);
46 match intersection.get_result(true) {
47 Ok(returning) => println!(
48 "Returning visitors (intersection estimate): {:.0}",
49 returning.get_estimate()
50 ),
51 Err(e) => println!("No intersection result: {e}"),
52 }
53
54 let a_not_b = ThetaAnotB::new();
56 let day1_only = a_not_b.compute(&visitors_day1, &visitors_day2, true);
57 println!(
58 "Day-1-only visitors (a-not-b estimate): {:.0}",
59 day1_only.get_estimate()
60 );
61
62 let similarity = jaccard_similarity(&visitors_day1, &visitors_day2);
64 println!(
65 "Jaccard similarity: {:.3} (range [{:.3}, {:.3}])",
66 similarity.estimate, similarity.lower_bound, similarity.upper_bound
67 );
68
69 let compact = visitors_day1.compact(true);
71 let bytes = compact.serialize_compact();
72 println!("Serialized day-1 sketch: {} bytes", bytes.len());
73 let restored = apache_datasketches::theta::CompactThetaSketch::deserialize(&bytes).unwrap();
74 println!("Restored estimate: {:.0}", restored.get_estimate());
75}