pub struct Row {
data: CompactBytes,
}
Expand description
A packed representation for Datum
s.
Datum
is easy to work with but very space inefficient. A Datum::Int32(42)
is laid out in memory like this:
tag: 3 padding: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 data: 0 0 0 42 padding: 0 0 0 0 0 0 0 0 0 0 0 0
For a total of 32 bytes! The second set of padding is needed in case we were to write a 16-byte datum into this location. The first set of padding is needed to align that hypothetical decimal to a 16 bytes boundary.
A Row
stores zero or more Datum
s without any padding. We avoid the need
for the first set of padding by only providing access to the Datum
s via
calls to ptr::read_unaligned
, which on modern x86 is barely penalized. We
avoid the need for the second set of padding by not providing mutable access
to the Datum
. Instead, Row
is append-only.
A Row
can be built from a collection of Datum
s using Row::pack
, but it
is more efficient to use Row::pack_slice
so that a right-sized allocation
can be created. If that is not possible, consider using the row buffer
pattern: allocate one row, pack into it, and then call Row::clone
to
receive a copy of that row, leaving behind the original allocation to pack
future rows.
Creating a row via Row::pack_slice
:
let row = Row::pack_slice(&[Datum::Int32(0), Datum::Int32(1), Datum::Int32(2)]);
assert_eq!(row.unpack(), vec![Datum::Int32(0), Datum::Int32(1), Datum::Int32(2)])
Row
s can be unpacked by iterating over them:
let row = Row::pack_slice(&[Datum::Int32(0), Datum::Int32(1), Datum::Int32(2)]);
assert_eq!(row.iter().nth(1).unwrap(), Datum::Int32(1));
If you want random access to the Datum
s in a Row
, use Row::unpack
to create a Vec<Datum>
let row = Row::pack_slice(&[Datum::Int32(0), Datum::Int32(1), Datum::Int32(2)]);
let datums = row.unpack();
assert_eq!(datums[1], Datum::Int32(1));
§Performance
Rows are dynamically sized, but up to a fixed size their data is stored in-line.
It is best to re-use a Row
across multiple Row
creation calls, as this
avoids the allocations involved in Row::new()
.
Fields§
§data: CompactBytes
Implementations§
source§impl Row
impl Row
const SIZE: usize = 23usize
sourcepub fn decode_from_proto(
&mut self,
proto: &ProtoRow,
desc: &RelationDesc,
) -> Result<(), String>
pub fn decode_from_proto( &mut self, proto: &ProtoRow, desc: &RelationDesc, ) -> Result<(), String>
A variant of Row::from_proto
that allows for reuse of internal allocs
and validates the decoding against a provided RelationDesc
.
sourcepub fn with_capacity(cap: usize) -> Self
pub fn with_capacity(cap: usize) -> Self
Allocate an empty Row
with a pre-allocated capacity.
sourcepub unsafe fn from_bytes_unchecked(data: &[u8]) -> Self
pub unsafe fn from_bytes_unchecked(data: &[u8]) -> Self
Creates a new row from supplied bytes.
§Safety
This method relies on data
being an appropriate row encoding, and can
result in unsafety if this is not the case.
sourcepub fn packer(&mut self) -> RowPacker<'_>
pub fn packer(&mut self) -> RowPacker<'_>
Constructs a RowPacker
that will pack datums into this row’s
allocation.
This method clears the existing contents of the row, but retains the allocation.
sourcepub fn pack<'a, I, D>(iter: I) -> Row
pub fn pack<'a, I, D>(iter: I) -> Row
Take some Datum
s and pack them into a Row
.
This method builds a Row
by repeatedly increasing the backing
allocation. If the contents of the iterator are known ahead of
time, consider Row::with_capacity
to right-size the allocation
first, and then RowPacker::extend
to populate it with Datum
s.
This avoids the repeated allocation resizing and copying.
sourcepub fn pack_using<'a, I, D>(&mut self, iter: I) -> Row
pub fn pack_using<'a, I, D>(&mut self, iter: I) -> Row
Use self
to pack iter
, and then clone the result.
This is a convenience method meant to reduce boilerplate around row formation.
sourcepub fn try_pack<'a, I, D, E>(iter: I) -> Result<Row, E>
pub fn try_pack<'a, I, D, E>(iter: I) -> Result<Row, E>
Like Row::pack
, but the provided iterator is allowed to produce an
error, in which case the packing operation is aborted and the error
returned.
sourcepub fn pack_slice<'a>(slice: &[Datum<'a>]) -> Row
pub fn pack_slice<'a>(slice: &[Datum<'a>]) -> Row
Pack a slice of Datum
s into a Row
.
This method has the advantage over pack
that it can determine the required
allocation before packing the elements, ensuring only one allocation and no
redundant copies required.
sourcepub fn data_len(&self) -> usize
pub fn data_len(&self) -> usize
The length of the encoded row in bytes. Does not include the size of the Row
struct itself.
sourcepub fn byte_capacity(&self) -> usize
pub fn byte_capacity(&self) -> usize
Returns the total capacity in bytes used by this row.
sourcepub fn as_row_ref(&self) -> &RowRef
pub fn as_row_ref(&self) -> &RowRef
Extracts a Row slice containing the entire Row
.
Methods from Deref<Target = RowRef>§
sourcepub fn unpack(&self) -> Vec<Datum<'_>>
pub fn unpack(&self) -> Vec<Datum<'_>>
Unpack self
into a Vec<Datum>
for efficient random access.
sourcepub fn unpack_first(&self) -> Datum<'_>
pub fn unpack_first(&self) -> Datum<'_>
Trait Implementations§
source§impl Arbitrary for Row
impl Arbitrary for Row
§type Parameters = SizeRange
type Parameters = SizeRange
arbitrary_with
accepts for configuration
of the generated Strategy
. Parameters must implement Default
.§type Strategy = BoxedStrategy<Row>
type Strategy = BoxedStrategy<Row>
Strategy
used to generate values of type Self
.source§fn arbitrary_with(size: Self::Parameters) -> Self::Strategy
fn arbitrary_with(size: Self::Parameters) -> Self::Strategy
source§impl Codec for Row
impl Codec for Row
source§fn encode<B>(&self, buf: &mut B)where
B: BufMut,
fn encode<B>(&self, buf: &mut B)where
B: BufMut,
Encodes a row into the permanent storage format.
This perfectly round-trips through Row::decode. It’s guaranteed to be readable by future versions of Materialize through v(TODO: Figure out our policy).
source§fn decode(buf: &[u8], schema: &RelationDesc) -> Result<Row, String>
fn decode(buf: &[u8], schema: &RelationDesc) -> Result<Row, String>
Decodes a row from the permanent storage format.
This perfectly round-trips through Row::encode. It can read rows encoded by historical versions of Materialize back to v(TODO: Figure out our policy).
§type Storage = ProtoRow
type Storage = ProtoRow
()
if unnecessary.§type Schema = RelationDesc
type Schema = RelationDesc
source§fn codec_name() -> String
fn codec_name() -> String
source§fn decode_from<'a>(
&mut self,
buf: &'a [u8],
storage: &mut Option<ProtoRow>,
schema: &RelationDesc,
) -> Result<(), String>
fn decode_from<'a>( &mut self, buf: &'a [u8], storage: &mut Option<ProtoRow>, schema: &RelationDesc, ) -> Result<(), String>
source§fn validate(row: &Self, desc: &Self::Schema) -> Result<(), String>
fn validate(row: &Self, desc: &Self::Schema) -> Result<(), String>
source§fn encode_schema(schema: &Self::Schema) -> Bytes
fn encode_schema(schema: &Self::Schema) -> Bytes
source§fn decode_schema(buf: &Bytes) -> Self::Schema
fn decode_schema(buf: &Bytes) -> Self::Schema
source§impl ColumnDecoder<Row> for RowColumnarDecoder
impl ColumnDecoder<Row> for RowColumnarDecoder
source§fn stats(&self) -> StructStats
fn stats(&self) -> StructStats
source§impl ColumnEncoder<Row> for RowColumnarEncoder
impl ColumnEncoder<Row> for RowColumnarEncoder
§type FinishedColumn = StructArray
type FinishedColumn = StructArray
source§fn append_null(&mut self)
fn append_null(&mut self)
source§fn finish(self) -> Self::FinishedColumn
fn finish(self) -> Self::FinishedColumn
source§impl Columnation for Row
impl Columnation for Row
§type InnerRegion = RowStack
type InnerRegion = RowStack
Self
type. Note: not allocations of Self
, but of the
things that it owns.source§impl<'de> Deserialize<'de> for Row
impl<'de> Deserialize<'de> for Row
source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
source§impl FromDatumIter for Row
impl FromDatumIter for Row
source§fn from_datum_iter<'a, I, D>(&mut self, datum_iter: I) -> Self
fn from_datum_iter<'a, I, D>(&mut self, datum_iter: I) -> Self
Packs into self
the given iterator of datums and returns a clone.
source§fn try_from_datum_iter<'a, I, D, E>(&mut self, datum_iter: I) -> Result<Self, E>
fn try_from_datum_iter<'a, I, D, E>(&mut self, datum_iter: I) -> Result<Self, E>
Packs into self
by using the packer’s try_extend
method on the given iterator
and returns a clone.
source§impl<'a> IntoIterator for &'a Row
impl<'a> IntoIterator for &'a Row
source§impl IntoRowIterator for Row
impl IntoRowIterator for Row
type Iter = SingleRowIter
fn into_row_iter(self) -> Self::Iter
source§impl Ord for Row
impl Ord for Row
source§impl PartialOrd for Row
impl PartialOrd for Row
source§impl RustType<ProtoRow> for Row
impl RustType<ProtoRow> for Row
source§fn into_proto(&self) -> ProtoRow
fn into_proto(&self) -> ProtoRow
Self
into a Proto
value.source§fn from_proto(proto: ProtoRow) -> Result<Self, TryFromProtoError>
fn from_proto(proto: ProtoRow) -> Result<Self, TryFromProtoError>
source§fn into_proto_owned(self) -> Proto
fn into_proto_owned(self) -> Proto
Self::into_proto
that types can
optionally implement, otherwise, the default implementation
delegates to Self::into_proto
.source§impl Schema2<Row> for RelationDesc
impl Schema2<Row> for RelationDesc
§type ArrowColumn = StructArray
type ArrowColumn = StructArray
§type Statistics = OptionStats<StructStats>
type Statistics = OptionStats<StructStats>
§type Decoder = RowColumnarDecoder
type Decoder = RowColumnarDecoder
T
from Self::ArrowColumn
.§type Encoder = RowColumnarEncoder
type Encoder = RowColumnarEncoder
T
.source§fn decoder(&self, col: Self::ArrowColumn) -> Result<Self::Decoder, Error>
fn decoder(&self, col: Self::ArrowColumn) -> Result<Self::Decoder, Error>
T
from the provider column.source§fn decoder_any(&self, col: &dyn Array) -> Result<Self::Decoder, Error>
fn decoder_any(&self, col: &dyn Array) -> Result<Self::Decoder, Error>
T
from a type erased
arrow::array::Array
, erroring if the provided array is not Self::ArrowColumn
.source§impl ToDatumIter for Row
impl ToDatumIter for Row
§type DatumIter<'a> = DatumListIter<'a>
type DatumIter<'a> = DatumListIter<'a>
Datum iterator for Row
.
source§fn to_datum_iter<'a>(&'a self) -> Self::DatumIter<'a>
fn to_datum_iter<'a>(&'a self) -> Self::DatumIter<'a>
Borrows self
and gets an iterator from it.
impl Eq for Row
impl StructuralPartialEq for Row
Auto Trait Implementations§
impl Freeze for Row
impl RefUnwindSafe for Row
impl Send for Row
impl Sync for Row
impl Unpin for Row
impl UnwindSafe for Row
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§default unsafe fn clone_to_uninit(&self, dst: *mut T)
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.source§impl<T> FutureExt for T
impl<T> FutureExt for T
source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T
in a tonic::Request
source§impl<T, U> OverrideFrom<Option<&T>> for Uwhere
U: OverrideFrom<T>,
impl<T, U> OverrideFrom<Option<&T>> for Uwhere
U: OverrideFrom<T>,
source§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<T> PreferredContainer for T
impl<T> PreferredContainer for T
source§impl<T> ProgressEventTimestamp for T
impl<T> ProgressEventTimestamp for T
source§impl<P, R> ProtoType<R> for Pwhere
R: RustType<P>,
impl<P, R> ProtoType<R> for Pwhere
R: RustType<P>,
source§fn into_rust(self) -> Result<R, TryFromProtoError>
fn into_rust(self) -> Result<R, TryFromProtoError>
RustType::from_proto
.source§fn from_rust(rust: &R) -> P
fn from_rust(rust: &R) -> P
RustType::into_proto
.source§impl<'a, S, T> Semigroup<&'a S> for Twhere
T: Semigroup<S>,
impl<'a, S, T> Semigroup<&'a S> for Twhere
T: Semigroup<S>,
source§fn plus_equals(&mut self, rhs: &&'a S)
fn plus_equals(&mut self, rhs: &&'a S)
std::ops::AddAssign
, for types that do not implement AddAssign
.