Struct repr::Row [−][src]
Expand description
A packed representation for Datum
s.
Datum
is easy to work with but very space inefficent. 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 “packer”
pattern: allocate one row, pack into it, and then call
Row::finish_and_reuse
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: SmallVec<[u8; 24]>
Implementations
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 Row::extend
to populate it with Datum
s.
This avoids the repeated allocation resizing and copying.
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.
Allocate an empty Row
with a pre-allocated capacity.
Extend an existing Row
with a Datum
.
pub fn extend<'a, I, D>(&mut self, iter: I) where
I: IntoIterator<Item = D>,
D: Borrow<Datum<'a>>,
pub fn extend<'a, I, D>(&mut self, iter: I) where
I: IntoIterator<Item = D>,
D: Borrow<Datum<'a>>,
Extend an existing Row
with additional Datum
s.
pub fn try_extend<'a, I, E, D>(&mut self, iter: I) -> Result<(), E> where
I: IntoIterator<Item = Result<D, E>>,
D: Borrow<Datum<'a>>,
pub fn try_extend<'a, I, E, D>(&mut self, iter: I) -> Result<(), E> where
I: IntoIterator<Item = Result<D, E>>,
D: Borrow<Datum<'a>>,
Extend an existing Row
with additional Datum
s.
In the case the iterator produces an error, the pushing of
datums in terminated and the error returned. The Row
will
be incomplete, but it will be safe to read datums from it.
Appends the datums of an entire Row
.
Clears the contents of the row without de-allocating its backing memory.
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.
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.
Pushes a DatumList
that is built from a closure.
The supplied closure will be invoked once with a Row
that can
be used to populate the list. It is valid to call any method on the
Row
except for Row::finish_and_reuse
or Row::truncate
.
Returns the value returned by the closure, if any.
let mut row = Row::default();
row.push_list_with(|row| {
row.push(Datum::String("age"));
row.push(Datum::Int64(42));
});
assert_eq!(
row.unpack_first().unwrap_list().iter().collect::<Vec<_>>(),
vec![Datum::String("age"), Datum::Int64(42)],
);
Pushes a DatumMap
that is built from a closure.
The supplied closure will be invoked once with a Row
that can be
used to populate the dict.
The closure must alternate pushing string keys and arbitary values, otherwise reading the dict will cause a panic.
The closure must push keys in ascending order, otherwise equality
checks on the resulting Row
may be wrong and reading the dict IN DEBUG
MODE will cause a panic.
The closure must not call Row::finish_and_reuse
.
Example
let mut row = Row::default();
row.push_dict_with(|row| {
// key
row.push(Datum::String("age"));
// value
row.push(Datum::Int64(42));
// key
row.push(Datum::String("name"));
// value
row.push(Datum::String("bob"));
});
assert_eq!(
row.unpack_first().unwrap_map().iter().collect::<Vec<_>>(),
vec![("age", Datum::Int64(42)), ("name", Datum::String("bob"))]
);
pub fn push_array<'a, I, D>(
&mut self,
dims: &[ArrayDimension],
iter: I
) -> Result<(), InvalidArrayError> where
I: IntoIterator<Item = D>,
D: Borrow<Datum<'a>>,
pub fn push_array<'a, I, D>(
&mut self,
dims: &[ArrayDimension],
iter: I
) -> Result<(), InvalidArrayError> where
I: IntoIterator<Item = D>,
D: Borrow<Datum<'a>>,
Convenience function to construct an array from an iter of Datum
s.
Returns an error if the number of elements in iter
does not match
the cardinality of the array as described by dims
, or if the
number of dimensions exceeds MAX_ARRAY_DIMENSIONS
. If an error
occurs, the packer’s state will be unchanged.
pub fn push_list<'a, I, D>(&mut self, iter: I) where
I: IntoIterator<Item = D>,
D: Borrow<Datum<'a>>,
pub fn push_list<'a, I, D>(&mut self, iter: I) where
I: IntoIterator<Item = D>,
D: Borrow<Datum<'a>>,
Convenience function to push a DatumList
from an iter of Datum
s
See Row::push_dict_with
if you need to be able to handle errors
Convenience function to push a DatumMap
from an iter of (&str, Datum)
pairs
Returns a copy of this Row
, clearing the data but not the allocation
in self
.
The intent is that self
’s allocation can be used to pack additional
rows, to reduce the amount of interaction with the allocator.
Truncates the underlying storage to the specified byte position.
Safety
pos
MUST specify a byte offset that lies on a datum boundary.
If pos
specifies a byte offset that is within a datum, the row
packer will produce an invalid row, the unpacking of which may
trigger undefined behavior!
To find the byte offset of a datum boundary, inspect the the packer’s
byte length by calling packer.data().len()
after pushing the desired
number of datums onto the packer.
Truncates the row to contain at most the first n
datums.
Panics
Methods from Deref<Target = RowRef>
Unpack self
into a Vec<Datum>
for efficient random access.
Return the first Datum
in self
Panics if the Row
is empty.
pub fn iter(&self) -> DatumListIter<'_>ⓘNotable traits for DatumListIter<'a>impl<'a> Iterator for DatumListIter<'a> type Item = Datum<'a>;
pub fn iter(&self) -> DatumListIter<'_>ⓘNotable traits for DatumListIter<'a>impl<'a> Iterator for DatumListIter<'a> type Item = Datum<'a>;
impl<'a> Iterator for DatumListIter<'a> type Item = Datum<'a>;
Iterate the Datum
elements of the Row
.
For debugging only
Trait Implementations
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).
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).
Name of the codec. Read more
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>,
Deserialize this value from the given Serde deserializer. Read more
These implementations order first by length, and then by slice contents. This allows many comparisons to complete without dereferencing memory.
This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
This method tests greater than (for self
and other
) and is used by the >
operator. Read more
Auto Trait Implementations
impl RefUnwindSafe for Row
impl UnwindSafe for Row
Blanket Implementations
Mutably borrows from an owned value. Read more
Formats an object with the “alternative” format ({:#}
) and returns it.
Compare self to key
and return true
if they are equal.
Attaches the provided Subscriber
to this type, returning a
WithDispatch
wrapper. Read more
Attaches the current default Subscriber
to this type, returning a
WithDispatch
wrapper. Read more