1use crate::{key::InternalKey, Slice};
6
7pub type UserKey = Slice;
9
10#[allow(clippy::module_name_repetitions)]
12pub type UserValue = Slice;
13
14pub type SeqNo = u64;
24
25#[derive(Copy, Clone, Debug, Eq, PartialEq)]
27#[allow(clippy::module_name_repetitions)]
28pub enum ValueType {
29 Value,
31
32 Tombstone,
34
35 WeakTombstone,
37}
38
39impl TryFrom<u8> for ValueType {
40 type Error = ();
41
42 fn try_from(value: u8) -> Result<Self, Self::Error> {
43 match value {
44 0 => Ok(Self::Value),
45 1 => Ok(Self::Tombstone),
46 2 => Ok(Self::WeakTombstone),
47 _ => Err(()),
48 }
49 }
50}
51
52impl From<ValueType> for u8 {
53 fn from(value: ValueType) -> Self {
54 match value {
55 ValueType::Value => 0,
56 ValueType::Tombstone => 1,
57 ValueType::WeakTombstone => 2,
58 }
59 }
60}
61
62#[allow(clippy::module_name_repetitions)]
64#[derive(Clone, Eq)]
65pub struct InternalValue {
66 pub key: InternalKey,
68
69 pub value: UserValue,
73}
74
75impl InternalValue {
76 pub fn new<V: Into<UserValue>>(key: InternalKey, value: V) -> Self {
82 let value = value.into();
83
84 assert!(!key.user_key.is_empty(), "key may not be empty");
85 assert!(
86 u32::try_from(value.len()).is_ok(),
87 "values can be 2^32 bytes in length"
88 );
89
90 Self { key, value }
91 }
92
93 pub fn from_components<K: Into<UserKey>, V: Into<UserValue>>(
99 user_key: K,
100 value: V,
101 seqno: SeqNo,
102 value_type: ValueType,
103 ) -> Self {
104 let key = InternalKey::new(user_key, seqno, value_type);
105 Self::new(key, value)
106 }
107
108 pub fn new_tombstone<K: Into<UserKey>>(key: K, seqno: u64) -> Self {
114 let key = InternalKey::new(key, seqno, ValueType::Tombstone);
115 Self::new(key, vec![])
116 }
117
118 pub fn new_weak_tombstone<K: Into<UserKey>>(key: K, seqno: u64) -> Self {
124 let key = InternalKey::new(key, seqno, ValueType::WeakTombstone);
125 Self::new(key, vec![])
126 }
127
128 #[doc(hidden)]
129 #[must_use]
130 pub fn is_tombstone(&self) -> bool {
131 self.key.is_tombstone()
132 }
133}
134
135impl PartialEq for InternalValue {
136 fn eq(&self, other: &Self) -> bool {
137 self.key == other.key
138 }
139}
140
141impl Ord for InternalValue {
142 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
143 self.key.cmp(&other.key)
144 }
145}
146
147impl PartialOrd for InternalValue {
148 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
149 Some(self.cmp(other))
150 }
151}
152
153impl std::fmt::Debug for InternalValue {
154 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155 write!(
156 f,
157 "{:?} => {:?}",
158 self.key,
159 if self.value.len() >= 64 {
160 format!("[ ... {} bytes ]", self.value.len())
161 } else {
162 format!("{:?}", self.value)
163 }
164 )
165 }
166}
167
168#[cfg(test)]
169mod tests {
170 use super::*;
171 use test_log::test;
172
173 #[test]
174 fn pik_cmp_user_key() {
175 let a = InternalKey::new(*b"a", 0, ValueType::Value);
176 let b = InternalKey::new(*b"b", 0, ValueType::Value);
177 assert!(a < b);
178 }
179
180 #[test]
181 fn pik_cmp_seqno() {
182 let a = InternalKey::new(*b"a", 0, ValueType::Value);
183 let b = InternalKey::new(*b"a", 1, ValueType::Value);
184 assert!(a > b);
185 }
186}