1use crate::{
2 delta_decode_array, delta_encode_array, unweave_and_delta_decode_3d_array,
3 unweave_and_delta_decode_array, weave_and_delta_encode_3d_array, weave_and_delta_encode_array,
4 CustomOrdWrapper, Point, Point3D, VectorPoints, VectorPoints3D, BBOX,
5};
6
7use pbf::{ProtoRead, ProtoWrite, Protobuf};
8
9use alloc::collections::BTreeMap;
10use alloc::string::String;
11use alloc::vec::Vec;
12use core::cell::RefCell;
13
14#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord)]
17pub enum OColumnName {
18 #[default]
20 String = 0,
21 Unsigned = 1,
24 Signed = 2,
26 Float = 3,
29 Double = 4,
32 Points = 5,
38 Points3D = 6,
44 Indices = 7,
48 Shapes = 8,
50 BBox = 9,
54}
55impl From<u8> for OColumnName {
56 fn from(value: u8) -> Self {
57 match value {
58 0 => OColumnName::String,
59 1 => OColumnName::Unsigned,
60 2 => OColumnName::Signed,
61 3 => OColumnName::Float,
62 4 => OColumnName::Double,
63 5 => OColumnName::Points,
64 6 => OColumnName::Points3D,
65 7 => OColumnName::Indices,
66 8 => OColumnName::Shapes,
67 9 => OColumnName::BBox,
68 _ => OColumnName::String,
69 }
70 }
71}
72impl From<OColumnName> for u64 {
73 fn from(col: OColumnName) -> Self {
74 col as u64
75 }
76}
77
78#[derive(Debug)]
84pub enum ColumnContainer<T> {
85 Pos(usize),
87 Data(T),
89}
90
91#[derive(Debug, Default)]
96pub struct ColumnCacheReader {
97 string: Vec<String>,
99 unsigned: Vec<u64>,
101 signed: Vec<i64>,
103 float: Vec<f32>,
105 double: Vec<f64>,
107 points: Vec<VectorPoints>,
109 points_3d: Vec<VectorPoints3D>,
111 indices: Vec<Vec<u32>>,
113 shapes: Vec<Vec<usize>>,
115 bbox: Vec<BBOX>,
117}
118impl ColumnCacheReader {
119 pub fn new() -> Self {
121 ColumnCacheReader { ..Default::default() }
122 }
123
124 pub fn get_string(&mut self, index: usize) -> String {
126 self.string[index].clone()
127 }
128
129 pub fn get_unsigned(&self, index: usize) -> u64 {
131 self.unsigned[index]
132 }
133
134 pub fn get_signed(&self, index: usize) -> i64 {
136 self.signed[index]
137 }
138
139 pub fn get_float(&self, index: usize) -> f32 {
141 self.float[index]
142 }
143
144 pub fn get_double(&self, index: usize) -> f64 {
146 self.double[index]
147 }
148
149 pub fn get_points(&mut self, index: usize) -> VectorPoints {
151 self.points[index].clone()
152 }
153
154 pub fn get_points_3d(&mut self, index: usize) -> VectorPoints3D {
156 self.points_3d[index].clone()
157 }
158
159 pub fn get_indices(&mut self, index: usize) -> Vec<u32> {
161 self.indices[index].clone()
162 }
163
164 pub fn get_shapes(&mut self, index: usize) -> Vec<usize> {
166 self.shapes[index].clone()
167 }
168
169 pub fn get_bbox(&mut self, index: usize) -> BBOX {
171 self.bbox[index]
172 }
173}
174impl ProtoRead for ColumnCacheReader {
175 fn read(&mut self, tag: u64, pb: &mut Protobuf) {
176 match tag {
177 0 => self.string.push(pb.read_string()),
178 1 => self.unsigned.push(pb.read_varint::<u64>()),
179 2 => self.signed.push(pb.read_s_varint::<i64>()),
180 3 => self.float.push(pb.read_varint::<f32>()),
181 4 => self.double.push(pb.read_varint::<f64>()),
182 5 => self.points.push(unweave_and_delta_decode_array(&pb.read_packed::<u64>())),
183 6 => self.points_3d.push(unweave_and_delta_decode_3d_array(&pb.read_packed::<u64>())),
184 7 => self.indices.push(delta_decode_array(&pb.read_packed::<u32>())),
185 8 => self.shapes.push(pb.read_packed::<usize>()),
186 9 => self.bbox.push((&pb.read_packed::<u8>()[..]).into()),
187 #[tarpaulin::skip]
188 _ => panic!("Unknown column type"),
189 }
190 }
191}
192
193#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord)]
197pub struct OColumnBaseChunk {
198 pub index: usize,
201 pub count: usize,
203}
204#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
208pub enum ColumnValue {
209 Number(usize),
211 Column(RefCell<OColumnBaseChunk>),
213}
214impl From<usize> for ColumnValue {
215 fn from(index: usize) -> Self {
216 ColumnValue::Number(index)
217 }
218}
219impl From<RefCell<OColumnBaseChunk>> for ColumnValue {
220 fn from(chunk: RefCell<OColumnBaseChunk>) -> Self {
221 ColumnValue::Column(chunk)
222 }
223}
224pub type OColumnBaseWrite<K> = BTreeMap<K, RefCell<OColumnBaseChunk>>;
226
227pub type OColumnBaseFloatWrite<K> = BTreeMap<CustomOrdWrapper<K>, RefCell<OColumnBaseChunk>>;
229
230#[derive(Debug, Default)]
234pub struct ColumnCacheWriter {
235 string: OColumnBaseWrite<String>,
237 unsigned: OColumnBaseWrite<u64>,
239 signed: OColumnBaseWrite<i64>,
241 float: OColumnBaseFloatWrite<f32>,
243 double: OColumnBaseFloatWrite<f64>,
245 points: OColumnBaseWrite<Vec<Point>>,
247 points_3d: OColumnBaseWrite<Vec<Point3D>>,
249 indices: OColumnBaseWrite<Vec<u32>>,
251 shapes: OColumnBaseWrite<Vec<ColumnValue>>,
253 bbox: OColumnBaseWrite<BBOX>,
255}
256impl ColumnCacheWriter {
257 pub fn add_string(&mut self, value: String) -> usize {
259 add(&mut self.string, value)
260 }
261
262 pub fn add_u64(&mut self, value: u64) -> RefCell<OColumnBaseChunk> {
264 add_number(&mut self.unsigned, value)
265 }
266
267 pub fn add_i64(&mut self, value: i64) -> RefCell<OColumnBaseChunk> {
269 add_number(&mut self.signed, value)
270 }
271
272 pub fn add_f32(&mut self, value: f32) -> RefCell<OColumnBaseChunk> {
274 add_number(&mut self.float, CustomOrdWrapper(value))
275 }
276
277 pub fn add_f64(&mut self, value: f64) -> RefCell<OColumnBaseChunk> {
279 add_number(&mut self.double, CustomOrdWrapper(value))
280 }
281
282 pub fn add_points(&mut self, value: Vec<Point>) -> usize {
284 add(&mut self.points, value)
285 }
286
287 pub fn add_points_3d(&mut self, value: Vec<Point3D>) -> usize {
289 add(&mut self.points_3d, value)
290 }
291
292 pub fn add_indices(&mut self, value: Vec<u32>) -> usize {
294 add(&mut self.indices, value)
295 }
296
297 pub fn add_shapes(&mut self, value: Vec<ColumnValue>) -> usize {
299 add(&mut self.shapes, value)
300 }
301
302 pub fn add_bbox(&mut self, value: BBOX) -> usize {
304 add(&mut self.bbox, value)
305 }
306}
307impl ProtoWrite for ColumnCacheWriter {
308 fn write(&self, pbf: &mut Protobuf) {
309 let mut strings: Vec<(&String, &RefCell<OColumnBaseChunk>)> = self.string.iter().collect();
311 let mut unsigned: Vec<(&u64, &RefCell<OColumnBaseChunk>)> = self.unsigned.iter().collect();
312 let mut signed: Vec<(&i64, &RefCell<OColumnBaseChunk>)> = self.signed.iter().collect();
313 let mut float: Vec<(&CustomOrdWrapper<f32>, &RefCell<OColumnBaseChunk>)> =
314 self.float.iter().collect();
315 let mut double: Vec<(&CustomOrdWrapper<f64>, &RefCell<OColumnBaseChunk>)> =
316 self.double.iter().collect();
317 let mut points: Vec<(&Vec<Point>, &RefCell<OColumnBaseChunk>)> =
318 self.points.iter().collect();
319 let mut points_3d: Vec<(&Vec<Point3D>, &RefCell<OColumnBaseChunk>)> =
320 self.points_3d.iter().collect();
321 let mut indices: Vec<(&Vec<u32>, &RefCell<OColumnBaseChunk>)> =
322 self.indices.iter().collect();
323 let mut shapes: Vec<(&Vec<ColumnValue>, &RefCell<OColumnBaseChunk>)> =
324 self.shapes.iter().collect();
325 let mut bbox: Vec<(&BBOX, &RefCell<OColumnBaseChunk>)> = self.bbox.iter().collect();
326
327 strings.sort_by(|a, b| a.1.borrow().index.cmp(&b.1.borrow().index));
334 unsigned.sort_by(|a, b| a.1.borrow().index.cmp(&b.1.borrow().index));
335 signed.sort_by(|a, b| a.1.borrow().index.cmp(&b.1.borrow().index));
336 float.sort_by(|a, b| a.1.borrow().index.cmp(&b.1.borrow().index));
337 double.sort_by(|a, b| a.1.borrow().index.cmp(&b.1.borrow().index));
338 points.sort_by(|a, b| a.1.borrow().index.cmp(&b.1.borrow().index));
339 points_3d.sort_by(|a, b| a.1.borrow().index.cmp(&b.1.borrow().index));
340 indices.sort_by(|a, b| a.1.borrow().index.cmp(&b.1.borrow().index));
341 shapes.sort_by(|a, b| a.1.borrow().index.cmp(&b.1.borrow().index));
342 bbox.sort_by(|a, b| a.1.borrow().index.cmp(&b.1.borrow().index));
343
344 for string in strings {
347 pbf.write_string_field(OColumnName::String.into(), string.0);
348 }
349 for u in unsigned {
351 pbf.write_varint_field(OColumnName::Unsigned.into(), *u.0);
352 }
353 for s in signed {
355 pbf.write_s_varint_field(OColumnName::Signed.into(), *s.0);
356 }
357 for f in float {
359 pbf.write_varint_field(OColumnName::Float.into(), f.0 .0);
360 }
361 for d in double {
363 pbf.write_varint_field(OColumnName::Double.into(), d.0 .0);
364 }
365 for p in points {
367 pbf.write_packed_varint(OColumnName::Points.into(), &weave_and_delta_encode_array(p.0));
368 }
369 for p_3d in points_3d {
371 pbf.write_packed_varint(
372 OColumnName::Points3D.into(),
373 &weave_and_delta_encode_3d_array(p_3d.0),
374 );
375 }
376 for i in indices {
378 pbf.write_packed_varint(OColumnName::Indices.into(), &delta_encode_array(i.0));
379 }
380 for s in shapes {
382 let packed: Vec<usize> =
383 s.0.iter()
384 .map(|v| match v {
385 ColumnValue::Number(n) => *n,
386 ColumnValue::Column(c) => c.borrow().index,
387 })
388 .collect();
389 pbf.write_packed_varint(OColumnName::Shapes.into(), &packed);
390 }
391 for bbox in bbox {
393 pbf.write_packed_varint(OColumnName::BBox.into(), &bbox.0.quantize());
394 }
395 }
396}
397
398pub fn add<T>(col: &mut OColumnBaseWrite<T>, value: T) -> usize
400where
401 T: Ord,
402{
403 if let Some(col) = col.get_mut(&value) {
404 let mut chunk = col.borrow_mut();
405 chunk.count += 1;
406 chunk.index
407 } else {
408 let index = col.len();
409 col.insert(value, RefCell::new(OColumnBaseChunk { index, count: 1 }));
410 index
411 }
412}
413
414pub fn add_number<T>(col: &mut OColumnBaseWrite<T>, value: T) -> RefCell<OColumnBaseChunk>
416where
417 T: Ord,
418{
419 if let Some(chunk) = col.get_mut(&value) {
420 {
421 let mut chunk_mut = chunk.borrow_mut();
422 chunk_mut.count += 1;
423 }
424 chunk.clone()
425 } else {
426 let index = col.len();
427 let new_chunk = RefCell::new(OColumnBaseChunk { index, count: 1 });
428 col.insert(value, new_chunk.clone());
429 new_chunk
430 }
431}
432
433