pub struct MultiVector<'a, Ts>where
Ts: VariadicRefFactory,{ /* private fields */ }
Expand description
A container for writing an indexed sequence of heterogeneous data items.
The concept of a multivector is used for storing and reading heterogeneous
flatdata structs in/from the same container. The data is indexed by
integers. Each index refers to a bucket which may contain a variable number
of items of different types unified in the same variant enum Ts
.
Such bucket may also be empty, which allows to represent sparse data in a
multivector. For those who are familiar with C++’s std::multimap
data
structure, a multivector can be considered as a std::multimap
mapping
integers to sequences of variable length.
A MultiVector
corresponds rather to ExternalVector
than to
Vector
, in the sense that the items are flushed to storage whenever the
internal buffer is full. In particular, it is only possible to modify the
last bucket. There is no access to the buckets previously stored.
For accessing and reading the data stored by in multivector, cf.
MultiArrayView
.
A multivector must be closed, after the last element was written to it. After closing, it can not be used anymore.
Internally data is stored like this:
Index
:Vector<Idx>
- encodes start/end byte inData
array for each elementi
. *Data
:Vec<u8>
- sequence of serialized (Tag
,ItemData
) tuples, whereTag
encodes the the variant type, andItemData
contains the underlying variant data.Tag
has size of 1 byte,ItemData
is of sizeTs::Type::SIZE_IN_BYTES
.
§Examples
struct A {
x : u32 : 16;
y : u32 : 16;
}
struct B {
id : u32 : 16;
}
archive Z {
ab : multivector<16, A, B>;
}
use flatdata::MemoryResourceStorage;
use flatdata::test::{A, B, AbRef, Z, ZBuilder};
// create multivector and serialize some data
let mut storage = MemoryResourceStorage::new("/root/multivec");
let mut builder = ZBuilder::new(storage.clone()).expect("Fail to create builder");
let mut mv = builder.start_ab().expect("failed to create MultiVector");
let mut item = mv.grow().expect("grow failed");
let mut a = item.add_a();
a.set_x(1);
a.set_y(2);
let mut b = item.add_b();
b.set_id(42);
mv.close().expect("close failed");
// open multivector and read the data
let archive = Z::open(storage).expect("open failed");
let mv = archive.ab();
assert_eq!(mv.len(), 1);
// Items are iterators over `AbRef` enums with variants `A` and `B`.
// The name of the item type is the name of the multivector in the archive with the `Ref`
// suffix.
let mut item = mv.at(0);
match item.next().unwrap() {
AbRef::A(a) => assert_eq!((a.x(), a.y()), (1, 2)),
_ => assert!(false),
}
match item.next().unwrap() {
AbRef::B(b) => assert_eq!(b.id(), 42),
_ => assert!(false),
}
Implementations§
Source§impl<'a, Ts> MultiVector<'a, Ts>where
Ts: VariadicRefFactory,
impl<'a, Ts> MultiVector<'a, Ts>where
Ts: VariadicRefFactory,
Sourcepub fn new(
index: ExternalVector<'a, Ts::Index>,
data_handle: ResourceHandle<'a>,
) -> Self
pub fn new( index: ExternalVector<'a, Ts::Index>, data_handle: ResourceHandle<'a>, ) -> Self
Creates an empty multivector.
Sourcepub fn grow(&mut self) -> Result<<Ts as VariadicStruct<'_>>::ItemMut>
pub fn grow(&mut self) -> Result<<Ts as VariadicStruct<'_>>::ItemMut>
Appends a new item to the end of this multivector and returns a builder for it.
The builder is used for storing different variants of Ts
in the newly
created item.
Calling this method may flush data to storage (cf. flush
), which
may fail due to different IO reasons.
Sourcepub fn close(self) -> Result<MultiArrayView<'a, Ts>, ResourceStorageError>
pub fn close(self) -> Result<MultiArrayView<'a, Ts>, ResourceStorageError>
Flushes the remaining not yet flushed elements in this multivector and finalizes the data inside the storage.
A multivector must be closed