-
Notifications
You must be signed in to change notification settings - Fork 203
Expand file tree
/
Copy pathcolumnar.rs
More file actions
103 lines (91 loc) · 3.22 KB
/
Copy pathcolumnar.rs
File metadata and controls
103 lines (91 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright the Vortex contributors
use vortex_error::VortexExpect;
use vortex_error::VortexResult;
use crate::AnyCanonical;
use crate::ArrayRef;
use crate::Canonical;
use crate::CanonicalView;
use crate::Executable;
use crate::ExecutionCtx;
use crate::IntoArray;
use crate::array::ArrayView;
use crate::arrays::Constant;
use crate::arrays::ConstantArray;
use crate::dtype::DType;
use crate::matcher::Matcher;
use crate::scalar::Scalar;
/// Represents a columnnar array of data, either in canonical form or as a constant array.
///
/// Since the [`Canonical`] enum has one variant per logical data type, it is inefficient for
/// representing constant arrays. The [`Columnar`] enum allows holding an array of data in either
/// canonical or constant form enabling efficient handling of constants during execution.
pub enum Columnar {
/// A columnar array in canonical form.
Canonical(Canonical),
/// A columnar array in constant form.
Constant(ConstantArray),
}
impl Columnar {
/// Creates a new columnar array from a scalar.
pub fn constant<S: Into<Scalar>>(scalar: S, len: usize) -> Self {
Columnar::Constant(ConstantArray::new(scalar.into(), len))
}
/// Returns the length of this columnar array.
pub fn len(&self) -> usize {
match self {
Columnar::Canonical(canonical) => canonical.len(),
Columnar::Constant(constant) => constant.len(),
}
}
/// Returns true if this columnar array has length zero.
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Returns the data type of this columnar array.
pub fn dtype(&self) -> &DType {
match self {
Columnar::Canonical(canonical) => canonical.dtype(),
Columnar::Constant(constant) => constant.dtype(),
}
}
}
impl IntoArray for Columnar {
fn into_array(self) -> ArrayRef {
match self {
Columnar::Canonical(canonical) => canonical.into_array(),
Columnar::Constant(constant) => constant.into_array(),
}
}
}
/// Execute into [`Columnar`] by running `execute_until` with the [`AnyColumnar`] matcher.
impl Executable for Columnar {
fn execute(array: ArrayRef, ctx: &mut ExecutionCtx) -> VortexResult<Self> {
let result = array.execute_until::<AnyColumnar>(ctx)?;
if let Some(constant) = result.as_opt::<Constant>() {
Ok(Columnar::Constant(constant.into_owned()))
} else {
Ok(Columnar::Canonical(
result
.as_opt::<AnyCanonical>()
.map(Canonical::from)
.vortex_expect("execute_until::<AnyColumnar> must return a columnar array"),
))
}
}
}
pub enum ColumnarView<'a> {
Canonical(CanonicalView<'a>),
Constant(ArrayView<'a, Constant>),
}
pub struct AnyColumnar;
impl Matcher for AnyColumnar {
type Match<'a> = ColumnarView<'a>;
fn try_match(array: &ArrayRef) -> Option<Self::Match<'_>> {
if let Some(constant) = array.as_opt::<Constant>() {
Some(ColumnarView::Constant(constant))
} else {
array.as_opt::<AnyCanonical>().map(ColumnarView::Canonical)
}
}
}