Skip to main content

reifydb_core/key/
row.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use 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::{object::ObjectId, storage::StorageId},
16	key::catalog::{KeyDeserializerCatalogExt, KeySerializerCatalogExt},
17};
18
19#[derive(Debug, Clone, PartialEq)]
20pub struct RowKey {
21	pub storage: StorageId,
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_object_id(self.storage).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 storage = StorageId::from_object(de.read_object_id().ok()?)?;
43		let row = de.read_row_number().ok()?;
44
45		Some(Self {
46			storage,
47			row,
48		})
49	}
50}
51
52#[derive(Debug, Clone, PartialEq)]
53pub struct RowKeyRange {
54	pub storage: StorageId,
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 storage = StorageId::from_object(de.read_object_id().ok()?)?;
67
68		Some(RowKeyRange {
69			storage,
70		})
71	}
72
73	pub fn scan_range(storage: StorageId, last_key: Option<&EncodedKey>) -> EncodedKeyRange {
74		let range = RowKeyRange {
75			storage,
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_object_id(self.storage);
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_object_id(ObjectId::from(self.storage).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(storage: impl Into<StorageId>, row: impl Into<RowNumber>) -> EncodedKey {
124		Self {
125			storage: storage.into(),
126			row: row.into(),
127		}
128		.encode()
129	}
130
131	pub fn full_scan(storage: impl Into<StorageId>) -> EncodedKeyRange {
132		let storage = storage.into();
133		EncodedKeyRange::start_end(Some(Self::storage_start(storage)), Some(Self::storage_end(storage)))
134	}
135
136	pub fn storage_start(storage: impl Into<StorageId>) -> EncodedKey {
137		let mut serializer = KeySerializer::with_capacity(10);
138		serializer.extend_u8(Self::KIND as u8).extend_object_id(storage.into());
139		serializer.to_encoded_key()
140	}
141
142	pub fn storage_end(storage: impl Into<StorageId>) -> EncodedKey {
143		let mut serializer = KeySerializer::with_capacity(10);
144		serializer.extend_u8(Self::KIND as u8).extend_object_id(ObjectId::from(storage.into()).prev());
145		serializer.to_encoded_key()
146	}
147}
148
149#[cfg(test)]
150pub mod tests {
151	use reifydb_value::value::row_number::RowNumber;
152
153	use super::{EncodableKey, RowKey};
154	use crate::interface::catalog::storage::StorageId;
155
156	#[test]
157	fn test_encode_decode() {
158		let key = RowKey {
159			storage: StorageId::table(0xABCD),
160			row: RowNumber(0x123456789ABCDEF0),
161		};
162		let encoded = key.encode();
163
164		let expected: Vec<u8> = vec![
165			0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43,
166			0x21, 0x0F,
167		];
168
169		assert_eq!(encoded.as_slice(), expected);
170
171		let key = RowKey::decode(&encoded).unwrap();
172		assert_eq!(key.storage, StorageId::table(0xABCD));
173		assert_eq!(key.row, 0x123456789ABCDEF0);
174	}
175
176	#[test]
177	fn test_order_preserving() {
178		let key1 = RowKey {
179			storage: StorageId::table(1),
180			row: RowNumber(100),
181		};
182		let key2 = RowKey {
183			storage: StorageId::table(1),
184			row: RowNumber(200),
185		};
186		let key3 = RowKey {
187			storage: StorageId::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}