1use std::{borrow::Cow, collections::Bound};
5
6use reifydb_codec::key::{
7 ByteSink, decode_u64_from,
8 deserializer::KeyDeserializer,
9 encode_u64,
10 encoded::{EncodedKey, EncodedKeyBuilder, EncodedKeyRange},
11 serializer::KeySerializer,
12};
13use reifydb_macro::KeyCodec;
14use reifydb_value::{
15 Result,
16 value::{dictionary::DictionaryId, sumtype::SumTypeId},
17};
18use smallvec::{SmallVec, smallvec};
19
20use super::{KeyRangeCodec, KeyTag};
21use crate::{
22 interface::catalog::{
23 id::{
24 BindingId, ColumnId, ColumnPropertyId, HandlerId, IndexId, NamespaceId, PrimaryKeyId,
25 RelationshipId, SinkId, SourceId, TableId, ViewId,
26 },
27 object::ObjectId,
28 },
29 key::{
30 any::{Field, KeyFields, RawEncoding, Width, index_tag},
31 bound::{TaggedKeyBound, TaggedKeyBoundRange, object_fields},
32 },
33 return_internal_error,
34 value::index::{encoded::EncodedIndexKey, range::EncodedIndexKeyRange},
35};
36
37pub fn serialize_object_id<B: ByteSink>(object: &ObjectId, out: &mut B) {
38 out.push(object.type_tag());
39 out.extend_from_slice(&encode_u64(object.as_u64()));
40}
41
42pub fn deserialize_object_id(input: &mut &[u8]) -> Result<ObjectId> {
43 if input.is_empty() {
44 return_internal_error!("Invalid ObjectId encoding: empty input");
45 }
46
47 let type_byte = input[0];
48 *input = &input[1..];
49 let id = decode_u64_from(input)?;
50
51 match ObjectId::from_type_tag(type_byte, id) {
52 Some(object) => Ok(object),
53 None => return_internal_error!("Invalid ObjectId type byte: 0x{:02x}.", type_byte),
54 }
55}
56
57pub fn serialize_index_id<B: ByteSink>(index: &IndexId, out: &mut B) {
58 match index {
59 IndexId::Primary(PrimaryKeyId(id)) => {
60 out.push(0x01);
61 out.extend_from_slice(&encode_u64(*id));
62 }
63 }
64}
65
66pub fn deserialize_index_id(input: &mut &[u8]) -> Result<IndexId> {
67 if input.is_empty() {
68 return_internal_error!("Invalid IndexId encoding: empty input");
69 }
70
71 let type_byte = input[0];
72 *input = &input[1..];
73 let id = decode_u64_from(input)?;
74
75 match type_byte {
76 0x01 => Ok(IndexId::Primary(PrimaryKeyId(id))),
77
78 _ => return_internal_error!("Invalid IndexId type byte: 0x{:02x}.", type_byte),
79 }
80}
81
82pub trait KeySerializerCatalogExt {
83 fn extend_object_id(&mut self, object: impl Into<ObjectId>) -> &mut Self;
84 fn extend_index_id(&mut self, index: impl Into<IndexId>) -> &mut Self;
85}
86
87impl KeySerializerCatalogExt for KeySerializer {
88 fn extend_object_id(&mut self, object: impl Into<ObjectId>) -> &mut Self {
89 let mut buf = Vec::new();
90 serialize_object_id(&object.into(), &mut buf);
91 self.extend_raw(&buf);
92 self
93 }
94
95 fn extend_index_id(&mut self, index: impl Into<IndexId>) -> &mut Self {
96 let mut buf = Vec::new();
97 serialize_index_id(&index.into(), &mut buf);
98 self.extend_raw(&buf);
99 self
100 }
101}
102
103pub trait KeyDeserializerCatalogExt {
104 fn read_object_id(&mut self) -> Result<ObjectId>;
105 fn read_index_id(&mut self) -> Result<IndexId>;
106}
107
108impl KeyDeserializerCatalogExt for KeyDeserializer<'_> {
109 fn read_object_id(&mut self) -> Result<ObjectId> {
110 let mut slice = self.remaining_bytes();
111 let before = slice.len();
112 let object_id = deserialize_object_id(&mut slice)?;
113 self.read_raw(before - slice.len())?;
114 Ok(object_id)
115 }
116
117 fn read_index_id(&mut self) -> Result<IndexId> {
118 let mut slice = self.remaining_bytes();
119 let before = slice.len();
120 let index_id = deserialize_index_id(&mut slice)?;
121 self.read_raw(before - slice.len())?;
122 Ok(index_id)
123 }
124}
125
126pub trait EncodedKeyBuilderCatalogExt {
127 fn object_id(self, object: impl Into<ObjectId>) -> Self;
128 fn index_id(self, index: impl Into<IndexId>) -> Self;
129}
130
131impl EncodedKeyBuilderCatalogExt for EncodedKeyBuilder {
132 fn object_id(self, object: impl Into<ObjectId>) -> Self {
133 let mut buf = Vec::new();
134 serialize_object_id(&object.into(), &mut buf);
135 self.raw(&buf)
136 }
137
138 fn index_id(self, index: impl Into<IndexId>) -> Self {
139 let mut buf = Vec::new();
140 serialize_index_id(&index.into(), &mut buf);
141 self.raw(&buf)
142 }
143}
144
145#[cfg(test)]
146pub mod index_entry_key_tests {
147 use reifydb_codec::key::encode_u64;
148
149 use super::{
150 serialize_index_id as serialize_index_id_inner, serialize_object_id as serialize_object_id_inner, *,
151 };
152 use crate::interface::catalog::vtable::VTableId;
153
154 fn serialize_object_id(object: &ObjectId) -> Vec<u8> {
155 let mut out = Vec::new();
156 serialize_object_id_inner(object, &mut out);
157 out
158 }
159
160 fn serialize_index_id(index: &IndexId) -> Vec<u8> {
161 let mut out = Vec::new();
162 serialize_index_id_inner(index, &mut out);
163 out
164 }
165
166 #[test]
167 fn test_object_id_ordering() {
168 let object1 = ObjectId::table(1);
169 let object2 = ObjectId::table(2);
170 let object100 = ObjectId::table(100);
171 let object200 = ObjectId::table(200);
172
173 let bytes1 = serialize_object_id(&object1);
174 let bytes2 = serialize_object_id(&object2);
175 let bytes100 = serialize_object_id(&object100);
176 let bytes200 = serialize_object_id(&object200);
177
178 assert!(bytes2 < bytes1, "object(2) should be < object(1) in bytes");
179 assert!(bytes200 < bytes100, "object(200) should be < object(100) in bytes");
180 assert!(bytes100 < bytes2, "object(100) should be < object(2) in bytes");
181 }
182
183 #[test]
184 fn test_range_boundaries() {
185 let object10 = ObjectId::table(10);
186 let object9 = object10.prev();
187
188 let bytes10 = serialize_object_id(&object10);
189 let bytes9 = serialize_object_id(&object9);
190
191 assert!(bytes9 > bytes10, "object(9) should be > object(10) in bytes");
192
193 let view10 = ObjectId::view(10);
194 let view9 = view10.prev();
195
196 let vbytes10 = serialize_object_id(&view10);
197 let vbytes9 = serialize_object_id(&view9);
198
199 assert!(vbytes9 > vbytes10, "view(9) should be > view(10) in bytes");
200
201 let virtual10 = ObjectId::vtable(10);
202 let virtual9 = virtual10.prev();
203
204 let tvbytes10 = serialize_object_id(&virtual10);
205 let tvbytes9 = serialize_object_id(&virtual9);
206
207 assert!(tvbytes9 > tvbytes10, "vtable(9) should be > vtable(10) in bytes");
208
209 assert_ne!(bytes10, vbytes10, "table(10) should != view(10)");
210 assert_ne!(bytes10, tvbytes10, "table(10) should != vtable(10)");
211 assert_ne!(vbytes10, tvbytes10, "view(10) should != vtable(10)");
212 assert_eq!(bytes10[0], 0x01, "table type byte should be 0x01");
213 assert_eq!(vbytes10[0], 0x02, "view type byte should be 0x02");
214 assert_eq!(tvbytes10[0], 0x03, "vtable type byte should be 0x03");
215
216 let row_key_10_100 = vec![0xFC];
217 let mut key1 = row_key_10_100.clone();
218 key1.extend(&bytes10);
219 key1.extend(&encode_u64(100u64));
220
221 let mut key2 = row_key_10_100.clone();
222 key2.extend(&bytes10);
223 key2.extend(&encode_u64(200u64));
224
225 let mut end_key = vec![0xFC];
226 end_key.extend(&bytes9);
227
228 assert!(key1 >= bytes10, "key1 should be >= start(object10)");
229 assert!(key1 < end_key, "key1 should be < end(object9)");
230 assert!(key2 >= bytes10, "key2 should be >= start(object10)");
231 assert!(key2 < end_key, "key2 should be < end(object9)");
232 }
233
234 #[test]
235 fn test_vtable_serialization() {
236 let virtual_object = ObjectId::vtable(42);
237 let bytes = serialize_object_id(&virtual_object);
238 let mut slice = &bytes[..];
239 let deserialized = deserialize_object_id(&mut slice).unwrap();
240 assert_eq!(virtual_object, deserialized);
241 assert!(slice.is_empty());
242
243 assert_eq!(bytes[0], 0x03);
244
245 let virtual_id = VTableId(123);
246 let object_from_id = ObjectId::from(virtual_id);
247 let bytes_from_id = serialize_object_id(&object_from_id);
248 let mut slice = &bytes_from_id[..];
249 let deserialized_id = deserialize_object_id(&mut slice).unwrap();
250 assert_eq!(object_from_id, deserialized_id);
251 assert!(slice.is_empty());
252
253 let virtual1 = ObjectId::vtable(1);
254 let virtual2 = ObjectId::vtable(2);
255 let bytes1 = serialize_object_id(&virtual1);
256 let bytes2 = serialize_object_id(&virtual2);
257
258 assert!(bytes2 < bytes1, "vtable(2) should be < vtable(1) in bytes");
259 }
260
261 #[test]
262 fn test_index_id_serialization() {
263 let index = IndexId::primary(42);
264 let bytes = serialize_index_id(&index);
265 let mut slice = &bytes[..];
266 let deserialized = deserialize_index_id(&mut slice).unwrap();
267 assert_eq!(index.as_u64(), deserialized.as_u64());
268 assert!(slice.is_empty());
269
270 assert_eq!(bytes[0], 0x01);
271
272 let primary_id = PrimaryKeyId(123);
273 let index_from_id = IndexId::Primary(primary_id);
274 let bytes_from_id = serialize_index_id(&index_from_id);
275 let mut slice = &bytes_from_id[..];
276 let deserialized_id = deserialize_index_id(&mut slice).unwrap();
277 assert_eq!(index_from_id.as_u64(), deserialized_id.as_u64());
278 assert!(slice.is_empty());
279 }
280
281 #[test]
282 fn test_index_id_ordering() {
283 let index1 = IndexId::primary(1);
284 let index2 = IndexId::primary(2);
285 let index100 = IndexId::primary(100);
286 let index200 = IndexId::primary(200);
287
288 let bytes1 = serialize_index_id(&index1);
289 let bytes2 = serialize_index_id(&index2);
290 let bytes100 = serialize_index_id(&index100);
291 let bytes200 = serialize_index_id(&index200);
292
293 assert!(bytes2 < bytes1, "index(2) should be < index(1) in bytes");
294 assert!(bytes200 < bytes100, "index(200) should be < index(100) in bytes");
295 assert!(bytes100 < bytes2, "index(100) should be < index(2) in bytes");
296 }
297
298 #[test]
299 fn test_index_id_range_boundaries() {
300 let index10 = IndexId::primary(10);
301 let index11 = IndexId::primary(11);
302
303 let bytes10 = serialize_index_id(&index10);
304 let bytes11 = serialize_index_id(&index11);
305
306 assert!(bytes11 < bytes10, "index(11) should be < index(10) in bytes");
307
308 assert_eq!(bytes10.len(), 9, "IndexId(10) should be 9 bytes");
309 assert_eq!(bytes10[0], 0x01, "Primary variant should have type byte 0x01");
310
311 let next_index = IndexId::primary(11);
312 let next_bytes = serialize_index_id(&next_index);
313
314 assert!(next_bytes < bytes10, "index(11) should be < index(10) for proper range boundaries");
315 }
316
317 #[test]
318 fn test_index_entry_key_encoding_with_discriminator() {
319 let object = ObjectId::table(42);
320 let index = IndexId::primary(7);
321
322 let object_bytes = serialize_object_id(&object);
323 let index_bytes = serialize_index_id(&index);
324
325 assert_eq!(object_bytes.len(), 9, "ObjectId(42) should be 9 bytes");
326 assert_eq!(index_bytes.len(), 9, "IndexId(7) should be 9 bytes");
327
328 assert_eq!(object_bytes[0], 0x01, "Table object should have type byte 0x01");
329 assert_eq!(index_bytes[0], 0x01, "Primary index should have type byte 0x01");
330
331 let total_prefix_size = 1 + 1 + object_bytes.len() + index_bytes.len();
332 assert_eq!(total_prefix_size, 20, "Total IndexEntryKey prefix should be 20 bytes");
333 }
334}
335
336#[cfg(test)]
337mod moved_catalog_key_tests {
338 use reifydb_codec::key::{deserializer::KeyDeserializer, serializer::KeySerializer};
339
340 use super::{KeyDeserializerCatalogExt, KeySerializerCatalogExt};
341 use crate::interface::catalog::{
342 id::{IndexId, PrimaryKeyId, TableId},
343 object::ObjectId,
344 };
345
346 #[test]
347 fn test_index_id() {
348 let mut serializer = KeySerializer::new();
349 serializer.extend_index_id(IndexId::Primary(PrimaryKeyId(123456789)));
350 let result = serializer.finish();
351
352 assert_eq!(result.len(), 9);
354 assert_eq!(result[0], 0x01); let mut serializer2 = KeySerializer::new();
359 serializer2.extend_index_id(IndexId::Primary(PrimaryKeyId(1)));
360 let result2 = serializer2.finish();
361
362 assert!(result2[1..] > result[1..]);
363 }
364
365 #[test]
366 fn test_object_id() {
367 let mut serializer = KeySerializer::new();
368 serializer.extend_object_id(ObjectId::Table(TableId(987654321)));
369 let result = serializer.finish();
370
371 assert_eq!(result.len(), 9);
373 assert_eq!(result[0], 0x01); let mut serializer2 = KeySerializer::new();
377 serializer2.extend_object_id(ObjectId::Table(TableId(987654322)));
378 let result2 = serializer2.finish();
379
380 assert!(result2[1..] < result[1..]);
381 }
382
383 #[test]
384 fn test_read_object_id() {
385 let mut ser = KeySerializer::new();
386 let object = ObjectId::table(42);
387 ser.extend_object_id(object);
388 let bytes = ser.finish();
389
390 let mut de = KeyDeserializer::from_bytes(&bytes);
391 assert_eq!(de.read_object_id().unwrap(), object);
392 assert!(de.is_empty());
393 }
394
395 #[test]
396 fn test_read_index_id() {
397 let mut ser = KeySerializer::new();
398 let index = IndexId::primary(999);
399 ser.extend_index_id(index);
400 let bytes = ser.finish();
401
402 let mut de = KeyDeserializer::from_bytes(&bytes);
403 assert_eq!(de.read_index_id().unwrap(), index);
404 assert!(de.is_empty());
405 }
406}
407
408#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
409#[key(tag = Dictionary)]
410pub struct DictionaryKey {
411 pub dictionary: DictionaryId,
412}
413
414impl DictionaryKey {
415 pub fn new(dictionary: DictionaryId) -> Self {
416 Self {
417 dictionary,
418 }
419 }
420
421 pub fn encoded(dictionary: impl Into<DictionaryId>) -> EncodedKey {
422 Self::new(dictionary.into()).encode()
423 }
424
425 pub fn full_scan() -> TaggedKeyBoundRange {
426 TaggedKeyBoundRange::kind(Self::TAG)
427 }
428}
429
430#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
431#[key(tag = DictionaryEntry)]
432pub struct DictionaryEntryKey {
433 pub dictionary: DictionaryId,
434 pub hash: [u8; 16],
435}
436
437impl DictionaryEntryKey {
438 pub fn new(dictionary: DictionaryId, hash: [u8; 16]) -> Self {
439 Self {
440 dictionary,
441 hash,
442 }
443 }
444
445 pub fn encoded(dictionary: impl Into<DictionaryId>, hash: [u8; 16]) -> EncodedKey {
446 Self::new(dictionary.into(), hash).encode()
447 }
448
449 pub fn full_scan(dictionary: DictionaryId) -> TaggedKeyBoundRange {
450 TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, dictionary.0 as u128)])
451 }
452}
453
454#[derive(Debug, Clone, PartialEq, Hash)]
455pub struct DictionaryEntryIndexKey {
456 pub dictionary: DictionaryId,
457 pub id: u128,
458}
459
460impl DictionaryEntryIndexKey {
461 pub fn new(dictionary: DictionaryId, id: u128) -> Self {
462 Self {
463 dictionary,
464 id,
465 }
466 }
467
468 pub fn encoded(dictionary: impl Into<DictionaryId>, id: u128) -> EncodedKey {
469 Self::new(dictionary.into(), id).encode()
470 }
471
472 pub fn full_scan(dictionary: DictionaryId) -> TaggedKeyBoundRange {
473 TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, dictionary.0 as u128)])
474 }
475}
476
477impl DictionaryEntryIndexKey {
478 pub const TAG: KeyTag = KeyTag::DictionaryEntryIndex;
479
480 pub fn encode(&self) -> EncodedKey {
481 let mut serializer = KeySerializer::with_capacity(25);
482 serializer.extend_u8(Self::TAG as u8).extend_u64(self.dictionary).extend_u128_varint(self.id);
483 serializer.to_encoded_key()
484 }
485
486 pub fn decode(key: &EncodedKey) -> Option<Self> {
487 let mut de = KeyDeserializer::from_bytes(key.as_slice());
488
489 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
490 if kind != Self::TAG {
491 return None;
492 }
493
494 let dictionary = de.read_u64().ok()?;
495 let id = de.read_u128_varint().ok()?;
496
497 Some(Self {
498 dictionary: DictionaryId(dictionary),
499 id,
500 })
501 }
502}
503
504#[derive(Debug, Clone, PartialEq)]
505pub struct DictionaryEntryIndexKeyRange {
506 pub dictionary: DictionaryId,
507 pub start_id: Option<u128>,
508 pub end_id: Option<u128>,
509}
510
511impl DictionaryEntryIndexKeyRange {
512 pub fn new(dictionary: DictionaryId, start_id: Option<u128>, end_id: Option<u128>) -> Self {
513 Self {
514 dictionary,
515 start_id,
516 end_id,
517 }
518 }
519
520 pub fn full(dictionary: DictionaryId) -> Self {
521 Self {
522 dictionary,
523 start_id: None,
524 end_id: None,
525 }
526 }
527}
528
529impl KeyRangeCodec for DictionaryEntryIndexKeyRange {
530 const TAG: KeyTag = KeyTag::DictionaryEntryIndex;
531
532 fn start(&self) -> Option<EncodedKey> {
533 let mut serializer = KeySerializer::with_capacity(25);
534 serializer.extend_u8(Self::TAG as u8).extend_u64(self.dictionary);
535 if let Some(id) = self.start_id {
536 serializer.extend_u128_varint(id);
537 }
538 Some(serializer.to_encoded_key())
539 }
540
541 fn end(&self) -> Option<EncodedKey> {
542 if let Some(id) = self.end_id {
543 let mut serializer = KeySerializer::with_capacity(25);
544 serializer.extend_u8(Self::TAG as u8).extend_u64(self.dictionary).extend_u128_varint(id - 1);
545 Some(serializer.to_encoded_key())
546 } else {
547 let mut serializer = KeySerializer::with_capacity(9);
548 serializer.extend_u8(Self::TAG as u8).extend_u64(*self.dictionary - 1);
549 Some(serializer.to_encoded_key())
550 }
551 }
552
553 fn decode(_range: &EncodedKeyRange) -> (Option<Self>, Option<Self>) {
554 (None, None)
555 }
556}
557
558#[cfg(test)]
559pub mod dictionary_key_tests {
560 use std::ops::Bound;
561
562 use super::*;
563
564 #[test]
565 fn test_dictionary_key_encode_decode() {
566 let key = DictionaryKey {
567 dictionary: DictionaryId(0x1234),
568 };
569 let encoded = key.encode();
570 let decoded = DictionaryKey::decode(&encoded).unwrap();
571 assert_eq!(decoded.dictionary, key.dictionary);
572 }
573
574 #[test]
575 fn test_dictionary_entry_key_encode_decode() {
576 let key = DictionaryEntryKey {
577 dictionary: DictionaryId(42),
578 hash: [
579 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
580 0x0f, 0x10,
581 ],
582 };
583 let encoded = key.encode();
584 let decoded = DictionaryEntryKey::decode(&encoded).unwrap();
585 assert_eq!(decoded.dictionary, key.dictionary);
586 assert_eq!(decoded.hash, key.hash);
587 }
588
589 #[test]
590 fn a_dictionary_entry_hash_made_of_0xff_bytes_still_round_trips() {
591 let key = DictionaryEntryKey {
594 dictionary: DictionaryId(42),
595 hash: [0xff; 16],
596 };
597 let encoded = key.encode();
598 assert_eq!(encoded.len(), 1 + 8 + 16);
599 assert_eq!(DictionaryEntryKey::decode(&encoded).unwrap(), key);
600 }
601
602 #[test]
603 fn test_dictionary_entry_index_key_encode_decode() {
604 let key = DictionaryEntryIndexKey {
605 dictionary: DictionaryId(99),
606 id: 12345,
607 };
608 let encoded = key.encode();
609 let decoded = DictionaryEntryIndexKey::decode(&encoded).unwrap();
610 assert_eq!(decoded.dictionary, key.dictionary);
611 assert_eq!(decoded.id, key.id);
612 }
613
614 #[test]
615 fn test_dictionary_key_full_scan() {
616 let range = DictionaryKey::full_scan();
617 assert!(matches!(range.start, Bound::Included(_) | Bound::Excluded(_)));
618 assert!(matches!(range.end, Bound::Included(_) | Bound::Excluded(_)));
619 }
620
621 #[test]
622 fn test_dictionary_entry_key_full_scan() {
623 let range = DictionaryEntryKey::full_scan(DictionaryId(42)).encode();
624 assert!(matches!(range.start, Bound::Included(_) | Bound::Excluded(_)));
625 assert!(matches!(range.end, Bound::Included(_) | Bound::Excluded(_)));
626 }
627
628 #[test]
629 fn test_dictionary_entry_index_key_full_scan() {
630 let range = DictionaryEntryIndexKey::full_scan(DictionaryId(42)).encode();
631 assert!(matches!(range.start, Bound::Included(_) | Bound::Excluded(_)));
632 assert!(matches!(range.end, Bound::Included(_) | Bound::Excluded(_)));
633 }
634
635 #[test]
636 fn test_dictionary_entry_index_key_range() {
637 let range = DictionaryEntryIndexKeyRange::full(DictionaryId(42));
638 let start = range.start();
639 let end = range.end();
640 assert!(start.is_some());
641 assert!(end.is_some());
642 }
643}
644
645#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
646#[key(tag = Index)]
647pub struct IndexKey {
648 pub object: ObjectId,
649 pub index: IndexId,
650}
651
652#[derive(Debug, Clone, PartialEq)]
653pub struct ObjectIndexKeyRange {
654 pub object: ObjectId,
655}
656
657impl ObjectIndexKeyRange {
658 fn decode_key(key: &EncodedKey) -> Option<Self> {
659 let mut de = KeyDeserializer::from_bytes(key.as_slice());
660
661 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
662 if kind != Self::TAG {
663 return None;
664 }
665
666 let object = de.read_object_id().ok()?;
667
668 Some(ObjectIndexKeyRange {
669 object,
670 })
671 }
672}
673
674impl KeyRangeCodec for ObjectIndexKeyRange {
675 const TAG: KeyTag = KeyTag::Index;
676
677 fn start(&self) -> Option<EncodedKey> {
678 let mut serializer = KeySerializer::with_capacity(10);
679 serializer.extend_u8(Self::TAG as u8).extend_object_id(self.object);
680 Some(serializer.to_encoded_key())
681 }
682
683 fn end(&self) -> Option<EncodedKey> {
684 let mut serializer = KeySerializer::with_capacity(10);
685 serializer.extend_u8(Self::TAG as u8).extend_object_id(self.object.prev());
686 Some(serializer.to_encoded_key())
687 }
688
689 fn decode(range: &EncodedKeyRange) -> (Option<Self>, Option<Self>)
690 where
691 Self: Sized,
692 {
693 let start_key = match &range.start {
694 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
695 Bound::Unbounded => None,
696 };
697
698 let end_key = match &range.end {
699 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
700 Bound::Unbounded => None,
701 };
702
703 (start_key, end_key)
704 }
705}
706
707impl IndexKey {
708 pub fn new(object: impl Into<ObjectId>, index: impl Into<IndexId>) -> Self {
709 Self {
710 object: object.into(),
711 index: index.into(),
712 }
713 }
714
715 pub fn encoded(object: impl Into<ObjectId>, index: impl Into<IndexId>) -> EncodedKey {
716 Self {
717 object: object.into(),
718 index: index.into(),
719 }
720 .encode()
721 }
722
723 pub fn full_scan(object: impl Into<ObjectId>) -> TaggedKeyBoundRange {
724 TaggedKeyBoundRange::prefix(Self::TAG, object_fields(object.into()))
725 }
726}
727
728#[cfg(test)]
729pub mod index_key_tests {
730 use super::IndexKey;
731 use crate::interface::catalog::{id::IndexId, object::ObjectId};
732
733 #[test]
734 fn test_encode_decode() {
735 let key = IndexKey {
736 object: ObjectId::table(0xABCD),
737 index: IndexId::primary(0x123456789ABCDEF0u64),
738 };
739 let encoded = key.encode();
740
741 let expected: Vec<u8> = vec![
742 0xF3, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43,
743 0x21, 0x0F,
744 ];
745
746 assert_eq!(encoded.as_slice(), expected);
747
748 let key = IndexKey::decode(&encoded).unwrap();
749 assert_eq!(key.object, 0xABCD);
750 assert_eq!(key.index, 0x123456789ABCDEF0);
751 }
752
753 #[test]
754 fn test_order_preserving() {
755 let key1 = IndexKey {
756 object: ObjectId::table(1),
757 index: IndexId::primary(100),
758 };
759 let key2 = IndexKey {
760 object: ObjectId::table(1),
761 index: IndexId::primary(200),
762 };
763 let key3 = IndexKey {
764 object: ObjectId::table(2),
765 index: IndexId::primary(50),
766 };
767
768 let encoded1 = key1.encode();
769 let encoded2 = key2.encode();
770 let encoded3 = key3.encode();
771
772 assert!(encoded3 < encoded2, "ordering not preserved");
773 assert!(encoded2 < encoded1, "ordering not preserved");
774 }
775}
776
777#[derive(Debug, Clone, PartialEq, Hash)]
778pub struct IndexEntryKey {
779 pub object: ObjectId,
780 pub index: IndexId,
781 pub key: EncodedIndexKey,
782}
783
784impl IndexEntryKey {
785 pub fn new(object: impl Into<ObjectId>, index: IndexId, key: EncodedIndexKey) -> Self {
786 Self {
787 object: object.into(),
788 index,
789 key,
790 }
791 }
792
793 pub fn encoded(object: impl Into<ObjectId>, index: IndexId, key: EncodedIndexKey) -> EncodedKey {
794 Self::new(object, index, key).encode()
795 }
796}
797
798#[derive(Debug, Clone, PartialEq)]
799pub struct IndexEntryKeyRange {
800 pub object: ObjectId,
801 pub index: IndexId,
802}
803
804impl IndexEntryKeyRange {
805 fn decode_key(key: &EncodedKey) -> Option<Self> {
806 let mut de = KeyDeserializer::from_bytes(key.as_slice());
807
808 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
809 if kind != Self::TAG {
810 return None;
811 }
812
813 let object = de.read_object_id().ok()?;
814 let index = de.read_index_id().ok()?;
815
816 Some(IndexEntryKeyRange {
817 object,
818 index,
819 })
820 }
821}
822
823impl KeyRangeCodec for IndexEntryKeyRange {
824 const TAG: KeyTag = KeyTag::IndexEntry;
825
826 fn start(&self) -> Option<EncodedKey> {
827 let mut serializer = KeySerializer::with_capacity(19);
828 serializer.extend_u8(Self::TAG as u8).extend_object_id(self.object).extend_index_id(self.index);
829 Some(serializer.to_encoded_key())
830 }
831
832 fn end(&self) -> Option<EncodedKey> {
833 let mut serializer = KeySerializer::with_capacity(19);
834 serializer.extend_u8(Self::TAG as u8).extend_object_id(self.object).extend_index_id(self.index.prev());
835 Some(serializer.to_encoded_key())
836 }
837
838 fn decode(range: &EncodedKeyRange) -> (Option<Self>, Option<Self>)
839 where
840 Self: Sized,
841 {
842 let start_key = match &range.start {
843 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
844 Bound::Unbounded => None,
845 };
846
847 let end_key = match &range.end {
848 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
849 Bound::Unbounded => None,
850 };
851
852 (start_key, end_key)
853 }
854}
855
856impl IndexEntryKey {
857 pub const TAG: KeyTag = KeyTag::IndexEntry;
858
859 pub fn encode(&self) -> EncodedKey {
860 let mut serializer = KeySerializer::with_capacity(20 + self.key.len());
861 serializer
862 .extend_u8(Self::TAG as u8)
863 .extend_object_id(self.object)
864 .extend_index_id(self.index)
865 .extend_raw(self.key.as_slice());
866 serializer.to_encoded_key()
867 }
868
869 pub fn decode(key: &EncodedKey) -> Option<Self> {
870 let mut de = KeyDeserializer::from_bytes(key.as_slice());
871
872 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
873 if kind != Self::TAG {
874 return None;
875 }
876
877 let object = de.read_object_id().ok()?;
878 let index = de.read_index_id().ok()?;
879
880 let remaining = de.remaining();
881 let remaining_bytes = de.read_raw(remaining).ok()?;
882 Some(Self {
883 object,
884 index,
885 key: EncodedIndexKey::new(remaining_bytes),
886 })
887 }
888}
889
890impl IndexEntryKey {
891 pub fn index_range(object: impl Into<ObjectId>, index: IndexId) -> TaggedKeyBoundRange {
892 let object = object.into();
893 TaggedKeyBoundRange::prefix(
894 <IndexEntryKeyRange as KeyRangeCodec>::TAG,
895 object_fields(object)
896 .into_iter()
897 .chain([Field::UAsc(Width::U8, 1), Field::UDesc(Width::U64, index.as_u64() as u128)]),
898 )
899 }
900
901 pub fn object_range(object: impl Into<ObjectId>) -> TaggedKeyBoundRange {
902 TaggedKeyBoundRange::prefix(KeyTag::IndexEntry, object_fields(object.into()))
903 }
904
905 pub fn key_prefix_range(object: impl Into<ObjectId>, index: IndexId, key_prefix: &[u8]) -> TaggedKeyBoundRange {
906 let object = object.into();
907 TaggedKeyBoundRange::prefix(
908 KeyTag::IndexEntry,
909 object_fields(object).into_iter().chain([
910 Field::UAsc(Width::U8, 1),
911 Field::UDesc(Width::U64, index.as_u64() as u128),
912 Field::RawAsc(RawEncoding::Verbatim, Cow::Owned(key_prefix.to_vec())),
913 ]),
914 )
915 }
916
917 pub fn key_range(
918 object: impl Into<ObjectId>,
919 index: IndexId,
920 index_range: EncodedIndexKeyRange,
921 ) -> TaggedKeyBoundRange {
922 let object = object.into();
923 let head = || {
924 object_fields(object)
925 .into_iter()
926 .chain([Field::UAsc(Width::U8, 1), Field::UDesc(Width::U64, index.as_u64() as u128)])
927 };
928 let at = |key: &EncodedIndexKey| {
929 TaggedKeyBound::prefix(
930 KeyTag::IndexEntry,
931 head().chain([Field::RawAsc(
932 RawEncoding::Verbatim,
933 Cow::Owned(key.as_slice().to_vec()),
934 )]),
935 )
936 };
937
938 let start = match &index_range.start {
939 Bound::Included(key) => Bound::Included(at(key)),
940 Bound::Excluded(key) => Bound::Excluded(at(key)),
941 Bound::Unbounded => Bound::Included(TaggedKeyBound::prefix(KeyTag::IndexEntry, head())),
942 };
943
944 let end = match &index_range.end {
945 Bound::Included(key) => Bound::Included(at(key)),
946 Bound::Excluded(key) => Bound::Excluded(at(key)),
947 Bound::Unbounded => Bound::Excluded(TaggedKeyBound::prefix_end(KeyTag::IndexEntry, head())),
948 };
949
950 TaggedKeyBoundRange {
951 start,
952 end,
953 }
954 }
955}
956
957#[cfg(test)]
958pub mod index_entry_key_tests_2 {
959 use reifydb_value::value::value_type::ValueType;
960
961 use super::*;
962 use crate::{sort::SortDirection, value::index::shape::IndexShape};
963
964 #[test]
965 fn test_encode_decode() {
966 let layout = IndexShape::new(
967 &[ValueType::Uint8, ValueType::Uint8],
968 &[SortDirection::Asc, SortDirection::Asc],
969 )
970 .unwrap();
971
972 let mut index_key = layout.allocate_key();
973 layout.set_u64(&mut index_key, 0, 100u64);
974 layout.set_row_number(&mut index_key, 1, 1u64);
975
976 let entry = IndexEntryKey {
977 object: ObjectId::table(42),
978 index: IndexId::primary(7),
979 key: index_key.clone(),
980 };
981
982 let encoded = entry.encode();
983 let decoded = IndexEntryKey::decode(&encoded).unwrap();
984
985 assert_eq!(decoded.object, ObjectId::table(42));
986 assert_eq!(decoded.index, IndexId::primary(7));
987 assert_eq!(decoded.key.as_slice(), index_key.as_slice());
988 }
989
990 #[test]
991 fn test_ordering() {
992 let layout = IndexShape::new(&[ValueType::Uint8], &[SortDirection::Asc]).unwrap();
993
994 let mut key1 = layout.allocate_key();
995 layout.set_u64(&mut key1, 0, 100u64);
996
997 let mut key2 = layout.allocate_key();
998 layout.set_u64(&mut key2, 0, 200u64);
999
1000 let entry1 = IndexEntryKey {
1001 object: ObjectId::table(1),
1002 index: IndexId::primary(1),
1003 key: key1,
1004 };
1005
1006 let entry2 = IndexEntryKey {
1007 object: ObjectId::table(1),
1008 index: IndexId::primary(1),
1009 key: key2,
1010 };
1011
1012 let encoded1 = entry1.encode();
1013 let encoded2 = entry2.encode();
1014
1015 assert!(encoded1.as_slice() < encoded2.as_slice());
1016 }
1017
1018 #[test]
1019 fn test_index_range() {
1020 let range = IndexEntryKey::index_range(ObjectId::table(10), IndexId::primary(5)).encode();
1021
1022 let layout = IndexShape::new(&[ValueType::Uint8], &[SortDirection::Asc]).unwrap();
1023
1024 let mut key = layout.allocate_key();
1025 layout.set_u64(&mut key, 0, 50u64);
1026
1027 let entry = IndexEntryKey {
1028 object: ObjectId::table(10),
1029 index: IndexId::primary(5),
1030 key,
1031 };
1032
1033 let encoded = entry.encode();
1034
1035 if let (Bound::Included(start), Bound::Excluded(end)) = (&range.start, &range.end) {
1036 assert!(encoded.as_slice() >= start.as_slice());
1037 assert!(encoded.as_slice() < end.as_slice());
1038 } else {
1039 panic!("Expected Included/Excluded bounds");
1040 }
1041
1042 let entry2 = IndexEntryKey {
1043 object: ObjectId::table(10),
1044 index: IndexId::primary(6),
1045 key: layout.allocate_key(),
1046 };
1047
1048 let encoded2 = entry2.encode();
1049
1050 if let (Bound::Included(start), Bound::Excluded(end)) = (&range.start, &range.end) {
1051 assert!(encoded2.as_slice() < start.as_slice() || encoded2.as_slice() >= end.as_slice());
1052 }
1053 }
1054
1055 #[test]
1056 fn test_key_prefix_range() {
1057 let layout = IndexShape::new(
1058 &[ValueType::Uint8, ValueType::Uint8],
1059 &[SortDirection::Asc, SortDirection::Asc],
1060 )
1061 .unwrap();
1062
1063 let mut key = layout.allocate_key();
1064 layout.set_u64(&mut key, 0, 100u64);
1065 layout.set_row_number(&mut key, 1, 0u64);
1066
1067 let prefix = &key.as_slice()[..layout.fields[1].offset];
1068 let range = IndexEntryKey::key_prefix_range(ObjectId::table(1), IndexId::primary(1), prefix).encode();
1069
1070 layout.set_row_number(&mut key, 1, 999u64);
1071 let entry = IndexEntryKey {
1072 object: ObjectId::table(1),
1073 index: IndexId::primary(1),
1074 key: key.clone(),
1075 };
1076
1077 let encoded = entry.encode();
1078
1079 if let (Bound::Included(start), Bound::Excluded(end)) = (&range.start, &range.end) {
1080 assert!(encoded.as_slice() >= start.as_slice());
1081 assert!(encoded.as_slice() < end.as_slice());
1082 }
1083
1084 let mut key2 = layout.allocate_key();
1085 layout.set_u64(&mut key2, 0, 200u64);
1086 layout.set_row_number(&mut key2, 1, 1u64);
1087
1088 let entry2 = IndexEntryKey {
1089 object: ObjectId::table(1),
1090 index: IndexId::primary(1),
1091 key: key2,
1092 };
1093
1094 let encoded2 = entry2.encode();
1095
1096 if let Bound::Excluded(end) = &range.end {
1097 assert!(encoded2.as_slice() >= end.as_slice());
1098 }
1099 }
1100}
1101
1102#[derive(Debug, Clone, PartialEq, Hash)]
1103pub struct SumTypeKey {
1104 pub sumtype: SumTypeId,
1105}
1106
1107impl SumTypeKey {
1108 pub fn new(sumtype: SumTypeId) -> Self {
1109 Self {
1110 sumtype,
1111 }
1112 }
1113
1114 pub fn encoded(sumtype: impl Into<SumTypeId>) -> EncodedKey {
1115 Self::new(sumtype.into()).encode()
1116 }
1117
1118 pub fn full_scan() -> TaggedKeyBoundRange {
1119 TaggedKeyBoundRange::kind(Self::TAG)
1120 }
1121}
1122
1123impl SumTypeKey {
1124 pub const TAG: KeyTag = KeyTag::SumType;
1125
1126 pub fn encode(&self) -> EncodedKey {
1127 let mut serializer = KeySerializer::with_capacity(9);
1128 serializer.extend_u8(SumTypeKey::TAG as u8).extend_u64(self.sumtype);
1129 serializer.to_encoded_key()
1130 }
1131
1132 pub fn decode(key: &EncodedKey) -> Option<Self> {
1133 let mut de = KeyDeserializer::from_bytes(key.as_slice());
1134
1135 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
1136 if kind != SumTypeKey::TAG {
1137 return None;
1138 }
1139
1140 let sumtype = de.read_u64().ok()?;
1141
1142 Some(Self {
1143 sumtype: SumTypeId(sumtype),
1144 })
1145 }
1146}
1147
1148#[cfg(test)]
1149mod sum_type_key_tests {
1150 use reifydb_value::value::sumtype::SumTypeId;
1151
1152 use super::SumTypeKey;
1153
1154 #[test]
1155 fn test_encode_decode() {
1156 let key = SumTypeKey {
1157 sumtype: SumTypeId(0xABCD),
1158 };
1159 let encoded = key.encode();
1160 let decoded = SumTypeKey::decode(&encoded).unwrap();
1161 assert_eq!(decoded.sumtype, SumTypeId(0xABCD));
1162 }
1163}
1164
1165#[derive(Debug, Clone, PartialEq, Hash)]
1166pub struct ViewKey {
1167 pub view: ViewId,
1168}
1169
1170impl ViewKey {
1171 pub const TAG: KeyTag = KeyTag::View;
1172
1173 pub fn encode(&self) -> EncodedKey {
1174 let mut serializer = KeySerializer::with_capacity(9);
1175 serializer.extend_u8(ViewKey::TAG as u8).extend_u64(self.view);
1176 serializer.to_encoded_key()
1177 }
1178
1179 pub fn decode(key: &EncodedKey) -> Option<Self> {
1180 let mut de = KeyDeserializer::from_bytes(key.as_slice());
1181
1182 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
1183 if kind != ViewKey::TAG {
1184 return None;
1185 }
1186
1187 let view = de.read_u64().ok()?;
1188
1189 Some(Self {
1190 view: ViewId(view),
1191 })
1192 }
1193}
1194
1195impl ViewKey {
1196 pub fn new(view: impl Into<ViewId>) -> Self {
1197 Self {
1198 view: view.into(),
1199 }
1200 }
1201
1202 pub fn encoded(view: impl Into<ViewId>) -> EncodedKey {
1203 Self::new(view).encode()
1204 }
1205
1206 pub fn full_scan() -> TaggedKeyBoundRange {
1207 TaggedKeyBoundRange::kind(Self::TAG)
1208 }
1209}
1210
1211#[cfg(test)]
1212pub mod view_key_tests {
1213 use super::ViewKey;
1214 use crate::interface::catalog::id::ViewId;
1215
1216 #[test]
1217 fn test_encode_decode() {
1218 let key = ViewKey {
1219 view: ViewId(0xABCD),
1220 };
1221 let encoded = key.encode();
1222 let expected = vec![0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32];
1223 assert_eq!(encoded.as_slice(), expected);
1224
1225 let key = ViewKey::decode(&encoded).unwrap();
1226 assert_eq!(key.view, 0xABCD);
1227 }
1228}
1229
1230#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1231#[key(tag = Table)]
1232pub struct TableKey {
1233 pub table: TableId,
1234}
1235
1236impl TableKey {
1237 pub fn new(table: impl Into<TableId>) -> Self {
1238 Self {
1239 table: table.into(),
1240 }
1241 }
1242
1243 pub fn encoded(table: impl Into<TableId>) -> EncodedKey {
1244 Self::new(table).encode()
1245 }
1246
1247 pub fn full_scan() -> TaggedKeyBoundRange {
1248 TaggedKeyBoundRange::kind(Self::TAG)
1249 }
1250}
1251
1252#[cfg(test)]
1253pub mod table_key_tests {
1254 use super::TableKey;
1255 use crate::interface::catalog::id::TableId;
1256
1257 #[test]
1258 fn test_encode_decode() {
1259 let key = TableKey {
1260 table: TableId(0xABCD),
1261 };
1262 let encoded = key.encode();
1263 let expected = vec![0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32];
1264 assert_eq!(encoded.as_slice(), expected);
1265
1266 let key = TableKey::decode(&encoded).unwrap();
1267 assert_eq!(key.table, 0xABCD);
1268 }
1269
1270 #[test]
1271 fn test_order_preserving() {
1272 let key1 = TableKey {
1273 table: TableId(1),
1274 };
1275 let key2 = TableKey {
1276 table: TableId(2),
1277 };
1278
1279 let encoded1 = key1.encode();
1280 let encoded2 = key2.encode();
1281
1282 assert!(encoded2 < encoded1, "ordering not preserved");
1283 }
1284}
1285
1286#[derive(Debug, Clone, PartialEq, Hash)]
1287pub struct SourceKey {
1288 pub source: SourceId,
1289}
1290
1291impl SourceKey {
1292 pub const TAG: KeyTag = KeyTag::Source;
1293
1294 pub fn encode(&self) -> EncodedKey {
1295 let mut serializer = KeySerializer::with_capacity(9);
1296 serializer.extend_u8(SourceKey::TAG as u8).extend_u64(self.source);
1297 serializer.to_encoded_key()
1298 }
1299
1300 pub fn decode(key: &EncodedKey) -> Option<Self> {
1301 let mut de = KeyDeserializer::from_bytes(key.as_slice());
1302
1303 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
1304 if kind != SourceKey::TAG {
1305 return None;
1306 }
1307
1308 let source = de.read_u64().ok()?;
1309
1310 Some(Self {
1311 source: SourceId(source),
1312 })
1313 }
1314}
1315
1316impl SourceKey {
1317 pub fn new(source: impl Into<SourceId>) -> Self {
1318 Self {
1319 source: source.into(),
1320 }
1321 }
1322
1323 pub fn encoded(source: impl Into<SourceId>) -> EncodedKey {
1324 Self::new(source).encode()
1325 }
1326
1327 pub fn full_scan() -> TaggedKeyBoundRange {
1328 TaggedKeyBoundRange::kind(Self::TAG)
1329 }
1330}
1331
1332#[cfg(test)]
1333pub mod source_key_tests {
1334 use super::SourceKey;
1335 use crate::interface::catalog::id::SourceId;
1336
1337 #[test]
1338 fn test_encode_decode() {
1339 let key = SourceKey {
1340 source: SourceId(0x1234),
1341 };
1342 let encoded = key.encode();
1343 let decoded = SourceKey::decode(&encoded).unwrap();
1344 assert_eq!(decoded.source, SourceId(0x1234));
1345 assert_eq!(key, decoded);
1346 }
1347}
1348
1349#[derive(Debug, Clone, PartialEq, Hash)]
1350pub struct SinkKey {
1351 pub sink: SinkId,
1352}
1353
1354impl SinkKey {
1355 pub const TAG: KeyTag = KeyTag::Sink;
1356
1357 pub fn encode(&self) -> EncodedKey {
1358 let mut serializer = KeySerializer::with_capacity(9);
1359 serializer.extend_u8(SinkKey::TAG as u8).extend_u64(self.sink);
1360 serializer.to_encoded_key()
1361 }
1362
1363 pub fn decode(key: &EncodedKey) -> Option<Self> {
1364 let mut de = KeyDeserializer::from_bytes(key.as_slice());
1365
1366 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
1367 if kind != SinkKey::TAG {
1368 return None;
1369 }
1370
1371 let sink = de.read_u64().ok()?;
1372
1373 Some(Self {
1374 sink: SinkId(sink),
1375 })
1376 }
1377}
1378
1379impl SinkKey {
1380 pub fn new(sink: impl Into<SinkId>) -> Self {
1381 Self {
1382 sink: sink.into(),
1383 }
1384 }
1385
1386 pub fn encoded(sink: impl Into<SinkId>) -> EncodedKey {
1387 Self::new(sink).encode()
1388 }
1389
1390 pub fn full_scan() -> TaggedKeyBoundRange {
1391 TaggedKeyBoundRange::kind(Self::TAG)
1392 }
1393}
1394
1395#[cfg(test)]
1396pub mod sink_key_tests {
1397 use super::SinkKey;
1398 use crate::interface::catalog::id::SinkId;
1399
1400 #[test]
1401 fn test_encode_decode() {
1402 let key = SinkKey {
1403 sink: SinkId(0x1234),
1404 };
1405 let encoded = key.encode();
1406 let decoded = SinkKey::decode(&encoded).unwrap();
1407 assert_eq!(decoded.sink, SinkId(0x1234));
1408 assert_eq!(key, decoded);
1409 }
1410}
1411
1412#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1413#[key(tag = Relationship)]
1414pub struct RelationshipKey {
1415 pub relationship: RelationshipId,
1416}
1417
1418impl RelationshipKey {
1419 pub fn new(relationship: impl Into<RelationshipId>) -> Self {
1420 Self {
1421 relationship: relationship.into(),
1422 }
1423 }
1424
1425 pub fn encoded(relationship: impl Into<RelationshipId>) -> EncodedKey {
1426 Self::new(relationship).encode()
1427 }
1428
1429 pub fn full_scan() -> TaggedKeyBoundRange {
1430 TaggedKeyBoundRange::kind(Self::TAG)
1431 }
1432}
1433
1434#[cfg(test)]
1435mod relationship_key_tests {
1436 use super::RelationshipKey;
1437 use crate::interface::catalog::id::RelationshipId;
1438
1439 #[test]
1440 fn test_encode_decode() {
1441 let key = RelationshipKey {
1442 relationship: RelationshipId(0xABCD),
1443 };
1444 let encoded = key.encode();
1445 let decoded = RelationshipKey::decode(&encoded).unwrap();
1446 assert_eq!(decoded.relationship, RelationshipId(0xABCD));
1447 }
1448}
1449
1450#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1451#[key(tag = ColumnProperty)]
1452pub struct ColumnPropertyKey {
1453 pub column: ColumnId,
1454 pub property: ColumnPropertyId,
1455}
1456
1457impl ColumnPropertyKey {
1458 pub fn new(column: impl Into<ColumnId>, property: impl Into<ColumnPropertyId>) -> Self {
1459 Self {
1460 column: column.into(),
1461 property: property.into(),
1462 }
1463 }
1464
1465 pub fn encoded(column: impl Into<ColumnId>, property: impl Into<ColumnPropertyId>) -> EncodedKey {
1466 Self::new(column, property).encode()
1467 }
1468
1469 pub fn full_scan(column: ColumnId) -> TaggedKeyBoundRange {
1470 TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, column.0 as u128)])
1471 }
1472}
1473
1474#[cfg(test)]
1475pub mod column_property_key_tests {
1476 use super::ColumnPropertyKey;
1477 use crate::interface::catalog::id::{ColumnId, ColumnPropertyId};
1478
1479 #[test]
1480 fn test_encode_decode() {
1481 let key = ColumnPropertyKey {
1482 column: ColumnId(0xABCD),
1483 property: ColumnPropertyId(0x123456789ABCDEF0),
1484 };
1485 let encoded = key.encode();
1486
1487 let expected: Vec<u8> = vec![
1488 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43, 0x21,
1489 0x0F,
1490 ];
1491
1492 assert_eq!(encoded.as_slice(), expected);
1493
1494 let key = ColumnPropertyKey::decode(&encoded).unwrap();
1495 assert_eq!(key.column, 0xABCD);
1496 assert_eq!(key.property, 0x123456789ABCDEF0);
1497 }
1498
1499 #[test]
1500 fn test_order_preserving() {
1501 let key1 = ColumnPropertyKey {
1502 column: ColumnId(1),
1503 property: ColumnPropertyId(100),
1504 };
1505 let key2 = ColumnPropertyKey {
1506 column: ColumnId(1),
1507 property: ColumnPropertyId(200),
1508 };
1509 let key3 = ColumnPropertyKey {
1510 column: ColumnId(2),
1511 property: ColumnPropertyId(0),
1512 };
1513
1514 let encoded1 = key1.encode();
1515 let encoded2 = key2.encode();
1516 let encoded3 = key3.encode();
1517
1518 assert!(encoded3 < encoded2, "ordering not preserved");
1519 assert!(encoded2 < encoded1, "ordering not preserved");
1520 }
1521}
1522
1523#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1524#[key(tag = Handler)]
1525pub struct HandlerKey {
1526 pub handler: HandlerId,
1527}
1528
1529impl HandlerKey {
1530 pub fn new(handler: HandlerId) -> Self {
1531 Self {
1532 handler,
1533 }
1534 }
1535
1536 pub fn encoded(handler: impl Into<HandlerId>) -> EncodedKey {
1537 Self::new(handler.into()).encode()
1538 }
1539
1540 pub fn full_scan() -> TaggedKeyBoundRange {
1541 TaggedKeyBoundRange::kind(Self::TAG)
1542 }
1543}
1544
1545#[cfg(test)]
1546pub mod handler_key_tests {
1547 use super::HandlerKey;
1548 use crate::interface::catalog::id::HandlerId;
1549
1550 #[test]
1551 fn test_encode_decode() {
1552 let key = HandlerKey {
1553 handler: HandlerId(0xABCD),
1554 };
1555 let encoded = key.encode();
1556 let expected = vec![0xD4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32];
1557 assert_eq!(encoded.as_slice(), expected);
1558
1559 let decoded = HandlerKey::decode(&encoded).unwrap();
1560 assert_eq!(decoded.handler, HandlerId(0xABCD));
1561 }
1562
1563 #[test]
1564 fn test_order_preserving() {
1565 let key1 = HandlerKey {
1566 handler: HandlerId(1),
1567 };
1568 let key2 = HandlerKey {
1569 handler: HandlerId(2),
1570 };
1571
1572 let encoded1 = key1.encode();
1573 let encoded2 = key2.encode();
1574
1575 assert!(encoded2 < encoded1, "ordering not preserved");
1576 }
1577}
1578
1579#[cfg(test)]
1580mod verify_byte_identical_handler_key {
1581 use reifydb_codec::key::serializer::KeySerializer;
1582
1583 use super::HandlerKey;
1584 use crate::interface::catalog::id::HandlerId;
1585
1586 fn legacy_encode(key: &HandlerKey) -> Vec<u8> {
1587 let mut serializer = KeySerializer::with_capacity(9);
1588 serializer.extend_u8(HandlerKey::TAG as u8).extend_u64(key.handler);
1589 serializer.to_encoded_key().as_slice().to_vec()
1590 }
1591
1592 #[test]
1593 fn matches_legacy_byte_layout() {
1594 for handler in [0u64, 1, 42, 0xABCD, u64::MAX] {
1595 let key = HandlerKey {
1596 handler: HandlerId(handler),
1597 };
1598 assert_eq!(legacy_encode(&key), key.encode().as_slice().to_vec(), "handler={handler:#x}");
1599 }
1600 }
1601}
1602
1603#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1604#[key(tag = VariantHandler)]
1605pub struct VariantHandlerKey {
1606 pub namespace: NamespaceId,
1607 pub sumtype: SumTypeId,
1608 pub variant_tag: u8,
1609 pub handler: HandlerId,
1610}
1611
1612impl VariantHandlerKey {
1613 pub fn new(namespace: NamespaceId, sumtype: SumTypeId, variant_tag: u8, handler: HandlerId) -> Self {
1614 Self {
1615 namespace,
1616 sumtype,
1617 variant_tag,
1618 handler,
1619 }
1620 }
1621
1622 pub fn encoded(
1623 namespace: impl Into<NamespaceId>,
1624 sumtype: impl Into<SumTypeId>,
1625 variant_tag: u8,
1626 handler: impl Into<HandlerId>,
1627 ) -> EncodedKey {
1628 Self::new(namespace.into(), sumtype.into(), variant_tag, handler.into()).encode()
1629 }
1630
1631 pub fn variant_scan(namespace: NamespaceId, sumtype: SumTypeId, variant_tag: u8) -> TaggedKeyBoundRange {
1632 TaggedKeyBoundRange::prefix(
1633 Self::TAG,
1634 [
1635 Field::UDesc(Width::U64, namespace.0 as u128),
1636 Field::UDesc(Width::U64, sumtype.0 as u128),
1637 Field::UDesc(Width::U8, variant_tag as u128),
1638 ],
1639 )
1640 }
1641}
1642
1643#[cfg(test)]
1644pub mod variant_handler_key_tests {
1645 use std::ops::Bound;
1646
1647 use reifydb_value::value::sumtype::SumTypeId;
1648
1649 use super::VariantHandlerKey;
1650 use crate::interface::catalog::id::{HandlerId, NamespaceId};
1651
1652 #[test]
1653 fn test_encode_decode() {
1654 let key = VariantHandlerKey {
1655 namespace: NamespaceId(0xABCD),
1656 sumtype: SumTypeId(0x1234),
1657 variant_tag: 5,
1658 handler: HandlerId(0x6789),
1659 };
1660 let encoded = key.encode();
1661 let expected: Vec<u8> = vec![
1662 0xD2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED,
1663 0xCB, 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x98, 0x76,
1664 ];
1665 assert_eq!(encoded.as_slice(), expected);
1666
1667 let decoded = VariantHandlerKey::decode(&encoded).unwrap();
1668 assert_eq!(decoded.namespace, NamespaceId(0xABCD));
1669 assert_eq!(decoded.sumtype, SumTypeId(0x1234));
1670 assert_eq!(decoded.variant_tag, 5);
1671 assert_eq!(decoded.handler, HandlerId(0x6789));
1672 }
1673
1674 #[test]
1675 fn test_order_preserving() {
1676 let key1 = VariantHandlerKey {
1677 namespace: NamespaceId::SYSTEM,
1678 sumtype: SumTypeId(5),
1679 variant_tag: 3,
1680 handler: HandlerId(100),
1681 };
1682 let key2 = VariantHandlerKey {
1683 namespace: NamespaceId::SYSTEM,
1684 sumtype: SumTypeId(5),
1685 variant_tag: 3,
1686 handler: HandlerId(200),
1687 };
1688 let key3 = VariantHandlerKey {
1689 namespace: NamespaceId::SYSTEM,
1690 sumtype: SumTypeId(5),
1691 variant_tag: 4,
1692 handler: HandlerId(1),
1693 };
1694 let key4 = VariantHandlerKey {
1695 namespace: NamespaceId::DEFAULT,
1696 sumtype: SumTypeId(1),
1697 variant_tag: 0,
1698 handler: HandlerId(1),
1699 };
1700
1701 let encoded1 = key1.encode();
1702 let encoded2 = key2.encode();
1703 let encoded3 = key3.encode();
1704 let encoded4 = key4.encode();
1705
1706 assert!(encoded4 < encoded3, "ordering not preserved");
1707 assert!(encoded3 < encoded2, "ordering not preserved");
1708 assert!(encoded2 < encoded1, "ordering not preserved");
1709 }
1710
1711 #[test]
1712 fn test_variant_scan() {
1713 let ns = NamespaceId::SYSTEM;
1714 let st = SumTypeId(10);
1715 let tag = 5u8;
1716
1717 let range = VariantHandlerKey::variant_scan(ns, st, tag).encode();
1718 let start = match &range.start {
1719 Bound::Included(k) | Bound::Excluded(k) => k,
1720 Bound::Unbounded => panic!("expected bounded start"),
1721 };
1722 let end = match &range.end {
1723 Bound::Included(k) | Bound::Excluded(k) => k,
1724 Bound::Unbounded => panic!("expected bounded end"),
1725 };
1726
1727 let key = VariantHandlerKey {
1728 namespace: ns,
1729 sumtype: st,
1730 variant_tag: tag,
1731 handler: HandlerId(42),
1732 };
1733 let encoded = key.encode();
1734 assert!(encoded.as_slice() >= start.as_slice());
1735 assert!(encoded.as_slice() <= end.as_slice());
1736
1737 let other = VariantHandlerKey {
1738 namespace: ns,
1739 sumtype: st,
1740 variant_tag: tag + 1,
1741 handler: HandlerId(42),
1742 };
1743 let other_encoded = other.encode();
1744 assert!(other_encoded.as_slice() < start.as_slice());
1745 }
1746}
1747
1748#[cfg(test)]
1749mod verify_byte_identical_variant_handler_key {
1750 use reifydb_codec::key::serializer::KeySerializer;
1751 use reifydb_value::value::sumtype::SumTypeId;
1752
1753 use super::VariantHandlerKey;
1754 use crate::interface::catalog::id::{HandlerId, NamespaceId};
1755
1756 fn legacy_encode(key: &VariantHandlerKey) -> Vec<u8> {
1757 let mut serializer = KeySerializer::with_capacity(26);
1758 serializer
1759 .extend_u8(VariantHandlerKey::TAG as u8)
1760 .extend_u64(key.namespace)
1761 .extend_u64(key.sumtype)
1762 .extend_u8(key.variant_tag)
1763 .extend_u64(key.handler);
1764 serializer.to_encoded_key().as_slice().to_vec()
1765 }
1766
1767 #[test]
1768 fn matches_legacy_byte_layout() {
1769 for (namespace, sumtype, variant_tag, handler) in [
1770 (0u64, 0u64, 0u8, 0u64),
1771 (1, 2, 3, 4),
1772 (0xABCD, 0x1234, 5, 0x6789),
1773 (u64::MAX, u64::MAX, u8::MAX, u64::MAX),
1774 ] {
1775 let key = VariantHandlerKey {
1776 namespace: NamespaceId(namespace),
1777 sumtype: SumTypeId(sumtype),
1778 variant_tag,
1779 handler: HandlerId(handler),
1780 };
1781 assert_eq!(
1782 legacy_encode(&key),
1783 key.encode().as_slice().to_vec(),
1784 "namespace={namespace:#x} sumtype={sumtype:#x} variant_tag={variant_tag:#x} handler={handler:#x}"
1785 );
1786 }
1787 }
1788}
1789
1790#[derive(Debug, Clone, PartialEq, Hash)]
1791pub struct BindingKey {
1792 pub binding: BindingId,
1793}
1794
1795impl BindingKey {
1796 pub const TAG: KeyTag = KeyTag::Binding;
1797
1798 pub fn encode(&self) -> EncodedKey {
1799 let mut serializer = KeySerializer::with_capacity(9);
1800 serializer.extend_u8(BindingKey::TAG as u8).extend_u64(self.binding);
1801 serializer.to_encoded_key()
1802 }
1803
1804 pub fn decode(key: &EncodedKey) -> Option<Self> {
1805 let mut de = KeyDeserializer::from_bytes(key.as_slice());
1806
1807 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
1808 if kind != BindingKey::TAG {
1809 return None;
1810 }
1811
1812 let binding = de.read_u64().ok()?;
1813
1814 Some(Self {
1815 binding: BindingId(binding),
1816 })
1817 }
1818}
1819
1820impl BindingKey {
1821 pub fn new(binding: impl Into<BindingId>) -> Self {
1822 Self {
1823 binding: binding.into(),
1824 }
1825 }
1826
1827 pub fn encoded(binding: impl Into<BindingId>) -> EncodedKey {
1828 Self::new(binding).encode()
1829 }
1830
1831 pub fn full_scan() -> TaggedKeyBoundRange {
1832 TaggedKeyBoundRange::kind(Self::TAG)
1833 }
1834}
1835
1836#[cfg(test)]
1837pub mod binding_key_tests {
1838 use super::BindingKey;
1839 use crate::interface::catalog::id::BindingId;
1840
1841 #[test]
1842 fn test_encode_decode() {
1843 let key = BindingKey {
1844 binding: BindingId(0xABCD),
1845 };
1846 let encoded = key.encode();
1847 let decoded = BindingKey::decode(&encoded).unwrap();
1848 assert_eq!(decoded.binding, 0xABCD);
1849 }
1850}
1851
1852#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
1853#[key(tag = PrimaryKey)]
1854pub struct PrimaryKeyKey {
1855 pub primary_key: PrimaryKeyId,
1856}
1857
1858impl PrimaryKeyKey {
1859 pub fn new(primary_key: impl Into<PrimaryKeyId>) -> Self {
1860 Self {
1861 primary_key: primary_key.into(),
1862 }
1863 }
1864
1865 pub fn encoded(primary_key: impl Into<PrimaryKeyId>) -> EncodedKey {
1866 Self::new(primary_key).encode()
1867 }
1868
1869 pub fn full_scan() -> TaggedKeyBoundRange {
1870 TaggedKeyBoundRange::kind(Self::TAG)
1871 }
1872}
1873
1874#[cfg(test)]
1875mod primary_key_key_tests {
1876 use super::PrimaryKeyKey;
1877 use crate::interface::catalog::id::PrimaryKeyId;
1878
1879 #[test]
1880 fn test_encode_decode() {
1881 let key = PrimaryKeyKey {
1882 primary_key: PrimaryKeyId(0xABCD),
1883 };
1884 let encoded = key.encode();
1885 let decoded = PrimaryKeyKey::decode(&encoded).unwrap();
1886 assert_eq!(decoded.primary_key, PrimaryKeyId(0xABCD));
1887 }
1888}
1889
1890impl KeyFields for DictionaryEntryIndexKey {
1891 fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
1892 smallvec![Field::UDesc(Width::U64, self.dictionary.0 as u128), Field::UDesc(Width::Varint, self.id)]
1893 }
1894}
1895
1896impl KeyFields for IndexEntryKey {
1897 fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
1898 smallvec![
1899 Field::UAsc(Width::U8, self.object.type_tag() as u128),
1900 Field::UDesc(Width::U64, self.object.as_u64() as u128),
1901 Field::UAsc(Width::U8, index_tag(&self.index) as u128),
1902 Field::UDesc(Width::U64, self.index.as_u64() as u128),
1903 Field::RawAsc(RawEncoding::Verbatim, Cow::Borrowed(self.key.as_slice())),
1904 ]
1905 }
1906}
1907
1908impl KeyFields for BindingKey {
1909 fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
1910 smallvec![Field::UDesc(Width::U64, self.binding.0 as u128)]
1911 }
1912}
1913
1914impl KeyFields for SinkKey {
1915 fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
1916 smallvec![Field::UDesc(Width::U64, self.sink.0 as u128)]
1917 }
1918}
1919
1920impl KeyFields for SourceKey {
1921 fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
1922 smallvec![Field::UDesc(Width::U64, self.source.0 as u128)]
1923 }
1924}
1925
1926impl KeyFields for ViewKey {
1927 fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
1928 smallvec![Field::UDesc(Width::U64, self.view.0 as u128)]
1929 }
1930}
1931
1932impl KeyFields for SumTypeKey {
1933 fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
1934 smallvec![Field::UDesc(Width::U64, self.sumtype.0 as u128)]
1935 }
1936}