#![deny(unsafe_code)]
pub mod glob;
pub mod machine;
pub mod pool;
pub mod real;
pub mod sim;
pub mod submit;
#[cfg(test)]
mod scratch;
use std::fmt::Debug;
use std::path::{Path, PathBuf};
use rudb_common::Result;
pub use glob::expand;
pub use machine::{default_memory_limit, execution_cores, physical_memory};
pub use pool::{Config, Pool, Pooled, Stats};
pub use real::RealFilesystem;
pub use sim::{Completions, Crash, Op, SimFilesystem};
pub use submit::{Completion, Filler, Request, Response};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OpenMode {
Read,
ReadWrite,
Create,
CreateNew,
}
impl OpenMode {
#[must_use]
pub fn writable(self) -> bool {
!matches!(self, Self::Read)
}
}
pub trait File: Debug + Send + Sync {
fn read_at(&self, offset: u64, buf: &mut [u8]) -> Result<usize>;
fn submit(&self, requests: Vec<Request>) -> Completion {
let (completion, filler) = Completion::pending(requests.len());
for (index, request) in requests.into_iter().enumerate() {
let offset = request.offset();
let mut buf = request.into_buffer();
let outcome =
self.read_at(offset, &mut buf).map(|read| Response::new(index, offset, read, buf));
filler.finish(index, outcome);
}
completion
}
fn read_exact_at(&self, offset: u64, buf: &mut [u8]) -> Result<()> {
let read = self.read_at(offset, buf)?;
if read == buf.len() {
Ok(())
} else {
Err(rudb_common::Error::io(format!(
"wanted {} bytes at offset {offset} and the file had {read}",
buf.len()
)))
}
}
fn write_at(&self, offset: u64, data: &[u8]) -> Result<()>;
fn sync(&self) -> Result<()>;
fn truncate(&self, len: u64) -> Result<()>;
fn len(&self) -> Result<u64>;
fn is_empty(&self) -> Result<bool> {
Ok(self.len()? == 0)
}
}
pub trait Filesystem: Debug + Send + Sync {
fn open(&self, path: &Path, mode: OpenMode) -> Result<Box<dyn File>>;
fn exists(&self, path: &Path) -> bool;
fn is_dir(&self, path: &Path) -> bool;
fn read_dir(&self, path: &Path) -> Result<Vec<PathBuf>>;
fn remove(&self, path: &Path) -> Result<()>;
fn rename(&self, from: &Path, to: &Path) -> Result<()>;
fn create_dir_all(&self, path: &Path) -> Result<()>;
fn sync_dir(&self, path: &Path) -> Result<()>;
}