Skip to main content

reifydb_core/key/
subscription_column.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use super::{EncodableKey, KeyKind};
5use crate::{
6	encoded::key::{EncodedKey, EncodedKeyRange},
7	interface::catalog::id::{SubscriptionColumnId, SubscriptionId},
8	util::encoding::keycode::{deserializer::KeyDeserializer, serializer::KeySerializer},
9};
10
11#[derive(Debug, Clone, PartialEq)]
12pub struct SubscriptionColumnKey {
13	pub subscription: SubscriptionId,
14	pub column: SubscriptionColumnId,
15}
16
17const VERSION: u8 = 1;
18
19impl EncodableKey for SubscriptionColumnKey {
20	const KIND: KeyKind = KeyKind::SubscriptionColumn;
21
22	fn encode(&self) -> EncodedKey {
23		let mut serializer = KeySerializer::with_capacity(18); // 1 + 1 + 8 (subscription u64) + 8 (column)
24		serializer
25			.extend_u8(VERSION)
26			.extend_u8(Self::KIND as u8)
27			.extend_u64(self.subscription.0)
28			.extend_u64(self.column);
29		serializer.to_encoded_key()
30	}
31
32	fn decode(key: &EncodedKey) -> Option<Self> {
33		let mut de = KeyDeserializer::from_bytes(key.as_slice());
34
35		let version = de.read_u8().ok()?;
36		if version != VERSION {
37			return None;
38		}
39
40		let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
41		if kind != Self::KIND {
42			return None;
43		}
44
45		let subscription_id = de.read_u64().ok()?;
46		let column = de.read_u64().ok()?;
47
48		Some(Self {
49			subscription: SubscriptionId(subscription_id),
50			column: SubscriptionColumnId(column),
51		})
52	}
53}
54
55impl SubscriptionColumnKey {
56	pub fn encoded(subscription: impl Into<SubscriptionId>, column: impl Into<SubscriptionColumnId>) -> EncodedKey {
57		Self {
58			subscription: subscription.into(),
59			column: column.into(),
60		}
61		.encode()
62	}
63
64	/// Returns a range for scanning all columns of a specific subscription
65	pub fn subscription_range(subscription: impl Into<SubscriptionId>) -> EncodedKeyRange {
66		let subscription = subscription.into();
67		EncodedKeyRange::start_end(
68			Some(Self::subscription_start(subscription)),
69			Some(Self::subscription_end(subscription)),
70		)
71	}
72
73	fn subscription_start(subscription: SubscriptionId) -> EncodedKey {
74		let mut serializer = KeySerializer::with_capacity(10);
75		serializer.extend_u8(VERSION).extend_u8(Self::KIND as u8).extend_u64(subscription.0);
76		serializer.to_encoded_key()
77	}
78
79	fn subscription_end(subscription: SubscriptionId) -> EncodedKey {
80		let mut serializer = KeySerializer::with_capacity(10);
81		serializer.extend_u8(VERSION).extend_u8(Self::KIND as u8).extend_u64(subscription.0.wrapping_sub(1));
82		serializer.to_encoded_key()
83	}
84}
85
86#[cfg(test)]
87pub mod tests {
88	use super::{EncodableKey, SubscriptionColumnKey};
89	use crate::interface::catalog::id::{SubscriptionColumnId, SubscriptionId};
90
91	#[test]
92	fn test_encode_decode() {
93		let subscription_id = SubscriptionId(12345);
94		let key = SubscriptionColumnKey {
95			subscription: subscription_id,
96			column: SubscriptionColumnId(0x1234),
97		};
98		let encoded = key.encode();
99
100		let decoded = SubscriptionColumnKey::decode(&encoded).unwrap();
101		assert_eq!(decoded.subscription, subscription_id);
102		assert_eq!(decoded.column, SubscriptionColumnId(0x1234));
103	}
104}