reifydb_value/value/partition/
mod.rs1use postcard::to_extend;
5use serde::{Deserialize, Serialize};
6
7use super::Value;
8use crate::util::hash::xxh3_128;
9
10#[repr(transparent)]
11#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
12#[serde(transparent)]
13pub struct Partition(pub u128);
14
15impl Partition {
16 pub fn of(values: &[Value]) -> Self {
17 let mut buf: Vec<u8> = Vec::new();
18 for value in values {
19 buf = to_extend(value, buf).expect("postcard serialization of a Value is total");
20 }
21 Partition(xxh3_128(&buf).0)
22 }
23}
24
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub enum ScanPartitions {
27 All,
28 One(Partition),
29 Many(Vec<Partition>),
30}
31
32impl From<u128> for Partition {
33 fn from(value: u128) -> Self {
34 Partition(value)
35 }
36}
37
38#[cfg(test)]
39#[allow(clippy::disallowed_methods)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn test_deterministic() {
45 let a = Partition::of(&[Value::Utf8("us".to_string())]);
46 let b = Partition::of(&[Value::Utf8("us".to_string())]);
47 assert_eq!(a, b, "same values must hash to the same partition");
48 }
49
50 #[test]
51 fn test_distinct_values_distinct_partition() {
52 let us = Partition::of(&[Value::Utf8("us".to_string())]);
53 let eu = Partition::of(&[Value::Utf8("eu".to_string())]);
54 assert_ne!(us, eu, "different values should (overwhelmingly) hash differently");
55 }
56
57 #[test]
58 fn test_multi_column() {
59 let a = Partition::of(&[Value::Utf8("us".to_string()), Value::Uint8(1)]);
60 let b = Partition::of(&[Value::Utf8("us".to_string()), Value::Uint8(2)]);
61 assert_ne!(a, b);
62 }
63}