Skip to main content

OutputSink

Trait OutputSink 

Source
pub unsafe trait OutputSink<Options>: 'static + Sized {
    type Rows<'a>: ViewLen
       where Self: 'a;
    type Row<'a>
       where Self: 'a;
    type WriteToken: 'static;

    // Required methods
    fn return_dtype(options: &Options) -> VortexResult<DType>;
    fn with_capacity(rows: usize) -> VortexResult<Self>;
    fn rows(&mut self) -> Self::Rows<'_>;
    unsafe fn row_unchecked<'a>(
        rows: &'a mut Self::Rows<'_>,
        index: usize,
    ) -> Self::Row<'a>;
    unsafe fn finish(self) -> VortexResult<ArrayRef>;

    // Provided method
    fn skipped_rows_initializer() -> Option<for<'a> fn(&mut Self::Rows<'a>)> { ... }
}
Expand description

A column allocated once per batch that a row closure writes into, one row at a time.

A sink can use function options to build a runtime-shaped output or own shared batch state. The executor passes each row slot into an Fn closure.

Rows arrive in increasing index order. Ordinary execution visits 0..row_count exactly once. Execution can omit invalid rows when skipped_rows_initializer returns an initializer.

§Errors

Lifecycle methods report only incidental failures such as allocation. A semantic error that depends on input values must come from the row callback through a fallible SinkResult, or RowFn::INFALLIBLE cannot protect optimizations such as dictionary push-down.

§Safety

An implementation must uphold all of these requirements:

  • Every index below ViewLen::len for Rows must identify one distinct row owned by this sink.
  • A borrowed Rows view must retain its length and index-to-row mapping until it is dropped. Calls to row_unchecked and safe uses of a returned Row must preserve both properties.
  • skipped_rows_initializer is the only exception to this stability requirement. The executor checks the length again after the initializer. The initializer must initialize every row.
  • A row must either be initialized before the callback or require a WriteToken that safe code cannot produce without initializing that exact row. Evidence for an uninitialized row must not be safely forgeable, reusable, or substitutable.
  • Self and every borrowed Rows view must remain safe to drop if decoding, preparation, skipped-row initialization, or a row callback returns an error or unwinds. The executor can abandon a sink after any prefix of rows.
  • finish must be sound once every visited callback returned its required token and the skipped-row initializer, when present, ran successfully.
  • Violating these requirements can cause undefined behavior.

Required Associated Types§

Source

type Rows<'a>: ViewLen where Self: 'a

A loop-local view of all output rows.

Borrowed once before execution so the sink’s buffer descriptor and shape become loop invariants rather than being re-read through &mut Self for every row.

Source

type Row<'a> where Self: 'a

The place a row closure writes one row through, borrowed from the sink.

Source

type WriteToken: 'static

Proof that a successful row closure left its row handle initialized.

Use () for initialized row handles. A sink exposing uninitialized storage uses a token returned after initialization. If a sink uses the token to justify unsafe code, safe code must not be able to construct one without establishing the invariant.

Required Methods§

Source

fn return_dtype(options: &Options) -> VortexResult<DType>

The dtype of the column this sink builds, given the function options.

Must be non-nullable: batch execution derives nullability from the inputs, widens the result, and masks the null rows.

Source

fn with_capacity(rows: usize) -> VortexResult<Self>

Allocate a sink for rows rows.

Source

fn rows(&mut self) -> Self::Rows<'_>

Borrow all output rows for the hot loop.

Source

unsafe fn row_unchecked<'a>( rows: &'a mut Self::Rows<'_>, index: usize, ) -> Self::Row<'a>

Hand out the place to write row index. Must be O(1): it is called in the row loop.

§Safety

index must be less than ViewLen::len for rows.

Source

unsafe fn finish(self) -> VortexResult<ArrayRef>

Finish into the built column, whose dtype must be this sink’s return_dtype. Called once per batch.

§Safety

The executor must have completed every row callback successfully, and each callback must have returned this sink’s WriteToken. When skipped rows are allowed, the initializer returned by skipped_rows_initializer must have run before traversal.

Provided Methods§

Source

fn skipped_rows_initializer() -> Option<for<'a> fn(&mut Self::Rows<'a>)>

The operation that initializes every output position before skip-invalid execution.

Some enables this strategy. The initializer must make every row safe to finish. Callbacks overwrite valid rows, and batch execution masks skipped rows.

None makes skip-invalid execution unavailable for this sink.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl<T: OutputElement + Copy + Default, Options> OutputSink<Options> for UninitElementSink<T>

Source§

type Rows<'a> = &'a mut [MaybeUninit<T>]

Source§

type Row<'a> = &'a mut MaybeUninit<T>

Source§

type WriteToken = InitializedElement