Skip to main content

Chunk

Struct Chunk 

Source
pub struct Chunk { /* private fields */ }
Expand description

A batch of columns of equal length.

Implementations§

Source§

impl Chunk

Source

pub fn new(columns: Vec<Vector>) -> Result<Self>

A chunk of columns, taking the row count from the first of them.

§Errors

If the columns are not all the same length, or if there are more rows than VECTOR_SIZE.

Source

pub fn with_rows(columns: Vec<Vector>, rows: usize) -> Result<Self>

A chunk of columns that is rows long, for the case where there are no columns to take the count from.

§Errors

If any column is not rows long, or if rows is more than VECTOR_SIZE.

Source

pub fn empty(types: &[LogicalType]) -> Self

A chunk of the given types with no rows in it.

What a scan of an empty table returns and what an operator returns when it is done. The types are kept, because a consumer asks a chunk what its columns are before it asks whether there are any.

Source

pub fn columns(&self) -> &[Vector]

The columns.

Source

pub fn column(&self, index: usize) -> Result<&Vector>

One column.

§Errors

If there is no column at index.

Source

pub fn into_columns(self) -> Vec<Vector>

The columns, given up.

Source

pub fn width(&self) -> usize

How many columns.

Source

pub fn len(&self) -> usize

How many rows.

Source

pub fn is_empty(&self) -> bool

Whether there are no rows.

Source

pub fn types(&self) -> Vec<LogicalType>

The type of each column.

Source

pub fn value_at(&self, row: usize, column: usize) -> Value

The value at a row and a column, or null if either is past the end.

The slow path, same as Vector::value_at. It is what a result set is read out with and what a test asserts on.

Source

pub fn row(&self, row: usize) -> impl Iterator<Item = Value> + '_

One row, left to right.

Source

pub fn select(self, selection: &Selection) -> Result<Self>

The rows a selection kept, without moving any of the values.

Every column becomes a dictionary vector whose codes are the selection, which is the form spec/07-execution.md section 7.1 asks a filter to produce rather than compacting. It takes the chunk by value because that is what makes it free: the payload is moved into the new vector rather than copied, so a filter that keeps one row in a thousand still costs the selection and nothing else.

§Errors

If the selection points past the end of the chunk.

Source

pub fn compact(self, selection: &Selection) -> Result<Self>

The rows a selection kept, copied, so that nothing downstream reads through an indirection.

The copying counterpart to Self::select, and the two exist because neither one is right twice. Which one to call is measured rather than argued, and the measurement says something other than what the argument does, so here is both.

The argument is that selecting pays nothing now and one redirection on every later read of every kept row, while compacting pays a copy now and nothing afterwards, so the deciding variable is selectivity: keep a few rows and select, keep most of them and compact. The measurement says the deciding variable is not selectivity at all, it is how many times the rows are read again afterwards, and selectivity barely moves the line. On server3, over a chunk of two integer columns, compacting loses to selecting at every selectivity from one percent to a hundred when there is one later pass over the kept rows, and beats it at every selectivity from one percent to a hundred when there are sixteen. With four later passes the two are within a few percent of each other everywhere. Put a varchar column in the chunk and compaction loses almost everywhere, because copying string bytes is most of what it costs and the dictionary it avoids is most of what it saves.

Which is why nothing in the streaming pipeline calls this yet. A filter today feeds an aggregate or a projection and that is one pass or two, and end to end on two million rows SELECT sum(a), sum(b), count(*) FROM t WHERE a > ? measures the same either way at one percent selectivity and fifty percent slower compacting at fifty percent selectivity. The operators that will want this are the ones that hold chunks rather than pass them on, the hash join build side and the sort, because a chunk that is kept alive as a selection keeps the whole chunk it was selected from alive with it, and that is a hundred to one on memory rather than a few percent on time.

Takes the chunk by value like Self::select does, even though the payload is copied rather than moved, because a caller that still wanted the original after compacting it would be holding both copies and should say so.

§Errors

If the selection points past the end of the chunk, or if a column has a type with no flat layout, which today means the nested types.

Source

pub fn project(self, positions: &[usize]) -> Result<Self>

The columns at the given positions, in that order.

A position may appear twice, which is what SELECT x, x FROM t is, and the second one costs a copy. Every other position is moved.

§Errors

If a position is past the end of the chunk.

Source

pub fn flatten(&self) -> Result<Self>

The same rows with every column in flat form.

Costs a copy per column that was not already flat. It is here for the result set at the top of a query, where the dictionary vectors a filter left behind would otherwise be handed to a caller who has to understand them.

§Errors

If a column has a type that cannot be stored flat yet, which today means the nested types.

Trait Implementations§

Source§

impl Clone for Chunk

Source§

fn clone(&self) -> Chunk

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Chunk

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for Chunk

Source§

fn eq(&self, other: &Chunk) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Chunk

Auto Trait Implementations§

§

impl Freeze for Chunk

§

impl RefUnwindSafe for Chunk

§

impl Send for Chunk

§

impl Sync for Chunk

§

impl Unpin for Chunk

§

impl UnsafeUnpin for Chunk

§

impl UnwindSafe for Chunk

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.