reifydb_codec/row/catalog/
mod.rs1use std::ops::Deref;
5
6use reifydb_value::{
7 byte_size::ByteSize,
8 error::{Error as ValueError, TypeError},
9 util::cowvec::CowVec,
10};
11use thiserror::Error;
12
13use crate::row::{
14 bytes::{CATALOG_HEADER_SIZE, EncodedBytes, EncodedRowBuilder, RowBuilder, read_defined_at, sealed::Sealed},
15 shape::fingerprint::RowShapeFingerprint,
16};
17
18const FINGERPRINT_OFFSET: usize = 0;
19
20#[derive(Debug, Error, PartialEq)]
21pub enum CatalogError {
22 #[error("catalog row is {len} bytes, too short to carry the fingerprint header")]
23 Truncated {
24 len: usize,
25 },
26}
27
28impl From<CatalogError> for ValueError {
29 fn from(err: CatalogError) -> Self {
30 TypeError::SerdeDeserialize {
31 message: err.to_string(),
32 }
33 .into()
34 }
35}
36
37#[inline]
38pub fn read_fingerprint(buf: &[u8]) -> RowShapeFingerprint {
39 RowShapeFingerprint::from_le_bytes(
40 buf[FINGERPRINT_OFFSET..CATALOG_HEADER_SIZE].try_into().expect("the catalog header is length-checked"),
41 )
42}
43
44#[inline]
45pub fn write_fingerprint(buf: &mut [u8], fingerprint: RowShapeFingerprint) {
46 buf[FINGERPRINT_OFFSET..CATALOG_HEADER_SIZE].copy_from_slice(&fingerprint.to_le_bytes());
47}
48
49#[repr(transparent)]
50#[derive(Debug, Clone, PartialEq)]
51pub struct EncodedCatalogRow(EncodedBytes);
52
53impl EncodedCatalogRow {
54 pub fn new(body: &[u8], fingerprint: RowShapeFingerprint) -> Self {
55 let mut buffer = Vec::with_capacity(CATALOG_HEADER_SIZE + body.len());
56 buffer.extend_from_slice(&fingerprint.to_le_bytes());
57 buffer.extend_from_slice(body);
58 Self(EncodedBytes(CowVec::new(buffer)))
59 }
60
61 pub fn view(bytes: &EncodedBytes) -> &Self {
62 unsafe { &*(bytes as *const EncodedBytes as *const Self) }
65 }
66
67 pub fn bytes(&self) -> &EncodedBytes {
68 &self.0
69 }
70
71 pub fn as_slice(&self) -> &[u8] {
72 self.0.as_slice()
73 }
74
75 pub fn into_bytes(self) -> EncodedBytes {
76 self.0
77 }
78
79 #[inline]
80 pub fn fingerprint(&self) -> RowShapeFingerprint {
81 read_fingerprint(&self.0)
82 }
83
84 pub fn set_fingerprint(&mut self, fingerprint: RowShapeFingerprint) {
85 write_fingerprint(self.0.make_mut(), fingerprint);
86 }
87
88 #[inline]
89 pub fn is_defined(&self, index: usize) -> bool {
90 read_defined_at(&self.0, CATALOG_HEADER_SIZE, index)
91 }
92
93 pub fn body(&self) -> &[u8] {
94 &self.0[CATALOG_HEADER_SIZE..]
95 }
96
97 pub fn body_mut(&mut self) -> &mut [u8] {
98 &mut self.0.make_mut()[CATALOG_HEADER_SIZE..]
99 }
100
101 pub fn len(&self) -> usize {
102 self.0.len()
103 }
104
105 pub fn is_empty(&self) -> bool {
106 self.body().is_empty()
107 }
108
109 pub fn byte_size(&self) -> ByteSize {
110 ByteSize::from(self.0.len() as u64)
111 }
112
113 pub fn thaw(self) -> EncodedCatalogRowBuilder {
114 EncodedCatalogRowBuilder(self.0.thaw())
115 }
116}
117
118impl TryFrom<EncodedBytes> for EncodedCatalogRow {
119 type Error = CatalogError;
120
121 fn try_from(bytes: EncodedBytes) -> Result<Self, Self::Error> {
122 if bytes.len() < CATALOG_HEADER_SIZE {
123 return Err(CatalogError::Truncated {
124 len: bytes.len(),
125 });
126 }
127 Ok(Self(bytes))
128 }
129}
130
131impl From<EncodedCatalogRow> for EncodedBytes {
132 fn from(row: EncodedCatalogRow) -> Self {
133 row.0
134 }
135}
136
137#[repr(transparent)]
138#[derive(Debug, Clone, PartialEq, Eq)]
139pub struct EncodedCatalogRowBuilder(EncodedRowBuilder);
140
141impl EncodedCatalogRowBuilder {
142 pub(crate) fn wrap(builder: EncodedRowBuilder) -> Self {
143 Self(builder)
144 }
145
146 #[inline]
147 pub fn fingerprint(&self) -> RowShapeFingerprint {
148 read_fingerprint(self.as_slice())
149 }
150
151 pub fn set_fingerprint(&mut self, fingerprint: RowShapeFingerprint) {
152 write_fingerprint(self.as_mut_slice(), fingerprint);
153 }
154
155 #[inline]
156 pub fn is_defined(&self, index: usize) -> bool {
157 read_defined_at(self.as_slice(), CATALOG_HEADER_SIZE, index)
158 }
159
160 pub fn body(&self) -> &[u8] {
161 &self.as_slice()[CATALOG_HEADER_SIZE..]
162 }
163
164 pub fn freeze(self) -> EncodedCatalogRow {
165 EncodedCatalogRow(self.0.freeze())
166 }
167}
168
169impl Sealed for EncodedCatalogRowBuilder {
170 fn buffer(&self) -> &Vec<u8> {
171 self.0.buffer()
172 }
173
174 fn buffer_mut(&mut self) -> &mut Vec<u8> {
175 self.0.buffer_mut()
176 }
177
178 fn take_buffer(self) -> Vec<u8> {
179 self.0.take_buffer()
180 }
181}
182
183impl Deref for EncodedCatalogRowBuilder {
184 type Target = [u8];
185
186 fn deref(&self) -> &Self::Target {
187 self.as_slice()
188 }
189}