Skip to main content

File

Trait File 

Source
pub trait File:
    Debug
    + Send
    + Sync {
    // Required methods
    fn read_at(&self, offset: u64, buf: &mut [u8]) -> Result<usize>;
    fn write_at(&self, offset: u64, data: &[u8]) -> Result<()>;
    fn sync(&self) -> Result<()>;
    fn truncate(&self, len: u64) -> Result<()>;
    fn len(&self) -> Result<u64>;

    // Provided methods
    fn submit(&self, requests: Vec<Request>) -> Completion { ... }
    fn read_exact_at(&self, offset: u64, buf: &mut [u8]) -> Result<()> { ... }
    fn is_empty(&self) -> Result<bool> { ... }
}
Expand description

An open file, addressed by offset rather than by a cursor.

Implementors are shared across threads, which is why every method takes &self. A File here is closer to a block device with a name than to std::fs::File.

Required Methods§

Source

fn read_at(&self, offset: u64, buf: &mut [u8]) -> Result<usize>

Reads into buf starting at offset and returns how many bytes were read.

A short read at the end of the file is not an error, it is a short read. The caller knows how long the file is and what it expected.

§Errors

If the underlying read fails.

Source

fn write_at(&self, offset: u64, data: &[u8]) -> Result<()>

Writes all of data starting at offset, extending the file if it has to.

This does not make the write durable. Nothing is durable until Self::sync returns, and a write that has not been synced can be present, absent or reordered against another unsynced write after a crash. That is not a quirk of the simulation, it is what the hardware does, and it is the reason the simulation models it.

§Errors

If the underlying write fails, or if the file was not opened for writing.

Source

fn sync(&self) -> Result<()>

Makes every write issued before this call durable.

§Errors

If the underlying sync fails. An error here is not recoverable by retrying, per the write handling discussion in spec/11-transactions.md: a failed fsync on Linux can drop the dirty pages, so a second call may return success while the data is gone.

Source

fn truncate(&self, len: u64) -> Result<()>

Cuts the file to len bytes, or extends it with zeroes.

§Errors

If the underlying truncate fails.

Source

fn len(&self) -> Result<u64>

How many bytes long the file currently is.

§Errors

If the length cannot be determined.

Provided Methods§

Source

fn submit(&self, requests: Vec<Request>) -> Completion

States every read the caller wants and hands back something to wait on or poll.

This is the interface a scan is written against, per spec/engine/05-scan.md section 5.3. A row group scan knows all of its byte ranges before it reads any of them, so it says all of them at once, and a backend that hears all of them at once can issue them concurrently and can coalesce the adjacent ones. Neither is available to a caller that asks one range at a time, which is the whole reason the method exists.

The default here is the loop over Self::read_at, so every backend has a correct implementation from the moment it exists and a backend with a real queue underneath it overrides this rather than being the only thing that works. A failed read fails that one request and leaves the rest of the batch alone, because the caller may well be able to answer the query from what did arrive, and in any case it is the caller that knows.

Source

fn read_exact_at(&self, offset: u64, buf: &mut [u8]) -> Result<()>

Reads exactly buf.len() bytes starting at offset.

§Errors

If the read fails, or if the file ends first. The second case is a real error here, unlike in Self::read_at, because a caller who asked for an exact read said it knew the length.

Source

fn is_empty(&self) -> Result<bool>

Whether the file has no bytes in it.

§Errors

If the length cannot be determined.

Dyn Compatibility§

This trait is dyn compatible.

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

Implementors§