Skip to main content

reifydb_codec/row/operator/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use std::ops::Deref;
5
6use reifydb_value::{byte_size::ByteSize, encoding::LeBytes, util::cowvec::CowVec, value::datetime::DateTime};
7
8use crate::row::bytes::{EncodedBytes, EncodedRowBuilder, RowBuilder, read_defined_at, sealed::Sealed};
9
10pub mod state;
11
12const TIME_OFFSET: usize = 0;
13
14pub const OPERATOR_HEADER_SIZE: usize = TIME_OFFSET + DateTime::ENCODED_SIZE;
15
16#[inline]
17pub fn read_time(buf: &[u8]) -> Option<DateTime> {
18	let time = DateTime::from_le_bytes(
19		buf[TIME_OFFSET..OPERATOR_HEADER_SIZE].try_into().expect("the operator header is length-checked"),
20	);
21	(time != DateTime::MAX).then_some(time)
22}
23
24#[inline]
25pub fn write_time(buf: &mut [u8], time: DateTime) {
26	buf[TIME_OFFSET..OPERATOR_HEADER_SIZE].copy_from_slice(&time.to_le_bytes());
27}
28
29#[repr(transparent)]
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct EncodedOperatorRow(EncodedBytes);
32
33impl EncodedOperatorRow {
34	pub fn new(body: &[u8], time: DateTime) -> Self {
35		let mut buffer = Vec::with_capacity(OPERATOR_HEADER_SIZE + body.len());
36		buffer.extend_from_slice(&time.to_le_bytes());
37		buffer.extend_from_slice(body);
38		Self(EncodedBytes(CowVec::new(buffer)))
39	}
40
41	pub fn timeless(body: &[u8]) -> Self {
42		Self::new(body, DateTime::MAX)
43	}
44
45	pub fn view(bytes: &EncodedBytes) -> &Self {
46		// SAFETY: EncodedOperatorRow is repr(transparent) over EncodedBytes, so the pointer cast
47		// preserves layout, and the returned reference borrows the same allocation for the same lifetime.
48		unsafe { &*(bytes as *const EncodedBytes as *const Self) }
49	}
50
51	pub fn bytes(&self) -> &EncodedBytes {
52		&self.0
53	}
54
55	pub fn as_slice(&self) -> &[u8] {
56		self.0.as_slice()
57	}
58
59	pub fn into_bytes(self) -> EncodedBytes {
60		self.0
61	}
62
63	#[inline]
64	pub fn row_time(&self) -> Option<DateTime> {
65		read_time(&self.0)
66	}
67
68	#[inline]
69	pub fn time(&self) -> DateTime {
70		DateTime::from_le_bytes(
71			self.0[TIME_OFFSET..OPERATOR_HEADER_SIZE].try_into().expect("the header is length-checked"),
72		)
73	}
74
75	pub fn set_time(&mut self, time: DateTime) {
76		write_time(self.0.make_mut(), time);
77	}
78
79	pub fn body(&self) -> &[u8] {
80		&self.0[OPERATOR_HEADER_SIZE..]
81	}
82
83	pub fn body_mut(&mut self) -> &mut [u8] {
84		&mut self.0.make_mut()[OPERATOR_HEADER_SIZE..]
85	}
86
87	pub fn len(&self) -> usize {
88		self.0.len()
89	}
90
91	pub fn is_empty(&self) -> bool {
92		self.body().is_empty()
93	}
94
95	pub fn byte_size(&self) -> ByteSize {
96		ByteSize::from(self.0.len() as u64)
97	}
98}
99
100impl From<EncodedBytes> for EncodedOperatorRow {
101	fn from(bytes: EncodedBytes) -> Self {
102		Self(bytes)
103	}
104}
105
106impl From<EncodedOperatorRow> for EncodedBytes {
107	fn from(row: EncodedOperatorRow) -> Self {
108		row.0
109	}
110}
111
112#[repr(transparent)]
113#[derive(Debug, Clone, PartialEq, Eq)]
114pub struct EncodedOperatorRowBuilder(EncodedRowBuilder);
115
116impl EncodedOperatorRowBuilder {
117	pub(crate) fn wrap(builder: EncodedRowBuilder) -> Self {
118		Self(builder)
119	}
120
121	#[inline]
122	pub fn row_time(&self) -> Option<DateTime> {
123		read_time(self.as_slice())
124	}
125
126	pub fn set_time(&mut self, time: DateTime) {
127		write_time(self.as_mut_slice(), time);
128	}
129
130	#[inline]
131	pub fn is_defined(&self, index: usize) -> bool {
132		read_defined_at(self.as_slice(), OPERATOR_HEADER_SIZE, index)
133	}
134
135	pub fn body(&self) -> &[u8] {
136		&self.as_slice()[OPERATOR_HEADER_SIZE..]
137	}
138
139	pub fn freeze(self) -> EncodedOperatorRow {
140		EncodedOperatorRow(self.0.freeze())
141	}
142}
143
144impl Sealed for EncodedOperatorRowBuilder {
145	fn buffer(&self) -> &Vec<u8> {
146		self.0.buffer()
147	}
148
149	fn buffer_mut(&mut self) -> &mut Vec<u8> {
150		self.0.buffer_mut()
151	}
152
153	fn take_buffer(self) -> Vec<u8> {
154		self.0.take_buffer()
155	}
156}
157
158impl EncodedOperatorRow {
159	pub fn thaw(self) -> EncodedOperatorRowBuilder {
160		EncodedOperatorRowBuilder(self.0.thaw())
161	}
162}
163
164impl Deref for EncodedOperatorRowBuilder {
165	type Target = [u8];
166
167	fn deref(&self) -> &Self::Target {
168		self.as_slice()
169	}
170}