Skip to main content

Blocks

Trait Blocks 

Source
pub trait Blocks {
    // Required methods
    fn put(&mut self, bytes: &[u8]) -> Result<Addr>;
    fn get(&self, at: Addr) -> Result<&[u8]>;
    fn bytes(&self) -> u64;

    // Provided method
    fn release(&mut self) { ... }
}
Expand description

Somewhere chunks go, and come back from.

Deliberately two methods. Everything this module needs from a log is an append that hands back an address and a read that takes one, and writing the trait that small is what lets the tests run against a vector instead of a file.

Required Methods§

Source

fn put(&mut self, bytes: &[u8]) -> Result<Addr>

Put these bytes somewhere and say where they went.

Source

fn get(&self, at: Addr) -> Result<&[u8]>

Read back what was put at at.

The length is not passed in because the store knows it. A log record carries its own length, and a caller that had to remember it would be keeping a second copy of something that is already written down.

Source

fn bytes(&self) -> u64

How many bytes the store is holding, for the storage limit.

The store’s own size and not the sum of what was put in it. A log that has been written to and compacted knows what it occupies and nothing above it does, and maxstore is a limit on the file rather than on the payload that went into it.

Provided Methods§

Source

fn release(&mut self)

Says that every borrow handed out by Blocks::get is finished with.

A store that borrows from something it already holds has nothing to do here and takes the default. A store that has to copy the bytes somewhere before it can lend them out needs a moment when that somewhere is known to be unused, because get takes &self and cannot free anything, and this is that moment: it takes &mut self, which is the proof that no borrow is alive.

A caller that never calls it is correct and grows. Reader holds several chunks of one value at once by design, so the call belongs before a read and not inside one, which is where Tier puts it.

Dyn Compatibility§

This trait is dyn compatible.

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

Implementors§

Source§

impl Blocks for Store

So that a store can be chosen at run time rather than at compile time.

Keyspace holds its tier behind this box, and the reason is that the alternative is a type parameter on Keyspace, which would spread to yo-resp and to every caller of either, all to name a type that only the code opening the file knows. The dispatch it costs is one indirect call on a path that is about to read a device, and nothing at all on a warm read, which never reaches this trait.