Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-parquet/src/arrow/read/deserialize/primitive/mod.rs
8506 views
1
use arrow::bitmap::BitmapBuilder;
2
use arrow::types::NativeType;
3
4
use crate::parquet::error::ParquetResult;
5
use crate::parquet::types::NativeType as ParquetNativeType;
6
use crate::read::deserialize::utils::Decoded;
7
use crate::read::expr::ParquetScalar;
8
9
mod float;
10
mod integer;
11
pub(crate) mod plain;
12
13
pub(crate) use float::FloatDecoder;
14
pub(crate) use integer::IntDecoder;
15
16
#[derive(Debug)]
17
pub(crate) struct PrimitiveDecoder<P, T, D>
18
where
19
P: ParquetNativeType,
20
T: NativeType,
21
D: DecoderFunction<P, T>,
22
{
23
pub(crate) decoder: D,
24
pub(crate) intermediate: Vec<P>,
25
_pd: std::marker::PhantomData<(P, T)>,
26
}
27
28
impl<P, T, D> PrimitiveDecoder<P, T, D>
29
where
30
P: ParquetNativeType,
31
T: NativeType,
32
D: DecoderFunction<P, T>,
33
{
34
#[inline]
35
pub(crate) fn new(decoder: D) -> Self {
36
Self {
37
decoder,
38
intermediate: Vec::new(),
39
_pd: std::marker::PhantomData,
40
}
41
}
42
43
fn extend_constant(
44
&mut self,
45
decoded: &mut (Vec<T>, BitmapBuilder),
46
length: usize,
47
value: &ParquetScalar,
48
) -> ParquetResult<()> {
49
if value.is_null() {
50
decoded.extend_nulls(length);
51
return Ok(());
52
}
53
54
let value = match P::try_from(value) {
55
Ok(v) => self.decoder.decode(v),
56
Err(_) => panic!(),
57
};
58
59
decoded.0.extend(std::iter::repeat_n(value, length));
60
decoded.1.extend_constant(length, false);
61
62
Ok(())
63
}
64
}
65
66
/// A function that defines how to decode from the
67
/// [`parquet::types::NativeType`][ParquetNativeType] to the [`arrow::types::NativeType`].
68
///
69
/// This should almost always be inlined.
70
pub(crate) trait DecoderFunction<P, T>: Copy
71
where
72
T: NativeType,
73
P: ParquetNativeType,
74
{
75
const NEED_TO_DECODE: bool;
76
const CAN_TRANSMUTE: bool = {
77
let has_same_size = size_of::<P>() == size_of::<T>();
78
let has_same_alignment = align_of::<P>() == align_of::<T>();
79
80
has_same_size && has_same_alignment
81
};
82
83
fn decode(self, x: P) -> T;
84
}
85
86
#[derive(Default, Clone, Copy)]
87
pub(crate) struct UnitDecoderFunction<T>(std::marker::PhantomData<T>);
88
impl<T: NativeType + ParquetNativeType> DecoderFunction<T, T> for UnitDecoderFunction<T> {
89
const NEED_TO_DECODE: bool = false;
90
91
#[inline(always)]
92
fn decode(self, x: T) -> T {
93
x
94
}
95
}
96
97
#[derive(Default, Clone, Copy)]
98
pub(crate) struct AsDecoderFunction<P: ParquetNativeType, T: NativeType>(
99
std::marker::PhantomData<(P, T)>,
100
);
101
macro_rules! as_decoder_impl {
102
($($p:ty => $t:ty,)+) => {
103
$(
104
impl DecoderFunction<$p, $t> for AsDecoderFunction<$p, $t> {
105
const NEED_TO_DECODE: bool = !Self::CAN_TRANSMUTE;
106
107
#[inline(always)]
108
fn decode(self, x : $p) -> $t {
109
x as $t
110
}
111
}
112
)+
113
};
114
}
115
116
as_decoder_impl![
117
i32 => i8,
118
i32 => i16,
119
i32 => u8,
120
i32 => u16,
121
i32 => u32,
122
i64 => i32,
123
i64 => u32,
124
i64 => u64,
125
];
126
127
#[derive(Default, Clone, Copy)]
128
pub(crate) struct IntoDecoderFunction<P, T>(std::marker::PhantomData<(P, T)>);
129
impl<P, T> DecoderFunction<P, T> for IntoDecoderFunction<P, T>
130
where
131
P: ParquetNativeType + Into<T>,
132
T: NativeType,
133
{
134
const NEED_TO_DECODE: bool = true;
135
136
#[inline(always)]
137
fn decode(self, x: P) -> T {
138
x.into()
139
}
140
}
141
142
#[derive(Clone, Copy)]
143
pub(crate) struct ClosureDecoderFunction<P, T, F>(F, std::marker::PhantomData<(P, T)>);
144
impl<P, T, F> DecoderFunction<P, T> for ClosureDecoderFunction<P, T, F>
145
where
146
P: ParquetNativeType,
147
T: NativeType,
148
F: Copy + Fn(P) -> T,
149
{
150
const NEED_TO_DECODE: bool = true;
151
152
#[inline(always)]
153
fn decode(self, x: P) -> T {
154
(self.0)(x)
155
}
156
}
157
158