Skip to main content

reifydb_core/key/operator/keyspace/
join.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use reifydb_codec::row::shape::fingerprint::RowShapeFingerprint;
5use reifydb_macro::operator_state;
6use reifydb_value::value::{datetime::DateTime, row_number::RowNumber};
7
8use crate::{
9	key::{
10		operator::{
11			state::{GroupId, GroupStateKey, KeyspaceId},
12			traits::Keyspace,
13		},
14		typed::{
15			BoundedKey, DenseKey, KeyLayout,
16			direction::{Asc, Desc, Direction, KeyField},
17			layout::{KeyColumn, KeyColumnType, KeyLayout, KeyValue, KeyValues},
18		},
19	},
20	metrics::heap::HeapSize,
21	state::{join::ContentVersion, typed::typed_key},
22};
23
24#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, KeyLayout, HeapSize)]
25pub struct JoinLeftKey {
26	pub group: Desc<GroupId>,
27	pub row: Asc<RowNumber>,
28}
29
30#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, KeyLayout, HeapSize)]
31pub struct JoinRightKey {
32	pub group: Desc<GroupId>,
33	pub row: Asc<RowNumber>,
34}
35
36#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, KeyLayout, HeapSize)]
37pub struct JoinPublishedKey {
38	pub group: Desc<GroupId>,
39	pub row: Asc<RowNumber>,
40}
41
42#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, KeyLayout, HeapSize)]
43pub struct JoinPinKey {
44	pub group: Desc<GroupId>,
45	pub row: Asc<RowNumber>,
46	pub version: Asc<ContentVersion>,
47}
48
49#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, KeyLayout, HeapSize)]
50pub struct JoinSchemaKey {
51	pub side: Asc<u8>,
52	pub fingerprint: Asc<RowShapeFingerprint>,
53}
54
55#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, KeyLayout, HeapSize)]
56pub struct JoinRowExpiryKey {
57	pub group: Desc<GroupId>,
58	pub side: Asc<u8>,
59	pub row: Asc<RowNumber>,
60}
61
62#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, KeyLayout, HeapSize)]
63pub struct JoinPinSuffix {
64	pub row: Asc<RowNumber>,
65	pub version: Asc<ContentVersion>,
66}
67
68#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, KeyLayout, HeapSize)]
69pub struct JoinRowExpirySuffix {
70	pub side: Asc<u8>,
71	pub row: Asc<RowNumber>,
72}
73
74#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, KeyLayout, HeapSize)]
75pub struct JoinExpiryDueKey {
76	pub at: Asc<DateTime>,
77	pub group: Desc<GroupId>,
78	pub side: Asc<u8>,
79	pub row: Asc<RowNumber>,
80}
81
82#[operator_state]
83#[derive(Clone)]
84pub struct JoinRowExpiryState {
85	pub at: DateTime,
86}
87
88#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, KeyLayout, HeapSize)]
89pub struct JoinRowMappingKey {
90	pub tag: Asc<u8>,
91	pub left: Desc<u64>,
92	pub right: Desc<u64>,
93}
94
95#[derive(Clone, Copy, Debug, PartialEq, Eq)]
96pub struct JoinLeft;
97
98impl Keyspace for JoinLeft {
99	const ID: KeyspaceId = KeyspaceId::JOIN_LEFT;
100	const NAME: &'static str = "JOIN_LEFT";
101	const RANGE_CACHED: bool = true;
102
103	type GroupedKey = JoinLeftKey;
104	type Suffix = Asc<RowNumber>;
105
106	fn split(key: &Self::GroupedKey) -> (GroupId, Self::Suffix) {
107		(key.group.0, key.row)
108	}
109
110	fn join(group: GroupId, suffix: Self::Suffix) -> Self::GroupedKey {
111		JoinLeftKey {
112			group: Desc(group),
113			row: suffix,
114		}
115	}
116}
117
118#[derive(Clone, Copy, Debug, PartialEq, Eq)]
119pub struct JoinRight;
120
121impl Keyspace for JoinRight {
122	const ID: KeyspaceId = KeyspaceId::JOIN_RIGHT;
123	const NAME: &'static str = "JOIN_RIGHT";
124	const RANGE_CACHED: bool = true;
125
126	type GroupedKey = JoinRightKey;
127	type Suffix = Asc<RowNumber>;
128
129	fn split(key: &Self::GroupedKey) -> (GroupId, Self::Suffix) {
130		(key.group.0, key.row)
131	}
132
133	fn join(group: GroupId, suffix: Self::Suffix) -> Self::GroupedKey {
134		JoinRightKey {
135			group: Desc(group),
136			row: suffix,
137		}
138	}
139}
140
141#[derive(Clone, Copy, Debug, PartialEq, Eq)]
142pub struct JoinPublished;
143
144impl Keyspace for JoinPublished {
145	const ID: KeyspaceId = KeyspaceId::JOIN_PUBLISHED;
146	const NAME: &'static str = "JOIN_PUBLISHED";
147	const RANGE_CACHED: bool = true;
148
149	type GroupedKey = JoinPublishedKey;
150	type Suffix = Asc<RowNumber>;
151
152	fn split(key: &Self::GroupedKey) -> (GroupId, Self::Suffix) {
153		(key.group.0, key.row)
154	}
155
156	fn join(group: GroupId, suffix: Self::Suffix) -> Self::GroupedKey {
157		JoinPublishedKey {
158			group: Desc(group),
159			row: suffix,
160		}
161	}
162}
163
164#[derive(Clone, Copy, Debug, PartialEq, Eq)]
165pub struct JoinPin;
166
167impl Keyspace for JoinPin {
168	const ID: KeyspaceId = KeyspaceId::JOIN_PIN;
169	const NAME: &'static str = "JOIN_PIN";
170	const RANGE_CACHED: bool = true;
171
172	type GroupedKey = JoinPinKey;
173	type Suffix = JoinPinSuffix;
174
175	fn split(key: &Self::GroupedKey) -> (GroupId, Self::Suffix) {
176		(
177			key.group.0,
178			JoinPinSuffix {
179				row: key.row,
180				version: key.version,
181			},
182		)
183	}
184
185	fn join(group: GroupId, suffix: Self::Suffix) -> Self::GroupedKey {
186		JoinPinKey {
187			group: Desc(group),
188			row: suffix.row,
189			version: suffix.version,
190		}
191	}
192}
193
194#[derive(Clone, Copy, Debug, PartialEq, Eq)]
195pub struct JoinSchema;
196
197impl Keyspace for JoinSchema {
198	const ID: KeyspaceId = KeyspaceId::JOIN_SCHEMA;
199	const NAME: &'static str = "JOIN_SCHEMA";
200	const RANGE_CACHED: bool = true;
201
202	type GroupedKey = JoinSchemaKey;
203	type Suffix = JoinSchemaKey;
204
205	fn split(key: &Self::GroupedKey) -> (GroupId, Self::Suffix) {
206		(GroupId::ROOT, *key)
207	}
208
209	fn join(_group: GroupId, suffix: Self::Suffix) -> Self::GroupedKey {
210		suffix
211	}
212}
213
214#[derive(Clone, Copy, Debug, PartialEq, Eq)]
215pub struct JoinRowExpiry;
216
217impl Keyspace for JoinRowExpiry {
218	const ID: KeyspaceId = KeyspaceId::JOIN_ROW_EXPIRY;
219	const NAME: &'static str = "JOIN_ROW_EXPIRY";
220	const RANGE_CACHED: bool = true;
221
222	type GroupedKey = JoinRowExpiryKey;
223	type Suffix = JoinRowExpirySuffix;
224
225	fn split(key: &Self::GroupedKey) -> (GroupId, Self::Suffix) {
226		(
227			key.group.0,
228			JoinRowExpirySuffix {
229				side: key.side,
230				row: key.row,
231			},
232		)
233	}
234
235	fn join(group: GroupId, suffix: Self::Suffix) -> Self::GroupedKey {
236		JoinRowExpiryKey {
237			group: Desc(group),
238			side: suffix.side,
239			row: suffix.row,
240		}
241	}
242}
243
244pub fn join_expiry_due_key(at: DateTime, group: GroupId, side: u8, row: RowNumber) -> GroupStateKey {
245	typed_key::<JoinExpiryDue>(
246		GroupId::ROOT,
247		&JoinExpiryDueKey {
248			at: Asc(at),
249			group: Desc(group),
250			side: Asc(side),
251			row: Asc(row),
252		},
253	)
254}
255
256#[derive(Clone, Copy, Debug, PartialEq, Eq)]
257pub struct JoinExpiryDue;
258
259impl Keyspace for JoinExpiryDue {
260	const ID: KeyspaceId = KeyspaceId::JOIN_EXPIRY_DUE;
261	const NAME: &'static str = "JOIN_EXPIRY_DUE";
262	const RANGE_CACHED: bool = true;
263
264	type GroupedKey = JoinExpiryDueKey;
265	type Suffix = JoinExpiryDueKey;
266
267	fn split(key: &Self::GroupedKey) -> (GroupId, Self::Suffix) {
268		(GroupId::ROOT, *key)
269	}
270
271	fn join(_group: GroupId, suffix: Self::Suffix) -> Self::GroupedKey {
272		suffix
273	}
274}
275
276#[derive(Clone, Copy, Debug, PartialEq, Eq)]
277pub struct JoinRowMapping;
278
279impl Keyspace for JoinRowMapping {
280	const ID: KeyspaceId = KeyspaceId::JOIN_ROW_MAPPING;
281	const NAME: &'static str = "JOIN_ROW_MAPPING";
282	const RANGE_CACHED: bool = true;
283
284	type GroupedKey = JoinRowMappingKey;
285	type Suffix = JoinRowMappingKey;
286
287	fn split(key: &Self::GroupedKey) -> (GroupId, Self::Suffix) {
288		(GroupId::ROOT, *key)
289	}
290
291	fn join(_group: GroupId, suffix: Self::Suffix) -> Self::GroupedKey {
292		suffix
293	}
294}