pub enum Seq {
Boxed(Vec<Value>),
Ints(Vec<i64>),
Floats(Vec<f64>),
}Expand description
A list’s elements. See the module docs for what a caller may not be able to tell.
Variants§
Boxed(Vec<Value>)
Any elements at all.
Ints(Vec<i64>)
Int elements, dense.
Floats(Vec<f64>)
Float elements, dense and as f64.
Implementations§
Source§impl Seq
impl Seq
Sourcepub fn pack(values: Vec<Value>) -> Seq
pub fn pack(values: Vec<Value>) -> Seq
The elements a primitive produced, in whatever layout they fit.
One pass over a list that has just been built by a pass over something else, so this is a constant on a cost the caller was already paying — and it stops at the first element that does not fit, so a list of records pays a single comparison.
Sourcepub fn to_vec(&self) -> Vec<Value>
pub fn to_vec(&self) -> Vec<Value>
The elements, unpacked — what a caller that wants a Vec<Value> gets.
pub fn len(&self) -> usize
pub fn is_empty(&self) -> bool
Sourcepub fn get(&self, i: usize) -> Option<Value>
pub fn get(&self, i: usize) -> Option<Value>
One element, as a Value. By value rather than by reference, because a column has no
Value to lend — and an Int or a Float is two words, so there is nothing to save.
Sourcepub fn ints(&self) -> Option<&[i64]>
pub fn ints(&self) -> Option<&[i64]>
The elements as a dense i64 run, if that is what this list is.
Sourcepub fn floats(&self) -> Option<&[f64]>
pub fn floats(&self) -> Option<&[f64]>
The elements as a dense f64 run, if that is what this list is — the pointer a kernel
and an Arrow Float64Array both take, and the reason this module exists
(105 §105.8).
None for a boxed list rather than a copy of one: a caller that gets a slice knows it cost
nothing, and a caller that gets None can decide whether a copy is worth it. Handing back a
materialised buffer here would make the cheap case and the expensive one look alike, which
is the shape of every “why is this slow” question a zero-copy interface exists to prevent.
Sourcepub fn for_each(&self, f: impl FnMut(&Value))
pub fn for_each(&self, f: impl FnMut(&Value))
Every element, borrowed where the layout has one to lend.
Seq::iter yields by value, which is right for a caller that wanted an owned Value and
wrong for one that only wanted to look: cloning a Value::Data is an atomic increment and a
later decrement, and the digest, the wire format and to_json each walk every element of
every list without keeping any of them. Those walk through here, so the boxed layout — which
is every list that is not a column — pays exactly what it paid before this module existed.
A column has no Value to lend, so one is built on the stack and lent; it is two words and
no allocation.
Sourcepub fn try_for_each<E>(
&self,
f: impl FnMut(&Value) -> Result<(), E>,
) -> Result<(), E>
pub fn try_for_each<E>( &self, f: impl FnMut(&Value) -> Result<(), E>, ) -> Result<(), E>
Seq::for_each for a walk that can fail, which is what a wire encoder is.
Sourcepub fn as_values(&self) -> Cow<'_, [Value]>
pub fn as_values(&self) -> Cow<'_, [Value]>
The elements as a slice, borrowed when the layout allows and materialised when it does not.
Sourcepub fn min(&self) -> Option<Value>
pub fn min(&self) -> Option<Value>
The smallest element, and the largest — over the dense buffer where there is one.
This is the half of 105 §105.10’s
aggregate row that costs nothing to take: min over an Ints column is a pass over i64s
with no Value built at all, where the boxed form builds one per element to compare it.
pub fn max(&self) -> Option<Value>
Sourcepub fn is_column(&self) -> bool
pub fn is_column(&self) -> bool
Whether this list is stored as a column — for a gate and for a report, never for a decision about what a program means.
Sourcepub fn heap_bytes(&self) -> usize
pub fn heap_bytes(&self) -> usize
What this list occupies on the heap, in bytes, not counting anything its elements point at.
The number the second layout exists to move, so it is readable rather than inferred.
Sourcepub fn push(&mut self, value: Value)
pub fn push(&mut self, value: Value)
Add one element to the end.
An empty list promotes to the layout its first element fits, which is what gives the
accumulator idiom a column; a list that already has elements keeps its layout, or falls back
to Seq::Boxed once for an element that does not fit. Both are O(1) amortised. What is
deliberately not here is a re-examination of a boxed list on every push: that would be the
quadratic 70 removed from this
idiom, put straight back.
Trait Implementations§
Source§impl FromIterator<Value> for Seq
impl FromIterator<Value> for Seq
Source§impl<'a> IntoIterator for &'a Seq
impl<'a> IntoIterator for &'a Seq
Source§impl Ord for Seq
impl Ord for Seq
Source§fn cmp(&self, other: &Seq) -> Ordering
fn cmp(&self, other: &Seq) -> Ordering
Lexicographic over the elements, which is what Vec<Value>’s derived order was.
A Floats column is compared through Value::float, not as raw f64. The two agree
on every ordinary number because the order key is monotone, and disagree on exactly the two
IEEE values Value::float exists to canonicalise — NaN, which has no partial_cmp, and
-0.0, which compares equal to 0.0 and hashes differently. Going through the constructor
is how those two stay the one value the language says they are.