Skip to main content

reifydb_core/key/
series_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};
11
12use super::{EncodableKey, KeyKind};
13use crate::{
14	interface::catalog::{id::SeriesId, shape::ShapeId},
15	key::catalog::{KeyDeserializerCatalogExt, KeySerializerCatalogExt},
16};
17
18#[derive(Debug, Clone, PartialEq)]
19pub struct SeriesRowKey {
20	pub series: SeriesId,
21	pub variant_tag: Option<u8>,
22	pub key: u64,
23	pub sequence: u64,
24}
25
26impl EncodableKey for SeriesRowKey {
27	const KIND: KeyKind = KeyKind::Row;
28
29	fn encode(&self) -> EncodedKey {
30		let object = ShapeId::Series(self.series);
31		let capacity = if self.variant_tag.is_some() {
32			28
33		} else {
34			27
35		};
36		let mut serializer = KeySerializer::with_capacity(capacity);
37		serializer.extend_u8(Self::KIND as u8).extend_shape_id(object);
38		if let Some(tag) = self.variant_tag {
39			serializer.extend_u8(tag);
40		}
41		serializer.extend_u64(self.key).extend_u64(self.sequence);
42		serializer.to_encoded_key()
43	}
44
45	fn decode(key: &EncodedKey) -> Option<Self> {
46		let mut de = KeyDeserializer::from_bytes(key.as_slice());
47
48		let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
49		if kind != Self::KIND {
50			return None;
51		}
52
53		let object = de.read_shape_id().ok()?;
54		let series = match object {
55			ShapeId::Series(id) => id,
56			_ => return None,
57		};
58
59		let mut temp_de = KeyDeserializer::from_bytes(de.remaining_bytes());
60		let tag_present = if temp_de.read_u64().is_ok() {
61			if temp_de.read_u64().is_ok() {
62				!temp_de.is_empty()
63			} else {
64				true
65			}
66		} else {
67			true
68		};
69
70		let variant_tag = if tag_present {
71			Some(de.read_u8().ok()?)
72		} else {
73			None
74		};
75
76		let key = de.read_u64().ok()?;
77		let sequence = de.read_u64().ok()?;
78
79		Some(Self {
80			series,
81			variant_tag,
82			key,
83			sequence,
84		})
85	}
86}
87
88#[derive(Debug, Clone)]
89pub struct SeriesRowKeyRange {
90	pub series: SeriesId,
91	pub variant_tag: Option<u8>,
92	pub key_start: Option<u64>,
93	pub key_end: Option<u64>,
94}
95
96impl SeriesRowKeyRange {
97	pub fn full_scan(series: SeriesId, variant_tag: Option<u8>) -> EncodedKeyRange {
98		let range = SeriesRowKeyRange {
99			series,
100			variant_tag,
101			key_start: None,
102			key_end: None,
103		};
104		EncodedKeyRange::new(Bound::Included(range.start_key()), Bound::Included(range.end_key()))
105	}
106
107	pub fn scan_range(
108		series: SeriesId,
109		variant_tag: Option<u8>,
110		key_start: Option<u64>,
111		key_end: Option<u64>,
112		last_key: Option<&EncodedKey>,
113	) -> EncodedKeyRange {
114		if matches!(key_end, Some(0)) {
115			let empty = EncodedKey::new(Vec::<u8>::new());
116			return EncodedKeyRange::new(Bound::Excluded(empty.clone()), Bound::Excluded(empty));
117		}
118
119		let range = SeriesRowKeyRange {
120			series,
121			variant_tag,
122			key_start,
123			key_end,
124		};
125
126		let start = if let Some(last_key) = last_key {
127			Bound::Excluded(last_key.clone())
128		} else {
129			Bound::Included(range.start_key())
130		};
131
132		EncodedKeyRange::new(start, Bound::Included(range.end_key()))
133	}
134
135	fn start_key(&self) -> EncodedKey {
136		let object = ShapeId::Series(self.series);
137		let mut serializer = KeySerializer::with_capacity(27);
138		serializer.extend_u8(KeyKind::Row as u8).extend_shape_id(object);
139		if let Some(tag) = self.variant_tag {
140			serializer.extend_u8(tag);
141		}
142
143		if let Some(key_val) = self.key_end {
144			serializer.extend_u64(key_val - 1);
145		}
146		serializer.to_encoded_key()
147	}
148
149	fn end_key(&self) -> EncodedKey {
150		if let Some(key_val) = self.key_start {
151			let object = ShapeId::Series(self.series);
152			let mut serializer = KeySerializer::with_capacity(27);
153			serializer.extend_u8(KeyKind::Row as u8).extend_shape_id(object);
154			if let Some(tag) = self.variant_tag {
155				serializer.extend_u8(tag);
156			}
157
158			serializer.extend_u64(key_val).extend_u64(0u64);
159			serializer.to_encoded_key()
160		} else {
161			let object = ShapeId::Series(self.series);
162			let mut serializer = KeySerializer::with_capacity(10);
163			serializer.extend_u8(KeyKind::Row as u8).extend_shape_id(object.prev());
164			serializer.to_encoded_key()
165		}
166	}
167}
168
169#[cfg(test)]
170mod tests {
171	use super::*;
172
173	#[test]
174	fn test_encode_decode_without_tag() {
175		let key = SeriesRowKey {
176			series: SeriesId(42),
177			variant_tag: None,
178			key: 1706745600000,
179			sequence: 1,
180		};
181		let encoded = key.encode();
182		let decoded = SeriesRowKey::decode(&encoded).unwrap();
183		assert_eq!(decoded.series, SeriesId(42));
184		assert_eq!(decoded.variant_tag, None);
185		assert_eq!(decoded.key, 1706745600000);
186		assert_eq!(decoded.sequence, 1);
187	}
188
189	#[test]
190	fn test_encode_decode_with_tag() {
191		let key = SeriesRowKey {
192			series: SeriesId(42),
193			variant_tag: Some(3),
194			key: 1706745600000,
195			sequence: 5,
196		};
197		let encoded = key.encode();
198		let decoded = SeriesRowKey::decode(&encoded).unwrap();
199		assert_eq!(decoded.series, SeriesId(42));
200		assert_eq!(decoded.variant_tag, Some(3));
201		assert_eq!(decoded.key, 1706745600000);
202		assert_eq!(decoded.sequence, 5);
203	}
204
205	#[test]
206	fn test_ordering_by_key() {
207		let key1 = SeriesRowKey {
208			series: SeriesId(1),
209			variant_tag: None,
210			key: 100,
211			sequence: 0,
212		};
213		let key2 = SeriesRowKey {
214			series: SeriesId(1),
215			variant_tag: None,
216			key: 200,
217			sequence: 0,
218		};
219		let e1 = key1.encode();
220		let e2 = key2.encode();
221
222		assert!(e1 > e2, "key descending ordering not preserved");
223	}
224
225	#[test]
226	fn test_ordering_by_sequence() {
227		let key1 = SeriesRowKey {
228			series: SeriesId(1),
229			variant_tag: None,
230			key: 100,
231			sequence: 1,
232		};
233		let key2 = SeriesRowKey {
234			series: SeriesId(1),
235			variant_tag: None,
236			key: 100,
237			sequence: 2,
238		};
239		let e1 = key1.encode();
240		let e2 = key2.encode();
241
242		assert!(e1 > e2, "sequence descending ordering not preserved");
243	}
244}