Skip to main content

reifydb_core/key/
namespace.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use reifydb_codec::key::encoded::EncodedKey;
5use reifydb_macro::KeyCodec;
6use reifydb_value::value::{dictionary::DictionaryId, sumtype::SumTypeId};
7
8use super::KeyTag;
9use crate::{
10	interface::catalog::{
11		flow::FlowId,
12		id::{
13			BindingId, HandlerId, NamespaceId, ProcedureId, QueueId, RingBufferId, SeriesId, SinkId,
14			SourceId, TableId, ViewId,
15		},
16	},
17	key::{
18		any::{Field, KeyFields, Width},
19		bound::TaggedKeyBoundRange,
20	},
21};
22
23#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
24#[key(tag = Namespace)]
25pub struct NamespaceKey {
26	pub namespace: NamespaceId,
27}
28
29impl NamespaceKey {
30	pub fn new(namespace: impl Into<NamespaceId>) -> Self {
31		Self {
32			namespace: namespace.into(),
33		}
34	}
35
36	pub fn encoded(namespace: impl Into<NamespaceId>) -> EncodedKey {
37		Self::new(namespace).encode()
38	}
39
40	pub fn full_scan() -> TaggedKeyBoundRange {
41		TaggedKeyBoundRange::kind(Self::TAG)
42	}
43}
44
45#[cfg(test)]
46pub mod namespace_key_tests {
47	use super::NamespaceKey;
48	use crate::interface::catalog::id::NamespaceId;
49
50	#[test]
51	fn test_encode_decode() {
52		let key = NamespaceKey {
53			namespace: NamespaceId(0xABCD),
54		};
55		let encoded = key.encode();
56		let expected = vec![0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32];
57		assert_eq!(encoded.as_slice(), expected);
58
59		let key = NamespaceKey::decode(&encoded).unwrap();
60		assert_eq!(key.namespace, 0xABCD);
61	}
62}
63
64#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
65#[key(tag = NamespaceBinding)]
66pub struct NamespaceBindingKey {
67	pub namespace: NamespaceId,
68	pub binding: BindingId,
69}
70
71impl NamespaceBindingKey {
72	pub fn new(namespace: impl Into<NamespaceId>, binding: impl Into<BindingId>) -> Self {
73		Self {
74			namespace: namespace.into(),
75			binding: binding.into(),
76		}
77	}
78
79	pub fn encoded(namespace: impl Into<NamespaceId>, binding: impl Into<BindingId>) -> EncodedKey {
80		Self::new(namespace, binding).encode()
81	}
82
83	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
84		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
85	}
86}
87
88#[cfg(test)]
89pub mod namespace_binding_key_tests {
90	use super::NamespaceBindingKey;
91	use crate::interface::catalog::id::{BindingId, NamespaceId};
92
93	#[test]
94	fn test_encode_decode() {
95		let key = NamespaceBindingKey {
96			namespace: NamespaceId(0xABCD),
97			binding: BindingId(0x123456789ABCDEF0),
98		};
99		let encoded = key.encode();
100		let decoded = NamespaceBindingKey::decode(&encoded).unwrap();
101		assert_eq!(decoded.namespace, NamespaceId(0xABCD));
102		assert_eq!(decoded.binding, BindingId(0x123456789ABCDEF0));
103		assert_eq!(key, decoded);
104	}
105}
106
107#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
108#[key(tag = NamespaceDictionary)]
109pub struct NamespaceDictionaryKey {
110	pub namespace: NamespaceId,
111	pub dictionary: DictionaryId,
112}
113
114impl NamespaceDictionaryKey {
115	pub fn new(namespace: NamespaceId, dictionary: DictionaryId) -> Self {
116		Self {
117			namespace,
118			dictionary,
119		}
120	}
121
122	pub fn encoded(namespace: impl Into<NamespaceId>, dictionary: impl Into<DictionaryId>) -> EncodedKey {
123		Self::new(namespace.into(), dictionary.into()).encode()
124	}
125
126	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
127		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
128	}
129}
130
131#[cfg(test)]
132pub mod namespace_dictionary_key_tests {
133	use std::ops::Bound;
134
135	use super::*;
136
137	#[test]
138	fn test_namespace_dictionary_key_encode_decode() {
139		let key = NamespaceDictionaryKey {
140			namespace: NamespaceId(1025),
141			dictionary: DictionaryId(2048),
142		};
143		let encoded = key.encode();
144		let decoded = NamespaceDictionaryKey::decode(&encoded).unwrap();
145		assert_eq!(decoded.namespace, key.namespace);
146		assert_eq!(decoded.dictionary, key.dictionary);
147	}
148
149	#[test]
150	fn test_namespace_dictionary_key_full_scan() {
151		let range = NamespaceDictionaryKey::full_scan(NamespaceId(1025)).encode();
152		assert!(matches!(range.start, Bound::Included(_) | Bound::Excluded(_)));
153		assert!(matches!(range.end, Bound::Included(_) | Bound::Excluded(_)));
154	}
155}
156
157#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
158#[key(tag = NamespaceFlow)]
159pub struct NamespaceFlowKey {
160	pub namespace: NamespaceId,
161	pub flow: FlowId,
162}
163
164impl NamespaceFlowKey {
165	pub fn new(namespace: impl Into<NamespaceId>, flow: impl Into<FlowId>) -> Self {
166		Self {
167			namespace: namespace.into(),
168			flow: flow.into(),
169		}
170	}
171
172	pub fn encoded(namespace: impl Into<NamespaceId>, flow: impl Into<FlowId>) -> EncodedKey {
173		Self::new(namespace, flow).encode()
174	}
175
176	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
177		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
178	}
179}
180
181#[cfg(test)]
182pub mod namespace_flow_key_tests {
183	use super::NamespaceFlowKey;
184	use crate::interface::catalog::{flow::FlowId, id::NamespaceId};
185
186	#[test]
187	fn test_encode_decode() {
188		let key = NamespaceFlowKey {
189			namespace: NamespaceId(0xABCD),
190			flow: FlowId(0x123456789ABCDEF0),
191		};
192		let encoded = key.encode();
193		let decoded = NamespaceFlowKey::decode(&encoded).unwrap();
194		assert_eq!(decoded.namespace, NamespaceId(0xABCD));
195		assert_eq!(decoded.flow, FlowId(0x123456789ABCDEF0));
196		assert_eq!(key, decoded);
197	}
198
199	#[test]
200	fn test_order_preserving() {
201		let key1 = NamespaceFlowKey {
202			namespace: NamespaceId::SYSTEM,
203			flow: FlowId(100),
204		};
205		let key2 = NamespaceFlowKey {
206			namespace: NamespaceId::SYSTEM,
207			flow: FlowId(200),
208		};
209		let key3 = NamespaceFlowKey {
210			namespace: NamespaceId::DEFAULT,
211			flow: FlowId(0),
212		};
213
214		let encoded1 = key1.encode();
215		let encoded2 = key2.encode();
216		let encoded3 = key3.encode();
217
218		assert!(encoded3 < encoded2, "ordering not preserved");
219		assert!(encoded2 < encoded1, "ordering not preserved");
220	}
221}
222
223#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
224#[key(tag = NamespaceHandler)]
225pub struct NamespaceHandlerKey {
226	pub namespace: NamespaceId,
227	pub handler: HandlerId,
228}
229
230impl NamespaceHandlerKey {
231	pub fn new(namespace: NamespaceId, handler: HandlerId) -> Self {
232		Self {
233			namespace,
234			handler,
235		}
236	}
237
238	pub fn encoded(namespace: impl Into<NamespaceId>, handler: impl Into<HandlerId>) -> EncodedKey {
239		Self::new(namespace.into(), handler.into()).encode()
240	}
241
242	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
243		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
244	}
245}
246
247#[cfg(test)]
248pub mod namespace_handler_key_tests {
249	use super::NamespaceHandlerKey;
250	use crate::interface::catalog::id::{HandlerId, NamespaceId};
251
252	#[test]
253	fn test_encode_decode() {
254		let key = NamespaceHandlerKey {
255			namespace: NamespaceId(0xABCD),
256			handler: HandlerId(0x123456789ABCDEF0),
257		};
258		let encoded = key.encode();
259		let expected: Vec<u8> = vec![
260			0xD3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43, 0x21,
261			0x0F,
262		];
263		assert_eq!(encoded.as_slice(), expected);
264
265		let decoded = NamespaceHandlerKey::decode(&encoded).unwrap();
266		assert_eq!(decoded.namespace, NamespaceId(0xABCD));
267		assert_eq!(decoded.handler, HandlerId(0x123456789ABCDEF0));
268	}
269
270	#[test]
271	fn test_order_preserving() {
272		let key1 = NamespaceHandlerKey {
273			namespace: NamespaceId::SYSTEM,
274			handler: HandlerId(100),
275		};
276		let key2 = NamespaceHandlerKey {
277			namespace: NamespaceId::SYSTEM,
278			handler: HandlerId(200),
279		};
280		let key3 = NamespaceHandlerKey {
281			namespace: NamespaceId::DEFAULT,
282			handler: HandlerId(1),
283		};
284
285		let encoded1 = key1.encode();
286		let encoded2 = key2.encode();
287		let encoded3 = key3.encode();
288
289		assert!(encoded3 < encoded2, "ordering not preserved");
290		assert!(encoded2 < encoded1, "ordering not preserved");
291	}
292}
293
294#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
295#[key(tag = NamespaceProcedure)]
296pub struct NamespaceProcedureKey {
297	pub namespace: NamespaceId,
298	pub procedure: ProcedureId,
299}
300
301impl NamespaceProcedureKey {
302	pub fn new(namespace: impl Into<NamespaceId>, procedure: impl Into<ProcedureId>) -> Self {
303		Self {
304			namespace: namespace.into(),
305			procedure: procedure.into(),
306		}
307	}
308
309	pub fn encoded(namespace: impl Into<NamespaceId>, procedure: impl Into<ProcedureId>) -> EncodedKey {
310		Self::new(namespace, procedure).encode()
311	}
312
313	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
314		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
315	}
316}
317
318#[cfg(test)]
319pub mod namespace_procedure_key_tests {
320	use super::NamespaceProcedureKey;
321	use crate::interface::catalog::id::{NamespaceId, ProcedureId};
322
323	#[test]
324	fn test_encode_decode() {
325		let key = NamespaceProcedureKey {
326			namespace: NamespaceId(0xABCD),
327			procedure: ProcedureId::from_raw(0x123456789ABCDEF0),
328		};
329		let encoded = key.encode();
330		let key = NamespaceProcedureKey::decode(&encoded).unwrap();
331		assert_eq!(key.namespace, 0xABCD);
332		assert_eq!(key.procedure, 0x123456789ABCDEF0);
333	}
334
335	#[test]
336	fn test_order_preserving() {
337		let key1 = NamespaceProcedureKey {
338			namespace: NamespaceId::SYSTEM,
339			procedure: ProcedureId::persistent(100),
340		};
341		let key2 = NamespaceProcedureKey {
342			namespace: NamespaceId::SYSTEM,
343			procedure: ProcedureId::persistent(200),
344		};
345		let key3 = NamespaceProcedureKey {
346			namespace: NamespaceId::DEFAULT,
347			procedure: ProcedureId::persistent(0),
348		};
349
350		let encoded1 = key1.encode();
351		let encoded2 = key2.encode();
352		let encoded3 = key3.encode();
353
354		assert!(encoded3 < encoded2, "ordering not preserved");
355		assert!(encoded2 < encoded1, "ordering not preserved");
356	}
357}
358
359#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
360#[key(tag = NamespaceQueue)]
361pub struct NamespaceQueueKey {
362	pub namespace: NamespaceId,
363	pub queue: QueueId,
364}
365
366impl NamespaceQueueKey {
367	pub fn new(namespace: NamespaceId, queue: QueueId) -> Self {
368		Self {
369			namespace,
370			queue,
371		}
372	}
373
374	pub fn encoded(namespace: impl Into<NamespaceId>, queue: impl Into<QueueId>) -> EncodedKey {
375		Self::new(namespace.into(), queue.into()).encode()
376	}
377
378	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
379		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
380	}
381}
382
383#[cfg(test)]
384mod namespace_queue_key_tests {
385	use std::ops::Bound;
386
387	use super::*;
388
389	#[test]
390	fn test_encode_decode_roundtrip() {
391		// The link row is what makes a queue findable by name; losing either component makes DROP
392		// NAMESPACE miss its queues.
393		let encoded = NamespaceQueueKey::encoded(NamespaceId(3), QueueId(42));
394		let decoded = NamespaceQueueKey::decode(&encoded).unwrap();
395		assert_eq!(decoded.namespace, NamespaceId(3));
396		assert_eq!(decoded.queue, QueueId(42));
397	}
398
399	#[test]
400	fn test_full_scan_contains_only_the_target_namespace() {
401		// Keys are stored bitwise-inverted, so a bound derived with the wrong sign would make DROP
402		// NAMESPACE either miss its queues or reach into a sibling.
403		let range = NamespaceQueueKey::full_scan(NamespaceId(3)).encode();
404		let Bound::Included(start) = &range.start else {
405			panic!("expected an included start bound")
406		};
407		let Bound::Excluded(end) = &range.end else {
408			panic!("expected an excluded end bound")
409		};
410
411		assert!(start.as_slice() < end.as_slice(), "the range must be non-empty under byte order");
412
413		for queue in [QueueId(1), QueueId(u64::MAX)] {
414			let inside = NamespaceQueueKey::encoded(NamespaceId(3), queue);
415			assert!(
416				inside.as_slice() >= start.as_slice() && inside.as_slice() < end.as_slice(),
417				"queue {queue:?} in namespace 3 must fall inside the scan range"
418			);
419		}
420
421		for namespace in [NamespaceId(2), NamespaceId(4)] {
422			let neighbour = NamespaceQueueKey::encoded(namespace, QueueId(1));
423			assert!(
424				neighbour.as_slice() < start.as_slice() || neighbour.as_slice() >= end.as_slice(),
425				"namespace {namespace:?} must fall outside namespace 3's scan range"
426			);
427		}
428	}
429}
430
431#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
432#[key(tag = NamespaceRingBuffer)]
433pub struct NamespaceRingBufferKey {
434	pub namespace: NamespaceId,
435	pub ringbuffer: RingBufferId,
436}
437
438impl NamespaceRingBufferKey {
439	pub fn new(namespace: NamespaceId, ringbuffer: RingBufferId) -> Self {
440		Self {
441			namespace,
442			ringbuffer,
443		}
444	}
445
446	pub fn encoded(namespace: impl Into<NamespaceId>, ringbuffer: impl Into<RingBufferId>) -> EncodedKey {
447		Self::new(namespace.into(), ringbuffer.into()).encode()
448	}
449
450	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
451		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
452	}
453}
454
455#[cfg(test)]
456pub mod namespace_ring_buffer_key_tests {
457	use super::NamespaceRingBufferKey;
458	use crate::interface::catalog::id::{NamespaceId, RingBufferId};
459
460	#[test]
461	fn test_encode_decode() {
462		let key = NamespaceRingBufferKey::new(NamespaceId(0xABCD), RingBufferId(0x123456789ABCDEF0));
463		let encoded = key.encode();
464		let decoded = NamespaceRingBufferKey::decode(&encoded).unwrap();
465		assert_eq!(decoded.namespace, NamespaceId(0xABCD));
466		assert_eq!(decoded.ringbuffer, RingBufferId(0x123456789ABCDEF0));
467		assert_eq!(key, decoded);
468	}
469
470	#[test]
471	fn test_order_preserving() {
472		let key1 = NamespaceRingBufferKey::new(NamespaceId::SYSTEM, RingBufferId(100));
473		let key2 = NamespaceRingBufferKey::new(NamespaceId::SYSTEM, RingBufferId(200));
474		let key3 = NamespaceRingBufferKey::new(NamespaceId::DEFAULT, RingBufferId(0));
475
476		let encoded1 = key1.encode();
477		let encoded2 = key2.encode();
478		let encoded3 = key3.encode();
479
480		assert!(encoded3 < encoded2, "ordering not preserved");
481		assert!(encoded2 < encoded1, "ordering not preserved");
482	}
483}
484
485#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
486#[key(tag = NamespaceSeries)]
487pub struct NamespaceSeriesKey {
488	pub namespace: NamespaceId,
489	pub series: SeriesId,
490}
491
492impl NamespaceSeriesKey {
493	pub fn new(namespace: NamespaceId, series: SeriesId) -> Self {
494		Self {
495			namespace,
496			series,
497		}
498	}
499
500	pub fn encoded(namespace: impl Into<NamespaceId>, series: impl Into<SeriesId>) -> EncodedKey {
501		Self::new(namespace.into(), series.into()).encode()
502	}
503
504	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
505		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
506	}
507}
508
509#[cfg(test)]
510pub mod namespace_series_key_tests {
511	use super::NamespaceSeriesKey;
512	use crate::interface::catalog::id::{NamespaceId, SeriesId};
513
514	#[test]
515	fn test_encode_decode() {
516		let key = NamespaceSeriesKey::new(NamespaceId(0xABCD), SeriesId(0x123456789ABCDEF0));
517		let encoded = key.encode();
518		let decoded = NamespaceSeriesKey::decode(&encoded).unwrap();
519		assert_eq!(decoded.namespace, NamespaceId(0xABCD));
520		assert_eq!(decoded.series, SeriesId(0x123456789ABCDEF0));
521		assert_eq!(key, decoded);
522	}
523
524	#[test]
525	fn test_order_preserving() {
526		let key1 = NamespaceSeriesKey::new(NamespaceId::SYSTEM, SeriesId(100));
527		let key2 = NamespaceSeriesKey::new(NamespaceId::SYSTEM, SeriesId(200));
528		let key3 = NamespaceSeriesKey::new(NamespaceId::DEFAULT, SeriesId(0));
529
530		let encoded1 = key1.encode();
531		let encoded2 = key2.encode();
532		let encoded3 = key3.encode();
533
534		assert!(encoded3 < encoded2, "ordering not preserved");
535		assert!(encoded2 < encoded1, "ordering not preserved");
536	}
537}
538
539#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
540#[key(tag = NamespaceSink)]
541pub struct NamespaceSinkKey {
542	pub namespace: NamespaceId,
543	pub sink: SinkId,
544}
545
546impl NamespaceSinkKey {
547	pub fn new(namespace: impl Into<NamespaceId>, sink: impl Into<SinkId>) -> Self {
548		Self {
549			namespace: namespace.into(),
550			sink: sink.into(),
551		}
552	}
553
554	pub fn encoded(namespace: impl Into<NamespaceId>, sink: impl Into<SinkId>) -> EncodedKey {
555		Self::new(namespace, sink).encode()
556	}
557
558	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
559		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
560	}
561}
562
563#[cfg(test)]
564pub mod namespace_sink_key_tests {
565	use super::NamespaceSinkKey;
566	use crate::interface::catalog::id::{NamespaceId, SinkId};
567
568	#[test]
569	fn test_encode_decode() {
570		let key = NamespaceSinkKey {
571			namespace: NamespaceId(0xABCD),
572			sink: SinkId(0x123456789ABCDEF0),
573		};
574		let encoded = key.encode();
575		let decoded = NamespaceSinkKey::decode(&encoded).unwrap();
576		assert_eq!(decoded.namespace, NamespaceId(0xABCD));
577		assert_eq!(decoded.sink, SinkId(0x123456789ABCDEF0));
578		assert_eq!(key, decoded);
579	}
580
581	#[test]
582	fn test_order_preserving() {
583		let key1 = NamespaceSinkKey {
584			namespace: NamespaceId::SYSTEM,
585			sink: SinkId(100),
586		};
587		let key2 = NamespaceSinkKey {
588			namespace: NamespaceId::SYSTEM,
589			sink: SinkId(200),
590		};
591		let key3 = NamespaceSinkKey {
592			namespace: NamespaceId::DEFAULT,
593			sink: SinkId(0),
594		};
595
596		let encoded1 = key1.encode();
597		let encoded2 = key2.encode();
598		let encoded3 = key3.encode();
599
600		assert!(encoded3 < encoded2, "ordering not preserved");
601		assert!(encoded2 < encoded1, "ordering not preserved");
602	}
603}
604
605#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
606#[key(tag = NamespaceSource)]
607pub struct NamespaceSourceKey {
608	pub namespace: NamespaceId,
609	pub source: SourceId,
610}
611
612impl NamespaceSourceKey {
613	pub fn new(namespace: impl Into<NamespaceId>, source: impl Into<SourceId>) -> Self {
614		Self {
615			namespace: namespace.into(),
616			source: source.into(),
617		}
618	}
619
620	pub fn encoded(namespace: impl Into<NamespaceId>, source: impl Into<SourceId>) -> EncodedKey {
621		Self::new(namespace, source).encode()
622	}
623
624	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
625		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
626	}
627}
628
629#[cfg(test)]
630pub mod namespace_source_key_tests {
631	use super::NamespaceSourceKey;
632	use crate::interface::catalog::id::{NamespaceId, SourceId};
633
634	#[test]
635	fn test_encode_decode() {
636		let key = NamespaceSourceKey {
637			namespace: NamespaceId(0xABCD),
638			source: SourceId(0x123456789ABCDEF0),
639		};
640		let encoded = key.encode();
641		let decoded = NamespaceSourceKey::decode(&encoded).unwrap();
642		assert_eq!(decoded.namespace, NamespaceId(0xABCD));
643		assert_eq!(decoded.source, SourceId(0x123456789ABCDEF0));
644		assert_eq!(key, decoded);
645	}
646
647	#[test]
648	fn test_order_preserving() {
649		let key1 = NamespaceSourceKey {
650			namespace: NamespaceId::SYSTEM,
651			source: SourceId(100),
652		};
653		let key2 = NamespaceSourceKey {
654			namespace: NamespaceId::SYSTEM,
655			source: SourceId(200),
656		};
657		let key3 = NamespaceSourceKey {
658			namespace: NamespaceId::DEFAULT,
659			source: SourceId(0),
660		};
661
662		let encoded1 = key1.encode();
663		let encoded2 = key2.encode();
664		let encoded3 = key3.encode();
665
666		assert!(encoded3 < encoded2, "ordering not preserved");
667		assert!(encoded2 < encoded1, "ordering not preserved");
668	}
669}
670
671#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
672#[key(tag = NamespaceSumType)]
673pub struct NamespaceSumTypeKey {
674	pub namespace: NamespaceId,
675	pub sumtype: SumTypeId,
676}
677
678impl NamespaceSumTypeKey {
679	pub fn new(namespace: NamespaceId, sumtype: SumTypeId) -> Self {
680		Self {
681			namespace,
682			sumtype,
683		}
684	}
685
686	pub fn encoded(namespace: impl Into<NamespaceId>, sumtype: impl Into<SumTypeId>) -> EncodedKey {
687		Self::new(namespace.into(), sumtype.into()).encode()
688	}
689
690	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
691		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
692	}
693}
694
695#[cfg(test)]
696pub mod namespace_sum_type_key_tests {
697	use reifydb_value::value::sumtype::SumTypeId;
698
699	use super::NamespaceSumTypeKey;
700	use crate::interface::catalog::id::NamespaceId;
701
702	#[test]
703	fn test_encode_decode() {
704		let key = NamespaceSumTypeKey::new(NamespaceId(0xABCD), SumTypeId(0x123456789ABCDEF0));
705		let encoded = key.encode();
706		let decoded = NamespaceSumTypeKey::decode(&encoded).unwrap();
707		assert_eq!(decoded.namespace, NamespaceId(0xABCD));
708		assert_eq!(decoded.sumtype, SumTypeId(0x123456789ABCDEF0));
709		assert_eq!(key, decoded);
710	}
711
712	#[test]
713	fn test_order_preserving() {
714		let key1 = NamespaceSumTypeKey::new(NamespaceId::SYSTEM, SumTypeId(100));
715		let key2 = NamespaceSumTypeKey::new(NamespaceId::SYSTEM, SumTypeId(200));
716		let key3 = NamespaceSumTypeKey::new(NamespaceId::DEFAULT, SumTypeId(0));
717
718		let encoded1 = key1.encode();
719		let encoded2 = key2.encode();
720		let encoded3 = key3.encode();
721
722		assert!(encoded3 < encoded2, "ordering not preserved");
723		assert!(encoded2 < encoded1, "ordering not preserved");
724	}
725}
726
727#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
728#[key(tag = NamespaceTable)]
729pub struct NamespaceTableKey {
730	pub namespace: NamespaceId,
731	pub table: TableId,
732}
733
734impl NamespaceTableKey {
735	pub fn new(namespace: impl Into<NamespaceId>, table: impl Into<TableId>) -> Self {
736		Self {
737			namespace: namespace.into(),
738			table: table.into(),
739		}
740	}
741
742	pub fn encoded(namespace: impl Into<NamespaceId>, table: impl Into<TableId>) -> EncodedKey {
743		Self::new(namespace, table).encode()
744	}
745
746	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
747		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
748	}
749}
750
751#[cfg(test)]
752pub mod namespace_table_key_tests {
753	use super::NamespaceTableKey;
754	use crate::interface::catalog::id::{NamespaceId, TableId};
755
756	#[test]
757	fn test_encode_decode() {
758		let key = NamespaceTableKey {
759			namespace: NamespaceId(0xABCD),
760			table: TableId(0x123456789ABCDEF0),
761		};
762		let encoded = key.encode();
763
764		let expected: Vec<u8> = vec![
765			0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43, 0x21,
766			0x0F,
767		];
768
769		assert_eq!(encoded.as_slice(), expected);
770
771		let key = NamespaceTableKey::decode(&encoded).unwrap();
772		assert_eq!(key.namespace, 0xABCD);
773		assert_eq!(key.table, 0x123456789ABCDEF0);
774	}
775
776	#[test]
777	fn test_order_preserving() {
778		let key1 = NamespaceTableKey {
779			namespace: NamespaceId::SYSTEM,
780			table: TableId(100),
781		};
782		let key2 = NamespaceTableKey {
783			namespace: NamespaceId::SYSTEM,
784			table: TableId(200),
785		};
786		let key3 = NamespaceTableKey {
787			namespace: NamespaceId::DEFAULT,
788			table: TableId(0),
789		};
790
791		let encoded1 = key1.encode();
792		let encoded2 = key2.encode();
793		let encoded3 = key3.encode();
794
795		assert!(encoded3 < encoded2, "ordering not preserved");
796		assert!(encoded2 < encoded1, "ordering not preserved");
797	}
798}
799
800#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
801#[key(tag = NamespaceView)]
802pub struct NamespaceViewKey {
803	pub namespace: NamespaceId,
804	pub view: ViewId,
805}
806
807impl NamespaceViewKey {
808	pub fn new(namespace: impl Into<NamespaceId>, view: impl Into<ViewId>) -> Self {
809		Self {
810			namespace: namespace.into(),
811			view: view.into(),
812		}
813	}
814
815	pub fn encoded(namespace: impl Into<NamespaceId>, view: impl Into<ViewId>) -> EncodedKey {
816		Self::new(namespace, view).encode()
817	}
818
819	pub fn full_scan(namespace: NamespaceId) -> TaggedKeyBoundRange {
820		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, namespace.0 as u128)])
821	}
822}
823
824#[cfg(test)]
825pub mod namespace_view_key_tests {
826	use super::NamespaceViewKey;
827	use crate::interface::catalog::id::{NamespaceId, ViewId};
828
829	#[test]
830	fn test_encode_decode() {
831		let key = NamespaceViewKey {
832			namespace: NamespaceId(0xABCD),
833			view: ViewId(0x123456789ABCDEF0),
834		};
835		let encoded = key.encode();
836
837		let expected: Vec<u8> = vec![
838			0xEE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43, 0x21,
839			0x0F,
840		];
841
842		assert_eq!(encoded.as_slice(), expected);
843
844		let key = NamespaceViewKey::decode(&encoded).unwrap();
845		assert_eq!(key.namespace, 0xABCD);
846		assert_eq!(key.view, 0x123456789ABCDEF0);
847	}
848
849	#[test]
850	fn test_order_preserving() {
851		let key1 = NamespaceViewKey {
852			namespace: NamespaceId::SYSTEM,
853			view: ViewId(100),
854		};
855		let key2 = NamespaceViewKey {
856			namespace: NamespaceId::SYSTEM,
857			view: ViewId(200),
858		};
859		let key3 = NamespaceViewKey {
860			namespace: NamespaceId::DEFAULT,
861			view: ViewId(1),
862		};
863
864		let encoded1 = key1.encode();
865		let encoded2 = key2.encode();
866		let encoded3 = key3.encode();
867
868		assert!(encoded3 < encoded2, "ordering not preserved");
869		assert!(encoded2 < encoded1, "ordering not preserved");
870	}
871}