pub struct Minisketch { /* private fields */ }
Expand description
Describes decoded sketches and holding underlying opaque type inside.
Implementations§
Source§impl Minisketch
impl Minisketch
Sourcepub fn try_new(
bits: u32,
implementation: u32,
capacity: usize,
) -> Result<Self, MinisketchError>
pub fn try_new( bits: u32, implementation: u32, capacity: usize, ) -> Result<Self, MinisketchError>
Tries to create a new empty sketch.
§Errors
If the combination of bits
and implementation
is unavailable, or if
capacity
is 0, an Err(MinisketchError)
is returned.
§Examples
use minisketch_rs::Minisketch;
let sketch = Minisketch::try_new(12, 0, 4)?;
Examples found in repository?
More examples
43fn create_sketch(elements: impl IntoIterator<Item = u64>) -> Result<Minisketch, MinisketchError> {
44 let mut sketch = Minisketch::try_new(12, 0, 4)?;
45 for item in elements.into_iter() {
46 sketch.add(item);
47 }
48
49 Ok(sketch)
50}
51
52fn create_sketch_alice() -> Result<Minisketch, MinisketchError> {
53 let set = 3_000..3_010;
54 println!(
55 "Alice's set: {:?}",
56 set.clone().into_iter().collect::<Vec<_>>()
57 );
58
59 Ok(create_sketch(set)?)
60}
61
62fn create_sketch_bob() -> Result<Minisketch, MinisketchError> {
63 let set = 3_002..3_012;
64 println!(
65 "Bob's set: {:?}",
66 set.clone().into_iter().collect::<Vec<_>>()
67 );
68
69 Ok(create_sketch(set)?)
70}
71
72fn reconcile_with_bob(msg_alice: &[u8]) -> Result<(), MinisketchError> {
73 let mut sketch_bob = create_sketch_bob()?;
74
75 // Restore Alice's sketch (not set!) from serialized message
76 let mut sketch_alice = Minisketch::try_new(12, 0, 4)?;
77 sketch_alice.deserialize(&msg_alice);
78
79 // Reconcile sets by merging sketches
80 sketch_bob.merge(&sketch_alice)?;
81
82 // Extract difference between two sets from merged sketch
83 let mut differences = [0u64; 4];
84 let num_differences = sketch_bob.decode(&mut differences[..])?;
85
86 println!("Differences between Alice and Bob: {}", num_differences);
87 assert!(num_differences > 0);
88
89 // Sort differences since they may come in arbitrary order from Minisketch::decode()
90 let mut differences = Vec::from(&differences[..]);
91 differences.sort();
92
93 for (i, diff) in differences.iter().enumerate() {
94 println!("Difference #{}: {}", (i + 1), diff);
95 }
96
97 assert_eq!(differences[0], 3_000);
98 assert_eq!(differences[1], 3_001);
99 assert_eq!(differences[2], 3_010);
100 assert_eq!(differences[3], 3_011);
101
102 Ok(())
103}
Sourcepub fn bits_supported(bits: u32) -> bool
pub fn bits_supported(bits: u32) -> bool
Determine whether support for elements of size of bits
bits was compiled in.
Sourcepub fn implementation_max() -> u32
pub fn implementation_max() -> u32
Determine the maximum number of implementations available.
Multiple implementations may be available for a given element size, with different performance characteristics on different hardware.
Each implementation is identified by a number from 0 to the output of this function call, inclusive. Note that not every combination of implementation and element size may exist.
Sourcepub fn implementation(&self) -> u32
pub fn implementation(&self) -> u32
Returns implementation version number.
Sourcepub fn serialized_size(&self) -> usize
pub fn serialized_size(&self) -> usize
Returns the size in bytes for serializing a given sketch.
Examples found in repository?
105pub fn main() -> Result<(), MinisketchError> {
106 // Create sketch of Alice's set
107 let sketch_alice = create_sketch_alice()?;
108
109 // Serialize sketch as bytes
110 let mut buf_a = vec![0u8; sketch_alice.serialized_size()];
111 sketch_alice.serialize(buf_a.as_mut_slice())?;
112
113 println!("Message: {}, {:?}", buf_a.len(), buf_a);
114
115 // Send bytes to Bob for set reconciliation
116 reconcile_with_bob(&buf_a)?;
117
118 Ok(())
119}
More examples
69fn sub_sketches(s1: &[u8], s2: &[u8], d: usize, seed: Option<u64>) -> Vec<u8> {
70 let mut a = create_minisketch(d, seed);
71 if let Some(seed) = seed {
72 a.set_seed(seed);
73 }
74 a.deserialize(s1);
75
76 let mut b = create_minisketch(d, seed);
77 if let Some(seed) = seed {
78 b.set_seed(seed);
79 }
80 b.deserialize(s2);
81
82 a.merge(&b).expect("Sketch sub merge");
83
84 let mut sketch = vec![0u8; a.serialized_size()];
85 a.serialize(&mut sketch).expect("Serialize sketch sub");
86
87 sketch
88}
89
90/// Creates a_whole set from a_whole range of elements
91fn sketch_from_range(
92 range: impl IntoIterator<Item = u64>,
93 capacity: usize,
94 seed: Option<u64>,
95) -> Minisketch {
96 let mut sketch = create_minisketch(capacity, seed);
97 for i in range {
98 sketch.add(i);
99 }
100 sketch
101}
102
103/// Creates `Minisketch` for given `capacity` and optional `seed`.
104fn create_minisketch(capacity: usize, seed: Option<u64>) -> Minisketch {
105 let mut minisketch = Minisketch::try_new(64, 0, capacity).unwrap();
106
107 if let Some(seed) = seed {
108 minisketch.set_seed(seed);
109 }
110
111 minisketch
112}
113
114/// Creates serialized sketch.
115fn serialize_sketch(sketch: Minisketch) -> Vec<u8> {
116 let mut buf = vec![0u8; sketch.serialized_size()];
117 sketch.serialize(&mut buf).expect("Minisketch serialize");
118
119 buf
120}
Sourcepub fn add(&mut self, element: u64)
pub fn add(&mut self, element: u64)
Adds a u64
element to a sketch.
If the element to be added is too large for the sketch, the most significant
bits of the element are dropped. More precisely, if the element size of
sketch
is b bits, then this function adds the unsigned integer represented
by the b least significant bits of element
to sketch
.
If the element to be added is 0 (after potentially dropping the most significant bits), then this function is a no-op. Sketches cannot contain an element with the value 0.
Note that adding the same element a second time removes it again, as sketches have set semantics, not multiset semantics.
§Examples
use minisketch_rs::Minisketch;
let mut sketch = Minisketch::try_new(12, 0, 4)?;
sketch.add(42);
Examples found in repository?
More examples
Sourcepub fn set_seed(&mut self, seed: u64)
pub fn set_seed(&mut self, seed: u64)
Set the seed for randomizing algorithm choices to a fixed value.
By default, sketches are initialized with a random seed. This is important to avoid scenarios where an attacker could force worst-case behavior.
This function initializes the seed to a user-provided value (any 64-bit integer is acceptable, regardless of field size).
When seed is std::u64::MAX
, a fixed internal value with predictable behavior is used.
It is only intended for testing.
§Examples
use minisketch_rs::Minisketch;
let mut sketch = Minisketch::try_new(12, 0, 4)?;
sketch.set_seed(42);
Examples found in repository?
69fn sub_sketches(s1: &[u8], s2: &[u8], d: usize, seed: Option<u64>) -> Vec<u8> {
70 let mut a = create_minisketch(d, seed);
71 if let Some(seed) = seed {
72 a.set_seed(seed);
73 }
74 a.deserialize(s1);
75
76 let mut b = create_minisketch(d, seed);
77 if let Some(seed) = seed {
78 b.set_seed(seed);
79 }
80 b.deserialize(s2);
81
82 a.merge(&b).expect("Sketch sub merge");
83
84 let mut sketch = vec![0u8; a.serialized_size()];
85 a.serialize(&mut sketch).expect("Serialize sketch sub");
86
87 sketch
88}
89
90/// Creates a_whole set from a_whole range of elements
91fn sketch_from_range(
92 range: impl IntoIterator<Item = u64>,
93 capacity: usize,
94 seed: Option<u64>,
95) -> Minisketch {
96 let mut sketch = create_minisketch(capacity, seed);
97 for i in range {
98 sketch.add(i);
99 }
100 sketch
101}
102
103/// Creates `Minisketch` for given `capacity` and optional `seed`.
104fn create_minisketch(capacity: usize, seed: Option<u64>) -> Minisketch {
105 let mut minisketch = Minisketch::try_new(64, 0, capacity).unwrap();
106
107 if let Some(seed) = seed {
108 minisketch.set_seed(seed);
109 }
110
111 minisketch
112}
Sourcepub fn merge(&mut self, other: &Self) -> Result<usize, MinisketchError>
pub fn merge(&mut self, other: &Self) -> Result<usize, MinisketchError>
Merge the elements of another sketch into this sketch.
After merging, sketch
will contain every element that existed in one but not
both of the input sketches. It can be seen as an exclusive or operation on
the set elements. If the capacity of other_sketch
is lower than sketch
’s,
merging reduces the capacity of sketch
to that of other_sketch
.
Returns the Ok(capacity)
of sketch
after merging has been performed (where this capacity
is at least 1)
It is also possible to perform this operation directly on the serializations of two sketches with the same element size and capacity by performing a bitwise XOR of the serializations.
You can also merge two sketches by doing xor-assignment (^=
).
§Errors
Returns Err(MinisketchError)
to indicate that merging has failed
because the two input sketches differ in their element size or implementation. If Err
is
returned, sketch
(and its capacity) have not been modified.
§Examples
use minisketch_rs::Minisketch;
let mut sketch_a = Minisketch::try_new(12, 0, 4)?;
sketch_a.add(10);
sketch_a.add(43);
let mut sketch_b = Minisketch::try_new(12, 0, 4)?;
sketch_b.add(42);
sketch_b.add(43);
// Merge two sketches and extract a difference
let num_diffs = sketch_a.merge(&sketch_b)?;
// Extract difference
let mut differences = vec![0u64; num_diffs];
sketch_a.decode(&mut differences)?;
assert!((differences[0] == 42 || differences[0] == 10) && (differences[1] == 10 || differences[1] == 42));
Examples found in repository?
69fn sub_sketches(s1: &[u8], s2: &[u8], d: usize, seed: Option<u64>) -> Vec<u8> {
70 let mut a = create_minisketch(d, seed);
71 if let Some(seed) = seed {
72 a.set_seed(seed);
73 }
74 a.deserialize(s1);
75
76 let mut b = create_minisketch(d, seed);
77 if let Some(seed) = seed {
78 b.set_seed(seed);
79 }
80 b.deserialize(s2);
81
82 a.merge(&b).expect("Sketch sub merge");
83
84 let mut sketch = vec![0u8; a.serialized_size()];
85 a.serialize(&mut sketch).expect("Serialize sketch sub");
86
87 sketch
88}
89
90/// Creates a_whole set from a_whole range of elements
91fn sketch_from_range(
92 range: impl IntoIterator<Item = u64>,
93 capacity: usize,
94 seed: Option<u64>,
95) -> Minisketch {
96 let mut sketch = create_minisketch(capacity, seed);
97 for i in range {
98 sketch.add(i);
99 }
100 sketch
101}
102
103/// Creates `Minisketch` for given `capacity` and optional `seed`.
104fn create_minisketch(capacity: usize, seed: Option<u64>) -> Minisketch {
105 let mut minisketch = Minisketch::try_new(64, 0, capacity).unwrap();
106
107 if let Some(seed) = seed {
108 minisketch.set_seed(seed);
109 }
110
111 minisketch
112}
113
114/// Creates serialized sketch.
115fn serialize_sketch(sketch: Minisketch) -> Vec<u8> {
116 let mut buf = vec![0u8; sketch.serialized_size()];
117 sketch.serialize(&mut buf).expect("Minisketch serialize");
118
119 buf
120}
121
122/// Does set reconciliation from two sets.
123fn reconcile(
124 sketch_a: &[u8],
125 sketch_b: &[u8],
126 capacity: usize,
127 seed: Option<u64>,
128) -> Result<Vec<u64>, ()> {
129 let mut a = create_minisketch(capacity, seed);
130 a.deserialize(sketch_a);
131
132 let mut b = create_minisketch(capacity, seed);
133 b.deserialize(sketch_b);
134
135 a.merge(&b).expect("Minisketch merge");
136
137 let mut diffs = vec![0u64; capacity];
138 let num_diffs = a.decode(&mut diffs).map_err(|_| ())?;
139
140 Ok(diffs.into_iter().take(num_diffs).collect())
141}
More examples
72fn reconcile_with_bob(msg_alice: &[u8]) -> Result<(), MinisketchError> {
73 let mut sketch_bob = create_sketch_bob()?;
74
75 // Restore Alice's sketch (not set!) from serialized message
76 let mut sketch_alice = Minisketch::try_new(12, 0, 4)?;
77 sketch_alice.deserialize(&msg_alice);
78
79 // Reconcile sets by merging sketches
80 sketch_bob.merge(&sketch_alice)?;
81
82 // Extract difference between two sets from merged sketch
83 let mut differences = [0u64; 4];
84 let num_differences = sketch_bob.decode(&mut differences[..])?;
85
86 println!("Differences between Alice and Bob: {}", num_differences);
87 assert!(num_differences > 0);
88
89 // Sort differences since they may come in arbitrary order from Minisketch::decode()
90 let mut differences = Vec::from(&differences[..]);
91 differences.sort();
92
93 for (i, diff) in differences.iter().enumerate() {
94 println!("Difference #{}: {}", (i + 1), diff);
95 }
96
97 assert_eq!(differences[0], 3_000);
98 assert_eq!(differences[1], 3_001);
99 assert_eq!(differences[2], 3_010);
100 assert_eq!(differences[3], 3_011);
101
102 Ok(())
103}
Sourcepub fn decode(&self, elements: &mut [u64]) -> Result<usize, MinisketchError>
pub fn decode(&self, elements: &mut [u64]) -> Result<usize, MinisketchError>
Decode a sketch.
elements
is a mutable reference to a buffer of u64
, which will be filled with the
elements in this sketch.
Returns Ok(num. of decoded elements)
§Errors
Returns Err(MinisketchError)
if decoding failed for any reason.
§Examples
use minisketch_rs::Minisketch;
let mut sketch = Minisketch::try_new(12, 0, 2)?;
sketch.add(42);
sketch.add(10);
let mut elements = [0u64; 2];
sketch.decode(&mut elements)?;
// Elements may come in arbitrary order, so check all possible variants
assert!((elements[0] == 42 || elements[0] == 10) && (elements[1] == 10 || elements[1] == 42));
Examples found in repository?
123fn reconcile(
124 sketch_a: &[u8],
125 sketch_b: &[u8],
126 capacity: usize,
127 seed: Option<u64>,
128) -> Result<Vec<u64>, ()> {
129 let mut a = create_minisketch(capacity, seed);
130 a.deserialize(sketch_a);
131
132 let mut b = create_minisketch(capacity, seed);
133 b.deserialize(sketch_b);
134
135 a.merge(&b).expect("Minisketch merge");
136
137 let mut diffs = vec![0u64; capacity];
138 let num_diffs = a.decode(&mut diffs).map_err(|_| ())?;
139
140 Ok(diffs.into_iter().take(num_diffs).collect())
141}
More examples
72fn reconcile_with_bob(msg_alice: &[u8]) -> Result<(), MinisketchError> {
73 let mut sketch_bob = create_sketch_bob()?;
74
75 // Restore Alice's sketch (not set!) from serialized message
76 let mut sketch_alice = Minisketch::try_new(12, 0, 4)?;
77 sketch_alice.deserialize(&msg_alice);
78
79 // Reconcile sets by merging sketches
80 sketch_bob.merge(&sketch_alice)?;
81
82 // Extract difference between two sets from merged sketch
83 let mut differences = [0u64; 4];
84 let num_differences = sketch_bob.decode(&mut differences[..])?;
85
86 println!("Differences between Alice and Bob: {}", num_differences);
87 assert!(num_differences > 0);
88
89 // Sort differences since they may come in arbitrary order from Minisketch::decode()
90 let mut differences = Vec::from(&differences[..]);
91 differences.sort();
92
93 for (i, diff) in differences.iter().enumerate() {
94 println!("Difference #{}: {}", (i + 1), diff);
95 }
96
97 assert_eq!(differences[0], 3_000);
98 assert_eq!(differences[1], 3_001);
99 assert_eq!(differences[2], 3_010);
100 assert_eq!(differences[3], 3_011);
101
102 Ok(())
103}
Sourcepub fn deserialize(&mut self, buf: &[u8])
pub fn deserialize(&mut self, buf: &[u8])
Deserialize a sketch from bytes.
§Examples
use minisketch_rs::Minisketch;
// Create Alice's sketch
let mut sketch_alice = Minisketch::try_new(12, 0, 2)?;
sketch_alice.add(42);
sketch_alice.add(10);
// Serialize sketch on Alice's side
let mut message = vec![0u8; sketch_alice.serialized_size()];
sketch_alice.serialize(&mut message);
// ... message is sent from Alice to Bob ...
// Deserialize sketch from Alice on Bob's side
let mut sketch_bob = Minisketch::try_new(12, 0, 2)?;
sketch_bob.deserialize(&message);
// Decode received sketch
let mut elements = [0u64; 2];
sketch_bob.decode(&mut elements)?;
// Elements may come in arbitrary order, so check all possible variants
assert!((elements[0] == 42 || elements[0] == 10) && (elements[1] == 10 || elements[1] == 42));
Examples found in repository?
69fn sub_sketches(s1: &[u8], s2: &[u8], d: usize, seed: Option<u64>) -> Vec<u8> {
70 let mut a = create_minisketch(d, seed);
71 if let Some(seed) = seed {
72 a.set_seed(seed);
73 }
74 a.deserialize(s1);
75
76 let mut b = create_minisketch(d, seed);
77 if let Some(seed) = seed {
78 b.set_seed(seed);
79 }
80 b.deserialize(s2);
81
82 a.merge(&b).expect("Sketch sub merge");
83
84 let mut sketch = vec![0u8; a.serialized_size()];
85 a.serialize(&mut sketch).expect("Serialize sketch sub");
86
87 sketch
88}
89
90/// Creates a_whole set from a_whole range of elements
91fn sketch_from_range(
92 range: impl IntoIterator<Item = u64>,
93 capacity: usize,
94 seed: Option<u64>,
95) -> Minisketch {
96 let mut sketch = create_minisketch(capacity, seed);
97 for i in range {
98 sketch.add(i);
99 }
100 sketch
101}
102
103/// Creates `Minisketch` for given `capacity` and optional `seed`.
104fn create_minisketch(capacity: usize, seed: Option<u64>) -> Minisketch {
105 let mut minisketch = Minisketch::try_new(64, 0, capacity).unwrap();
106
107 if let Some(seed) = seed {
108 minisketch.set_seed(seed);
109 }
110
111 minisketch
112}
113
114/// Creates serialized sketch.
115fn serialize_sketch(sketch: Minisketch) -> Vec<u8> {
116 let mut buf = vec![0u8; sketch.serialized_size()];
117 sketch.serialize(&mut buf).expect("Minisketch serialize");
118
119 buf
120}
121
122/// Does set reconciliation from two sets.
123fn reconcile(
124 sketch_a: &[u8],
125 sketch_b: &[u8],
126 capacity: usize,
127 seed: Option<u64>,
128) -> Result<Vec<u64>, ()> {
129 let mut a = create_minisketch(capacity, seed);
130 a.deserialize(sketch_a);
131
132 let mut b = create_minisketch(capacity, seed);
133 b.deserialize(sketch_b);
134
135 a.merge(&b).expect("Minisketch merge");
136
137 let mut diffs = vec![0u64; capacity];
138 let num_diffs = a.decode(&mut diffs).map_err(|_| ())?;
139
140 Ok(diffs.into_iter().take(num_diffs).collect())
141}
More examples
72fn reconcile_with_bob(msg_alice: &[u8]) -> Result<(), MinisketchError> {
73 let mut sketch_bob = create_sketch_bob()?;
74
75 // Restore Alice's sketch (not set!) from serialized message
76 let mut sketch_alice = Minisketch::try_new(12, 0, 4)?;
77 sketch_alice.deserialize(&msg_alice);
78
79 // Reconcile sets by merging sketches
80 sketch_bob.merge(&sketch_alice)?;
81
82 // Extract difference between two sets from merged sketch
83 let mut differences = [0u64; 4];
84 let num_differences = sketch_bob.decode(&mut differences[..])?;
85
86 println!("Differences between Alice and Bob: {}", num_differences);
87 assert!(num_differences > 0);
88
89 // Sort differences since they may come in arbitrary order from Minisketch::decode()
90 let mut differences = Vec::from(&differences[..]);
91 differences.sort();
92
93 for (i, diff) in differences.iter().enumerate() {
94 println!("Difference #{}: {}", (i + 1), diff);
95 }
96
97 assert_eq!(differences[0], 3_000);
98 assert_eq!(differences[1], 3_001);
99 assert_eq!(differences[2], 3_010);
100 assert_eq!(differences[3], 3_011);
101
102 Ok(())
103}
Sourcepub fn serialize(&self, buf: &mut [u8]) -> Result<(), MinisketchError>
pub fn serialize(&self, buf: &mut [u8]) -> Result<(), MinisketchError>
Serialize a sketch to bytes.
§Errors
Returns Err(MinisketchError)
if .len()
of the provided buffer buf
is less than a size in bytes of
the serialized representation of the sketch.
§Examples
use minisketch_rs::Minisketch;
let mut sketch = Minisketch::try_new(12, 0, 2)?;
sketch.add(42);
sketch.add(10);
let mut buf = vec![0u8; sketch.serialized_size()];
sketch.serialize(&mut buf);
Examples found in repository?
105pub fn main() -> Result<(), MinisketchError> {
106 // Create sketch of Alice's set
107 let sketch_alice = create_sketch_alice()?;
108
109 // Serialize sketch as bytes
110 let mut buf_a = vec![0u8; sketch_alice.serialized_size()];
111 sketch_alice.serialize(buf_a.as_mut_slice())?;
112
113 println!("Message: {}, {:?}", buf_a.len(), buf_a);
114
115 // Send bytes to Bob for set reconciliation
116 reconcile_with_bob(&buf_a)?;
117
118 Ok(())
119}
More examples
69fn sub_sketches(s1: &[u8], s2: &[u8], d: usize, seed: Option<u64>) -> Vec<u8> {
70 let mut a = create_minisketch(d, seed);
71 if let Some(seed) = seed {
72 a.set_seed(seed);
73 }
74 a.deserialize(s1);
75
76 let mut b = create_minisketch(d, seed);
77 if let Some(seed) = seed {
78 b.set_seed(seed);
79 }
80 b.deserialize(s2);
81
82 a.merge(&b).expect("Sketch sub merge");
83
84 let mut sketch = vec![0u8; a.serialized_size()];
85 a.serialize(&mut sketch).expect("Serialize sketch sub");
86
87 sketch
88}
89
90/// Creates a_whole set from a_whole range of elements
91fn sketch_from_range(
92 range: impl IntoIterator<Item = u64>,
93 capacity: usize,
94 seed: Option<u64>,
95) -> Minisketch {
96 let mut sketch = create_minisketch(capacity, seed);
97 for i in range {
98 sketch.add(i);
99 }
100 sketch
101}
102
103/// Creates `Minisketch` for given `capacity` and optional `seed`.
104fn create_minisketch(capacity: usize, seed: Option<u64>) -> Minisketch {
105 let mut minisketch = Minisketch::try_new(64, 0, capacity).unwrap();
106
107 if let Some(seed) = seed {
108 minisketch.set_seed(seed);
109 }
110
111 minisketch
112}
113
114/// Creates serialized sketch.
115fn serialize_sketch(sketch: Minisketch) -> Vec<u8> {
116 let mut buf = vec![0u8; sketch.serialized_size()];
117 sketch.serialize(&mut buf).expect("Minisketch serialize");
118
119 buf
120}
Trait Implementations§
Source§impl BitXorAssign for Minisketch
Custom ^=
operator implementation on two sketches that performs merging.
impl BitXorAssign for Minisketch
Custom ^=
operator implementation on two sketches that performs merging.
§Example
use minisketch_rs::Minisketch;
let mut sketch_a = Minisketch::try_new(12, 0, 4)?;
sketch_a.add(10);
sketch_a.add(43);
let mut sketch_b = Minisketch::try_new(12, 0, 4)?;
sketch_b.add(42);
sketch_b.add(43);
// Merge two sketches with ^= operator
sketch_a ^= sketch_b;
// Extract difference
let mut differences = vec![0u64; 2];
sketch_a.decode(&mut differences)?;
assert!((differences[0] == 42 || differences[0] == 10) && (differences[1] == 10 || differences[1] == 42));
Source§fn bitxor_assign(&mut self, rhs: Minisketch)
fn bitxor_assign(&mut self, rhs: Minisketch)
^=
operation. Read more