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