1use std::collections::Bound;
5
6use reifydb_codec::key::{
7 deserializer::KeyDeserializer,
8 encoded::{EncodedKey, EncodedKeyRange},
9 serializer::KeySerializer,
10};
11use reifydb_value::value::row_number::RowNumber;
12
13use super::{EncodableKey, EncodableKeyRange, KeyKind};
14use crate::{
15 interface::catalog::shape::ShapeId,
16 key::catalog::{KeyDeserializerCatalogExt, KeySerializerCatalogExt},
17};
18
19#[derive(Debug, Clone, PartialEq)]
20pub struct RowKey {
21 pub shape: ShapeId,
22 pub row: RowNumber,
23}
24
25impl EncodableKey for RowKey {
26 const KIND: KeyKind = KeyKind::Row;
27
28 fn encode(&self) -> EncodedKey {
29 let mut serializer = KeySerializer::with_capacity(18);
30 serializer.extend_u8(Self::KIND as u8).extend_shape_id(self.shape).extend_u64(self.row.0);
31 serializer.to_encoded_key()
32 }
33
34 fn decode(key: &EncodedKey) -> Option<Self> {
35 let mut de = KeyDeserializer::from_bytes(key.as_slice());
36
37 let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
38 if kind != Self::KIND {
39 return None;
40 }
41
42 let shape = de.read_shape_id().ok()?;
43 let row = de.read_row_number().ok()?;
44
45 Some(Self {
46 shape,
47 row,
48 })
49 }
50}
51
52#[derive(Debug, Clone, PartialEq)]
53pub struct RowKeyRange {
54 pub shape: ShapeId,
55}
56
57impl RowKeyRange {
58 fn decode_key(key: &EncodedKey) -> Option<Self> {
59 let mut de = KeyDeserializer::from_bytes(key.as_slice());
60
61 let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
62 if kind != Self::KIND {
63 return None;
64 }
65
66 let shape = de.read_shape_id().ok()?;
67
68 Some(RowKeyRange {
69 shape,
70 })
71 }
72
73 pub fn scan_range(shape: ShapeId, last_key: Option<&EncodedKey>) -> EncodedKeyRange {
74 let range = RowKeyRange {
75 shape,
76 };
77
78 if let Some(last_key) = last_key {
79 EncodedKeyRange::new(Bound::Excluded(last_key.clone()), Bound::Included(range.end().unwrap()))
80 } else {
81 EncodedKeyRange::new(
82 Bound::Included(range.start().unwrap()),
83 Bound::Included(range.end().unwrap()),
84 )
85 }
86 }
87}
88
89impl EncodableKeyRange for RowKeyRange {
90 const KIND: KeyKind = KeyKind::Row;
91
92 fn start(&self) -> Option<EncodedKey> {
93 let mut serializer = KeySerializer::with_capacity(10);
94 serializer.extend_u8(Self::KIND as u8).extend_shape_id(self.shape);
95 Some(serializer.to_encoded_key())
96 }
97
98 fn end(&self) -> Option<EncodedKey> {
99 let mut serializer = KeySerializer::with_capacity(10);
100 serializer.extend_u8(Self::KIND as u8).extend_shape_id(self.shape.prev());
101 Some(serializer.to_encoded_key())
102 }
103
104 fn decode(range: &EncodedKeyRange) -> (Option<Self>, Option<Self>)
105 where
106 Self: Sized,
107 {
108 let start_key = match &range.start {
109 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
110 Bound::Unbounded => None,
111 };
112
113 let end_key = match &range.end {
114 Bound::Included(key) | Bound::Excluded(key) => Self::decode_key(key),
115 Bound::Unbounded => None,
116 };
117
118 (start_key, end_key)
119 }
120}
121
122impl RowKey {
123 pub fn encoded(shape: impl Into<ShapeId>, row: impl Into<RowNumber>) -> EncodedKey {
124 Self {
125 shape: shape.into(),
126 row: row.into(),
127 }
128 .encode()
129 }
130
131 pub fn full_scan(shape: impl Into<ShapeId>) -> EncodedKeyRange {
132 let shape = shape.into();
133 EncodedKeyRange::start_end(Some(Self::shape_start(shape)), Some(Self::shape_end(shape)))
134 }
135
136 pub fn shape_start(shape: impl Into<ShapeId>) -> EncodedKey {
137 let shape = shape.into();
138 let mut serializer = KeySerializer::with_capacity(10);
139 serializer.extend_u8(Self::KIND as u8).extend_shape_id(shape);
140 serializer.to_encoded_key()
141 }
142
143 pub fn shape_end(shape: impl Into<ShapeId>) -> EncodedKey {
144 let shape = shape.into();
145 let mut serializer = KeySerializer::with_capacity(10);
146 serializer.extend_u8(Self::KIND as u8).extend_shape_id(shape.prev());
147 serializer.to_encoded_key()
148 }
149}
150
151#[cfg(test)]
152pub mod tests {
153 use reifydb_value::value::row_number::RowNumber;
154
155 use super::{EncodableKey, RowKey};
156 use crate::interface::catalog::shape::ShapeId;
157
158 #[test]
159 fn test_encode_decode() {
160 let key = RowKey {
161 shape: ShapeId::table(0xABCD),
162 row: RowNumber(0x123456789ABCDEF0),
163 };
164 let encoded = key.encode();
165
166 let expected: Vec<u8> =
167 vec![0xFC, 0x01, 0x3F, 0x54, 0x32, 0x00, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43, 0x21, 0x0F];
168
169 assert_eq!(encoded.as_slice(), expected);
170
171 let key = RowKey::decode(&encoded).unwrap();
172 assert_eq!(key.shape, ShapeId::table(0xABCD));
173 assert_eq!(key.row, 0x123456789ABCDEF0);
174 }
175
176 #[test]
177 fn test_order_preserving() {
178 let key1 = RowKey {
179 shape: ShapeId::table(1),
180 row: RowNumber(100),
181 };
182 let key2 = RowKey {
183 shape: ShapeId::table(1),
184 row: RowNumber(200),
185 };
186 let key3 = RowKey {
187 shape: ShapeId::table(2),
188 row: RowNumber(1),
189 };
190
191 let encoded1 = key1.encode();
192 let encoded2 = key2.encode();
193 let encoded3 = key3.encode();
194
195 assert!(encoded3 < encoded2, "ordering not preserved");
196 assert!(encoded2 < encoded1, "ordering not preserved");
197 }
198}