1use std::{borrow::Cow, cmp::Ordering, collections::Bound};
5
6use reifydb_codec::{
7 key::{
8 ByteSink,
9 deserializer::KeyDeserializer,
10 encoded::{EncodedKey, EncodedKeyRange},
11 serializer::KeySerializer,
12 },
13 row::shape::fingerprint::RowShapeFingerprint,
14};
15use reifydb_macro::KeyCodec;
16use reifydb_value::value::{partition::Partition, row_number::RowNumber};
17use serde::{Deserialize, Serialize};
18use smallvec::{SmallVec, smallvec};
19
20use super::{KeyRangeCodec, KeyTag};
21use crate::{
22 interface::catalog::{object::ObjectId, storage::StorageId},
23 key::{
24 any::{Field, KeyFields, RawEncoding, TaggedKey, Width},
25 bound::{TaggedKeyBoundRange, object_fields},
26 catalog::{KeyDeserializerCatalogExt, KeySerializerCatalogExt},
27 sort_run::SortRun,
28 typed::{
29 BoundedKey, DenseKey,
30 direction::{Asc, Desc},
31 },
32 },
33 metrics::heap::HeapSize,
34};
35
36#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
37#[key(tag = Row)]
38pub struct RowKey {
39 pub storage: StorageId,
40 pub row: RowNumber,
41}
42
43#[derive(Debug, Clone, PartialEq)]
44pub struct RowKeyRange {
45 pub storage: StorageId,
46}
47
48impl RowKeyRange {
49 fn decode_key(key: &EncodedKey) -> Option<Self> {
50 let mut de = KeyDeserializer::from_bytes(key.as_slice());
51
52 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
53 if kind != Self::TAG {
54 return None;
55 }
56
57 let storage = StorageId::from_object(de.read_object_id().ok()?)?;
58
59 Some(RowKeyRange {
60 storage,
61 })
62 }
63
64 pub fn storage_scan(storage: StorageId) -> TaggedKeyBoundRange {
65 TaggedKeyBoundRange::prefix(Self::TAG, object_fields(ObjectId::from(storage)))
66 }
67
68 pub fn scan_range(storage: StorageId, last: Option<&TaggedKey>) -> TaggedKeyBoundRange {
69 Self::storage_scan(storage).resume_after(last)
70 }
71
72 pub fn scan_range_rev(storage: StorageId, last: Option<&TaggedKey>) -> TaggedKeyBoundRange {
73 Self::storage_scan(storage).resume_before(last)
74 }
75}
76
77impl KeyRangeCodec for RowKeyRange {
78 const TAG: KeyTag = KeyTag::Row;
79
80 fn start(&self) -> Option<EncodedKey> {
81 let mut serializer = KeySerializer::with_capacity(10);
82 serializer.extend_u8(Self::TAG as u8).extend_object_id(self.storage);
83 Some(serializer.to_encoded_key())
84 }
85
86 fn end(&self) -> Option<EncodedKey> {
87 let mut serializer = KeySerializer::with_capacity(10);
88 serializer.extend_u8(Self::TAG as u8).extend_object_id(ObjectId::from(self.storage).prev());
89 Some(serializer.to_encoded_key())
90 }
91
92 fn decode(range: &EncodedKeyRange) -> (Option<Self>, Option<Self>)
93 where
94 Self: Sized,
95 {
96 let start_key = match &range.start {
97 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
98 Bound::Unbounded => None,
99 };
100
101 let end_key = match &range.end {
102 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
103 Bound::Unbounded => None,
104 };
105
106 (start_key, end_key)
107 }
108}
109
110impl RowKey {
111 pub fn new(storage: impl Into<StorageId>, row: impl Into<RowNumber>) -> Self {
112 Self {
113 storage: storage.into(),
114 row: row.into(),
115 }
116 }
117
118 pub fn encoded(storage: impl Into<StorageId>, row: impl Into<RowNumber>) -> EncodedKey {
119 Self {
120 storage: storage.into(),
121 row: row.into(),
122 }
123 .encode()
124 }
125
126 pub fn full_scan(storage: impl Into<StorageId>) -> TaggedKeyBoundRange {
127 TaggedKeyBoundRange::prefix(Self::TAG, object_fields(ObjectId::from(storage.into())))
128 }
129
130 pub fn storage_start(storage: impl Into<StorageId>) -> EncodedKey {
131 let mut serializer = KeySerializer::with_capacity(10);
132 serializer.extend_u8(RowKey::TAG as u8).extend_object_id(storage.into());
133 serializer.to_encoded_key()
134 }
135
136 pub fn storage_end(storage: impl Into<StorageId>) -> EncodedKey {
137 let mut serializer = KeySerializer::with_capacity(10);
138 serializer.extend_u8(RowKey::TAG as u8).extend_object_id(ObjectId::from(storage.into()).prev());
139 serializer.to_encoded_key()
140 }
141}
142
143#[derive(Debug, Clone, PartialEq, Eq, Hash)]
144pub struct SortedViewRowKey {
145 pub storage: StorageId,
146 pub run: SortRun,
147 pub row: Asc<RowNumber>,
148}
149
150impl SortedViewRowKey {
151 pub const TAG: KeyTag = KeyTag::SortedViewRow;
152
153 pub fn encode(&self) -> EncodedKey {
154 let mut serializer = KeySerializer::with_capacity(20 + self.run.len());
155 serializer.extend_u8(Self::TAG as u8).extend_object_id(self.storage);
156 extend_sort_run(&mut serializer, &self.run);
157 serializer.extend_raw(&self.row.0.0.to_be_bytes());
158 serializer.to_encoded_key()
159 }
160
161 pub fn decode(key: &EncodedKey) -> Option<Self> {
162 let mut de = KeyDeserializer::from_bytes(key.as_slice());
163 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
164 if kind != Self::TAG {
165 return None;
166 }
167 let storage = StorageId::from_object(de.read_object_id().ok()?)?;
168 let run = read_sort_run(&mut de)?;
169 let row = read_row_tail(&mut de)?;
170 if !de.is_empty() {
171 return None;
172 }
173 Some(Self {
174 storage,
175 run,
176 row,
177 })
178 }
179}
180
181impl Ord for SortedViewRowKey {
182 fn cmp(&self, other: &Self) -> Ordering {
183 storage_order(self.storage)
184 .cmp(&storage_order(other.storage))
185 .then_with(|| self.run.cmp(&other.run))
186 .then_with(|| self.row.cmp(&other.row))
187 }
188}
189
190impl PartialOrd for SortedViewRowKey {
191 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
192 Some(self.cmp(other))
193 }
194}
195
196impl SortedViewRowKey {
197 pub fn new(storage: impl Into<StorageId>, run: SortRun, row: RowNumber) -> Self {
198 Self {
199 storage: storage.into(),
200 run,
201 row: Asc(row),
202 }
203 }
204
205 pub fn encoded(storage: impl Into<StorageId>, run: SortRun, row: RowNumber) -> EncodedKey {
206 Self::new(storage, run, row).encode()
207 }
208
209 pub fn storage_start(storage: impl Into<StorageId>) -> EncodedKey {
210 let mut serializer = KeySerializer::with_capacity(10);
211 serializer.extend_u8(Self::TAG as u8).extend_object_id(storage.into());
212 serializer.to_encoded_key()
213 }
214
215 pub fn storage_scan(storage: impl Into<StorageId>) -> TaggedKeyBoundRange {
216 TaggedKeyBoundRange::prefix(Self::TAG, object_fields(ObjectId::from(storage.into())))
217 }
218
219 pub fn scan_range(storage: impl Into<StorageId>, last: Option<&TaggedKey>) -> TaggedKeyBoundRange {
220 Self::storage_scan(storage).resume_after(last)
221 }
222
223 pub fn storage_of(key: &EncodedKey) -> Option<StorageId> {
224 let mut de = KeyDeserializer::from_bytes(key.as_slice());
225 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
226 if kind != Self::TAG {
227 return None;
228 }
229 StorageId::from_object(de.read_object_id().ok()?)
230 }
231
232 pub fn row_of(key: &EncodedKey) -> Option<RowNumber> {
233 let bytes = key.as_slice();
234 if KeyTag::of(bytes)? != Self::TAG {
235 return None;
236 }
237 let tail = bytes.len().checked_sub(8)?;
238 Some(RowNumber(u64::from_be_bytes(bytes[tail..].try_into().ok()?)))
239 }
240
241 pub fn range_storage_of(range: &EncodedKeyRange) -> Option<StorageId> {
242 let start = bound_storage_of(&range.start, Self::TAG)?;
243 bound_storage_of(&range.end, Self::TAG)?;
244 Some(start)
245 }
246}
247
248const SORT_RUN_MARKER: u8 = 0x00;
249const SORT_RUN_ZERO: u8 = 0xff;
250const SORT_RUN_END: u8 = 0x00;
251
252pub(crate) fn encode_sort_run<B: ByteSink>(run: &[u8], out: &mut B) {
253 for &byte in run {
254 if byte == SORT_RUN_MARKER {
255 out.extend_from_slice(&[SORT_RUN_MARKER, SORT_RUN_ZERO]);
256 } else {
257 out.push(byte);
258 }
259 }
260 out.extend_from_slice(&[SORT_RUN_MARKER, SORT_RUN_END]);
261}
262
263fn extend_sort_run(serializer: &mut KeySerializer, run: &SortRun) {
264 encode_sort_run(run.as_slice(), serializer);
265}
266
267fn read_sort_run(de: &mut KeyDeserializer) -> Option<SortRun> {
268 let mut run: Vec<u8> = Vec::new();
269 loop {
270 let byte = de.read_raw(1).ok()?[0];
271 if byte != SORT_RUN_MARKER {
272 run.push(byte);
273 continue;
274 }
275 match de.read_raw(1).ok()?[0] {
276 SORT_RUN_END => return Some(SortRun::new(run)),
277 SORT_RUN_ZERO => run.push(0x00),
278 _ => return None,
279 }
280 }
281}
282
283fn read_row_tail(de: &mut KeyDeserializer) -> Option<Asc<RowNumber>> {
284 let bytes: [u8; 8] = de.read_raw(8).ok()?.try_into().ok()?;
285 Some(Asc(RowNumber(u64::from_be_bytes(bytes))))
286}
287
288fn storage_order(storage: StorageId) -> (u8, Desc<u64>) {
289 (ObjectId::from(storage).type_tag(), Desc(storage.as_u64()))
290}
291
292fn bound_storage_of(bound: &Bound<EncodedKey>, kind: KeyTag) -> Option<StorageId> {
293 let key = match bound {
294 Bound::Included(key) | Bound::Excluded(key) => key,
295 Bound::Unbounded => return None,
296 };
297 let mut de = KeyDeserializer::from_bytes(key.as_slice());
298 if KeyTag::try_from(de.read_u8().ok()?).ok()? != kind {
299 return None;
300 }
301 StorageId::from_object(de.read_object_id().ok()?)
302}
303
304#[derive(Debug, Clone, PartialEq, Eq, Hash)]
305pub struct PartitionedSortedViewRowKey {
306 pub storage: StorageId,
307 pub partition: Partition,
308 pub run: SortRun,
309 pub row: Asc<RowNumber>,
310}
311
312impl PartitionedSortedViewRowKey {
313 pub const TAG: KeyTag = KeyTag::PartitionedSortedViewRow;
314
315 pub fn encode(&self) -> EncodedKey {
316 let mut serializer = KeySerializer::with_capacity(36 + self.run.len());
317 serializer.extend_u8(Self::TAG as u8).extend_object_id(self.storage).extend_u128(self.partition.0);
318 extend_sort_run(&mut serializer, &self.run);
319 serializer.extend_raw(&self.row.0.0.to_be_bytes());
320 serializer.to_encoded_key()
321 }
322
323 pub fn decode(key: &EncodedKey) -> Option<Self> {
324 let mut de = KeyDeserializer::from_bytes(key.as_slice());
325 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
326 if kind != Self::TAG {
327 return None;
328 }
329 let storage = StorageId::from_object(de.read_object_id().ok()?)?;
330 let partition = Partition(de.read_u128().ok()?);
331 let run = read_sort_run(&mut de)?;
332 let row = read_row_tail(&mut de)?;
333 if !de.is_empty() {
334 return None;
335 }
336 Some(Self {
337 storage,
338 partition,
339 run,
340 row,
341 })
342 }
343}
344
345impl Ord for PartitionedSortedViewRowKey {
346 fn cmp(&self, other: &Self) -> Ordering {
347 storage_order(self.storage)
348 .cmp(&storage_order(other.storage))
349 .then_with(|| Desc(self.partition).cmp(&Desc(other.partition)))
350 .then_with(|| self.run.cmp(&other.run))
351 .then_with(|| self.row.cmp(&other.row))
352 }
353}
354
355impl PartialOrd for PartitionedSortedViewRowKey {
356 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
357 Some(self.cmp(other))
358 }
359}
360
361impl PartitionedSortedViewRowKey {
362 pub fn new(storage: impl Into<StorageId>, partition: Partition, run: SortRun, row: RowNumber) -> Self {
363 Self {
364 storage: storage.into(),
365 partition,
366 run,
367 row: Asc(row),
368 }
369 }
370
371 pub fn encoded(
372 storage: impl Into<StorageId>,
373 partition: Partition,
374 run: SortRun,
375 row: RowNumber,
376 ) -> EncodedKey {
377 Self::new(storage, partition, run, row).encode()
378 }
379
380 pub fn storage_start(storage: impl Into<StorageId>) -> EncodedKey {
381 let mut serializer = KeySerializer::with_capacity(10);
382 serializer.extend_u8(Self::TAG as u8).extend_object_id(storage.into());
383 serializer.to_encoded_key()
384 }
385
386 pub fn storage_scan(storage: impl Into<StorageId>) -> TaggedKeyBoundRange {
387 TaggedKeyBoundRange::prefix(Self::TAG, object_fields(ObjectId::from(storage.into())))
388 }
389
390 pub fn scan_range(storage: impl Into<StorageId>, last: Option<&TaggedKey>) -> TaggedKeyBoundRange {
391 Self::storage_scan(storage).resume_after(last)
392 }
393
394 pub fn partition_range(storage: impl Into<StorageId>, partition: Partition) -> TaggedKeyBoundRange {
395 TaggedKeyBoundRange::prefix(
396 Self::TAG,
397 object_fields(ObjectId::from(storage.into()))
398 .into_iter()
399 .chain([Field::UDesc(Width::U128, partition.0)])
400 .collect::<Vec<_>>(),
401 )
402 }
403
404 pub fn partition_scan_range(
405 storage: impl Into<StorageId>,
406 partition: Partition,
407 last: Option<&TaggedKey>,
408 ) -> TaggedKeyBoundRange {
409 Self::partition_range(storage, partition).resume_after(last)
410 }
411
412 pub fn storage_of(key: &EncodedKey) -> Option<StorageId> {
413 let mut de = KeyDeserializer::from_bytes(key.as_slice());
414 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
415 if kind != Self::TAG {
416 return None;
417 }
418 StorageId::from_object(de.read_object_id().ok()?)
419 }
420
421 pub fn row_of(key: &EncodedKey) -> Option<RowNumber> {
422 let bytes = key.as_slice();
423 if KeyTag::of(bytes)? != Self::TAG {
424 return None;
425 }
426 let tail = bytes.len().checked_sub(8)?;
427 Some(RowNumber(u64::from_be_bytes(bytes[tail..].try_into().ok()?)))
428 }
429
430 pub fn range_storage_of(range: &EncodedKeyRange) -> Option<StorageId> {
431 let start = bound_storage_of(&range.start, Self::TAG)?;
432 bound_storage_of(&range.end, Self::TAG)?;
433 Some(start)
434 }
435}
436
437#[cfg(test)]
438mod sorted_view_row_key_tests {
439 use std::ops::RangeBounds;
440
441 use reifydb_codec::key::encoded::EncodedKey;
442 use reifydb_value::value::{Value, partition::Partition, row_number::RowNumber};
443
444 use super::{PartitionedSortedViewRowKey, RowKey, SortedViewRowKey, TaggedKey};
445 use crate::{interface::catalog::storage::StorageId, key::sort_run::SortRun};
446
447 fn part(v: &str) -> Partition {
448 Partition::of(&[Value::Utf8(v.to_string())])
449 }
450
451 fn sorted_view(storage: StorageId, sort: &[u8], row: RowNumber) -> EncodedKey {
452 SortedViewRowKey::encoded(storage, SortRun::new(sort), row)
453 }
454
455 fn sorted_view_cursor(storage: StorageId, sort: &[u8], row: RowNumber) -> TaggedKey {
456 TaggedKey::from(SortedViewRowKey::new(storage, SortRun::new(sort), row))
457 }
458
459 fn partitioned(storage: StorageId, partition: Partition, sort: &[u8], row: RowNumber) -> EncodedKey {
460 PartitionedSortedViewRowKey::encoded(storage, partition, SortRun::new(sort), row)
461 }
462
463 #[test]
464 fn test_row_comes_from_the_tail_not_the_sort_prefix() {
465 let storage = StorageId::view(3);
468 let a = sorted_view(storage, &[0xAA; 8], RowNumber(7));
469 let b = sorted_view(storage, &[0xBB; 24], RowNumber(9));
470
471 assert_eq!(SortedViewRowKey::row_of(&a), Some(RowNumber(7)));
472 assert_eq!(SortedViewRowKey::row_of(&b), Some(RowNumber(9)));
473 assert_eq!(SortedViewRowKey::storage_of(&a), Some(storage));
474 }
475
476 #[test]
477 fn test_row_of_rejects_a_plain_row_key() {
478 let plain = RowKey::encoded(StorageId::view(3), RowNumber(7));
481 assert_eq!(SortedViewRowKey::row_of(&plain), None);
482 assert_eq!(PartitionedSortedViewRowKey::row_of(&plain), None);
483 }
484
485 #[test]
486 fn test_scan_range_covers_its_storage_and_nothing_else() {
487 let storage = StorageId::view(3);
488 let range = SortedViewRowKey::scan_range(storage, None).encode();
489
490 assert!(range.contains(&sorted_view(storage, &[0x00; 8], RowNumber(1))));
491 assert!(range.contains(&sorted_view(storage, &[0xFF; 8], RowNumber(u64::MAX))));
492 assert!(!range.contains(&sorted_view(StorageId::view(4), &[0x00; 8], RowNumber(1))));
493 }
494
495 #[test]
496 fn test_scan_range_resumes_strictly_after_the_last_key() {
497 let storage = StorageId::view(3);
499 let last = sorted_view_cursor(storage, &[0x40; 8], RowNumber(5));
500 let range = SortedViewRowKey::scan_range(storage, Some(&last)).encode();
501
502 assert!(!range.contains(&last.encode()));
503 assert!(range.contains(&sorted_view(storage, &[0x41; 8], RowNumber(1))));
504 }
505
506 #[test]
507 fn test_sort_prefix_orders_the_keyspace() {
508 let storage = StorageId::view(3);
511 let early_sort_late_row = sorted_view(storage, &[0x10; 8], RowNumber(999));
512 let late_sort_early_row = sorted_view(storage, &[0x20; 8], RowNumber(1));
513
514 assert!(early_sort_late_row < late_sort_early_row);
515 }
516
517 #[test]
518 fn test_partition_range_contains_only_its_partition() {
519 let storage = StorageId::view(3);
520 let range = PartitionedSortedViewRowKey::partition_range(storage, part("us")).encode();
521
522 assert!(range.contains(&partitioned(storage, part("us"), &[0x10; 8], RowNumber(1))));
523 assert!(!range.contains(&partitioned(storage, part("eu"), &[0x10; 8], RowNumber(1))));
524 }
525
526 #[test]
527 fn test_partitioned_row_comes_from_the_tail() {
528 let storage = StorageId::view(3);
529 let key = partitioned(storage, part("us"), &[0xAA; 8], RowNumber(42));
530
531 assert_eq!(PartitionedSortedViewRowKey::row_of(&key), Some(RowNumber(42)));
532 assert_eq!(PartitionedSortedViewRowKey::storage_of(&key), Some(storage));
533 assert_eq!(SortedViewRowKey::row_of(&key), None);
534 }
535}
536
537#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
538pub struct StorageRowKey(pub Desc<RowNumber>);
539
540impl From<RowKey> for StorageRowKey {
541 fn from(key: RowKey) -> Self {
542 StorageRowKey::new(key.row)
543 }
544}
545
546impl StorageRowKey {
547 pub fn new(row: RowNumber) -> Self {
548 StorageRowKey(Desc(row))
549 }
550
551 pub fn row(self) -> RowNumber {
552 self.0.0
553 }
554
555 pub fn with_storage(self, storage: StorageId) -> RowKey {
556 RowKey {
557 storage,
558 row: self.row(),
559 }
560 }
561}
562
563impl HeapSize for StorageRowKey {
564 fn heap_size(&self) -> usize {
565 0
566 }
567}
568
569impl BoundedKey for StorageRowKey {
570 fn low() -> Self {
571 StorageRowKey(<Desc<RowNumber> as BoundedKey>::low())
572 }
573}
574
575impl DenseKey for StorageRowKey {
576 fn successor(&self) -> Option<Self> {
577 self.0.successor().map(StorageRowKey)
578 }
579}
580
581#[cfg(test)]
582pub mod row_key_tests {
583 use reifydb_value::value::row_number::RowNumber;
584
585 use super::{RowKey, StorageRowKey};
586 use crate::{
587 interface::catalog::storage::StorageId,
588 key::typed::{BoundedKey, DenseKey},
589 };
590
591 #[test]
592 fn test_encode_decode() {
593 let key = RowKey {
594 storage: StorageId::table(0xABCD),
595 row: RowNumber(0x123456789ABCDEF0),
596 };
597 let encoded = key.encode();
598
599 let expected: Vec<u8> = vec![
600 0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43,
601 0x21, 0x0F,
602 ];
603
604 assert_eq!(encoded.as_slice(), expected);
605
606 let key = RowKey::decode(&encoded).unwrap();
607 assert_eq!(key.storage, StorageId::table(0xABCD));
608 assert_eq!(key.row, 0x123456789ABCDEF0);
609 }
610
611 #[test]
612 fn test_encode_decode_view() {
613 let key = RowKey {
615 storage: StorageId::view(0xABCD),
616 row: RowNumber(0x123456789ABCDEF0),
617 };
618 let encoded = key.encode();
619
620 let expected: Vec<u8> = vec![
621 0xFC, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43,
622 0x21, 0x0F,
623 ];
624
625 assert_eq!(encoded.as_slice(), expected);
626
627 let key = RowKey::decode(&encoded).unwrap();
628 assert_eq!(key.storage, StorageId::view(0xABCD));
629 assert_eq!(key.row, 0x123456789ABCDEF0);
630 }
631
632 #[test]
633 fn test_order_preserving() {
634 let key1 = RowKey {
635 storage: StorageId::table(1),
636 row: RowNumber(100),
637 };
638 let key2 = RowKey {
639 storage: StorageId::table(1),
640 row: RowNumber(200),
641 };
642 let key3 = RowKey {
643 storage: StorageId::table(2),
644 row: RowNumber(1),
645 };
646
647 let encoded1 = key1.encode();
648 let encoded2 = key2.encode();
649 let encoded3 = key3.encode();
650
651 assert!(encoded3 < encoded2, "ordering not preserved");
652 assert!(encoded2 < encoded1, "ordering not preserved");
653 }
654
655 #[test]
656 fn test_row_ident_roundtrip() {
657 let key = RowKey {
658 storage: StorageId::table(7),
659 row: RowNumber(42),
660 };
661
662 let ident: StorageRowKey = key.clone().into();
664 let restored = ident.with_storage(key.storage);
665 assert_eq!(restored, key);
666 }
667
668 #[test]
669 fn test_row_ident_ordering_matches_the_encoded_key() {
670 let storage = StorageId::table(1);
671 let one = StorageRowKey::new(RowNumber(1));
672 let two = StorageRowKey::new(RowNumber(2));
673
674 assert!(two < one);
677 assert_eq!(
678 two < one,
679 RowKey::encoded(storage, RowNumber(2)).as_slice()
680 < RowKey::encoded(storage, RowNumber(1)).as_slice()
681 );
682 }
683
684 #[test]
685 fn test_row_ident_low_is_the_greatest_row() {
686 assert_eq!(<StorageRowKey as BoundedKey>::low(), StorageRowKey::new(RowNumber(u64::MAX)));
689 }
690
691 #[test]
692 fn test_row_ident_successor_is_the_next_key_in_scan_order() {
693 let ident = StorageRowKey::new(RowNumber(5));
695 let next = ident.successor().unwrap();
696 assert_eq!(next, StorageRowKey::new(RowNumber(4)));
697 assert!(next > ident);
698 assert!(StorageRowKey::new(RowNumber(3)) > next);
699 }
700
701 #[test]
702 fn test_row_ident_successor_runs_out_at_row_zero() {
703 assert_eq!(StorageRowKey::new(RowNumber(0)).successor(), None);
705 }
706}
707
708#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
709#[key(tag = RowSequence)]
710pub struct RowSequenceKey {
711 pub storage: StorageId,
712}
713
714impl RowSequenceKey {
715 pub fn new(storage: StorageId) -> Self {
716 Self {
717 storage,
718 }
719 }
720
721 pub fn encoded(storage: impl Into<StorageId>) -> EncodedKey {
722 Self::new(storage.into()).encode()
723 }
724
725 pub fn full_scan() -> TaggedKeyBoundRange {
726 TaggedKeyBoundRange::kind(Self::TAG)
727 }
728}
729
730#[cfg(test)]
731pub mod row_sequence_key_tests {
732 use super::RowSequenceKey;
733 use crate::interface::catalog::storage::StorageId;
734
735 #[test]
736 fn test_encode_decode() {
737 let key = RowSequenceKey {
738 storage: StorageId::table(0xABCD),
739 };
740 let encoded = key.encode();
741 let expected = vec![0xF7, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32];
742 assert_eq!(encoded.as_slice(), expected);
743
744 let key = RowSequenceKey::decode(&encoded).unwrap();
745 assert_eq!(key.storage, StorageId::table(0xABCD));
746 }
747
748 #[test]
749 fn test_encode_decode_view() {
750 let key = RowSequenceKey {
752 storage: StorageId::view(0xABCD),
753 };
754 let encoded = key.encode();
755 let expected = vec![0xF7, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32];
756 assert_eq!(encoded.as_slice(), expected);
757
758 let key = RowSequenceKey::decode(&encoded).unwrap();
759 assert_eq!(key.storage, StorageId::view(0xABCD));
760 }
761}
762
763#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, KeyCodec, Hash)]
764#[key(tag = RowSettings)]
765pub struct RowSettingsKey {
766 pub storage: StorageId,
767}
768
769impl RowSettingsKey {
770 pub fn new(storage: StorageId) -> Self {
771 Self {
772 storage,
773 }
774 }
775
776 pub fn encoded(storage: StorageId) -> EncodedKey {
777 Self::new(storage).encode()
778 }
779
780 pub fn full_scan() -> TaggedKeyBoundRange {
781 TaggedKeyBoundRange::kind(Self::TAG)
782 }
783}
784
785#[cfg(test)]
786pub mod row_settings_key_tests {
787 use super::*;
788 use crate::interface::catalog::id::{RingBufferId, SeriesId, TableId, ViewId};
789
790 #[test]
791 fn test_row_settings_key_encoding() {
792 let key = RowSettingsKey {
793 storage: StorageId::Table(TableId(42)),
794 };
795
796 let encoded = key.encode();
797 let decoded = RowSettingsKey::decode(&encoded).unwrap();
798 assert_eq!(key, decoded);
799 }
800
801 #[test]
802 fn test_row_settings_key_roundtrip_view() {
803 let key = RowSettingsKey {
805 storage: StorageId::View(ViewId(13)),
806 };
807
808 let encoded = key.encode();
809 let decoded = RowSettingsKey::decode(&encoded).unwrap();
810 assert_eq!(key, decoded);
811 }
812
813 #[test]
814 fn test_row_settings_key_roundtrip_ringbuffer() {
815 let key = RowSettingsKey {
816 storage: StorageId::RingBuffer(RingBufferId(99)),
817 };
818
819 let encoded = key.encode();
820 let decoded = RowSettingsKey::decode(&encoded).unwrap();
821 assert_eq!(key, decoded);
822 }
823
824 #[test]
825 fn test_row_settings_key_roundtrip_series() {
826 let key = RowSettingsKey {
827 storage: StorageId::Series(SeriesId(7)),
828 };
829
830 let encoded = key.encode();
831 let decoded = RowSettingsKey::decode(&encoded).unwrap();
832 assert_eq!(key, decoded);
833 }
834}
835
836#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
837#[key(tag = RowShape)]
838pub struct RowShapeKey {
839 pub fingerprint: RowShapeFingerprint,
840}
841
842impl RowShapeKey {
843 pub fn new(fingerprint: RowShapeFingerprint) -> Self {
844 Self {
845 fingerprint,
846 }
847 }
848
849 pub fn encoded(fingerprint: RowShapeFingerprint) -> EncodedKey {
850 Self {
851 fingerprint,
852 }
853 .encode()
854 }
855
856 pub fn full_scan() -> TaggedKeyBoundRange {
857 TaggedKeyBoundRange::kind(Self::TAG)
858 }
859}
860
861#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
862#[key(tag = RowShapeField)]
863pub struct RowShapeFieldKey {
864 pub shape_fingerprint: RowShapeFingerprint,
865 pub field_index: u16,
866}
867
868impl RowShapeFieldKey {
869 pub fn new(shape_fingerprint: RowShapeFingerprint, field_index: u16) -> Self {
870 Self {
871 shape_fingerprint,
872 field_index,
873 }
874 }
875
876 pub fn encoded(shape_fingerprint: RowShapeFingerprint, field_index: u16) -> EncodedKey {
877 Self::new(shape_fingerprint, field_index).encode()
878 }
879
880 pub fn scan_for_shape(fingerprint: RowShapeFingerprint) -> TaggedKeyBoundRange {
881 TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, fingerprint.as_u64() as u128)])
882 }
883}
884
885#[cfg(test)]
886mod row_shape_key_tests {
887 use super::*;
888
889 #[test]
890 fn test_shape_key_encode_decode() {
891 let key = RowShapeKey {
892 fingerprint: RowShapeFingerprint::new(0xDEADBEEFCAFEBABE),
893 };
894 let encoded = key.encode();
895 let decoded = RowShapeKey::decode(&encoded).unwrap();
896 assert_eq!(decoded.fingerprint, RowShapeFingerprint::new(0xDEADBEEFCAFEBABE));
897 }
898
899 #[test]
900 fn test_shape_field_key_encode_decode() {
901 let key = RowShapeFieldKey {
902 shape_fingerprint: RowShapeFingerprint::new(0x1234567890ABCDEF),
903 field_index: 42,
904 };
905 let encoded = key.encode();
906 let decoded = RowShapeFieldKey::decode(&encoded).unwrap();
907 assert_eq!(decoded.shape_fingerprint, RowShapeFingerprint::new(0x1234567890ABCDEF));
908 assert_eq!(decoded.field_index, 42);
909 }
910}
911
912#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
913#[key(tag = PartitionedRow)]
914pub struct PartitionedRowKey {
915 pub storage: StorageId,
916 pub partition: Partition,
917 pub row: RowNumber,
918}
919
920impl PartitionedRowKey {
921 pub fn new(storage: impl Into<StorageId>, partition: Partition, row: RowNumber) -> Self {
922 Self {
923 storage: storage.into(),
924 partition,
925 row,
926 }
927 }
928
929 pub fn encoded(storage: impl Into<StorageId>, partition: Partition, row: RowNumber) -> EncodedKey {
930 Self::new(storage, partition, row).encode()
931 }
932
933 pub fn storage_start(storage: impl Into<StorageId>) -> EncodedKey {
934 let mut serializer = KeySerializer::with_capacity(10);
935 serializer.extend_u8(PartitionedRowKey::TAG as u8).extend_object_id(storage.into());
936 serializer.to_encoded_key()
937 }
938
939 pub fn storage_end(storage: impl Into<StorageId>) -> EncodedKey {
940 let mut serializer = KeySerializer::with_capacity(10);
941 serializer
942 .extend_u8(PartitionedRowKey::TAG as u8)
943 .extend_object_id(ObjectId::from(storage.into()).prev());
944 serializer.to_encoded_key()
945 }
946
947 pub fn storage_of(key: &EncodedKey) -> Option<StorageId> {
948 let mut de = KeyDeserializer::from_bytes(key.as_slice());
949 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
950 if kind != Self::TAG {
951 return None;
952 }
953 StorageId::from_object(de.read_object_id().ok()?)
954 }
955
956 pub fn full_scan(storage: impl Into<StorageId>) -> TaggedKeyBoundRange {
957 TaggedKeyBoundRange::prefix(Self::TAG, object_fields(ObjectId::from(storage.into())))
958 }
959
960 pub fn scan_range(storage: impl Into<StorageId>, last: Option<&TaggedKey>) -> TaggedKeyBoundRange {
961 Self::full_scan(storage).resume_after(last)
962 }
963
964 pub fn partition_range(storage: impl Into<StorageId>, partition: Partition) -> TaggedKeyBoundRange {
965 TaggedKeyBoundRange::prefix(
966 Self::TAG,
967 object_fields(ObjectId::from(storage.into()))
968 .into_iter()
969 .chain([Field::UDesc(Width::U128, partition.0)])
970 .collect::<Vec<_>>(),
971 )
972 }
973
974 pub fn partition_scan_range(
975 storage: impl Into<StorageId>,
976 partition: Partition,
977 last: Option<&TaggedKey>,
978 ) -> TaggedKeyBoundRange {
979 Self::partition_range(storage, partition).resume_after(last)
980 }
981}
982
983#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
984pub struct StoragePartitionedRowKey {
985 pub partition: Desc<Partition>,
986 pub row: Desc<RowNumber>,
987}
988
989impl StoragePartitionedRowKey {
990 pub fn new(partition: Partition, row: RowNumber) -> Self {
991 Self {
992 partition: Desc(partition),
993 row: Desc(row),
994 }
995 }
996
997 pub fn partition(self) -> Partition {
998 self.partition.0
999 }
1000
1001 pub fn row(self) -> RowNumber {
1002 self.row.0
1003 }
1004
1005 pub fn partition_hi(self) -> u64 {
1006 (self.partition().0 >> 64) as u64
1007 }
1008
1009 pub fn partition_lo(self) -> u64 {
1010 self.partition().0 as u64
1011 }
1012
1013 pub fn from_halves(partition_hi: u64, partition_lo: u64, row: RowNumber) -> Self {
1014 Self::new(Partition(((partition_hi as u128) << 64) | partition_lo as u128), row)
1015 }
1016
1017 pub fn with_storage(self, storage: StorageId) -> PartitionedRowKey {
1018 PartitionedRowKey {
1019 storage,
1020 partition: self.partition(),
1021 row: self.row(),
1022 }
1023 }
1024}
1025
1026impl From<PartitionedRowKey> for StoragePartitionedRowKey {
1027 fn from(key: PartitionedRowKey) -> Self {
1028 StoragePartitionedRowKey::new(key.partition, key.row)
1029 }
1030}
1031
1032impl HeapSize for StoragePartitionedRowKey {
1033 fn heap_size(&self) -> usize {
1034 0
1035 }
1036}
1037
1038impl BoundedKey for StoragePartitionedRowKey {
1039 fn low() -> Self {
1040 Self {
1041 partition: <Desc<Partition> as BoundedKey>::low(),
1042 row: <Desc<RowNumber> as BoundedKey>::low(),
1043 }
1044 }
1045}
1046
1047impl DenseKey for StoragePartitionedRowKey {
1048 fn successor(&self) -> Option<Self> {
1049 if let Some(row) = self.row.successor() {
1050 return Some(Self {
1051 partition: self.partition,
1052 row,
1053 });
1054 }
1055 Some(Self {
1056 partition: self.partition.successor()?,
1057 row: <Desc<RowNumber> as BoundedKey>::low(),
1058 })
1059 }
1060}
1061
1062#[derive(Debug, Clone, PartialEq)]
1063pub struct PartitionedRowKeyRange {
1064 pub storage: StorageId,
1065}
1066
1067impl PartitionedRowKeyRange {
1068 fn decode_key(key: &EncodedKey) -> Option<Self> {
1069 let mut de = KeyDeserializer::from_bytes(key.as_slice());
1070
1071 let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
1072 if kind != Self::TAG {
1073 return None;
1074 }
1075
1076 let storage = StorageId::from_object(de.read_object_id().ok()?)?;
1077
1078 Some(PartitionedRowKeyRange {
1079 storage,
1080 })
1081 }
1082}
1083
1084impl KeyRangeCodec for PartitionedRowKeyRange {
1085 const TAG: KeyTag = KeyTag::PartitionedRow;
1086
1087 fn start(&self) -> Option<EncodedKey> {
1088 let mut serializer = KeySerializer::with_capacity(10);
1089 serializer.extend_u8(Self::TAG as u8).extend_object_id(self.storage);
1090 Some(serializer.to_encoded_key())
1091 }
1092
1093 fn end(&self) -> Option<EncodedKey> {
1094 let mut serializer = KeySerializer::with_capacity(10);
1095 serializer.extend_u8(Self::TAG as u8).extend_object_id(ObjectId::from(self.storage).prev());
1096 Some(serializer.to_encoded_key())
1097 }
1098
1099 fn decode(range: &EncodedKeyRange) -> (Option<Self>, Option<Self>)
1100 where
1101 Self: Sized,
1102 {
1103 let start_key = match &range.start {
1104 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
1105 Bound::Unbounded => None,
1106 };
1107
1108 let end_key = match &range.end {
1109 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
1110 Bound::Unbounded => None,
1111 };
1112
1113 (start_key, end_key)
1114 }
1115}
1116
1117#[cfg(test)]
1118mod partitioned_row_key_tests {
1119 use std::ops::RangeBounds;
1120
1121 use reifydb_codec::key::{encoded::EncodedKey, serializer::KeySerializer};
1122 use reifydb_value::value::{Value, partition::Partition, row_number::RowNumber};
1123
1124 use super::{PartitionedRowKey, RowKey, StoragePartitionedRowKey};
1125 use crate::{
1126 interface::catalog::{
1127 id::{TableId, ViewId},
1128 object::ObjectId,
1129 storage::StorageId,
1130 },
1131 key::{
1132 catalog::KeySerializerCatalogExt,
1133 typed::{BoundedKey, DenseKey},
1134 },
1135 };
1136
1137 fn part(v: &str) -> Partition {
1138 Partition::of(&[Value::Utf8(v.to_string())])
1139 }
1140
1141 #[test]
1142 fn test_table_roundtrip() {
1143 let key = PartitionedRowKey {
1144 storage: StorageId::Table(TableId(7)),
1145 partition: part("us"),
1146 row: RowNumber(42),
1147 };
1148 let decoded = PartitionedRowKey::decode(&key.encode()).unwrap();
1149 assert_eq!(decoded, key);
1150 }
1151
1152 #[test]
1153 fn test_view_roundtrip() {
1154 let key = PartitionedRowKey {
1156 storage: StorageId::View(ViewId(11)),
1157 partition: part("us"),
1158 row: RowNumber(42),
1159 };
1160 let decoded = PartitionedRowKey::decode(&key.encode()).unwrap();
1161 assert_eq!(decoded, key);
1162 }
1163
1164 #[test]
1165 fn test_storage_of() {
1166 let key = PartitionedRowKey::encoded(StorageId::Table(TableId(42)), part("us"), RowNumber(1));
1167 assert_eq!(PartitionedRowKey::storage_of(&key), Some(StorageId::Table(TableId(42))));
1168 }
1169
1170 #[test]
1171 fn test_storage_of_rejects_a_rowless_object() {
1172 let mut serializer = KeySerializer::with_capacity(10);
1174 serializer.extend_u8(PartitionedRowKey::TAG as u8).extend_object_id(ObjectId::vtable(42));
1175 assert_eq!(PartitionedRowKey::storage_of(&serializer.to_encoded_key()), None);
1176 }
1177
1178 #[test]
1179 fn test_partition_rows_cluster_together() {
1180 let storage = StorageId::Table(TableId(1));
1181 let us_a = PartitionedRowKey::encoded(storage, part("us"), RowNumber(1));
1182 let us_b = PartitionedRowKey::encoded(storage, part("us"), RowNumber(2));
1183 let eu = PartitionedRowKey::encoded(storage, part("eu"), RowNumber(1));
1184
1185 let mut keys = [us_a.clone(), us_b.clone(), eu.clone()];
1186 keys.sort();
1187 let us_positions: Vec<usize> =
1188 keys.iter().enumerate().filter(|(_, k)| **k == us_a || **k == us_b).map(|(i, _)| i).collect();
1189 assert_eq!(us_positions[1] - us_positions[0], 1, "us partition rows must be contiguous");
1190 }
1191
1192 #[test]
1193 fn test_partition_range_contains_only_its_partition() {
1194 let storage = StorageId::Table(TableId(1));
1195 let range = PartitionedRowKey::partition_range(storage, part("us")).encode();
1196 let us = PartitionedRowKey::encoded(storage, part("us"), RowNumber(500));
1197 let eu = PartitionedRowKey::encoded(storage, part("eu"), RowNumber(1));
1198 assert!(range.contains(&us), "us row must be inside the us partition range");
1199 assert!(!range.contains(&eu), "eu row must be outside the us partition range");
1200 }
1201
1202 #[test]
1203 fn test_partitioned_row_ident_roundtrip() {
1204 let key = PartitionedRowKey {
1205 storage: StorageId::Table(TableId(7)),
1206 partition: part("us"),
1207 row: RowNumber(42),
1208 };
1209
1210 let ident: StoragePartitionedRowKey = key.clone().into();
1212 let restored = ident.with_storage(key.storage);
1213 assert_eq!(restored, key);
1214 }
1215
1216 #[test]
1217 fn test_partitioned_row_ident_halves_split_correctly() {
1218 let partition = Partition(0x1122334455667788_99AABBCCDDEEFF00);
1219 let ident = StoragePartitionedRowKey::new(partition, RowNumber(1));
1220
1221 assert_eq!(ident.partition_hi(), 0x1122334455667788);
1223 assert_eq!(ident.partition_lo(), 0x99AABBCCDDEEFF00);
1224 assert_eq!(ident.partition(), partition);
1225 assert_eq!(
1226 StoragePartitionedRowKey::from_halves(ident.partition_hi(), ident.partition_lo(), RowNumber(1)),
1227 ident
1228 );
1229 }
1230
1231 #[test]
1232 fn test_partitioned_row_ident_ordering_matches_field_order() {
1233 let lower_partition = StoragePartitionedRowKey::new(Partition(1), RowNumber(999));
1234 let higher_partition = StoragePartitionedRowKey::new(Partition(2), RowNumber(1));
1235 let same_partition_lower_row = StoragePartitionedRowKey::new(Partition(2), RowNumber(1));
1236 let same_partition_higher_row = StoragePartitionedRowKey::new(Partition(2), RowNumber(2));
1237
1238 assert!(higher_partition < lower_partition);
1241 assert!(same_partition_higher_row < same_partition_lower_row);
1242 }
1243
1244 #[test]
1245 fn test_partitioned_row_ident_successor_carries_into_the_partition() {
1246 let last_row = StoragePartitionedRowKey::new(Partition(5), RowNumber(0));
1249 let next = last_row.successor().unwrap();
1250
1251 assert_eq!(next, StoragePartitionedRowKey::new(Partition(4), RowNumber(u64::MAX)));
1252 assert!(next > last_row);
1253 }
1254
1255 #[test]
1256 fn test_partitioned_row_ident_low_is_the_greatest_partition_and_row() {
1257 assert_eq!(
1258 <StoragePartitionedRowKey as BoundedKey>::low(),
1259 StoragePartitionedRowKey::new(Partition(u128::MAX), RowNumber(u64::MAX))
1260 );
1261 }
1262
1263 #[test]
1264 fn test_decode_rejects_trailing_bytes() {
1265 let exact = RowKey::encoded(StorageId::table(7), RowNumber(42));
1269 assert_eq!(exact.as_slice().len(), 18);
1270 assert_eq!(
1271 RowKey::decode(&exact),
1272 Some(RowKey {
1273 storage: StorageId::table(7),
1274 row: RowNumber(42)
1275 })
1276 );
1277
1278 let mut longer = exact.as_slice().to_vec();
1279 longer.push(0x00);
1280 assert_eq!(RowKey::decode(&EncodedKey::new(longer)), None);
1281 }
1282
1283 #[test]
1284 fn test_decode_rejects_a_longer_key_that_shares_the_kind_byte() {
1285 let mut sorted_view = RowKey::encoded(StorageId::view(3), RowNumber(1)).as_slice().to_vec();
1289 sorted_view.extend_from_slice(&[0xAA; 8]);
1290 sorted_view.extend_from_slice(&99u64.to_be_bytes());
1291
1292 assert_eq!(RowKey::decode(&EncodedKey::new(sorted_view)), None);
1293 }
1294}
1295
1296#[cfg(test)]
1297mod sorted_view_run_tests {
1298 use reifydb_codec::key::encoded::EncodedKey;
1299 use reifydb_value::value::{partition::Partition, row_number::RowNumber};
1300
1301 use super::{PartitionedSortedViewRowKey, SortRun, SortedViewRowKey};
1302 use crate::interface::catalog::storage::StorageId;
1303
1304 fn run(bytes: &[u8]) -> SortRun {
1305 SortRun::new(bytes)
1306 }
1307
1308 #[test]
1309 fn test_a_run_round_trips_through_the_terminator() {
1310 let key = SortedViewRowKey::new(StorageId::view(3), run(&[0x10, 0x00, 0xff, 0x00]), RowNumber(42));
1313 let decoded = SortedViewRowKey::decode(&key.encode()).unwrap();
1314 assert_eq!(decoded, key);
1315 assert_eq!(decoded.run.as_slice(), &[0x10, 0x00, 0xff, 0x00]);
1316 }
1317
1318 #[test]
1319 fn test_an_empty_run_round_trips() {
1320 let key = SortedViewRowKey::new(StorageId::view(3), run(&[]), RowNumber(1));
1321 assert_eq!(SortedViewRowKey::decode(&key.encode()), Some(key));
1322 }
1323
1324 #[test]
1325 fn test_a_partitioned_run_round_trips() {
1326 let key = PartitionedSortedViewRowKey::new(
1327 StorageId::view(3),
1328 Partition(0x1122334455667788_99AABBCCDDEEFF00),
1329 run(&[0x00, 0x00, 0x01]),
1330 RowNumber(7),
1331 );
1332 assert_eq!(PartitionedSortedViewRowKey::decode(&key.encode()), Some(key));
1333 }
1334
1335 #[test]
1336 fn test_decode_refuses_the_other_kind_and_trailing_bytes() {
1337 let partitioned = PartitionedSortedViewRowKey::encoded(
1339 StorageId::view(3),
1340 Partition(1),
1341 run(&[0x10]),
1342 RowNumber(1),
1343 );
1344 assert_eq!(SortedViewRowKey::decode(&partitioned), None);
1345
1346 let mut longer = SortedViewRowKey::encoded(StorageId::view(3), run(&[0x10]), RowNumber(1)).to_vec();
1347 longer.push(0x00);
1348 assert_eq!(SortedViewRowKey::decode(&EncodedKey::new(longer)), None);
1349 }
1350
1351 #[test]
1352 fn test_ord_matches_the_encoded_byte_order() {
1353 let mut keys = vec![
1356 SortedViewRowKey::new(StorageId::table(3), run(&[0x10]), RowNumber(1)),
1357 SortedViewRowKey::new(StorageId::view(3), run(&[0x10]), RowNumber(1)),
1358 SortedViewRowKey::new(StorageId::view(4), run(&[0x10]), RowNumber(1)),
1359 SortedViewRowKey::new(StorageId::view(3), run(&[0x10]), RowNumber(2)),
1360 SortedViewRowKey::new(StorageId::view(3), run(&[0x10, 0x00]), RowNumber(0)),
1361 SortedViewRowKey::new(StorageId::view(3), run(&[0x10, 0x01]), RowNumber(0)),
1362 SortedViewRowKey::new(StorageId::view(3), run(&[0x00]), RowNumber(0)),
1363 SortedViewRowKey::new(StorageId::view(3), run(&[]), RowNumber(u64::MAX)),
1364 ];
1365 keys.sort();
1366
1367 let encoded: Vec<EncodedKey> = keys.iter().map(|key| key.encode()).collect();
1368 let mut sorted_bytes = encoded.clone();
1369 sorted_bytes.sort();
1370 assert_eq!(encoded, sorted_bytes);
1371 }
1372
1373 #[test]
1374 fn test_partitioned_ord_matches_the_encoded_byte_order() {
1375 let mut keys = vec![
1376 PartitionedSortedViewRowKey::new(StorageId::view(3), Partition(1), run(&[0x10]), RowNumber(1)),
1377 PartitionedSortedViewRowKey::new(StorageId::view(3), Partition(2), run(&[0x10]), RowNumber(1)),
1378 PartitionedSortedViewRowKey::new(StorageId::view(3), Partition(2), run(&[0x00]), RowNumber(1)),
1379 PartitionedSortedViewRowKey::new(StorageId::view(3), Partition(2), run(&[0x10]), RowNumber(0)),
1380 PartitionedSortedViewRowKey::new(StorageId::view(4), Partition(2), run(&[0x10]), RowNumber(0)),
1381 ];
1382 keys.sort();
1383
1384 let encoded: Vec<EncodedKey> = keys.iter().map(|key| key.encode()).collect();
1385 let mut sorted_bytes = encoded.clone();
1386 sorted_bytes.sort();
1387 assert_eq!(encoded, sorted_bytes);
1388 }
1389
1390 #[test]
1391 fn test_a_shorter_run_sorts_before_the_run_that_extends_it() {
1392 let short = SortedViewRowKey::new(StorageId::view(3), run(&[0x10]), RowNumber(u64::MAX));
1395 let long = SortedViewRowKey::new(StorageId::view(3), run(&[0x10, 0x00]), RowNumber(0));
1396
1397 assert!(short < long);
1398 assert!(short.encode() < long.encode());
1399 }
1400
1401 #[test]
1402 fn test_the_helpers_still_read_the_new_layout() {
1403 let storage = StorageId::view(3);
1404 let key = SortedViewRowKey::encoded(storage, run(&[0x00, 0xAA]), RowNumber(9));
1405 assert_eq!(SortedViewRowKey::storage_of(&key), Some(storage));
1406 assert_eq!(SortedViewRowKey::row_of(&key), Some(RowNumber(9)));
1407
1408 let partitioned =
1409 PartitionedSortedViewRowKey::encoded(storage, Partition(5), run(&[0x00, 0xAA]), RowNumber(9));
1410 assert_eq!(PartitionedSortedViewRowKey::storage_of(&partitioned), Some(storage));
1411 assert_eq!(PartitionedSortedViewRowKey::row_of(&partitioned), Some(RowNumber(9)));
1412 assert_eq!(SortedViewRowKey::row_of(&partitioned), None);
1413 }
1414}
1415
1416impl KeyFields for SortedViewRowKey {
1417 fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
1418 smallvec![
1419 Field::UAsc(Width::U8, ObjectId::from(self.storage).type_tag() as u128),
1420 Field::UDesc(Width::U64, ObjectId::from(self.storage).as_u64() as u128),
1421 Field::RawAsc(RawEncoding::SortRun, Cow::Borrowed(self.run.as_slice())),
1422 Field::UAsc(Width::U64, self.row.0.0 as u128),
1423 ]
1424 }
1425}
1426
1427impl KeyFields for PartitionedSortedViewRowKey {
1428 fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
1429 smallvec![
1430 Field::UAsc(Width::U8, ObjectId::from(self.storage).type_tag() as u128),
1431 Field::UDesc(Width::U64, ObjectId::from(self.storage).as_u64() as u128),
1432 Field::UDesc(Width::U128, self.partition.0),
1433 Field::RawAsc(RawEncoding::SortRun, Cow::Borrowed(self.run.as_slice())),
1434 Field::UAsc(Width::U64, self.row.0.0 as u128),
1435 ]
1436 }
1437}