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§
Sourcefn put(&mut self, bytes: &[u8]) -> Result<Addr>
fn put(&mut self, bytes: &[u8]) -> Result<Addr>
Put these bytes somewhere and say where they went.
Sourcefn get(&self, at: Addr) -> Result<&[u8]>
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.
Sourcefn bytes(&self) -> u64
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§
Sourcefn release(&mut self)
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§
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.