Path: blob/main/crates/polars-parquet/src/arrow/read/deserialize/primitive/mod.rs
8506 views
use arrow::bitmap::BitmapBuilder;1use arrow::types::NativeType;23use crate::parquet::error::ParquetResult;4use crate::parquet::types::NativeType as ParquetNativeType;5use crate::read::deserialize::utils::Decoded;6use crate::read::expr::ParquetScalar;78mod float;9mod integer;10pub(crate) mod plain;1112pub(crate) use float::FloatDecoder;13pub(crate) use integer::IntDecoder;1415#[derive(Debug)]16pub(crate) struct PrimitiveDecoder<P, T, D>17where18P: ParquetNativeType,19T: NativeType,20D: DecoderFunction<P, T>,21{22pub(crate) decoder: D,23pub(crate) intermediate: Vec<P>,24_pd: std::marker::PhantomData<(P, T)>,25}2627impl<P, T, D> PrimitiveDecoder<P, T, D>28where29P: ParquetNativeType,30T: NativeType,31D: DecoderFunction<P, T>,32{33#[inline]34pub(crate) fn new(decoder: D) -> Self {35Self {36decoder,37intermediate: Vec::new(),38_pd: std::marker::PhantomData,39}40}4142fn extend_constant(43&mut self,44decoded: &mut (Vec<T>, BitmapBuilder),45length: usize,46value: &ParquetScalar,47) -> ParquetResult<()> {48if value.is_null() {49decoded.extend_nulls(length);50return Ok(());51}5253let value = match P::try_from(value) {54Ok(v) => self.decoder.decode(v),55Err(_) => panic!(),56};5758decoded.0.extend(std::iter::repeat_n(value, length));59decoded.1.extend_constant(length, false);6061Ok(())62}63}6465/// A function that defines how to decode from the66/// [`parquet::types::NativeType`][ParquetNativeType] to the [`arrow::types::NativeType`].67///68/// This should almost always be inlined.69pub(crate) trait DecoderFunction<P, T>: Copy70where71T: NativeType,72P: ParquetNativeType,73{74const NEED_TO_DECODE: bool;75const CAN_TRANSMUTE: bool = {76let has_same_size = size_of::<P>() == size_of::<T>();77let has_same_alignment = align_of::<P>() == align_of::<T>();7879has_same_size && has_same_alignment80};8182fn decode(self, x: P) -> T;83}8485#[derive(Default, Clone, Copy)]86pub(crate) struct UnitDecoderFunction<T>(std::marker::PhantomData<T>);87impl<T: NativeType + ParquetNativeType> DecoderFunction<T, T> for UnitDecoderFunction<T> {88const NEED_TO_DECODE: bool = false;8990#[inline(always)]91fn decode(self, x: T) -> T {92x93}94}9596#[derive(Default, Clone, Copy)]97pub(crate) struct AsDecoderFunction<P: ParquetNativeType, T: NativeType>(98std::marker::PhantomData<(P, T)>,99);100macro_rules! as_decoder_impl {101($($p:ty => $t:ty,)+) => {102$(103impl DecoderFunction<$p, $t> for AsDecoderFunction<$p, $t> {104const NEED_TO_DECODE: bool = !Self::CAN_TRANSMUTE;105106#[inline(always)]107fn decode(self, x : $p) -> $t {108x as $t109}110}111)+112};113}114115as_decoder_impl![116i32 => i8,117i32 => i16,118i32 => u8,119i32 => u16,120i32 => u32,121i64 => i32,122i64 => u32,123i64 => u64,124];125126#[derive(Default, Clone, Copy)]127pub(crate) struct IntoDecoderFunction<P, T>(std::marker::PhantomData<(P, T)>);128impl<P, T> DecoderFunction<P, T> for IntoDecoderFunction<P, T>129where130P: ParquetNativeType + Into<T>,131T: NativeType,132{133const NEED_TO_DECODE: bool = true;134135#[inline(always)]136fn decode(self, x: P) -> T {137x.into()138}139}140141#[derive(Clone, Copy)]142pub(crate) struct ClosureDecoderFunction<P, T, F>(F, std::marker::PhantomData<(P, T)>);143impl<P, T, F> DecoderFunction<P, T> for ClosureDecoderFunction<P, T, F>144where145P: ParquetNativeType,146T: NativeType,147F: Copy + Fn(P) -> T,148{149const NEED_TO_DECODE: bool = true;150151#[inline(always)]152fn decode(self, x: P) -> T {153(self.0)(x)154}155}156157158