Skip to main content

reifydb_core/key/
dictionary.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use reifydb_type::value::dictionary::DictionaryId;
5
6use super::{EncodableKey, EncodableKeyRange, KeyKind};
7use crate::{
8	encoded::key::{EncodedKey, EncodedKeyRange},
9	util::encoding::keycode::{deserializer::KeyDeserializer, serializer::KeySerializer},
10};
11
12#[derive(Debug, Clone, PartialEq)]
13pub struct DictionaryKey {
14	pub dictionary: DictionaryId,
15}
16
17impl DictionaryKey {
18	pub fn new(dictionary: DictionaryId) -> Self {
19		Self {
20			dictionary,
21		}
22	}
23
24	pub fn encoded(dictionary: impl Into<DictionaryId>) -> EncodedKey {
25		Self::new(dictionary.into()).encode()
26	}
27
28	pub fn full_scan() -> EncodedKeyRange {
29		EncodedKeyRange::start_end(Some(Self::dictionary_start()), Some(Self::dictionary_end()))
30	}
31
32	fn dictionary_start() -> EncodedKey {
33		let mut serializer = KeySerializer::with_capacity(1);
34		serializer.extend_u8(Self::KIND as u8);
35		serializer.to_encoded_key()
36	}
37
38	fn dictionary_end() -> EncodedKey {
39		let mut serializer = KeySerializer::with_capacity(1);
40		serializer.extend_u8(Self::KIND as u8 - 1);
41		serializer.to_encoded_key()
42	}
43}
44
45impl EncodableKey for DictionaryKey {
46	const KIND: KeyKind = KeyKind::Dictionary;
47
48	fn encode(&self) -> EncodedKey {
49		let mut serializer = KeySerializer::with_capacity(9);
50		serializer.extend_u8(Self::KIND as u8).extend_u64(self.dictionary);
51		serializer.to_encoded_key()
52	}
53
54	fn decode(key: &EncodedKey) -> Option<Self> {
55		let mut de = KeyDeserializer::from_bytes(key.as_slice());
56
57		let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
58		if kind != Self::KIND {
59			return None;
60		}
61
62		let dictionary = de.read_u64().ok()?;
63
64		Some(Self {
65			dictionary: DictionaryId(dictionary),
66		})
67	}
68}
69
70#[derive(Debug, Clone, PartialEq)]
71pub struct DictionaryEntryKey {
72	pub dictionary: DictionaryId,
73	pub hash: [u8; 16],
74}
75
76impl DictionaryEntryKey {
77	pub fn new(dictionary: DictionaryId, hash: [u8; 16]) -> Self {
78		Self {
79			dictionary,
80			hash,
81		}
82	}
83
84	pub fn encoded(dictionary: impl Into<DictionaryId>, hash: [u8; 16]) -> EncodedKey {
85		Self::new(dictionary.into(), hash).encode()
86	}
87
88	pub fn full_scan(dictionary: DictionaryId) -> EncodedKeyRange {
89		EncodedKeyRange::start_end(Some(Self::entry_start(dictionary)), Some(Self::entry_end(dictionary)))
90	}
91
92	fn entry_start(dictionary: DictionaryId) -> EncodedKey {
93		let mut serializer = KeySerializer::with_capacity(9);
94		serializer.extend_u8(Self::KIND as u8).extend_u64(dictionary);
95		serializer.to_encoded_key()
96	}
97
98	fn entry_end(dictionary: DictionaryId) -> EncodedKey {
99		let mut serializer = KeySerializer::with_capacity(9);
100		serializer.extend_u8(Self::KIND as u8).extend_u64(*dictionary - 1);
101		serializer.to_encoded_key()
102	}
103}
104
105impl EncodableKey for DictionaryEntryKey {
106	const KIND: KeyKind = KeyKind::DictionaryEntry;
107
108	fn encode(&self) -> EncodedKey {
109		let mut serializer = KeySerializer::with_capacity(25);
110		serializer.extend_u8(Self::KIND as u8).extend_u64(self.dictionary).extend_bytes(self.hash);
111		serializer.to_encoded_key()
112	}
113
114	fn decode(key: &EncodedKey) -> Option<Self> {
115		let mut de = KeyDeserializer::from_bytes(key.as_slice());
116
117		let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
118		if kind != Self::KIND {
119			return None;
120		}
121
122		let dictionary = de.read_u64().ok()?;
123		let hash_bytes = de.read_raw(16).ok()?;
124		let mut hash = [0u8; 16];
125		hash.copy_from_slice(hash_bytes);
126
127		Some(Self {
128			dictionary: DictionaryId(dictionary),
129			hash,
130		})
131	}
132}
133
134#[derive(Debug, Clone, PartialEq)]
135pub struct DictionaryEntryIndexKey {
136	pub dictionary: DictionaryId,
137	pub id: u64,
138}
139
140impl DictionaryEntryIndexKey {
141	pub fn new(dictionary: DictionaryId, id: u64) -> Self {
142		Self {
143			dictionary,
144			id,
145		}
146	}
147
148	pub fn encoded(dictionary: impl Into<DictionaryId>, id: u64) -> EncodedKey {
149		Self::new(dictionary.into(), id).encode()
150	}
151
152	pub fn full_scan(dictionary: DictionaryId) -> EncodedKeyRange {
153		EncodedKeyRange::start_end(Some(Self::index_start(dictionary)), Some(Self::index_end(dictionary)))
154	}
155
156	fn index_start(dictionary: DictionaryId) -> EncodedKey {
157		let mut serializer = KeySerializer::with_capacity(9);
158		serializer.extend_u8(Self::KIND as u8).extend_u64(dictionary);
159		serializer.to_encoded_key()
160	}
161
162	fn index_end(dictionary: DictionaryId) -> EncodedKey {
163		let mut serializer = KeySerializer::with_capacity(9);
164		serializer.extend_u8(Self::KIND as u8).extend_u64(*dictionary - 1);
165		serializer.to_encoded_key()
166	}
167}
168
169impl EncodableKey for DictionaryEntryIndexKey {
170	const KIND: KeyKind = KeyKind::DictionaryEntryIndex;
171
172	fn encode(&self) -> EncodedKey {
173		let mut serializer = KeySerializer::with_capacity(17);
174		serializer.extend_u8(Self::KIND as u8).extend_u64(self.dictionary).extend_u64(self.id);
175		serializer.to_encoded_key()
176	}
177
178	fn decode(key: &EncodedKey) -> Option<Self> {
179		let mut de = KeyDeserializer::from_bytes(key.as_slice());
180
181		let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
182		if kind != Self::KIND {
183			return None;
184		}
185
186		let dictionary = de.read_u64().ok()?;
187		let id = de.read_u64().ok()?;
188
189		Some(Self {
190			dictionary: DictionaryId(dictionary),
191			id,
192		})
193	}
194}
195
196#[derive(Debug, Clone, PartialEq)]
197pub struct DictionarySequenceKey {
198	pub dictionary: DictionaryId,
199}
200
201impl DictionarySequenceKey {
202	pub fn new(dictionary: DictionaryId) -> Self {
203		Self {
204			dictionary,
205		}
206	}
207
208	pub fn encoded(dictionary: impl Into<DictionaryId>) -> EncodedKey {
209		Self::new(dictionary.into()).encode()
210	}
211}
212
213impl EncodableKey for DictionarySequenceKey {
214	const KIND: KeyKind = KeyKind::DictionarySequence;
215
216	fn encode(&self) -> EncodedKey {
217		let mut serializer = KeySerializer::with_capacity(9);
218		serializer.extend_u8(Self::KIND as u8).extend_u64(self.dictionary);
219		serializer.to_encoded_key()
220	}
221
222	fn decode(key: &EncodedKey) -> Option<Self> {
223		let mut de = KeyDeserializer::from_bytes(key.as_slice());
224
225		let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
226		if kind != Self::KIND {
227			return None;
228		}
229
230		let dictionary = de.read_u64().ok()?;
231
232		Some(Self {
233			dictionary: DictionaryId(dictionary),
234		})
235	}
236}
237
238#[derive(Debug, Clone, PartialEq)]
239pub struct DictionaryEntryIndexKeyRange {
240	pub dictionary: DictionaryId,
241	pub start_id: Option<u64>,
242	pub end_id: Option<u64>,
243}
244
245impl DictionaryEntryIndexKeyRange {
246	pub fn new(dictionary: DictionaryId, start_id: Option<u64>, end_id: Option<u64>) -> Self {
247		Self {
248			dictionary,
249			start_id,
250			end_id,
251		}
252	}
253
254	pub fn full(dictionary: DictionaryId) -> Self {
255		Self {
256			dictionary,
257			start_id: None,
258			end_id: None,
259		}
260	}
261}
262
263impl EncodableKeyRange for DictionaryEntryIndexKeyRange {
264	const KIND: KeyKind = KeyKind::DictionaryEntryIndex;
265
266	fn start(&self) -> Option<EncodedKey> {
267		let mut serializer = KeySerializer::with_capacity(17);
268		serializer.extend_u8(Self::KIND as u8).extend_u64(self.dictionary);
269		if let Some(id) = self.start_id {
270			serializer.extend_u64(id);
271		}
272		Some(serializer.to_encoded_key())
273	}
274
275	fn end(&self) -> Option<EncodedKey> {
276		if let Some(id) = self.end_id {
277			let mut serializer = KeySerializer::with_capacity(17);
278			serializer.extend_u8(Self::KIND as u8).extend_u64(self.dictionary).extend_u64(id - 1);
279			Some(serializer.to_encoded_key())
280		} else {
281			let mut serializer = KeySerializer::with_capacity(9);
282			serializer.extend_u8(Self::KIND as u8).extend_u64(*self.dictionary - 1);
283			Some(serializer.to_encoded_key())
284		}
285	}
286
287	fn decode(_range: &EncodedKeyRange) -> (Option<Self>, Option<Self>) {
288		(None, None)
289	}
290}
291
292#[cfg(test)]
293pub mod tests {
294	use std::ops::Bound;
295
296	use super::*;
297
298	#[test]
299	fn test_dictionary_key_encode_decode() {
300		let key = DictionaryKey {
301			dictionary: DictionaryId(0x1234),
302		};
303		let encoded = key.encode();
304		let decoded = DictionaryKey::decode(&encoded).unwrap();
305		assert_eq!(decoded.dictionary, key.dictionary);
306	}
307
308	#[test]
309	fn test_dictionary_entry_key_encode_decode() {
310		let key = DictionaryEntryKey {
311			dictionary: DictionaryId(42),
312			hash: [
313				0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
314				0x0f, 0x10,
315			],
316		};
317		let encoded = key.encode();
318		let decoded = DictionaryEntryKey::decode(&encoded).unwrap();
319		assert_eq!(decoded.dictionary, key.dictionary);
320		assert_eq!(decoded.hash, key.hash);
321	}
322
323	#[test]
324	fn test_dictionary_entry_index_key_encode_decode() {
325		let key = DictionaryEntryIndexKey {
326			dictionary: DictionaryId(99),
327			id: 12345,
328		};
329		let encoded = key.encode();
330		let decoded = DictionaryEntryIndexKey::decode(&encoded).unwrap();
331		assert_eq!(decoded.dictionary, key.dictionary);
332		assert_eq!(decoded.id, key.id);
333	}
334
335	#[test]
336	fn test_dictionary_sequence_key_encode_decode() {
337		let key = DictionarySequenceKey {
338			dictionary: DictionaryId(7),
339		};
340		let encoded = key.encode();
341		let decoded = DictionarySequenceKey::decode(&encoded).unwrap();
342		assert_eq!(decoded.dictionary, key.dictionary);
343	}
344
345	#[test]
346	fn test_dictionary_key_full_scan() {
347		let range = DictionaryKey::full_scan();
348		assert!(matches!(range.start, Bound::Included(_) | Bound::Excluded(_)));
349		assert!(matches!(range.end, Bound::Included(_) | Bound::Excluded(_)));
350	}
351
352	#[test]
353	fn test_dictionary_entry_key_full_scan() {
354		let range = DictionaryEntryKey::full_scan(DictionaryId(42));
355		assert!(matches!(range.start, Bound::Included(_) | Bound::Excluded(_)));
356		assert!(matches!(range.end, Bound::Included(_) | Bound::Excluded(_)));
357	}
358
359	#[test]
360	fn test_dictionary_entry_index_key_full_scan() {
361		let range = DictionaryEntryIndexKey::full_scan(DictionaryId(42));
362		assert!(matches!(range.start, Bound::Included(_) | Bound::Excluded(_)));
363		assert!(matches!(range.end, Bound::Included(_) | Bound::Excluded(_)));
364	}
365
366	#[test]
367	fn test_dictionary_entry_index_key_range() {
368		let range = DictionaryEntryIndexKeyRange::full(DictionaryId(42));
369		let start = range.start();
370		let end = range.end();
371		assert!(start.is_some());
372		assert!(end.is_some());
373	}
374}