use super::{
Number, TypeTag, bytes_column_row, check_bytes_framing, frame_bytes_column,
frame_bytes_column_within,
};
use crate::config::ColumnEncoding;
use crate::table::column_page::{VAR_U64_MAX_LEN, put_varint, take, take_slice, take_varint};
use crate::table::columnar_predicate::Selection;
use crate::{Error, Result, Slice};
use alloc::{boxed::Box, vec::Vec};
use core::fmt;
pub const MAX_DEPTH: u8 = 5;
const PLAIN: u8 = 0;
const CONSTANT: u8 = 1;
const RLE: u8 = 2;
const DICT: u8 = 3;
const FFOR: u8 = 4;
const ORDINALS: u8 = 5;
const DELTA: u8 = 6;
const LENGTHS: u8 = 7;
const MALFORMED: Error = Error::InvalidHeader("columnar: malformed column encoding");
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Expression {
Plain,
Constant,
Rle {
values: Box<Self>,
ends: Box<Self>,
},
Dict {
values: Box<Self>,
codes: Box<Self>,
},
Ffor {
bit_width: u8,
exceptions: u32,
},
Ordinals(Box<Self>),
Delta(Box<Self>),
Lengths(Box<Self>),
}
impl fmt::Display for Expression {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Plain => f.write_str("plain"),
Self::Constant => f.write_str("constant"),
Self::Rle { values, ends } => write!(f, "rle(values={values}, ends={ends})"),
Self::Dict { values, codes } => write!(f, "dict(values={values}, codes={codes})"),
Self::Ffor {
bit_width,
exceptions: 0,
} => write!(f, "ffor({bit_width})"),
Self::Ffor {
bit_width,
exceptions,
} => write!(f, "ffor({bit_width}, {exceptions} exceptions)"),
Self::Ordinals(ints) => write!(f, "ordinals({ints})"),
Self::Delta(ints) => write!(f, "delta({ints})"),
Self::Lengths(ints) => write!(f, "lengths({ints})"),
}
}
}
#[derive(Clone, Debug)]
pub struct Ffor<'a> {
base: u64,
bit_width: u8,
packed: &'a [u8],
exception_count: u32,
exceptions: &'a [u8],
}
#[derive(Clone, Debug)]
pub enum Ints<'a> {
Constant(u64),
Ffor(Ffor<'a>),
Delta(Box<Self>),
Rle {
values: Box<Self>,
ends: Vec<u32>,
stored_ends: &'a [u8],
},
}
#[derive(Clone, Debug)]
pub enum Values<'a> {
Plain(&'a [u8]),
Constant(&'a [u8]),
Rle {
values: Box<Self>,
ends: Vec<u32>,
stored_ends: &'a [u8],
},
Dict {
values: Box<Self>,
size: u32,
codes: Ints<'a>,
},
Ordinals(Ints<'a>),
Lengths {
lengths: Ints<'a>,
lengths_len: usize,
payload: &'a [u8],
},
}
fn var_u32(rest: &mut &[u8]) -> Result<u32> {
let Some(value) = take_varint(rest, VAR_U64_MAX_LEN) else {
return Err(MALFORMED);
};
u32::try_from(value).map_err(|_| MALFORMED)
}
fn var_u64(rest: &mut &[u8]) -> Result<u64> {
let Some(value) = take_varint(rest, VAR_U64_MAX_LEN) else {
return Err(MALFORMED);
};
Ok(value)
}
fn byte(rest: &mut &[u8]) -> Result<u8> {
let Some([b]) = take::<1>(rest) else {
return Err(MALFORMED);
};
Ok(b)
}
fn bytes<'a>(rest: &mut &'a [u8], len: usize) -> Result<&'a [u8]> {
let Some(slice) = take_slice(rest, len) else {
return Err(MALFORMED);
};
Ok(slice)
}
fn packed_len(n: u32, bit_width: u8) -> Result<usize> {
usize::try_from((u64::from(n) * u64::from(bit_width)).div_ceil(8)).map_err(|_| MALFORMED)
}
fn check_ends(ends: &[u32], n: u32) -> Result<()> {
let mut prev = 0u32;
for &end in ends {
if end <= prev {
return Err(MALFORMED);
}
prev = end;
}
if prev != n {
return Err(MALFORMED);
}
Ok(())
}
impl<'a> Ints<'a> {
fn parse(rest: &mut &'a [u8], n: u32, depth: u8) -> Result<Self> {
if depth > MAX_DEPTH {
return Err(MALFORMED);
}
match byte(rest)? {
CONSTANT => Ok(Self::Constant(var_u64(rest)?)),
FFOR => {
let base = var_u64(rest)?;
let bit_width = byte(rest)?;
if bit_width > 64 {
return Err(MALFORMED);
}
let packed = bytes(rest, packed_len(n, bit_width)?)?;
let exception_count = var_u32(rest)?;
if exception_count > n {
return Err(MALFORMED);
}
let start = *rest;
let mut next = 0u64;
for _ in 0..exception_count {
let Some(position) = next.checked_add(var_u64(rest)?) else {
return Err(MALFORMED);
};
if position >= u64::from(n) {
return Err(MALFORMED);
}
var_u64(rest)?;
next = position + 1;
}
let used = start.len() - rest.len();
Ok(Self::Ffor(Ffor {
base,
bit_width,
packed,
exception_count,
exceptions: start.get(..used).unwrap_or_default(),
}))
}
DELTA => Ok(Self::Delta(Box::new(Self::parse(rest, n, depth + 1)?))),
RLE => {
let runs = var_u32(rest)?;
if runs == 0 || runs > n {
return Err(MALFORMED);
}
let values = Self::parse(rest, runs, depth + 1)?;
let (ends, stored_ends) = parse_ends(rest, runs, n, depth + 1)?;
Ok(Self::Rle {
values: Box::new(values),
ends,
stored_ends,
})
}
_ => Err(MALFORMED),
}
}
pub(crate) fn decode_into(&self, n: u32, out: &mut Vec<u64>) -> Result<()> {
match self {
Self::Constant(value) => {
out.resize(out.len() + n as usize, *value);
Ok(())
}
Self::Ffor(ffor) => ffor.decode_into(n, out),
Self::Delta(inner) => {
let start = out.len();
inner.decode_into(n, out)?;
let mut prev = 0u64;
for value in out.get_mut(start..).unwrap_or_default() {
prev = prev.wrapping_add(unzigzag(*value));
*value = prev;
}
Ok(())
}
Self::Rle { values, ends, .. } => {
let mut runs = Vec::with_capacity(ends.len());
values.decode_into(u32::try_from(ends.len()).map_err(|_| MALFORMED)?, &mut runs)?;
let mut start = 0u32;
for (&value, &end) in runs.iter().zip(ends) {
out.resize(out.len() + (end - start) as usize, value);
start = end;
}
Ok(())
}
}
}
fn held_rows(&self) -> u64 {
match self {
Self::Constant(_) | Self::Ffor(_) => 0,
Self::Delta(inner) => inner.held_rows(),
Self::Rle { values, ends, .. } => ends.len() as u64 + values.held_rows(),
}
}
fn describe(&self) -> Result<Expression> {
Ok(match self {
Self::Constant(_) => Expression::Constant,
Self::Ffor(ffor) => Expression::Ffor {
bit_width: ffor.bit_width,
exceptions: ffor.exception_count,
},
Self::Delta(inner) => Expression::Delta(Box::new(inner.describe()?)),
Self::Rle {
values,
ends,
stored_ends,
} => Expression::Rle {
values: Box::new(values.describe()?),
ends: Box::new(describe_ends(stored_ends, ends.len())?),
},
})
}
}
fn parse_ends<'a>(
rest: &mut &'a [u8],
runs: u32,
n: u32,
depth: u8,
) -> Result<(Vec<u32>, &'a [u8])> {
let start = *rest;
let ends = Ints::parse(rest, runs, depth)?;
let stored = start.get(..start.len() - rest.len()).unwrap_or_default();
let mut decoded = Vec::with_capacity(runs as usize);
ends.decode_into(runs, &mut decoded)?;
let ends: Vec<u32> = decoded
.into_iter()
.map(|end| u32::try_from(end).map_err(|_| MALFORMED))
.collect::<Result<_>>()?;
check_ends(&ends, n)?;
Ok((ends, stored))
}
fn describe_ends(stored: &[u8], runs: usize) -> Result<Expression> {
let mut rest = stored;
let runs = u32::try_from(runs).map_err(|_| MALFORMED)?;
Ints::parse(&mut rest, runs, 0)?.describe()
}
impl Ffor<'_> {
fn decode_into(&self, n: u32, out: &mut Vec<u64>) -> Result<()> {
let start = out.len();
out.reserve(n as usize);
let width = u32::from(self.bit_width);
if width == 0 {
out.resize(start + n as usize, self.base);
} else {
let mask = if width == 64 {
u64::MAX
} else {
(1u64 << width) - 1
};
let mut window = 0u128;
let mut held = 0u32;
let mut packed = self.packed.iter();
for _ in 0..n {
while held < width {
let Some(&b) = packed.next() else {
return Err(MALFORMED);
};
window |= u128::from(b) << held;
held += 8;
}
#[expect(clippy::cast_possible_truncation, reason = "masked to 64 bits")]
let offset = (window as u64) & mask;
window >>= width;
held -= width;
let Some(value) = self.base.checked_add(offset) else {
return Err(MALFORMED);
};
out.push(value);
}
}
let mut rest = self.exceptions;
let mut next = 0u64;
for _ in 0..self.exception_count {
let position = next + var_u64(&mut rest)?;
let value = var_u64(&mut rest)?;
let Some(slot) = usize::try_from(position)
.ok()
.and_then(|p| out.get_mut(start + p))
else {
return Err(MALFORMED);
};
*slot = value;
next = position + 1;
}
Ok(())
}
}
impl<'a> Values<'a> {
pub(crate) fn parse(type_tag: TypeTag, n: u32, bytes: &'a [u8]) -> Result<Self> {
let mut rest = bytes;
let values = Self::parse_from(&mut rest, type_tag, n, 0, true)?;
if !rest.is_empty() {
return Err(MALFORMED);
}
Ok(values)
}
fn parse_from(
rest: &mut &'a [u8],
type_tag: TypeTag,
n: u32,
depth: u8,
outer: bool,
) -> Result<Self> {
if depth > MAX_DEPTH {
return Err(MALFORMED);
}
let op = byte(rest)?;
match (op, type_tag.fixed_width()) {
(PLAIN, Some(width)) => {
let Some(len) = (n as usize).checked_mul(usize::from(width)) else {
return Err(MALFORMED);
};
Ok(Self::Plain(bytes(rest, len)?))
}
(PLAIN, None) => {
let Some(table) = (n as usize).checked_add(1).and_then(|c| c.checked_mul(4)) else {
return Err(MALFORMED);
};
let offsets = rest.get(..table).ok_or(MALFORMED)?;
let Some(last) = offsets.last_chunk::<4>() else {
return Err(MALFORMED);
};
let payload = u32::from_le_bytes(*last) as usize;
let data = bytes(rest, table.checked_add(payload).ok_or(MALFORMED)?)?;
check_bytes_framing(data, n)?;
Ok(Self::Plain(data))
}
(CONSTANT, Some(width)) if outer => {
Ok(Self::Constant(bytes(rest, usize::from(width))?))
}
(CONSTANT, None) if outer => {
let len = var_u32(rest)? as usize;
Ok(Self::Constant(bytes(rest, len)?))
}
(RLE, _) if outer => {
let runs = var_u32(rest)?;
if runs == 0 || runs > n {
return Err(MALFORMED);
}
let values = Self::parse_from(rest, type_tag, runs, depth + 1, false)?;
let (ends, stored_ends) = parse_ends(rest, runs, n, depth + 1)?;
Ok(Self::Rle {
values: Box::new(values),
ends,
stored_ends,
})
}
(DICT, _) if outer => {
let size = var_u32(rest)?;
if size == 0 || size > n {
return Err(MALFORMED);
}
let values = Self::parse_from(rest, type_tag, size, depth + 1, false)?;
let codes = Ints::parse(rest, n, depth + 1)?;
Ok(Self::Dict {
values: Box::new(values),
size,
codes,
})
}
(ORDINALS, Some(width)) if ordinal_width(type_tag) == Some(width) => {
Ok(Self::Ordinals(Ints::parse(rest, n, depth + 1)?))
}
(LENGTHS, None) => {
let before = rest.len();
let lengths = Ints::parse(rest, n, depth + 1)?;
let lengths_len = before - rest.len();
let len = var_u32(rest)? as usize;
Ok(Self::Lengths {
lengths,
lengths_len,
payload: bytes(rest, len)?,
})
}
_ => Err(MALFORMED),
}
}
pub(crate) fn held_rows(&self) -> u64 {
match self {
Self::Plain(_) | Self::Constant(_) => 0,
Self::Rle { values, ends, .. } => ends.len() as u64 + values.held_rows(),
Self::Dict { values, codes, .. } => values.held_rows() + codes.held_rows(),
Self::Ordinals(ints) | Self::Lengths { lengths: ints, .. } => ints.held_rows(),
}
}
pub(crate) fn describe(&self) -> Result<Expression> {
Ok(match self {
Self::Plain(_) => Expression::Plain,
Self::Constant(_) => Expression::Constant,
Self::Rle {
values,
ends,
stored_ends,
} => Expression::Rle {
values: Box::new(values.describe()?),
ends: Box::new(describe_ends(stored_ends, ends.len())?),
},
Self::Dict { values, codes, .. } => Expression::Dict {
values: Box::new(values.describe()?),
codes: Box::new(codes.describe()?),
},
Self::Ordinals(ints) => Expression::Ordinals(Box::new(ints.describe()?)),
Self::Lengths { lengths, .. } => Expression::Lengths(Box::new(lengths.describe()?)),
})
}
pub(crate) fn offsets_len(&self, type_tag: TypeTag, n: u32) -> Option<usize> {
match (self, type_tag) {
(Self::Plain(_), TypeTag::Bytes) => Some((n as usize + 1) * 4),
(Self::Lengths { lengths_len, .. }, _) => Some(*lengths_len),
_ => None,
}
}
pub(crate) fn materialize(
&self,
type_tag: TypeTag,
n: u32,
page: &Slice,
limit: u64,
) -> Result<Slice> {
if !matches!(self, Self::Plain(_)) {
fixed_within(type_tag, n, limit)?;
}
match self {
Self::Plain(data) => Ok(view_of(page, data)),
Self::Constant(value) => repeat(type_tag, n, value, limit),
Self::Rle { values, ends, .. } => {
let runs = u32::try_from(ends.len()).map_err(|_| MALFORMED)?;
let heads = values.materialize(type_tag, runs, page, limit)?;
let mut run = 0usize;
let mut rows = Vec::with_capacity(n as usize);
for row in 0..n {
while ends.get(run).is_some_and(|&end| row >= end) {
run += 1;
}
rows.push(u32::try_from(run).map_err(|_| MALFORMED)?);
}
gather(type_tag, &heads, runs, &rows, limit)
}
Self::Dict {
values,
size,
codes,
} => {
let dictionary = values.materialize(type_tag, *size, page, limit)?;
let mut decoded = Vec::with_capacity(n as usize);
codes.decode_into(n, &mut decoded)?;
let rows: Vec<u32> = decoded
.into_iter()
.map(|code| {
u32::try_from(code)
.ok()
.filter(|&c| c < *size)
.ok_or(MALFORMED)
})
.collect::<Result<_>>()?;
gather(type_tag, &dictionary, *size, &rows, limit)
}
Self::Ordinals(ints) => {
let TypeTag::Number(number) = type_tag else {
return Err(MALFORMED);
};
let mut ordinals = Vec::with_capacity(n as usize);
ints.decode_into(n, &mut ordinals)?;
from_ordinals(number, &ordinals)
}
Self::Lengths {
lengths, payload, ..
} => {
let mut decoded = Vec::with_capacity(n as usize);
lengths.decode_into(n, &mut decoded)?;
let mut at = 0usize;
let cells: Vec<&[u8]> = decoded
.iter()
.map(|&len| {
let end = usize::try_from(len)
.ok()
.and_then(|len| at.checked_add(len))
.ok_or(MALFORMED)?;
let cell = payload.get(at..end).ok_or(MALFORMED)?;
at = end;
Ok(cell)
})
.collect::<Result<_>>()?;
if at != payload.len() {
return Err(MALFORMED);
}
frame_bytes_column_within(cells.len(), limit, || cells.iter().copied())
}
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum Bounds<'b> {
Bytes {
lower: Option<&'b [u8]>,
upper: Option<&'b [u8]>,
},
Ordinals {
number: Number,
lo: u128,
hi: u128,
},
Nothing,
}
impl Bounds<'_> {
fn keeps(&self, cell: &[u8]) -> bool {
match *self {
Self::Bytes { lower, upper } => {
lower.is_none_or(|lo| cell >= lo) && upper.is_none_or(|hi| cell <= hi)
}
Self::Ordinals { number, lo, hi } => {
let ordinal = number.ordinal(cell);
lo <= ordinal && ordinal <= hi
}
Self::Nothing => false,
}
}
fn keeps_ordinal(&self, ordinal: u64) -> bool {
match *self {
Self::Ordinals { lo, hi, .. } => {
let ordinal = u128::from(ordinal);
lo <= ordinal && ordinal <= hi
}
Self::Bytes { .. } | Self::Nothing => false,
}
}
}
impl Ints<'_> {
fn select(&self, n: u32, bounds: &Bounds<'_>) -> Result<Selection> {
match self {
Self::Constant(value) => Ok(if bounds.keeps_ordinal(*value) {
Selection::all(n)
} else {
Selection::none(n)
}),
Self::Rle { values, ends, .. } => {
let runs = u32::try_from(ends.len()).map_err(|_| MALFORMED)?;
let kept = values.select(runs, bounds)?;
let mut out = Selection::none(n);
let mut start = 0u32;
for (run, &end) in (0u32..).zip(ends) {
if kept.contains(run) {
out.insert_range(start..end);
}
start = end;
}
Ok(out)
}
Self::Ffor(_) | Self::Delta(_) => {
let mut values = Vec::with_capacity(n as usize);
self.decode_into(n, &mut values)?;
let mut out = Selection::none(n);
for (row, value) in (0u32..).zip(values) {
if bounds.keeps_ordinal(value) {
out.insert(row);
}
}
Ok(out)
}
}
}
}
impl Values<'_> {
pub(crate) fn select(
&self,
type_tag: TypeTag,
n: u32,
bounds: &Bounds<'_>,
) -> Result<Selection> {
if matches!(bounds, Bounds::Nothing) {
return Ok(Selection::none(n));
}
match self {
Self::Plain(data) => Ok(select_plain(type_tag, data, n, bounds)),
Self::Constant(value) => Ok(if bounds.keeps(value) {
Selection::all(n)
} else {
Selection::none(n)
}),
Self::Rle { values, ends, .. } => {
let runs = u32::try_from(ends.len()).map_err(|_| MALFORMED)?;
let kept = values.select(type_tag, runs, bounds)?;
let mut out = Selection::none(n);
let mut start = 0u32;
for (run, &end) in (0u32..).zip(ends) {
if kept.contains(run) {
out.insert_range(start..end);
}
start = end;
}
Ok(out)
}
Self::Dict {
values,
size,
codes,
} => {
let kept = values.select(type_tag, *size, bounds)?;
if kept.count() == 0 {
return Ok(Selection::none(n));
}
let mut decoded = Vec::with_capacity(n as usize);
codes.decode_into(n, &mut decoded)?;
let mut out = Selection::none(n);
for (row, code) in (0u32..).zip(decoded) {
let Some(code) = u32::try_from(code).ok().filter(|c| c < size) else {
return Err(MALFORMED);
};
if kept.contains(code) {
out.insert(row);
}
}
Ok(out)
}
Self::Ordinals(ints) => ints.select(n, bounds),
Self::Lengths {
lengths, payload, ..
} => {
let mut decoded = Vec::with_capacity(n as usize);
lengths.decode_into(n, &mut decoded)?;
let mut out = Selection::none(n);
let mut at = 0usize;
for (row, len) in (0u32..).zip(decoded) {
let end = usize::try_from(len)
.ok()
.and_then(|len| at.checked_add(len))
.ok_or(MALFORMED)?;
if bounds.keeps(payload.get(at..end).ok_or(MALFORMED)?) {
out.insert(row);
}
at = end;
}
if at != payload.len() {
return Err(MALFORMED);
}
Ok(out)
}
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum Cell<'a> {
Borrowed(&'a [u8]),
Inline {
bytes: [u8; 16],
len: u8,
},
}
impl core::ops::Deref for Cell<'_> {
type Target = [u8];
fn deref(&self) -> &[u8] {
match self {
Self::Borrowed(bytes) => bytes,
Self::Inline { bytes, len } => bytes.get(..usize::from(*len)).unwrap_or_default(),
}
}
}
#[derive(Clone, Debug)]
pub enum IntRows<'a> {
Constant(u64),
Ffor {
base: u64,
bit_width: u8,
packed: &'a [u8],
exceptions: Vec<(u32, u64)>,
},
Decoded(Vec<u64>),
Runs {
ends: Vec<u32>,
values: Box<Self>,
},
}
impl<'a> IntRows<'a> {
fn new(ints: Ints<'a>, n: u32) -> Result<Self> {
Ok(match ints {
Ints::Constant(value) => Self::Constant(value),
Ints::Ffor(ffor) => {
let mut exceptions = Vec::with_capacity(ffor.exception_count as usize);
let mut rest = ffor.exceptions;
let mut next = 0u32;
for _ in 0..ffor.exception_count {
let position = next + var_u32(&mut rest)?;
exceptions.push((position, var_u64(&mut rest)?));
next = position + 1;
}
Self::Ffor {
base: ffor.base,
bit_width: ffor.bit_width,
packed: ffor.packed,
exceptions,
}
}
delta @ Ints::Delta(_) => {
let mut values = Vec::with_capacity(n as usize);
delta.decode_into(n, &mut values)?;
Self::Decoded(values)
}
Ints::Rle { values, ends, .. } => {
let runs = u32::try_from(ends.len()).map_err(|_| MALFORMED)?;
Self::Runs {
values: Box::new(Self::new(*values, runs)?),
ends,
}
}
})
}
pub fn get(&self, row: u32) -> Result<u64> {
match self {
Self::Constant(value) => Ok(*value),
Self::Ffor {
base,
bit_width,
packed,
exceptions,
} => {
if !exceptions.is_empty()
&& let Ok(at) = exceptions.binary_search_by_key(&row, |&(position, _)| position)
&& let Some(&(_, value)) = exceptions.get(at)
{
return Ok(value);
}
let offset = unpack_one(packed, *bit_width, row)?;
let Some(value) = base.checked_add(offset) else {
return Err(MALFORMED);
};
Ok(value)
}
Self::Decoded(values) => {
let Some(&value) = values.get(row as usize) else {
return Err(MALFORMED);
};
Ok(value)
}
Self::Runs { ends, values } => {
#[expect(clippy::cast_possible_truncation, reason = "a u32 run count")]
let run = ends.partition_point(|&end| end <= row) as u32;
values.get(run)
}
}
}
}
fn unpack_one(packed: &[u8], bit_width: u8, row: u32) -> Result<u64> {
if bit_width == 0 {
return Ok(0);
}
let width = u64::from(bit_width);
let bit = u64::from(row) * width;
let (Ok(first), Ok(last)) = (
usize::try_from(bit / 8),
usize::try_from((bit + width).div_ceil(8)),
) else {
return Err(MALFORMED);
};
let Some(bytes) = packed.get(first..last) else {
return Err(MALFORMED);
};
let mut window = 0u128;
for (i, &b) in bytes.iter().enumerate() {
window |= u128::from(b) << (8 * i);
}
let mask = if width == 64 {
u128::from(u64::MAX)
} else {
(1u128 << width) - 1
};
#[expect(clippy::cast_possible_truncation, reason = "masked to 64 bits")]
Ok(((window >> (bit % 8)) & mask) as u64)
}
#[derive(Clone, Debug)]
pub enum Rows<'a> {
Plain(&'a [u8]),
Constant(&'a [u8]),
Runs {
ends: Vec<u32>,
values: Box<Self>,
},
Dict {
size: u32,
codes: IntRows<'a>,
values: Box<Self>,
},
Ordinals {
number: Number,
ordinals: IntRows<'a>,
},
Stride {
len: usize,
payload: &'a [u8],
},
Lengths {
offsets: Vec<u32>,
payload: &'a [u8],
},
}
impl<'a> Values<'a> {
pub(crate) fn rows(self, type_tag: TypeTag, n: u32) -> Result<Rows<'a>> {
Ok(match self {
Self::Plain(data) => Rows::Plain(data),
Self::Constant(value) => Rows::Constant(value),
Self::Rle { values, ends, .. } => {
let runs = u32::try_from(ends.len()).map_err(|_| MALFORMED)?;
Rows::Runs {
values: Box::new(values.rows(type_tag, runs)?),
ends,
}
}
Self::Dict {
values,
size,
codes,
} => Rows::Dict {
size,
codes: IntRows::new(codes, n)?,
values: Box::new(values.rows(type_tag, size)?),
},
Self::Ordinals(ints) => {
let TypeTag::Number(number) = type_tag else {
return Err(MALFORMED);
};
Rows::Ordinals {
number,
ordinals: IntRows::new(ints, n)?,
}
}
Self::Lengths {
lengths: Ints::Constant(len),
payload,
..
} => {
let Some(len) = usize::try_from(len)
.ok()
.filter(|&len| len.checked_mul(n as usize) == Some(payload.len()))
else {
return Err(MALFORMED);
};
Rows::Stride { len, payload }
}
Self::Lengths {
lengths, payload, ..
} => {
let mut decoded = Vec::with_capacity(n as usize);
lengths.decode_into(n, &mut decoded)?;
let mut offsets = Vec::with_capacity(decoded.len() + 1);
let mut at = 0u32;
offsets.push(at);
for len in decoded {
at = u32::try_from(len)
.ok()
.and_then(|len| at.checked_add(len))
.ok_or(MALFORMED)?;
offsets.push(at);
}
if at as usize != payload.len() {
return Err(MALFORMED);
}
Rows::Lengths { offsets, payload }
}
})
}
}
impl<'a> Rows<'a> {
pub fn get(&self, type_tag: TypeTag, n: u32, row: u32) -> Result<Cell<'a>> {
if row >= n {
return Err(MALFORMED);
}
match self {
Self::Plain(data) => cell(type_tag, data, n, row).map(Cell::Borrowed),
Self::Constant(value) => Ok(Cell::Borrowed(value)),
Self::Runs { ends, values } => {
let run = ends.partition_point(|&end| end <= row);
let runs = u32::try_from(ends.len()).map_err(|_| MALFORMED)?;
values.get(type_tag, runs, u32::try_from(run).map_err(|_| MALFORMED)?)
}
Self::Dict {
size,
codes,
values,
} => {
let code = codes.get(row)?;
if code >= u64::from(*size) {
return Err(MALFORMED);
}
#[expect(clippy::cast_possible_truncation, reason = "below a u32 size")]
values.get(type_tag, *size, code as u32)
}
Self::Ordinals { number, ordinals } => {
let mut bytes = [0u8; 16];
let len = number.width();
let ordinal = ordinals.get(row)?;
let Some(out) = bytes.get_mut(..usize::from(len)) else {
return Err(MALFORMED);
};
if !number.write_ordinal(u128::from(ordinal), out) {
return Err(MALFORMED);
}
Ok(Cell::Inline { bytes, len })
}
Self::Stride { len, payload } => {
let start = row as usize * len;
let Some(value) = payload.get(start..start + len) else {
return Err(MALFORMED);
};
Ok(Cell::Borrowed(value))
}
Self::Lengths { offsets, payload } => {
let (Some(&start), Some(&end)) =
(offsets.get(row as usize), offsets.get(row as usize + 1))
else {
return Err(MALFORMED);
};
let Some(value) = payload.get(start as usize..end as usize) else {
return Err(MALFORMED);
};
Ok(Cell::Borrowed(value))
}
}
}
}
impl Values<'_> {
pub(crate) fn materialize_rows(
self,
type_tag: TypeTag,
n: u32,
keep: &Selection,
limit: u64,
) -> Result<Slice> {
if let Self::Plain(data) = self {
return gather_plain(type_tag, data, n, keep);
}
fixed_within(type_tag, keep.count(), limit)?;
let count = keep.count() as usize;
let access = self.rows(type_tag, n)?;
let cells = keep
.rows()
.map(|row| access.get(type_tag, n, row))
.collect::<Result<Vec<_>>>()?;
match type_tag.fixed_width() {
Some(width) => Ok(super::gather_fixed_column(
usize::from(width),
count,
cells.iter().map(|c| Some(&**c)),
)),
None => frame_bytes_column_within(count, limit, || cells.iter().map(|c| &**c)),
}
}
}
fn view_of(page: &Slice, data: &[u8]) -> Slice {
let outer = page.as_ptr_range();
let inner = data.as_ptr_range();
if outer.start <= inner.start && inner.end <= outer.end {
let start = inner.start as usize - outer.start as usize;
page.slice(start..start + data.len())
} else {
Slice::from(data)
}
}
pub fn ordinal_width(type_tag: TypeTag) -> Option<u8> {
match type_tag {
TypeTag::Number(number) if number.width() <= 8 => Some(number.width()),
_ => None,
}
}
fn fixed_within(type_tag: TypeTag, rows: u32, limit: u64) -> Result<()> {
let Some(width) = type_tag.fixed_width() else {
return Ok(());
};
let len = u64::from(rows) * u64::from(width);
if len > limit {
return Err(Error::DecompressedSizeTooLarge {
declared: len,
limit,
});
}
Ok(())
}
fn repeat(type_tag: TypeTag, n: u32, value: &[u8], limit: u64) -> Result<Slice> {
match type_tag.fixed_width() {
Some(_) => Ok(super::gather_fixed_column(
value.len(),
n as usize,
(0..n).map(|_| Some(value)),
)),
None => frame_bytes_column_within(n as usize, limit, || (0..n).map(|_| value)),
}
}
fn cell(type_tag: TypeTag, data: &[u8], rows: u32, row: u32) -> Result<&[u8]> {
match type_tag.fixed_width() {
Some(width) => {
let width = usize::from(width);
let Some(value) = (row as usize)
.checked_mul(width)
.and_then(|start| data.get(start..start + width))
else {
return Err(MALFORMED);
};
Ok(value)
}
None => bytes_column_row(data, rows, row),
}
}
fn plain_bytes_cells(data: &[u8], n: u32) -> impl Iterator<Item = &[u8]> {
let table = (n as usize + 1) * 4;
let (offsets, payload) = data.split_at_checked(table).unwrap_or_default();
let mut start = 0usize;
offsets.chunks_exact(4).skip(1).map_while(move |end| {
let end = u32::from_le_bytes(end.try_into().ok()?) as usize;
let value = payload.get(start..end)?;
start = end;
Some(value)
})
}
fn select_plain(type_tag: TypeTag, data: &[u8], n: u32, bounds: &Bounds<'_>) -> Selection {
let mut out = Selection::none(n);
match (type_tag.fixed_width().map(usize::from), *bounds) {
(Some(width @ 1..), Bounds::Ordinals { number, lo, hi }) => {
for (row, value) in (0u32..).zip(data.chunks_exact(width)) {
let ordinal = number.ordinal(value);
if lo <= ordinal && ordinal <= hi {
out.insert(row);
}
}
}
(Some(width @ 1..), _) => {
for (row, value) in (0u32..).zip(data.chunks_exact(width)) {
if bounds.keeps(value) {
out.insert(row);
}
}
}
(Some(_), _) => {
if bounds.keeps(&[]) {
out.insert_range(0..n);
}
}
(None, _) => {
for (row, value) in (0u32..).zip(plain_bytes_cells(data, n)) {
if bounds.keeps(value) {
out.insert(row);
}
}
}
}
out
}
fn gather_plain(type_tag: TypeTag, data: &[u8], n: u32, keep: &Selection) -> Result<Slice> {
let count = keep.count() as usize;
if let Some(width) = type_tag.fixed_width() {
let width = usize::from(width);
return Ok(super::gather_fixed_column(
width,
count,
keep.rows()
.map(|row| data.get(row as usize * width..row as usize * width + width)),
));
}
let table = (n as usize + 1) * 4;
let (offsets, payload) = data.split_at_checked(table).unwrap_or_default();
let at = |i: u32| {
offsets
.get(i as usize * 4..i as usize * 4 + 4)
.and_then(|b| b.try_into().ok())
.map(|b| u32::from_le_bytes(b) as usize)
};
frame_bytes_column(count, || {
keep.rows().map(move |row| {
at(row)
.zip(at(row + 1))
.and_then(|(start, end)| payload.get(start..end))
.unwrap_or_default()
})
})
}
fn gather(
type_tag: TypeTag,
source: &[u8],
source_rows: u32,
rows: &[u32],
limit: u64,
) -> Result<Slice> {
for &row in rows {
cell(type_tag, source, source_rows, row)?;
}
let take = |row: u32| cell(type_tag, source, source_rows, row).unwrap_or_default();
if let Some(width) = type_tag.fixed_width() {
Ok(super::gather_fixed_column(
usize::from(width),
rows.len(),
rows.iter().map(|&row| Some(take(row))),
))
} else {
frame_bytes_column_within(rows.len(), limit, || rows.iter().map(|&row| take(row)))
}
}
fn from_ordinals(number: Number, ordinals: &[u64]) -> Result<Slice> {
let width = usize::from(number.width());
let mut out = alloc::vec![0u8; ordinals.len() * width];
for (dst, &ordinal) in out.chunks_exact_mut(width.max(1)).zip(ordinals) {
if !number.write_ordinal(u128::from(ordinal), dst) {
return Err(MALFORMED);
}
}
Ok(Slice::from(out))
}
const fn zigzag(delta: u64) -> u64 {
let signed = delta.cast_signed();
((signed << 1) ^ (signed >> 63)).cast_unsigned()
}
const fn unzigzag(value: u64) -> u64 {
(value >> 1) ^ (value & 1).wrapping_neg()
}
mod cost {
pub(super) const STORED_BYTE: u64 = 1000;
pub(super) const BUILT_BYTE: u64 = 60;
pub(super) const UNPACK: u64 = 300;
pub(super) const PATCH: u64 = 2000;
pub(super) const DELTA: u64 = 150;
pub(super) const EXPAND: u64 = 100;
pub(super) const GATHER: u64 = 250;
pub(super) const ORDINAL: u64 = 150;
pub(super) const LENGTH: u64 = 100;
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Candidate {
pub expression: Expression,
pub bytes: usize,
pub overhead: usize,
pub cost: u64,
}
struct Trial {
expression: Expression,
bytes: Vec<u8>,
payload: usize,
work: u64,
}
impl Trial {
fn cost(&self) -> u64 {
self.bytes.len() as u64 * cost::STORED_BYTE + self.work
}
fn candidate(&self) -> Candidate {
Candidate {
expression: self.expression.clone(),
bytes: self.bytes.len(),
overhead: self.bytes.len() - self.payload,
cost: self.cost(),
}
}
}
fn cheapest(trials: Vec<Trial>) -> Option<Trial> {
let mut best: Option<Trial> = None;
for trial in trials {
if best.as_ref().is_none_or(|b| trial.cost() < b.cost()) {
best = Some(trial);
}
}
best
}
#[expect(clippy::cast_possible_truncation, reason = "at most 64")]
const fn bits(value: u64) -> u8 {
(u64::BITS - value.leading_zeros()) as u8
}
const fn var_len(value: u64) -> usize {
if value == 0 {
1
} else {
(bits(value) as usize).div_ceil(7)
}
}
fn ffor(values: &[u64]) -> Trial {
let n = u32::try_from(values.len()).unwrap_or(u32::MAX);
let base = values.iter().copied().min().unwrap_or(0);
let mut count = [0u64; 65];
let mut whole = [0u64; 65];
for &value in values {
let width = usize::from(bits(value - base));
if let (Some(c), Some(w)) = (count.get_mut(width), whole.get_mut(width)) {
*c += 1;
*w += var_len(value) as u64;
}
}
let mut best_width = 64u8;
let mut best_cost = u64::MAX;
let (mut above_count, mut above_whole) = (0u64, 0u64);
for width in (0..=64u8).rev() {
let size = (u64::from(n) * u64::from(width)).div_ceil(8) + above_count + above_whole;
let cost = size * cost::STORED_BYTE + above_count * cost::PATCH;
if cost <= best_cost {
best_cost = cost;
best_width = width;
}
above_count += count.get(usize::from(width)).copied().unwrap_or(0);
above_whole += whole.get(usize::from(width)).copied().unwrap_or(0);
}
ffor_at(values, base, best_width)
}
fn ffor_at(values: &[u64], base: u64, bit_width: u8) -> Trial {
let n = u32::try_from(values.len()).unwrap_or(u32::MAX);
let mut bytes = vec![FFOR];
put_varint(&mut bytes, base);
bytes.push(bit_width);
let fits = |offset: u64| bit_width == 64 || offset >> bit_width == 0;
let packed_start = bytes.len();
let mut window = 0u128;
let mut held = 0u32;
let mut exceptions = Vec::new();
for (row, &value) in values.iter().enumerate() {
let offset = value - base;
let stored = if fits(offset) {
offset
} else {
exceptions.push((row, value));
0
};
if bit_width > 0 {
window |= u128::from(stored) << held;
held += u32::from(bit_width);
while held >= 8 {
#[expect(clippy::cast_possible_truncation, reason = "one byte")]
bytes.push(window as u8);
window >>= 8;
held -= 8;
}
}
}
if held > 0 {
#[expect(clippy::cast_possible_truncation, reason = "one byte")]
bytes.push(window as u8);
}
let packed = bytes.len() - packed_start;
let count = u32::try_from(exceptions.len()).unwrap_or(u32::MAX);
put_varint(&mut bytes, u64::from(count));
let exceptions_start = bytes.len();
let mut next = 0usize;
for &(row, value) in &exceptions {
put_varint(&mut bytes, (row - next) as u64);
put_varint(&mut bytes, value);
next = row + 1;
}
let payload = packed + (bytes.len() - exceptions_start);
Trial {
expression: Expression::Ffor {
bit_width,
exceptions: count,
},
bytes,
payload,
work: u64::from(n) * cost::UNPACK + u64::from(count) * cost::PATCH,
}
}
fn int_constant(value: u64, n: usize) -> Trial {
let mut bytes = vec![CONSTANT];
put_varint(&mut bytes, value);
Trial {
expression: Expression::Constant,
bytes,
payload: 0,
work: n as u64,
}
}
fn int_runs(values: &[u64]) -> (Vec<u64>, Vec<u64>) {
let mut heads = Vec::new();
let mut ends = Vec::new();
for (row, &value) in values.iter().enumerate() {
if heads.last() != Some(&value) || row == 0 {
if row > 0 {
ends.push(row as u64);
}
heads.push(value);
}
}
if !values.is_empty() {
ends.push(values.len() as u64);
}
(heads, ends)
}
fn int_trials(values: &[u64], nested: bool) -> Vec<Trial> {
let n = values.len();
let mut trials = Vec::new();
let first = values.first().copied().unwrap_or(0);
if values.iter().all(|&v| v == first) {
trials.push(int_constant(first, n));
return trials;
}
trials.push(ffor(values));
let deltas: Vec<u64> = {
let mut prev = 0u64;
values
.iter()
.map(|&v| {
let d = zigzag(v.wrapping_sub(prev));
prev = v;
d
})
.collect()
};
let inner = ffor(&deltas);
let mut bytes = vec![DELTA];
bytes.extend_from_slice(&inner.bytes);
trials.push(Trial {
expression: Expression::Delta(Box::new(inner.expression)),
payload: inner.payload,
work: inner.work + n as u64 * cost::DELTA,
bytes,
});
if !nested {
let (heads, ends) = int_runs(values);
if heads.len() * 2 <= n
&& let (Some(values_trial), Some(ends_trial)) = (
cheapest(int_trials(&heads, true)),
cheapest(int_trials(&ends, true)),
)
{
let mut bytes = vec![RLE];
put_varint(&mut bytes, heads.len() as u64);
bytes.extend_from_slice(&values_trial.bytes);
bytes.extend_from_slice(&ends_trial.bytes);
trials.push(Trial {
expression: Expression::Rle {
values: Box::new(values_trial.expression),
ends: Box::new(ends_trial.expression),
},
payload: values_trial.payload + ends_trial.payload,
work: values_trial.work + ends_trial.work + n as u64 * cost::EXPAND,
bytes,
});
}
}
trials
}
fn best_ints(values: &[u64], nested: bool) -> Trial {
cheapest(int_trials(values, nested)).unwrap_or_else(|| int_constant(0, values.len()))
}
struct Cells<'a> {
type_tag: TypeTag,
rows: u32,
data: &'a [u8],
}
impl<'a> Cells<'a> {
fn get(&self, row: u32) -> &'a [u8] {
cell(self.type_tag, self.data, self.rows, row).unwrap_or_default()
}
fn iter(&self) -> impl Iterator<Item = &'a [u8]> + '_ {
(0..self.rows).map(|row| self.get(row))
}
fn built(&self) -> u64 {
self.data.len() as u64 * cost::BUILT_BYTE
}
}
fn order_key(type_tag: TypeTag, cell: &[u8]) -> (u128, &[u8]) {
match type_tag {
TypeTag::Number(number) => (number.ordinal(cell), &[]),
TypeTag::Bytes | TypeTag::Fixed(_) => (0, cell),
}
}
fn values_plain(cells: &Cells<'_>) -> Trial {
let mut bytes = vec![PLAIN];
bytes.extend_from_slice(cells.data);
Trial {
expression: Expression::Plain,
payload: cells.data.len(),
bytes,
work: 0,
}
}
fn values_ordinals(cells: &Cells<'_>, number: Number) -> Trial {
let ordinals: Vec<u64> = cells
.iter()
.map(|c| u64::try_from(number.ordinal(c)).unwrap_or(u64::MAX))
.collect();
let inner = best_ints(&ordinals, false);
let mut bytes = vec![ORDINALS];
bytes.extend_from_slice(&inner.bytes);
Trial {
expression: Expression::Ordinals(Box::new(inner.expression)),
payload: inner.payload,
work: inner.work + u64::from(cells.rows) * cost::ORDINAL + cells.built(),
bytes,
}
}
fn values_lengths(cells: &Cells<'_>) -> Trial {
let lengths: Vec<u64> = cells.iter().map(|c| c.len() as u64).collect();
let inner = best_ints(&lengths, false);
let payload_len: usize = cells.iter().map(<[u8]>::len).sum();
let mut bytes = vec![LENGTHS];
bytes.extend_from_slice(&inner.bytes);
put_varint(&mut bytes, payload_len as u64);
for c in cells.iter() {
bytes.extend_from_slice(c);
}
Trial {
expression: Expression::Lengths(Box::new(inner.expression)),
payload: inner.payload + payload_len,
work: inner.work + u64::from(cells.rows) * cost::LENGTH + cells.built(),
bytes,
}
}
fn inner_values(cells: &Cells<'_>) -> Trial {
let mut trials = vec![values_plain(cells)];
match cells.type_tag {
TypeTag::Number(number) if ordinal_width(cells.type_tag).is_some() => {
trials.push(values_ordinals(cells, number));
}
TypeTag::Bytes => trials.push(values_lengths(cells)),
TypeTag::Number(_) | TypeTag::Fixed(_) => {}
}
cheapest(trials).unwrap_or_else(|| values_plain(cells))
}
fn layout(type_tag: TypeTag, rows: &[&[u8]]) -> Result<Slice> {
match type_tag.fixed_width() {
Some(width) => Ok(super::gather_fixed_column(
usize::from(width),
rows.len(),
rows.iter().map(|&c| Some(c)),
)),
None => frame_bytes_column(rows.len(), || rows.iter().copied()),
}
}
fn values_trials(cells: &Cells<'_>) -> Result<Vec<Trial>> {
let n = cells.rows as usize;
let mut trials = vec![values_plain(cells)];
let Some(first) = cells.iter().next() else {
return Ok(trials);
};
if cells.iter().all(|c| c == first) {
let mut bytes = vec![CONSTANT];
if cells.type_tag.fixed_width().is_none() {
put_varint(&mut bytes, first.len() as u64);
}
bytes.extend_from_slice(first);
trials.push(Trial {
expression: Expression::Constant,
payload: first.len(),
bytes,
work: cells.built(),
});
return Ok(trials);
}
match cells.type_tag {
TypeTag::Number(number) if ordinal_width(cells.type_tag).is_some() => {
trials.push(values_ordinals(cells, number));
}
TypeTag::Bytes => trials.push(values_lengths(cells)),
TypeTag::Number(_) | TypeTag::Fixed(_) => {}
}
let mut heads: Vec<&[u8]> = Vec::new();
let mut ends: Vec<u64> = Vec::new();
for (row, c) in cells.iter().enumerate() {
if heads.last() != Some(&c) || row == 0 {
if row > 0 {
ends.push(row as u64);
}
heads.push(c);
}
}
ends.push(n as u64);
if heads.len() * 2 <= n {
let head_data = layout(cells.type_tag, &heads)?;
let head_cells = Cells {
type_tag: cells.type_tag,
rows: u32::try_from(heads.len()).map_err(|_| MALFORMED)?,
data: &head_data,
};
let values = inner_values(&head_cells);
let ends_trial = best_ints(&ends, true);
let mut bytes = vec![RLE];
put_varint(&mut bytes, heads.len() as u64);
bytes.extend_from_slice(&values.bytes);
bytes.extend_from_slice(&ends_trial.bytes);
trials.push(Trial {
expression: Expression::Rle {
values: Box::new(values.expression),
ends: Box::new(ends_trial.expression),
},
payload: values.payload + ends_trial.payload,
work: values.work + ends_trial.work + n as u64 * cost::EXPAND + cells.built(),
bytes,
});
}
let mut distinct: crate::HashMap<&[u8], u32> = crate::HashMap::default();
for c in cells.iter() {
let next = u32::try_from(distinct.len()).unwrap_or(u32::MAX);
distinct.entry(c).or_insert(next);
if distinct.len() * 2 > n {
break;
}
}
if distinct.len() * 2 <= n {
let mut sorted: Vec<&[u8]> = distinct.keys().copied().collect();
sorted.sort_unstable_by(|a, b| {
order_key(cells.type_tag, a).cmp(&order_key(cells.type_tag, b))
});
for (rank, value) in sorted.iter().enumerate() {
if let Some(code) = distinct.get_mut(value) {
*code = u32::try_from(rank).unwrap_or(u32::MAX);
}
}
let codes: Vec<u64> = cells
.iter()
.map(|c| u64::from(distinct.get(c).copied().unwrap_or(0)))
.collect();
let dictionary = layout(cells.type_tag, &sorted)?;
let dictionary_cells = Cells {
type_tag: cells.type_tag,
rows: u32::try_from(sorted.len()).map_err(|_| MALFORMED)?,
data: &dictionary,
};
let values = inner_values(&dictionary_cells);
let codes_trial = best_ints(&codes, false);
let mut bytes = vec![DICT];
put_varint(&mut bytes, sorted.len() as u64);
bytes.extend_from_slice(&values.bytes);
bytes.extend_from_slice(&codes_trial.bytes);
trials.push(Trial {
expression: Expression::Dict {
values: Box::new(values.expression),
codes: Box::new(codes_trial.expression),
},
payload: values.payload + codes_trial.payload,
work: values.work + codes_trial.work + n as u64 * cost::GATHER + cells.built(),
bytes,
});
}
Ok(trials)
}
pub struct Choice {
pub bytes: Vec<u8>,
pub expression: Expression,
}
pub fn choose(
type_tag: TypeTag,
rows: u32,
data: &[u8],
encoding: ColumnEncoding,
) -> Result<Choice> {
let cells = Cells {
type_tag,
rows,
data,
};
if encoding == ColumnEncoding::Plain {
let plain = values_plain(&cells);
return Ok(Choice {
bytes: plain.bytes,
expression: plain.expression,
});
}
let trials = values_trials(&cells)?;
let Some(best) = cheapest(trials) else {
return Err(MALFORMED);
};
Ok(Choice {
bytes: best.bytes,
expression: best.expression,
})
}
pub fn candidates(type_tag: TypeTag, rows: u32, data: &[u8]) -> Result<Vec<Candidate>> {
super::check_layout(type_tag, rows, data)?;
Ok(values_trials(&Cells {
type_tag,
rows,
data,
})?
.iter()
.map(Trial::candidate)
.collect())
}
#[cfg(test)]
#[expect(
clippy::expect_used,
clippy::indexing_slicing,
reason = "test code: a failed expectation is the assertion"
)]
mod tests;