subspace_farmer/single_disk_farm/farming/
rayon_files.rsuse std::fs::{File, OpenOptions};
use std::io;
use std::path::Path;
use subspace_farmer_components::file_ext::{FileExt, OpenOptionsExt};
use subspace_farmer_components::ReadAtSync;
#[derive(Debug)]
pub struct RayonFiles<File> {
files: Vec<File>,
}
impl<File> ReadAtSync for RayonFiles<File>
where
File: ReadAtSync,
{
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<()> {
let thread_index = rayon::current_thread_index().unwrap_or_default();
let file = self.files.get(thread_index).ok_or_else(|| {
io::Error::new(io::ErrorKind::Other, "No files entry for this rayon thread")
})?;
file.read_at(buf, offset)
}
}
impl<File> ReadAtSync for &RayonFiles<File>
where
File: ReadAtSync,
{
#[inline]
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<()> {
(*self).read_at(buf, offset)
}
}
impl RayonFiles<File> {
pub fn open<P>(path: P) -> io::Result<Self>
where
P: AsRef<Path>,
{
let files = (0..rayon::current_num_threads())
.map(|_| {
let file = OpenOptions::new()
.read(true)
.advise_random_access()
.open(path.as_ref())?;
file.advise_random_access()?;
Ok::<_, io::Error>(file)
})
.collect::<Result<Vec<_>, _>>()?;
Ok(Self { files })
}
}
impl<File> RayonFiles<File>
where
File: ReadAtSync,
{
pub fn open_with<P>(path: P, open: fn(&Path) -> io::Result<File>) -> io::Result<Self>
where
P: AsRef<Path>,
{
let files = (0..rayon::current_num_threads())
.map(|_| open(path.as_ref()))
.collect::<Result<Vec<_>, _>>()?;
Ok(Self { files })
}
}