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