1use reifydb_codec::key::{
5 deserializer::KeyDeserializer,
6 encoded::{EncodedKey, EncodedKeyRange},
7 serializer::KeySerializer,
8};
9use reifydb_value::value::sumtype::SumTypeId;
10
11use crate::{
12 interface::catalog::id::{HandlerId, NamespaceId},
13 key::{EncodableKey, KeyKind},
14};
15
16#[derive(Debug, Clone, PartialEq)]
17pub struct VariantHandlerKey {
18 pub namespace: NamespaceId,
19 pub sumtype: SumTypeId,
20 pub variant_tag: u8,
21 pub handler: HandlerId,
22}
23
24impl VariantHandlerKey {
25 pub fn new(namespace: NamespaceId, sumtype: SumTypeId, variant_tag: u8, handler: HandlerId) -> Self {
26 Self {
27 namespace,
28 sumtype,
29 variant_tag,
30 handler,
31 }
32 }
33
34 pub fn encoded(
35 namespace: impl Into<NamespaceId>,
36 sumtype: impl Into<SumTypeId>,
37 variant_tag: u8,
38 handler: impl Into<HandlerId>,
39 ) -> EncodedKey {
40 Self::new(namespace.into(), sumtype.into(), variant_tag, handler.into()).encode()
41 }
42
43 pub fn variant_scan(namespace: NamespaceId, sumtype: SumTypeId, variant_tag: u8) -> EncodedKeyRange {
44 EncodedKeyRange::start_end(
45 Some(Self::variant_start(namespace, sumtype, variant_tag)),
46 Some(Self::variant_end(namespace, sumtype, variant_tag)),
47 )
48 }
49
50 fn variant_start(namespace: NamespaceId, sumtype: SumTypeId, variant_tag: u8) -> EncodedKey {
51 let mut serializer = KeySerializer::with_capacity(18);
52 serializer.extend_u8(Self::KIND as u8).extend_u64(namespace).extend_u64(sumtype).extend_u8(variant_tag);
53 serializer.to_encoded_key()
54 }
55
56 fn variant_end(namespace: NamespaceId, sumtype: SumTypeId, variant_tag: u8) -> EncodedKey {
57 let mut serializer = KeySerializer::with_capacity(18);
58 serializer
59 .extend_u8(Self::KIND as u8)
60 .extend_u64(namespace)
61 .extend_u64(sumtype)
62 .extend_u8(variant_tag.wrapping_sub(1));
63 serializer.to_encoded_key()
64 }
65}
66
67impl EncodableKey for VariantHandlerKey {
68 const KIND: KeyKind = KeyKind::VariantHandler;
69
70 fn encode(&self) -> EncodedKey {
71 let mut serializer = KeySerializer::with_capacity(26);
72 serializer
73 .extend_u8(Self::KIND as u8)
74 .extend_u64(self.namespace)
75 .extend_u64(self.sumtype)
76 .extend_u8(self.variant_tag)
77 .extend_u64(self.handler);
78 serializer.to_encoded_key()
79 }
80
81 fn decode(key: &EncodedKey) -> Option<Self> {
82 let mut de = KeyDeserializer::from_bytes(key.as_slice());
83
84 let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
85 if kind != Self::KIND {
86 return None;
87 }
88
89 let namespace = de.read_u64().ok()?;
90 let sumtype = de.read_u64().ok()?;
91 let variant_tag = de.read_u8().ok()?;
92 let handler = de.read_u64().ok()?;
93
94 Some(Self {
95 namespace: NamespaceId(namespace),
96 sumtype: SumTypeId(sumtype),
97 variant_tag,
98 handler: HandlerId(handler),
99 })
100 }
101}
102
103#[cfg(test)]
104pub mod tests {
105 use std::ops::Bound;
106
107 use reifydb_value::value::sumtype::SumTypeId;
108
109 use super::{EncodableKey, VariantHandlerKey};
110 use crate::interface::catalog::id::{HandlerId, NamespaceId};
111
112 #[test]
113 fn test_encode_decode() {
114 let key = VariantHandlerKey {
115 namespace: NamespaceId(0xABCD),
116 sumtype: SumTypeId(0x1234),
117 variant_tag: 5,
118 handler: HandlerId(0x6789),
119 };
120 let encoded = key.encode();
121 let expected: Vec<u8> = vec![0xD0, 0x3F, 0x54, 0x32, 0x6D, 0xCB, 0xFA, 0x3F, 0x98, 0x76];
122 assert_eq!(encoded.as_slice(), expected);
123
124 let decoded = VariantHandlerKey::decode(&encoded).unwrap();
125 assert_eq!(decoded.namespace, NamespaceId(0xABCD));
126 assert_eq!(decoded.sumtype, SumTypeId(0x1234));
127 assert_eq!(decoded.variant_tag, 5);
128 assert_eq!(decoded.handler, HandlerId(0x6789));
129 }
130
131 #[test]
132 fn test_order_preserving() {
133 let key1 = VariantHandlerKey {
134 namespace: NamespaceId::SYSTEM,
135 sumtype: SumTypeId(5),
136 variant_tag: 3,
137 handler: HandlerId(100),
138 };
139 let key2 = VariantHandlerKey {
140 namespace: NamespaceId::SYSTEM,
141 sumtype: SumTypeId(5),
142 variant_tag: 3,
143 handler: HandlerId(200),
144 };
145 let key3 = VariantHandlerKey {
146 namespace: NamespaceId::SYSTEM,
147 sumtype: SumTypeId(5),
148 variant_tag: 4,
149 handler: HandlerId(1),
150 };
151 let key4 = VariantHandlerKey {
152 namespace: NamespaceId::DEFAULT,
153 sumtype: SumTypeId(1),
154 variant_tag: 0,
155 handler: HandlerId(1),
156 };
157
158 let encoded1 = key1.encode();
159 let encoded2 = key2.encode();
160 let encoded3 = key3.encode();
161 let encoded4 = key4.encode();
162
163 assert!(encoded4 < encoded3, "ordering not preserved");
164 assert!(encoded3 < encoded2, "ordering not preserved");
165 assert!(encoded2 < encoded1, "ordering not preserved");
166 }
167
168 #[test]
169 fn test_variant_scan() {
170 let ns = NamespaceId::SYSTEM;
171 let st = SumTypeId(10);
172 let tag = 5u8;
173
174 let range = VariantHandlerKey::variant_scan(ns, st, tag);
175 let start = match &range.start {
176 Bound::Included(k) | Bound::Excluded(k) => k,
177 Bound::Unbounded => panic!("expected bounded start"),
178 };
179 let end = match &range.end {
180 Bound::Included(k) | Bound::Excluded(k) => k,
181 Bound::Unbounded => panic!("expected bounded end"),
182 };
183
184 let key = VariantHandlerKey {
185 namespace: ns,
186 sumtype: st,
187 variant_tag: tag,
188 handler: HandlerId(42),
189 };
190 let encoded = key.encode();
191 assert!(encoded.as_slice() >= start.as_slice());
192 assert!(encoded.as_slice() <= end.as_slice());
193
194 let other = VariantHandlerKey {
195 namespace: ns,
196 sumtype: st,
197 variant_tag: tag + 1,
198 handler: HandlerId(42),
199 };
200 let other_encoded = other.encode();
201 assert!(other_encoded.as_slice() < start.as_slice());
202 }
203}