Skip to main content

reifydb_core/key/
column_snapshot.rs

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