After some discussion with PVH I realise that the repo structure in the last reorg was very rust-centric. In an attempt to put each language on a level footing move the rust code and project files into ./rust
138 lines
4.1 KiB
Rust
138 lines
4.1 KiB
Rust
use std::ops::Range;
|
|
|
|
use super::{CellValue, SimpleColIter, SimpleColRange, SimpleValue};
|
|
use crate::columnar::{
|
|
column_range::{RleRange, ValueIter, ValueRange},
|
|
encoding::{col_error::DecodeColumnError, RleDecoder},
|
|
};
|
|
|
|
/// A group column range is one with a "num" column and zero or more "grouped" columns. The "num"
|
|
/// column contains RLE encoded u64s, each `u64` represents the number of values to read from each
|
|
/// of the grouped columns in order to produce a `CellValue::Group` for the current row.
|
|
#[derive(Debug, Clone)]
|
|
pub(crate) struct GroupRange {
|
|
pub(crate) num: RleRange<u64>,
|
|
pub(crate) values: Vec<GroupedColumnRange>,
|
|
}
|
|
|
|
impl GroupRange {
|
|
pub(crate) fn new(num: RleRange<u64>, values: Vec<GroupedColumnRange>) -> Self {
|
|
Self { num, values }
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub(crate) fn iter<'a>(&self, data: &'a [u8]) -> GroupIter<'a> {
|
|
GroupIter {
|
|
num: self.num.decoder(data),
|
|
values: self.values.iter().map(|v| v.iter(data)).collect(),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn range(&self) -> Range<usize> {
|
|
let start = self.num.start();
|
|
let end = self
|
|
.values
|
|
.last()
|
|
.map(|v| v.range().end)
|
|
.unwrap_or_else(|| self.num.end());
|
|
start..end
|
|
}
|
|
}
|
|
|
|
/// The type of ranges which can be the "grouped" columns in a `GroupRange`
|
|
#[derive(Debug, Clone)]
|
|
pub(crate) enum GroupedColumnRange {
|
|
Value(ValueRange),
|
|
Simple(SimpleColRange),
|
|
}
|
|
|
|
impl GroupedColumnRange {
|
|
fn iter<'a>(&self, data: &'a [u8]) -> GroupedColIter<'a> {
|
|
match self {
|
|
Self::Value(vr) => GroupedColIter::Value(vr.iter(data)),
|
|
Self::Simple(sc) => GroupedColIter::Simple(sc.iter(data)),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn range(&self) -> Range<usize> {
|
|
match self {
|
|
Self::Value(vr) => vr.range(),
|
|
Self::Simple(s) => s.range(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub(crate) struct GroupIter<'a> {
|
|
num: RleDecoder<'a, u64>,
|
|
values: Vec<GroupedColIter<'a>>,
|
|
}
|
|
|
|
impl<'a> GroupIter<'a> {
|
|
fn try_next(&mut self) -> Result<Option<CellValue>, DecodeColumnError> {
|
|
let num = self
|
|
.num
|
|
.next()
|
|
.transpose()
|
|
.map_err(|e| DecodeColumnError::decode_raw("num", e))?;
|
|
match num {
|
|
None => Ok(None),
|
|
Some(None) => Err(DecodeColumnError::unexpected_null("num")),
|
|
Some(Some(num)) => {
|
|
let mut row = Vec::new();
|
|
for _ in 0..num {
|
|
let mut inner_row = Vec::new();
|
|
for (index, value_col) in self.values.iter_mut().enumerate() {
|
|
match value_col.next().transpose()? {
|
|
None => {
|
|
return Err(DecodeColumnError::unexpected_null(format!(
|
|
"col {}",
|
|
index
|
|
)))
|
|
}
|
|
Some(v) => {
|
|
inner_row.push(v);
|
|
}
|
|
}
|
|
}
|
|
row.push(inner_row);
|
|
}
|
|
Ok(Some(CellValue::Group(row)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> Iterator for GroupIter<'a> {
|
|
type Item = Result<CellValue, DecodeColumnError>;
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
self.try_next().transpose()
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
enum GroupedColIter<'a> {
|
|
Value(ValueIter<'a>),
|
|
Simple(SimpleColIter<'a>),
|
|
}
|
|
|
|
impl<'a> GroupedColIter<'a> {
|
|
fn try_next(&mut self) -> Result<Option<SimpleValue>, DecodeColumnError> {
|
|
match self {
|
|
Self::Value(viter) => Ok(viter.next().transpose()?.map(SimpleValue::Value)),
|
|
Self::Simple(siter) => siter
|
|
.next()
|
|
.transpose()
|
|
.map_err(|e| DecodeColumnError::decode_raw("a simple column", e)),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> Iterator for GroupedColIter<'a> {
|
|
type Item = Result<SimpleValue, DecodeColumnError>;
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
self.try_next().transpose()
|
|
}
|
|
}
|