1use super::PartitionKey;
6use lsm_tree::{UserKey, UserValue, ValueType};
7
8pub enum CompactItem<K, V> {
12 Value {
14 key: K,
16 value: V,
18 },
19 Tombstone(K),
21 WeakTombstone(K),
23}
24
25impl<K: Ord, V> Ord for CompactItem<K, V> {
26 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
27 self.key().cmp(other.key())
28 }
29}
30
31impl<K: Ord, V> PartialOrd for CompactItem<K, V> {
32 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
33 Some(self.cmp(other))
34 }
35}
36
37impl<K: Eq, V> PartialEq for CompactItem<K, V> {
38 fn eq(&self, other: &Self) -> bool {
39 self.key() == other.key()
40 }
41}
42
43impl<K: Eq, V> Eq for CompactItem<K, V> {}
44
45impl<K, V> CompactItem<K, V> {
46 fn key(&self) -> &K {
47 match self {
48 Self::Value { key, .. } | Self::Tombstone(key) | Self::WeakTombstone(key) => key,
49 }
50 }
51}
52
53#[derive(Clone, PartialEq, Eq)]
54pub struct Item {
55 pub partition: PartitionKey,
59
60 pub key: UserKey,
64
65 pub value: UserValue,
69
70 pub value_type: ValueType,
72}
73
74impl std::fmt::Debug for Item {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 write!(
77 f,
78 "{}:{:?}:{} => {:?}",
79 self.partition,
80 self.key,
81 match self.value_type {
82 ValueType::Value => "V",
83 ValueType::Tombstone => "T",
84 ValueType::WeakTombstone => "W",
85 },
86 self.value
87 )
88 }
89}
90
91impl Item {
92 pub fn new<P: Into<PartitionKey>, K: Into<UserKey>, V: Into<UserValue>>(
96 partition: P,
97 key: K,
98 value: V,
99 value_type: ValueType,
100 ) -> Self {
101 let p = partition.into();
102 let k = key.into();
103 let v = value.into();
104
105 assert!(!p.is_empty());
106 assert!(!k.is_empty());
107
108 assert!(u8::try_from(p.len()).is_ok(), "Partition name too long");
109 assert!(
110 u16::try_from(k.len()).is_ok(),
111 "Keys can be up to 65535 bytes long"
112 );
113 assert!(
114 u32::try_from(v.len()).is_ok(),
115 "Values can be up to 2^32 bytes long"
116 );
117
118 Self {
119 partition: p,
120 key: k,
121 value: v,
122 value_type,
123 }
124 }
125}