Skip to main content

Crate barrique

Crate barrique 

Source
Expand description

Standard implementation of barrique binary serialization format

barrique is a serialization format designed for local out-of-memory caches, featuring metadata, compression and streaming. Data stored in the core primitive — region. Regions are LZ4 compressed blocks of encoded bytes additionally storing small metadata header.

§Example

Most likely you’ll start with implementations generated by derive macro:

use barrique::region::{AllocOrd, Seed};
use barrique::{Encode, Decode};
use barrique::frame::Frame;

#[derive(Encode, Decode, Clone, Debug, PartialEq)]
struct Bee {
    name: String,
    state: State,
    #[barrique(skip(default_expr = "2"))]
    age: u8,
}

#[derive(Encode, Decode, Clone, Debug, PartialEq)]
#[barrique(tag_repr = "u8")]
enum State {
    Collecting(i32, i32),
    Buzzing {
        sound_level: u8
    },
    Sleeping
}

let bee = Bee {
    name: "Oh, hey!".to_string(),
    state: State::Sleeping,
    age: 2
};
let mut dst = vec![];

let frame = Frame::new(&mut dst, Seed::new(0))
    .with_label("A beehive".try_into().unwrap());
frame.encode(bee.clone()).unwrap();

let frame: Frame<Bee, _> = Frame::decode(dst.as_slice(), Seed::new(0))
    .expect("Failed to open a frame");

assert_eq!(frame.get_value(AllocOrd::default()).unwrap(), bee);

Frame is specification-defined format wrapping a stream primitive. Streams available as StreamEncoder and StreamDecoder.

§Streaming

barrique format was designed to keep buffer memory usage constant, which is 128 KiB (AllocOrd allows to specify it if a value to encode is less than 128 KiB). The buffer size limit is exact length of two raw regions, previous region is stored to improve LZ4 compression ratio, which maximum window size is 64 KiB.

The crate provides a wrapper for std::io::Write and std::io::Read traits called CursorView in order to utilize streaming, making memory usage up to 192 KiB where 128 KiB allocated by the stream primitive and additional 64 KiB is the maximum size of dynamic buffer of a CursorView (although it can be more than 64 KiB, stream primitive requests up to 64 KiB per request).

An example of CursorView application:

use barrique::encode::{StreamEncoder, Encode};
use barrique::region::{AllocOrd, Seed};
use barrique::cursor::CursorView;

use std::fs::File;

let file = File::create("serialized.bin").unwrap();
let mut dst = CursorView::new(file);

let mut encoder = StreamEncoder::new(&mut dst, Seed::new(0), AllocOrd::full());
<str as Encode>::encode(&mut encoder, "Hello, world!").unwrap();

encoder.flush().unwrap(); // Buffer -> `dst`
dst.flush().unwrap(); // `dst` -> File

§no_std support

Available via no_std feature, however, alloc crate is required

Modules§

cursor
Implementations of Reader and Writer traits for types requiring additional tracking of the state
decode
encode
frame
impl
region

Derive Macros§

Decode
Encode