Skip to main content

reifydb_transaction/interceptor/
ringbuffer_row.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use reifydb_codec::row::{bytes::EncodedBytes, ringbuffer::EncodedRingBufferRowBuilder};
5use reifydb_core::interface::catalog::ringbuffer::RingBuffer;
6use reifydb_value::{Result, value::row_number::RowNumber};
7
8use super::WithInterceptors;
9use crate::interceptor::chain::InterceptorChain;
10
11pub struct RingBufferRowPreInsertContext<'a> {
12	pub ringbuffer: &'a RingBuffer,
13	pub rows: &'a mut [EncodedRingBufferRowBuilder],
14}
15
16impl<'a> RingBufferRowPreInsertContext<'a> {
17	pub fn new(ringbuffer: &'a RingBuffer, rows: &'a mut [EncodedRingBufferRowBuilder]) -> Self {
18		Self {
19			ringbuffer,
20			rows,
21		}
22	}
23}
24
25pub trait RingBufferRowPreInsertInterceptor: Send + Sync {
26	fn intercept<'a>(&self, ctx: &mut RingBufferRowPreInsertContext<'a>) -> Result<()>;
27}
28
29impl InterceptorChain<dyn RingBufferRowPreInsertInterceptor + Send + Sync> {
30	pub fn execute(&self, mut ctx: RingBufferRowPreInsertContext) -> Result<()> {
31		let original_len = ctx.rows.len();
32		for interceptor in &self.interceptors {
33			interceptor.intercept(&mut ctx)?;
34			assert_eq!(ctx.rows.len(), original_len, "pre_insert interceptor changed row count");
35		}
36		Ok(())
37	}
38}
39
40pub struct ClosureRingBufferRowPreInsertInterceptor<F>
41where
42	F: for<'a> Fn(&mut RingBufferRowPreInsertContext<'a>) -> Result<()> + Send + Sync,
43{
44	closure: F,
45}
46
47impl<F> ClosureRingBufferRowPreInsertInterceptor<F>
48where
49	F: for<'a> Fn(&mut RingBufferRowPreInsertContext<'a>) -> Result<()> + Send + Sync,
50{
51	pub fn new(closure: F) -> Self {
52		Self {
53			closure,
54		}
55	}
56}
57
58impl<F> Clone for ClosureRingBufferRowPreInsertInterceptor<F>
59where
60	F: for<'a> Fn(&mut RingBufferRowPreInsertContext<'a>) -> Result<()> + Send + Sync + Clone,
61{
62	fn clone(&self) -> Self {
63		Self {
64			closure: self.closure.clone(),
65		}
66	}
67}
68
69impl<F> RingBufferRowPreInsertInterceptor for ClosureRingBufferRowPreInsertInterceptor<F>
70where
71	F: for<'a> Fn(&mut RingBufferRowPreInsertContext<'a>) -> Result<()> + Send + Sync,
72{
73	fn intercept<'a>(&self, ctx: &mut RingBufferRowPreInsertContext<'a>) -> Result<()> {
74		(self.closure)(ctx)
75	}
76}
77
78pub fn ringbuffer_row_pre_insert<F>(f: F) -> ClosureRingBufferRowPreInsertInterceptor<F>
79where
80	F: for<'a> Fn(&mut RingBufferRowPreInsertContext<'a>) -> Result<()> + Send + Sync + Clone + 'static,
81{
82	ClosureRingBufferRowPreInsertInterceptor::new(f)
83}
84
85pub struct RingBufferRowPostInsertContext<'a> {
86	pub ringbuffer: &'a RingBuffer,
87	pub ids: &'a [RowNumber],
88	pub rows: &'a [EncodedBytes],
89}
90
91impl<'a> RingBufferRowPostInsertContext<'a> {
92	pub fn new(ringbuffer: &'a RingBuffer, ids: &'a [RowNumber], rows: &'a [EncodedBytes]) -> Self {
93		assert_eq!(ids.len(), rows.len(), "ids/rows length mismatch");
94		Self {
95			ringbuffer,
96			ids,
97			rows,
98		}
99	}
100}
101
102pub trait RingBufferRowPostInsertInterceptor: Send + Sync {
103	fn intercept<'a>(&self, ctx: &mut RingBufferRowPostInsertContext<'a>) -> Result<()>;
104}
105
106impl InterceptorChain<dyn RingBufferRowPostInsertInterceptor + Send + Sync> {
107	pub fn execute<'a>(&self, mut ctx: RingBufferRowPostInsertContext<'a>) -> Result<()> {
108		for interceptor in &self.interceptors {
109			interceptor.intercept(&mut ctx)?;
110		}
111		Ok(())
112	}
113}
114
115pub struct ClosureRingBufferRowPostInsertInterceptor<F>
116where
117	F: for<'a> Fn(&mut RingBufferRowPostInsertContext<'a>) -> Result<()> + Send + Sync,
118{
119	closure: F,
120}
121
122impl<F> ClosureRingBufferRowPostInsertInterceptor<F>
123where
124	F: for<'a> Fn(&mut RingBufferRowPostInsertContext<'a>) -> Result<()> + Send + Sync,
125{
126	pub fn new(closure: F) -> Self {
127		Self {
128			closure,
129		}
130	}
131}
132
133impl<F> Clone for ClosureRingBufferRowPostInsertInterceptor<F>
134where
135	F: for<'a> Fn(&mut RingBufferRowPostInsertContext<'a>) -> Result<()> + Send + Sync + Clone,
136{
137	fn clone(&self) -> Self {
138		Self {
139			closure: self.closure.clone(),
140		}
141	}
142}
143
144impl<F> RingBufferRowPostInsertInterceptor for ClosureRingBufferRowPostInsertInterceptor<F>
145where
146	F: for<'a> Fn(&mut RingBufferRowPostInsertContext<'a>) -> Result<()> + Send + Sync,
147{
148	fn intercept<'a>(&self, ctx: &mut RingBufferRowPostInsertContext<'a>) -> Result<()> {
149		(self.closure)(ctx)
150	}
151}
152
153pub fn ringbuffer_row_post_insert<F>(f: F) -> ClosureRingBufferRowPostInsertInterceptor<F>
154where
155	F: for<'a> Fn(&mut RingBufferRowPostInsertContext<'a>) -> Result<()> + Send + Sync + Clone + 'static,
156{
157	ClosureRingBufferRowPostInsertInterceptor::new(f)
158}
159
160pub struct RingBufferRowPreUpdateContext<'a> {
161	pub ringbuffer: &'a RingBuffer,
162	pub ids: &'a [RowNumber],
163	pub rows: &'a mut [EncodedRingBufferRowBuilder],
164}
165
166impl<'a> RingBufferRowPreUpdateContext<'a> {
167	pub fn new(
168		ringbuffer: &'a RingBuffer,
169		ids: &'a [RowNumber],
170		rows: &'a mut [EncodedRingBufferRowBuilder],
171	) -> Self {
172		assert_eq!(ids.len(), rows.len(), "ids/rows length mismatch");
173		Self {
174			ringbuffer,
175			ids,
176			rows,
177		}
178	}
179}
180
181pub trait RingBufferRowPreUpdateInterceptor: Send + Sync {
182	fn intercept<'a>(&self, ctx: &mut RingBufferRowPreUpdateContext<'a>) -> Result<()>;
183}
184
185impl InterceptorChain<dyn RingBufferRowPreUpdateInterceptor + Send + Sync> {
186	pub fn execute(&self, mut ctx: RingBufferRowPreUpdateContext) -> Result<()> {
187		let original_len = ctx.rows.len();
188		for interceptor in &self.interceptors {
189			interceptor.intercept(&mut ctx)?;
190			assert_eq!(ctx.rows.len(), original_len, "pre_update interceptor changed row count");
191		}
192		Ok(())
193	}
194}
195
196pub struct ClosureRingBufferRowPreUpdateInterceptor<F>
197where
198	F: for<'a> Fn(&mut RingBufferRowPreUpdateContext<'a>) -> Result<()> + Send + Sync,
199{
200	closure: F,
201}
202
203impl<F> ClosureRingBufferRowPreUpdateInterceptor<F>
204where
205	F: for<'a> Fn(&mut RingBufferRowPreUpdateContext<'a>) -> Result<()> + Send + Sync,
206{
207	pub fn new(closure: F) -> Self {
208		Self {
209			closure,
210		}
211	}
212}
213
214impl<F> Clone for ClosureRingBufferRowPreUpdateInterceptor<F>
215where
216	F: for<'a> Fn(&mut RingBufferRowPreUpdateContext<'a>) -> Result<()> + Send + Sync + Clone,
217{
218	fn clone(&self) -> Self {
219		Self {
220			closure: self.closure.clone(),
221		}
222	}
223}
224
225impl<F> RingBufferRowPreUpdateInterceptor for ClosureRingBufferRowPreUpdateInterceptor<F>
226where
227	F: for<'a> Fn(&mut RingBufferRowPreUpdateContext<'a>) -> Result<()> + Send + Sync,
228{
229	fn intercept<'a>(&self, ctx: &mut RingBufferRowPreUpdateContext<'a>) -> Result<()> {
230		(self.closure)(ctx)
231	}
232}
233
234pub fn ringbuffer_row_pre_update<F>(f: F) -> ClosureRingBufferRowPreUpdateInterceptor<F>
235where
236	F: for<'a> Fn(&mut RingBufferRowPreUpdateContext<'a>) -> Result<()> + Send + Sync + Clone + 'static,
237{
238	ClosureRingBufferRowPreUpdateInterceptor::new(f)
239}
240
241pub struct RingBufferRowPostUpdateContext<'a> {
242	pub ringbuffer: &'a RingBuffer,
243	pub ids: &'a [RowNumber],
244	pub posts: &'a [EncodedBytes],
245	pub pres: &'a [EncodedBytes],
246}
247
248impl<'a> RingBufferRowPostUpdateContext<'a> {
249	pub fn new(
250		ringbuffer: &'a RingBuffer,
251		ids: &'a [RowNumber],
252		posts: &'a [EncodedBytes],
253		pres: &'a [EncodedBytes],
254	) -> Self {
255		assert_eq!(ids.len(), posts.len(), "ids/posts length mismatch");
256		assert_eq!(ids.len(), pres.len(), "ids/pres length mismatch");
257		Self {
258			ringbuffer,
259			ids,
260			posts,
261			pres,
262		}
263	}
264}
265
266pub trait RingBufferRowPostUpdateInterceptor: Send + Sync {
267	fn intercept<'a>(&self, ctx: &mut RingBufferRowPostUpdateContext<'a>) -> Result<()>;
268}
269
270impl InterceptorChain<dyn RingBufferRowPostUpdateInterceptor + Send + Sync> {
271	pub fn execute(&self, mut ctx: RingBufferRowPostUpdateContext) -> Result<()> {
272		for interceptor in &self.interceptors {
273			interceptor.intercept(&mut ctx)?;
274		}
275		Ok(())
276	}
277}
278
279pub struct ClosureRingBufferRowPostUpdateInterceptor<F>
280where
281	F: for<'a> Fn(&mut RingBufferRowPostUpdateContext<'a>) -> Result<()> + Send + Sync,
282{
283	closure: F,
284}
285
286impl<F> ClosureRingBufferRowPostUpdateInterceptor<F>
287where
288	F: for<'a> Fn(&mut RingBufferRowPostUpdateContext<'a>) -> Result<()> + Send + Sync,
289{
290	pub fn new(closure: F) -> Self {
291		Self {
292			closure,
293		}
294	}
295}
296
297impl<F> Clone for ClosureRingBufferRowPostUpdateInterceptor<F>
298where
299	F: for<'a> Fn(&mut RingBufferRowPostUpdateContext<'a>) -> Result<()> + Send + Sync + Clone,
300{
301	fn clone(&self) -> Self {
302		Self {
303			closure: self.closure.clone(),
304		}
305	}
306}
307
308impl<F> RingBufferRowPostUpdateInterceptor for ClosureRingBufferRowPostUpdateInterceptor<F>
309where
310	F: for<'a> Fn(&mut RingBufferRowPostUpdateContext<'a>) -> Result<()> + Send + Sync,
311{
312	fn intercept<'a>(&self, ctx: &mut RingBufferRowPostUpdateContext<'a>) -> Result<()> {
313		(self.closure)(ctx)
314	}
315}
316
317pub fn ringbuffer_row_post_update<F>(f: F) -> ClosureRingBufferRowPostUpdateInterceptor<F>
318where
319	F: for<'a> Fn(&mut RingBufferRowPostUpdateContext<'a>) -> Result<()> + Send + Sync + Clone + 'static,
320{
321	ClosureRingBufferRowPostUpdateInterceptor::new(f)
322}
323
324pub struct RingBufferRowPreDeleteContext<'a> {
325	pub ringbuffer: &'a RingBuffer,
326	pub ids: &'a [RowNumber],
327}
328
329impl<'a> RingBufferRowPreDeleteContext<'a> {
330	pub fn new(ringbuffer: &'a RingBuffer, ids: &'a [RowNumber]) -> Self {
331		Self {
332			ringbuffer,
333			ids,
334		}
335	}
336}
337
338pub trait RingBufferRowPreDeleteInterceptor: Send + Sync {
339	fn intercept<'a>(&self, ctx: &mut RingBufferRowPreDeleteContext<'a>) -> Result<()>;
340}
341
342impl InterceptorChain<dyn RingBufferRowPreDeleteInterceptor + Send + Sync> {
343	pub fn execute(&self, mut ctx: RingBufferRowPreDeleteContext) -> Result<()> {
344		for interceptor in &self.interceptors {
345			interceptor.intercept(&mut ctx)?;
346		}
347		Ok(())
348	}
349}
350
351pub struct ClosureRingBufferRowPreDeleteInterceptor<F>
352where
353	F: for<'a> Fn(&mut RingBufferRowPreDeleteContext<'a>) -> Result<()> + Send + Sync,
354{
355	closure: F,
356}
357
358impl<F> ClosureRingBufferRowPreDeleteInterceptor<F>
359where
360	F: for<'a> Fn(&mut RingBufferRowPreDeleteContext<'a>) -> Result<()> + Send + Sync,
361{
362	pub fn new(closure: F) -> Self {
363		Self {
364			closure,
365		}
366	}
367}
368
369impl<F> Clone for ClosureRingBufferRowPreDeleteInterceptor<F>
370where
371	F: for<'a> Fn(&mut RingBufferRowPreDeleteContext<'a>) -> Result<()> + Send + Sync + Clone,
372{
373	fn clone(&self) -> Self {
374		Self {
375			closure: self.closure.clone(),
376		}
377	}
378}
379
380impl<F> RingBufferRowPreDeleteInterceptor for ClosureRingBufferRowPreDeleteInterceptor<F>
381where
382	F: for<'a> Fn(&mut RingBufferRowPreDeleteContext<'a>) -> Result<()> + Send + Sync,
383{
384	fn intercept<'a>(&self, ctx: &mut RingBufferRowPreDeleteContext<'a>) -> Result<()> {
385		(self.closure)(ctx)
386	}
387}
388
389pub fn ringbuffer_row_pre_delete<F>(f: F) -> ClosureRingBufferRowPreDeleteInterceptor<F>
390where
391	F: for<'a> Fn(&mut RingBufferRowPreDeleteContext<'a>) -> Result<()> + Send + Sync + Clone + 'static,
392{
393	ClosureRingBufferRowPreDeleteInterceptor::new(f)
394}
395
396pub struct RingBufferRowPostDeleteContext<'a> {
397	pub ringbuffer: &'a RingBuffer,
398	pub ids: &'a [RowNumber],
399	pub deleted_rows: &'a [EncodedBytes],
400}
401
402impl<'a> RingBufferRowPostDeleteContext<'a> {
403	pub fn new(ringbuffer: &'a RingBuffer, ids: &'a [RowNumber], deleted_rows: &'a [EncodedBytes]) -> Self {
404		assert_eq!(ids.len(), deleted_rows.len(), "ids/deleted_rows length mismatch");
405		Self {
406			ringbuffer,
407			ids,
408			deleted_rows,
409		}
410	}
411}
412
413pub trait RingBufferRowPostDeleteInterceptor: Send + Sync {
414	fn intercept<'a>(&self, ctx: &mut RingBufferRowPostDeleteContext<'a>) -> Result<()>;
415}
416
417impl InterceptorChain<dyn RingBufferRowPostDeleteInterceptor + Send + Sync> {
418	pub fn execute(&self, mut ctx: RingBufferRowPostDeleteContext) -> Result<()> {
419		for interceptor in &self.interceptors {
420			interceptor.intercept(&mut ctx)?;
421		}
422		Ok(())
423	}
424}
425
426pub struct ClosureRingBufferRowPostDeleteInterceptor<F>
427where
428	F: for<'a> Fn(&mut RingBufferRowPostDeleteContext<'a>) -> Result<()> + Send + Sync,
429{
430	closure: F,
431}
432
433impl<F> ClosureRingBufferRowPostDeleteInterceptor<F>
434where
435	F: for<'a> Fn(&mut RingBufferRowPostDeleteContext<'a>) -> Result<()> + Send + Sync,
436{
437	pub fn new(closure: F) -> Self {
438		Self {
439			closure,
440		}
441	}
442}
443
444impl<F> Clone for ClosureRingBufferRowPostDeleteInterceptor<F>
445where
446	F: for<'a> Fn(&mut RingBufferRowPostDeleteContext<'a>) -> Result<()> + Send + Sync + Clone,
447{
448	fn clone(&self) -> Self {
449		Self {
450			closure: self.closure.clone(),
451		}
452	}
453}
454
455impl<F> RingBufferRowPostDeleteInterceptor for ClosureRingBufferRowPostDeleteInterceptor<F>
456where
457	F: for<'a> Fn(&mut RingBufferRowPostDeleteContext<'a>) -> Result<()> + Send + Sync,
458{
459	fn intercept<'a>(&self, ctx: &mut RingBufferRowPostDeleteContext<'a>) -> Result<()> {
460		(self.closure)(ctx)
461	}
462}
463
464pub fn ringbuffer_row_post_delete<F>(f: F) -> ClosureRingBufferRowPostDeleteInterceptor<F>
465where
466	F: for<'a> Fn(&mut RingBufferRowPostDeleteContext<'a>) -> Result<()> + Send + Sync + Clone + 'static,
467{
468	ClosureRingBufferRowPostDeleteInterceptor::new(f)
469}
470
471pub struct RingBufferRowInterceptor;
472
473impl RingBufferRowInterceptor {
474	pub fn pre_insert(
475		txn: &mut impl WithInterceptors,
476		ringbuffer: &RingBuffer,
477		rows: &mut [EncodedRingBufferRowBuilder],
478	) -> Result<()> {
479		let ctx = RingBufferRowPreInsertContext::new(ringbuffer, rows);
480		txn.ringbuffer_row_pre_insert_interceptors().execute(ctx)
481	}
482
483	pub fn post_insert(
484		txn: &mut impl WithInterceptors,
485		ringbuffer: &RingBuffer,
486		ids: &[RowNumber],
487		bytes_slice: &[EncodedBytes],
488	) -> Result<()> {
489		let ctx = RingBufferRowPostInsertContext::new(ringbuffer, ids, bytes_slice);
490		txn.ringbuffer_row_post_insert_interceptors().execute(ctx)
491	}
492
493	pub fn pre_update(
494		txn: &mut impl WithInterceptors,
495		ringbuffer: &RingBuffer,
496		ids: &[RowNumber],
497		rows: &mut [EncodedRingBufferRowBuilder],
498	) -> Result<()> {
499		let ctx = RingBufferRowPreUpdateContext::new(ringbuffer, ids, rows);
500		txn.ringbuffer_row_pre_update_interceptors().execute(ctx)
501	}
502
503	pub fn post_update(
504		txn: &mut impl WithInterceptors,
505		ringbuffer: &RingBuffer,
506		ids: &[RowNumber],
507		posts: &[EncodedBytes],
508		pres: &[EncodedBytes],
509	) -> Result<()> {
510		let ctx = RingBufferRowPostUpdateContext::new(ringbuffer, ids, posts, pres);
511		txn.ringbuffer_row_post_update_interceptors().execute(ctx)
512	}
513
514	pub fn pre_delete(txn: &mut impl WithInterceptors, ringbuffer: &RingBuffer, ids: &[RowNumber]) -> Result<()> {
515		let ctx = RingBufferRowPreDeleteContext::new(ringbuffer, ids);
516		txn.ringbuffer_row_pre_delete_interceptors().execute(ctx)
517	}
518
519	pub fn post_delete(
520		txn: &mut impl WithInterceptors,
521		ringbuffer: &RingBuffer,
522		ids: &[RowNumber],
523		deleted: &[EncodedBytes],
524	) -> Result<()> {
525		let ctx = RingBufferRowPostDeleteContext::new(ringbuffer, ids, deleted);
526		txn.ringbuffer_row_post_delete_interceptors().execute(ctx)
527	}
528}