reifydb_codec/frame/encoding/
plain.rs1use std::iter;
5
6use reifydb_value::{
7 util::bitvec::BitVec,
8 value::{
9 Value,
10 container::{blob::BlobContainer, dictionary::DictionaryContainer, utf8::Utf8Container},
11 date::Date,
12 datetime::DateTime,
13 decimal::Decimal,
14 dictionary::DictionaryEntryId,
15 duration::Duration,
16 frame::data::FrameColumnData,
17 identity::IdentityId,
18 int::Int,
19 time::Time,
20 uint::Uint,
21 uuid::{Uuid4, Uuid7},
22 value_type::ValueType,
23 },
24};
25
26use crate::{error::EncodeError, frame::encode::any::encode_any_value, tag::ValueKind};
27
28macro_rules! encode_fixed {
29 ($container:expr, $ty:expr, $elem_size:expr) => {{
30 let slice = &**$container;
31 let mut buf = Vec::with_capacity(slice.len() * $elem_size);
32 for v in slice {
33 buf.extend_from_slice(&v.to_le_bytes());
34 }
35 PlainEncoded {
36 data: buf,
37 offsets: vec![],
38 nones: vec![],
39 type_code: ValueKind::of_type(&$ty).byte(),
40 has_nones: false,
41 }
42 }};
43}
44
45pub struct PlainEncoded {
46 pub data: Vec<u8>,
47
48 pub offsets: Vec<u8>,
49
50 pub nones: Vec<u8>,
51
52 pub type_code: u8,
53
54 pub has_nones: bool,
55}
56
57pub fn encode_plain(col: &FrameColumnData) -> Result<PlainEncoded, EncodeError> {
58 match col {
59 FrameColumnData::Option {
60 inner,
61 bitvec,
62 } => {
63 let mut result = encode_plain_inner(inner)?;
64 result.nones = encode_bitvec(bitvec);
65 result.has_nones = true;
66 Ok(result)
67 }
68 other => encode_plain_inner(other),
69 }
70}
71
72fn encode_plain_inner(col: &FrameColumnData) -> Result<PlainEncoded, EncodeError> {
73 let result = match col {
74 FrameColumnData::Bool(c) => {
75 let bv: &BitVec = c;
76 PlainEncoded {
77 data: encode_bitvec(bv),
78 offsets: vec![],
79 nones: vec![],
80 type_code: ValueKind::Boolean.byte(),
81 has_nones: false,
82 }
83 }
84 FrameColumnData::Float4(c) => encode_fixed!(c, ValueType::Float4, 4),
85 FrameColumnData::Float8(c) => encode_fixed!(c, ValueType::Float8, 8),
86 FrameColumnData::Int1(c) => encode_fixed!(c, ValueType::Int1, 1),
87 FrameColumnData::Int2(c) => encode_fixed!(c, ValueType::Int2, 2),
88 FrameColumnData::Int4(c) => encode_fixed!(c, ValueType::Int4, 4),
89 FrameColumnData::Int8(c) => encode_fixed!(c, ValueType::Int8, 8),
90 FrameColumnData::Int16(c) => encode_fixed!(c, ValueType::Int16, 16),
91 FrameColumnData::Uint1(c) => encode_fixed!(c, ValueType::Uint1, 1),
92 FrameColumnData::Uint2(c) => encode_fixed!(c, ValueType::Uint2, 2),
93 FrameColumnData::Uint4(c) => encode_fixed!(c, ValueType::Uint4, 4),
94 FrameColumnData::Uint8(c) => encode_fixed!(c, ValueType::Uint8, 8),
95 FrameColumnData::Uint16(c) => encode_fixed!(c, ValueType::Uint16, 16),
96 FrameColumnData::Date(c) => {
97 let slice: &[Date] = c;
98 let mut buf = Vec::with_capacity(slice.len() * 4);
99 for v in slice {
100 buf.extend_from_slice(&v.to_days_since_epoch().to_le_bytes());
101 }
102 PlainEncoded {
103 data: buf,
104 offsets: vec![],
105 nones: vec![],
106 type_code: ValueKind::Date.byte(),
107 has_nones: false,
108 }
109 }
110 FrameColumnData::DateTime(c) => {
111 let slice: &[DateTime] = c;
112 let mut buf = Vec::with_capacity(slice.len() * 8);
113 for v in slice {
114 buf.extend_from_slice(&v.to_nanos().to_le_bytes());
115 }
116 PlainEncoded {
117 data: buf,
118 offsets: vec![],
119 nones: vec![],
120 type_code: ValueKind::DateTime.byte(),
121 has_nones: false,
122 }
123 }
124 FrameColumnData::Time(c) => {
125 let slice: &[Time] = c;
126 let mut buf = Vec::with_capacity(slice.len() * 8);
127 for v in slice {
128 buf.extend_from_slice(&v.to_nanos_since_midnight().to_le_bytes());
129 }
130 PlainEncoded {
131 data: buf,
132 offsets: vec![],
133 nones: vec![],
134 type_code: ValueKind::Time.byte(),
135 has_nones: false,
136 }
137 }
138 FrameColumnData::Duration(c) => {
139 let slice: &[Duration] = c;
140 let mut buf = Vec::with_capacity(slice.len() * 16);
141 for v in slice {
142 buf.extend_from_slice(&v.get_months().to_le_bytes());
143 buf.extend_from_slice(&v.get_days().to_le_bytes());
144 buf.extend_from_slice(&v.get_nanos().to_le_bytes());
145 }
146 PlainEncoded {
147 data: buf,
148 offsets: vec![],
149 nones: vec![],
150 type_code: ValueKind::Duration.byte(),
151 has_nones: false,
152 }
153 }
154 FrameColumnData::IdentityId(c) => {
155 let slice: &[IdentityId] = c;
156 let mut buf = Vec::with_capacity(slice.len() * 16);
157 for v in slice {
158 buf.extend_from_slice(v.0.0.as_bytes());
159 }
160 PlainEncoded {
161 data: buf,
162 offsets: vec![],
163 nones: vec![],
164 type_code: ValueKind::IdentityId.byte(),
165 has_nones: false,
166 }
167 }
168 FrameColumnData::Uuid4(c) => {
169 let slice: &[Uuid4] = c;
170 let mut buf = Vec::with_capacity(slice.len() * 16);
171 for v in slice {
172 buf.extend_from_slice(v.0.as_bytes());
173 }
174 PlainEncoded {
175 data: buf,
176 offsets: vec![],
177 nones: vec![],
178 type_code: ValueKind::Uuid4.byte(),
179 has_nones: false,
180 }
181 }
182 FrameColumnData::Uuid7(c) => {
183 let slice: &[Uuid7] = c;
184 let mut buf = Vec::with_capacity(slice.len() * 16);
185 for v in slice {
186 buf.extend_from_slice(v.0.as_bytes());
187 }
188 PlainEncoded {
189 data: buf,
190 offsets: vec![],
191 nones: vec![],
192 type_code: ValueKind::Uuid7.byte(),
193 has_nones: false,
194 }
195 }
196 FrameColumnData::Utf8(c) => encode_varlen_strings(c, ValueType::Utf8),
197 FrameColumnData::Blob(c) => encode_varlen_blobs(c, ValueType::Blob),
198 FrameColumnData::Int(c) => {
199 let slice: &[Int] = c;
200 encode_varlen(slice.len(), |i| slice[i].0.to_signed_bytes_le(), ValueType::Int)
201 }
202 FrameColumnData::Uint(c) => {
203 let slice: &[Uint] = c;
204 encode_varlen(slice.len(), |i| slice[i].0.to_signed_bytes_le(), ValueType::Uint)
205 }
206 FrameColumnData::Decimal(c) => {
207 let slice: &[Decimal] = c;
208 encode_varlen(slice.len(), |i| slice[i].to_string().into_bytes(), ValueType::Decimal)
209 }
210 FrameColumnData::Any(c) => {
211 let mut data = Vec::new();
212 let none = Value::none();
213 for i in 0..c.len() {
214 let val = c.get(i).unwrap_or(&none);
215 encode_any_value(val, &mut data)?;
216 }
217 return Ok(PlainEncoded {
218 data,
219 offsets: vec![],
220 nones: vec![],
221 type_code: ValueKind::Any.byte(),
222 has_nones: false,
223 });
224 }
225 FrameColumnData::DictionaryId(c) => encode_dictionary_ids(c),
226 FrameColumnData::Option {
227 ..
228 } => unreachable!("Option handled in encode_plain"),
229 };
230 Ok(result)
231}
232
233fn encode_varlen(count: usize, get_bytes: impl Fn(usize) -> Vec<u8>, ty: ValueType) -> PlainEncoded {
234 let mut offsets = Vec::with_capacity((count + 1) * 4);
235 let mut data = Vec::new();
236 let mut offset: u32 = 0;
237 offsets.extend_from_slice(&offset.to_le_bytes());
238 for i in 0..count {
239 let bytes = get_bytes(i);
240 data.extend_from_slice(&bytes);
241 offset += bytes.len() as u32;
242 offsets.extend_from_slice(&offset.to_le_bytes());
243 }
244 PlainEncoded {
245 data,
246 offsets,
247 nones: vec![],
248 type_code: ValueKind::of_type(&ty).byte(),
249 has_nones: false,
250 }
251}
252
253fn encode_varlen_strings(c: &Utf8Container, ty: ValueType) -> PlainEncoded {
254 encode_varlen(c.len(), |i| c.get(i).unwrap().as_bytes().to_vec(), ty)
255}
256
257fn encode_varlen_blobs(c: &BlobContainer, ty: ValueType) -> PlainEncoded {
258 encode_varlen(c.len(), |i| c.get(i).unwrap_or(&[]).to_vec(), ty)
259}
260
261fn encode_dictionary_ids(c: &DictionaryContainer) -> PlainEncoded {
262 let mut buf = Vec::new();
263 if !c.is_empty() {
264 let mut disc = 1u8;
265 for i in 0..c.len() {
266 if let Some(id) = c.get(i) {
267 let d = match id {
268 DictionaryEntryId::U1(_) => 1u8,
269 DictionaryEntryId::U2(_) => 2u8,
270 DictionaryEntryId::U4(_) => 4u8,
271 DictionaryEntryId::U8(_) => 8u8,
272 DictionaryEntryId::U16(_) => 16u8,
273 };
274 if d > disc {
275 disc = d;
276 }
277 }
278 }
279
280 buf.push(disc);
281 for i in 0..c.len() {
282 if let Some(id) = c.get(i) {
283 match disc {
284 1 => buf.push(id.to_u128() as u8),
285 2 => buf.extend_from_slice(&(id.to_u128() as u16).to_le_bytes()),
286 4 => buf.extend_from_slice(&(id.to_u128() as u32).to_le_bytes()),
287 8 => buf.extend_from_slice(&(id.to_u128() as u64).to_le_bytes()),
288 16 => buf.extend_from_slice(&id.to_u128().to_le_bytes()),
289 _ => unreachable!(),
290 }
291 } else {
292 buf.extend(iter::repeat_n(0, disc as usize));
293 }
294 }
295 }
296 PlainEncoded {
297 data: buf,
298 offsets: vec![],
299 nones: vec![],
300 type_code: ValueKind::DictionaryId.byte(),
301 has_nones: false,
302 }
303}
304
305pub fn encode_bitvec(bv: &BitVec) -> Vec<u8> {
306 let len = bv.len();
307 let byte_count = len.div_ceil(8);
308 let mut buf = Vec::with_capacity(byte_count);
309 for i in 0..byte_count {
310 let mut byte = 0u8;
311 for bit in 0..8 {
312 let idx = i * 8 + bit;
313 if idx < len && bv.get(idx) {
314 byte |= 1 << bit;
315 }
316 }
317 buf.push(byte);
318 }
319 buf
320}