Skip to main content

reifydb_core/key/
column_snapshot.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use reifydb_codec::key::{
5	deserializer::KeyDeserializer,
6	encoded::{EncodedKey, EncodedKeyRange},
7	serializer::KeySerializer,
8};
9
10use super::{EncodableKey, KeyKind};
11use crate::interface::catalog::id::{ColumnSnapshotId, SeriesId, TableId};
12
13const VERSION: u8 = 1;
14
15#[derive(Debug, Clone, PartialEq)]
16pub struct ColumnSnapshotKey {
17	pub snapshot: ColumnSnapshotId,
18}
19
20impl ColumnSnapshotKey {
21	pub fn new(snapshot: ColumnSnapshotId) -> Self {
22		Self {
23			snapshot,
24		}
25	}
26
27	pub fn encoded(snapshot: impl Into<ColumnSnapshotId>) -> EncodedKey {
28		Self::new(snapshot.into()).encode()
29	}
30
31	pub fn full_scan() -> EncodedKeyRange {
32		EncodedKeyRange::start_end(Some(Self::scan_start()), Some(Self::scan_end()))
33	}
34
35	fn scan_start() -> EncodedKey {
36		let mut serializer = KeySerializer::with_capacity(2);
37		serializer.extend_u8(VERSION);
38		serializer.extend_u8(Self::KIND as u8);
39		serializer.to_encoded_key()
40	}
41
42	fn scan_end() -> EncodedKey {
43		let mut serializer = KeySerializer::with_capacity(2);
44		serializer.extend_u8(VERSION).extend_u8(Self::KIND as u8 - 1);
45		serializer.to_encoded_key()
46	}
47}
48
49impl EncodableKey for ColumnSnapshotKey {
50	const KIND: KeyKind = KeyKind::ColumnSnapshot;
51
52	fn encode(&self) -> EncodedKey {
53		let mut serializer = KeySerializer::with_capacity(10);
54		serializer.extend_u8(VERSION).extend_u8(Self::KIND as u8).extend_u64(self.snapshot);
55		serializer.to_encoded_key()
56	}
57
58	fn decode(key: &EncodedKey) -> Option<Self> {
59		let mut de = KeyDeserializer::from_bytes(key.as_slice());
60
61		let version = de.read_u8().ok()?;
62		if version != VERSION {
63			return None;
64		}
65
66		let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
67		if kind != Self::KIND {
68			return None;
69		}
70
71		let snapshot = de.read_u64().ok()?;
72
73		Some(Self {
74			snapshot: ColumnSnapshotId(snapshot),
75		})
76	}
77}
78
79#[derive(Debug, Clone, PartialEq)]
80pub struct SeriesColumnSnapshotKey {
81	pub series: SeriesId,
82	pub snapshot: ColumnSnapshotId,
83}
84
85impl SeriesColumnSnapshotKey {
86	pub fn new(series: SeriesId, snapshot: ColumnSnapshotId) -> Self {
87		Self {
88			series,
89			snapshot,
90		}
91	}
92
93	pub fn encoded(series: impl Into<SeriesId>, snapshot: impl Into<ColumnSnapshotId>) -> EncodedKey {
94		Self::new(series.into(), snapshot.into()).encode()
95	}
96
97	pub fn full_scan(series: SeriesId) -> EncodedKeyRange {
98		EncodedKeyRange::start_end(Some(Self::link_start(series)), Some(Self::link_end(series)))
99	}
100
101	fn link_start(series: SeriesId) -> EncodedKey {
102		let mut serializer = KeySerializer::with_capacity(10);
103		serializer.extend_u8(VERSION).extend_u8(Self::KIND as u8).extend_u64(series);
104		serializer.to_encoded_key()
105	}
106
107	fn link_end(series: SeriesId) -> EncodedKey {
108		let mut serializer = KeySerializer::with_capacity(10);
109		serializer.extend_u8(VERSION).extend_u8(Self::KIND as u8).extend_u64(*series - 1);
110		serializer.to_encoded_key()
111	}
112}
113
114impl EncodableKey for SeriesColumnSnapshotKey {
115	const KIND: KeyKind = KeyKind::SeriesColumnSnapshot;
116
117	fn encode(&self) -> EncodedKey {
118		let mut serializer = KeySerializer::with_capacity(18);
119		serializer
120			.extend_u8(VERSION)
121			.extend_u8(Self::KIND as u8)
122			.extend_u64(self.series)
123			.extend_u64(self.snapshot);
124		serializer.to_encoded_key()
125	}
126
127	fn decode(key: &EncodedKey) -> Option<Self> {
128		let mut de = KeyDeserializer::from_bytes(key.as_slice());
129
130		let version = de.read_u8().ok()?;
131		if version != VERSION {
132			return None;
133		}
134
135		let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
136		if kind != Self::KIND {
137			return None;
138		}
139
140		let series = de.read_u64().ok()?;
141		let snapshot = de.read_u64().ok()?;
142
143		Some(Self {
144			series: SeriesId(series),
145			snapshot: ColumnSnapshotId(snapshot),
146		})
147	}
148}
149
150#[derive(Debug, Clone, PartialEq)]
151pub struct TableColumnSnapshotKey {
152	pub table: TableId,
153	pub snapshot: ColumnSnapshotId,
154}
155
156impl TableColumnSnapshotKey {
157	pub fn new(table: TableId, snapshot: ColumnSnapshotId) -> Self {
158		Self {
159			table,
160			snapshot,
161		}
162	}
163
164	pub fn encoded(table: impl Into<TableId>, snapshot: impl Into<ColumnSnapshotId>) -> EncodedKey {
165		Self::new(table.into(), snapshot.into()).encode()
166	}
167
168	pub fn full_scan(table: TableId) -> EncodedKeyRange {
169		EncodedKeyRange::start_end(Some(Self::link_start(table)), Some(Self::link_end(table)))
170	}
171
172	fn link_start(table: TableId) -> EncodedKey {
173		let mut serializer = KeySerializer::with_capacity(10);
174		serializer.extend_u8(VERSION).extend_u8(Self::KIND as u8).extend_u64(table);
175		serializer.to_encoded_key()
176	}
177
178	fn link_end(table: TableId) -> EncodedKey {
179		let mut serializer = KeySerializer::with_capacity(10);
180		serializer.extend_u8(VERSION).extend_u8(Self::KIND as u8).extend_u64(*table - 1);
181		serializer.to_encoded_key()
182	}
183}
184
185impl EncodableKey for TableColumnSnapshotKey {
186	const KIND: KeyKind = KeyKind::TableColumnSnapshot;
187
188	fn encode(&self) -> EncodedKey {
189		let mut serializer = KeySerializer::with_capacity(18);
190		serializer
191			.extend_u8(VERSION)
192			.extend_u8(Self::KIND as u8)
193			.extend_u64(self.table)
194			.extend_u64(self.snapshot);
195		serializer.to_encoded_key()
196	}
197
198	fn decode(key: &EncodedKey) -> Option<Self> {
199		let mut de = KeyDeserializer::from_bytes(key.as_slice());
200
201		let version = de.read_u8().ok()?;
202		if version != VERSION {
203			return None;
204		}
205
206		let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
207		if kind != Self::KIND {
208			return None;
209		}
210
211		let table = de.read_u64().ok()?;
212		let snapshot = de.read_u64().ok()?;
213
214		Some(Self {
215			table: TableId(table),
216			snapshot: ColumnSnapshotId(snapshot),
217		})
218	}
219}
220
221#[cfg(test)]
222pub mod tests {
223	use std::ops::Bound;
224
225	use super::*;
226
227	#[test]
228	fn test_column_snapshot_key_encode_decode() {
229		let key = ColumnSnapshotKey {
230			snapshot: ColumnSnapshotId(0x1234),
231		};
232		let encoded = key.encode();
233		let decoded = ColumnSnapshotKey::decode(&encoded).unwrap();
234		assert_eq!(decoded.snapshot, key.snapshot);
235	}
236
237	#[test]
238	fn test_column_snapshot_key_full_scan() {
239		let range = ColumnSnapshotKey::full_scan();
240		assert!(matches!(range.start, Bound::Included(_) | Bound::Excluded(_)));
241		assert!(matches!(range.end, Bound::Included(_) | Bound::Excluded(_)));
242	}
243
244	#[test]
245	fn test_series_column_snapshot_key_encode_decode() {
246		let key = SeriesColumnSnapshotKey {
247			series: SeriesId(42),
248			snapshot: ColumnSnapshotId(99),
249		};
250		let encoded = key.encode();
251		let decoded = SeriesColumnSnapshotKey::decode(&encoded).unwrap();
252		assert_eq!(decoded.series, key.series);
253		assert_eq!(decoded.snapshot, key.snapshot);
254	}
255
256	#[test]
257	fn test_table_column_snapshot_key_encode_decode() {
258		let key = TableColumnSnapshotKey {
259			table: TableId(42),
260			snapshot: ColumnSnapshotId(99),
261		};
262		let encoded = key.encode();
263		let decoded = TableColumnSnapshotKey::decode(&encoded).unwrap();
264		assert_eq!(decoded.table, key.table);
265		assert_eq!(decoded.snapshot, key.snapshot);
266	}
267}