reifydb_codec/row/operator/
mod.rs1use std::{cell::RefCell, collections::BTreeMap, mem, ops::Deref};
5
6use postcard::{from_bytes, to_extend};
7use reifydb_value::{
8 byte_size::ByteSize,
9 encoding::LeBytes,
10 error::{Error as ValueError, TypeError},
11 util::cowvec::CowVec,
12 value::datetime::DateTime,
13};
14use serde::{Serialize, de::DeserializeOwned};
15use thiserror::Error;
16
17use crate::row::bytes::{EncodedBytes, EncodedRowBuilder, RowBuilder, read_defined_at, sealed::Sealed};
18
19const CREATED_AT_OFFSET: usize = 0;
20
21const UPDATED_AT_OFFSET: usize = CREATED_AT_OFFSET + DateTime::ENCODED_SIZE;
22
23const TIME_OFFSET: usize = UPDATED_AT_OFFSET + DateTime::ENCODED_SIZE;
24
25pub const OPERATOR_HEADER_SIZE: usize = TIME_OFFSET + DateTime::ENCODED_SIZE;
26
27impl From<OperatorError> for ValueError {
28 fn from(err: OperatorError) -> Self {
29 match err {
30 OperatorError::Serialization(_) => TypeError::SerdeSerialize {
31 message: err.to_string(),
32 }
33 .into(),
34 _ => TypeError::SerdeDeserialize {
35 message: err.to_string(),
36 }
37 .into(),
38 }
39 }
40}
41
42#[derive(Debug, Error, PartialEq)]
43pub enum OperatorError {
44 #[error("operator state serialization failed: {0}")]
45 Serialization(String),
46
47 #[error("operator state deserialization failed: {0}")]
48 Deserialization(String),
49
50 #[error("operator row is {len} bytes, too short to carry the time header")]
51 Truncated {
52 len: usize,
53 },
54}
55
56#[inline]
57pub fn read_time(buf: &[u8]) -> Option<DateTime> {
58 let time = DateTime::from_le_bytes(
59 buf[TIME_OFFSET..OPERATOR_HEADER_SIZE].try_into().expect("the operator header is length-checked"),
60 );
61 (time != DateTime::MAX).then_some(time)
62}
63
64#[inline]
65pub fn write_time(buf: &mut [u8], time: DateTime) {
66 buf[TIME_OFFSET..OPERATOR_HEADER_SIZE].copy_from_slice(&time.to_le_bytes());
67}
68
69#[inline]
70pub fn read_created_at(buf: &[u8]) -> DateTime {
71 DateTime::from_le_bytes(
72 buf[CREATED_AT_OFFSET..UPDATED_AT_OFFSET].try_into().expect("the operator header is length-checked"),
73 )
74}
75
76#[inline]
77pub fn write_created_at(buf: &mut [u8], created_at: DateTime) {
78 buf[CREATED_AT_OFFSET..UPDATED_AT_OFFSET].copy_from_slice(&created_at.to_le_bytes());
79}
80
81#[inline]
82pub fn read_updated_at(buf: &[u8]) -> DateTime {
83 DateTime::from_le_bytes(
84 buf[UPDATED_AT_OFFSET..TIME_OFFSET].try_into().expect("the operator header is length-checked"),
85 )
86}
87
88#[inline]
89pub fn write_updated_at(buf: &mut [u8], updated_at: DateTime) {
90 buf[UPDATED_AT_OFFSET..TIME_OFFSET].copy_from_slice(&updated_at.to_le_bytes());
91}
92
93#[repr(transparent)]
94#[derive(Debug, Clone, PartialEq)]
95pub struct EncodedOperatorRow(EncodedBytes);
96
97impl EncodedOperatorRow {
98 pub fn new(body: &[u8], time: DateTime) -> Self {
99 let mut buffer = Vec::with_capacity(OPERATOR_HEADER_SIZE + body.len());
100 buffer.extend_from_slice(&DateTime::EPOCH.to_le_bytes());
101 buffer.extend_from_slice(&DateTime::EPOCH.to_le_bytes());
102 buffer.extend_from_slice(&time.to_le_bytes());
103 buffer.extend_from_slice(body);
104 Self(EncodedBytes(CowVec::new(buffer)))
105 }
106
107 pub fn timeless(body: &[u8]) -> Self {
108 Self::new(body, DateTime::MAX)
109 }
110
111 pub fn into_bytes(self) -> EncodedBytes {
112 self.0
113 }
114
115 pub fn bytes(&self) -> &EncodedBytes {
116 &self.0
117 }
118
119 pub fn view(bytes: &EncodedBytes) -> &Self {
120 unsafe { &*(bytes as *const EncodedBytes as *const Self) }
123 }
124
125 #[inline]
126 pub fn row_time(&self) -> Option<DateTime> {
127 read_time(&self.0)
128 }
129
130 #[inline]
131 pub fn time(&self) -> DateTime {
132 DateTime::from_le_bytes(
133 self.0[TIME_OFFSET..OPERATOR_HEADER_SIZE].try_into().expect("the header is length-checked"),
134 )
135 }
136
137 pub fn set_time(&mut self, time: DateTime) {
138 self.0.make_mut()[TIME_OFFSET..OPERATOR_HEADER_SIZE].copy_from_slice(&time.to_le_bytes());
139 }
140
141 pub fn body(&self) -> &[u8] {
142 &self.0[OPERATOR_HEADER_SIZE..]
143 }
144
145 pub fn body_mut(&mut self) -> &mut [u8] {
146 &mut self.0.make_mut()[OPERATOR_HEADER_SIZE..]
147 }
148
149 pub fn len(&self) -> usize {
150 self.0.len()
151 }
152
153 pub fn is_empty(&self) -> bool {
154 self.body().is_empty()
155 }
156
157 pub fn byte_size(&self) -> ByteSize {
158 ByteSize::from(self.0.len() as u64)
159 }
160}
161
162impl TryFrom<EncodedBytes> for EncodedOperatorRow {
163 type Error = OperatorError;
164
165 fn try_from(bytes: EncodedBytes) -> Result<Self, Self::Error> {
166 if bytes.len() < OPERATOR_HEADER_SIZE {
167 return Err(OperatorError::Truncated {
168 len: bytes.len(),
169 });
170 }
171 Ok(Self(bytes))
172 }
173}
174
175impl From<EncodedOperatorRow> for EncodedBytes {
176 fn from(row: EncodedOperatorRow) -> Self {
177 row.0
178 }
179}
180
181#[repr(transparent)]
184#[derive(Debug, Clone, PartialEq, Eq)]
185pub struct EncodedOperatorRowBuilder(EncodedRowBuilder);
186
187impl EncodedOperatorRowBuilder {
188 pub(crate) fn wrap(builder: EncodedRowBuilder) -> Self {
189 Self(builder)
190 }
191
192 #[inline]
193 pub fn row_time(&self) -> Option<DateTime> {
194 read_time(self.as_slice())
195 }
196
197 pub fn set_time(&mut self, time: DateTime) {
198 write_time(self.as_mut_slice(), time);
199 }
200
201 #[inline]
202 pub fn created_at(&self) -> DateTime {
203 read_created_at(self.as_slice())
204 }
205
206 #[inline]
207 pub fn updated_at(&self) -> DateTime {
208 read_updated_at(self.as_slice())
209 }
210
211 pub fn set_timestamps(&mut self, created_at: DateTime, updated_at: DateTime) {
212 write_created_at(self.as_mut_slice(), created_at);
213 write_updated_at(self.as_mut_slice(), updated_at);
214 }
215
216 #[inline]
217 pub fn is_defined(&self, index: usize) -> bool {
218 read_defined_at(self.as_slice(), OPERATOR_HEADER_SIZE, index)
219 }
220
221 pub fn body(&self) -> &[u8] {
222 &self.as_slice()[OPERATOR_HEADER_SIZE..]
223 }
224
225 pub fn freeze(self) -> EncodedOperatorRow {
226 EncodedOperatorRow(self.0.freeze())
227 }
228}
229
230impl Sealed for EncodedOperatorRowBuilder {
231 fn buffer(&self) -> &Vec<u8> {
232 self.0.buffer()
233 }
234
235 fn buffer_mut(&mut self) -> &mut Vec<u8> {
236 self.0.buffer_mut()
237 }
238
239 fn take_buffer(self) -> Vec<u8> {
240 self.0.take_buffer()
241 }
242}
243
244impl EncodedOperatorRow {
245 pub fn thaw(self) -> EncodedOperatorRowBuilder {
246 EncodedOperatorRowBuilder(self.0.thaw())
247 }
248}
249
250pub trait OperatorState: Sized + Send + 'static {
251 fn encode_state(&self, now: DateTime) -> Result<EncodedOperatorRow, OperatorError>;
252
253 fn decode_state(row: &EncodedOperatorRow) -> Result<Self, OperatorError>;
254}
255
256thread_local! {
257 static ENCODE_BUFFER: RefCell<Vec<u8>> = const { RefCell::new(Vec::new()) };
258}
259
260pub fn encode<T>(value: &T, now: DateTime) -> Result<EncodedOperatorRow, OperatorError>
261where
262 T: Serialize,
263{
264 let mut buffer = ENCODE_BUFFER.with(|cell| mem::take(&mut *cell.borrow_mut()));
265 buffer.clear();
266 let mut filled = to_extend(value, buffer).map_err(|e| OperatorError::Serialization(e.to_string()))?;
267 let result = EncodedOperatorRow::new(&filled, now);
268 filled.clear();
269 ENCODE_BUFFER.with(|cell| *cell.borrow_mut() = filled);
270 Ok(result)
271}
272
273pub fn decode_body<T>(row: &EncodedOperatorRow) -> Result<T, OperatorError>
274where
275 T: DeserializeOwned,
276{
277 from_bytes(row.body()).map_err(|e| OperatorError::Deserialization(e.to_string()))
278}
279
280pub fn decode<T: OperatorState>(row: &EncodedOperatorRow) -> Result<T, OperatorError> {
281 T::decode_state(row)
282}
283
284pub mod derive {
285 pub use serde::{self, Deserialize, Serialize};
286}
287
288pub trait StateCodec: Sized + Send + 'static + Serialize + DeserializeOwned {}
289
290impl<T> StateCodec for T where T: Sized + Send + 'static + Serialize + DeserializeOwned {}
291
292macro_rules! leaf_operator_state {
293 ($($ty:ty),* $(,)?) => {
294 $(impl OperatorState for $ty {
295 fn encode_state(&self, now: DateTime) -> Result<EncodedOperatorRow, OperatorError> {
296 encode(self, now)
297 }
298
299 fn decode_state(row: &EncodedOperatorRow) -> Result<Self, OperatorError> {
300 decode_body::<Self>(row)
301 }
302 })*
303 };
304}
305
306leaf_operator_state!(u64, i64, Vec<u8>, (i64, i64, i64), DateTime);
307
308impl<K, V> OperatorState for BTreeMap<K, V>
309where
310 K: Send + 'static,
311 V: Send + 'static,
312 Self: Serialize + DeserializeOwned,
313{
314 fn encode_state(&self, now: DateTime) -> Result<EncodedOperatorRow, OperatorError> {
315 encode(self, now)
316 }
317
318 fn decode_state(row: &EncodedOperatorRow) -> Result<Self, OperatorError> {
319 decode_body::<Self>(row)
320 }
321}
322
323impl Deref for EncodedOperatorRowBuilder {
324 type Target = [u8];
325
326 fn deref(&self) -> &Self::Target {
327 self.as_slice()
328 }
329}