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§
Sourcefn read_at(&self, offset: u64, buf: &mut [u8]) -> Result<usize>
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.
Sourcefn write_at(&self, offset: u64, data: &[u8]) -> Result<()>
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.
Sourcefn sync(&self) -> Result<()>
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.
Provided Methods§
Sourcefn submit(&self, requests: Vec<Request>) -> Completion
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.
Sourcefn read_exact_at(&self, offset: u64, buf: &mut [u8]) -> Result<()>
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.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".