Create mmap file storage
This commit is contained in:
parent
7031023a31
commit
ed05ffc6f7
3 changed files with 113 additions and 2 deletions
|
|
@ -62,8 +62,21 @@ impl StorageFactory for FilesystemStorageFactory {
|
|||
}
|
||||
|
||||
pub struct FilesystemStorage {
|
||||
output_folder: PathBuf,
|
||||
opened_files: Vec<OpenedFile>,
|
||||
pub(super) output_folder: PathBuf,
|
||||
pub(super) opened_files: Vec<OpenedFile>,
|
||||
}
|
||||
|
||||
impl FilesystemStorage {
|
||||
pub(super) fn take_fs(&self) -> anyhow::Result<Self> {
|
||||
Ok(Self {
|
||||
opened_files: self
|
||||
.opened_files
|
||||
.iter()
|
||||
.map(|f| f.take_clone())
|
||||
.collect::<anyhow::Result<Vec<_>>>()?,
|
||||
output_folder: self.output_folder.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TorrentStorage for FilesystemStorage {
|
||||
|
|
|
|||
97
crates/librqbit/src/storage/filesystem/mmap.rs
Normal file
97
crates/librqbit/src/storage/filesystem/mmap.rs
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
use std::path::Path;
|
||||
|
||||
use anyhow::Context;
|
||||
use memmap2::{MmapMut, MmapOptions};
|
||||
use parking_lot::RwLock;
|
||||
|
||||
use crate::torrent_state::ManagedTorrentInfo;
|
||||
|
||||
use crate::storage::{StorageFactory, TorrentStorage};
|
||||
|
||||
use super::{FilesystemStorage, FilesystemStorageFactory};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MmapFilesystemStorageFactory {}
|
||||
|
||||
type OpenedMmap = RwLock<MmapMut>;
|
||||
|
||||
fn dummy_mmap() -> anyhow::Result<MmapMut> {
|
||||
Ok(memmap2::MmapOptions::new().len(1).map_anon()?)
|
||||
}
|
||||
|
||||
impl StorageFactory for MmapFilesystemStorageFactory {
|
||||
type Storage = MmapFilesystemStorage;
|
||||
|
||||
fn init_storage(&self, meta: &ManagedTorrentInfo) -> anyhow::Result<Self::Storage> {
|
||||
let fs_storage = FilesystemStorageFactory::default().init_storage(meta)?;
|
||||
let mut mmaps = Vec::new();
|
||||
for file in fs_storage.opened_files.iter() {
|
||||
let mmap = unsafe { MmapOptions::new().map_mut(&*file.file.lock()) }
|
||||
.context("error mapping file")?;
|
||||
mmaps.push(RwLock::new(mmap));
|
||||
}
|
||||
|
||||
Ok(MmapFilesystemStorage {
|
||||
opened_mmaps: mmaps,
|
||||
fs: fs_storage,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MmapFilesystemStorage {
|
||||
opened_mmaps: Vec<OpenedMmap>,
|
||||
fs: FilesystemStorage,
|
||||
}
|
||||
|
||||
impl TorrentStorage for MmapFilesystemStorage {
|
||||
fn pread_exact(&self, file_id: usize, offset: u64, buf: &mut [u8]) -> anyhow::Result<()> {
|
||||
let g = self
|
||||
.opened_mmaps
|
||||
.get(file_id)
|
||||
.context("no such file")?
|
||||
.read();
|
||||
let start = offset;
|
||||
let end = offset + buf.len() as u64;
|
||||
let start = start.try_into()?;
|
||||
let end = end.try_into()?;
|
||||
buf.copy_from_slice(g.get(start..end).context("bug")?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn pwrite_all(&self, file_id: usize, offset: u64, buf: &[u8]) -> anyhow::Result<()> {
|
||||
let mut g = self
|
||||
.opened_mmaps
|
||||
.get(file_id)
|
||||
.context("no such file")?
|
||||
.write();
|
||||
let start = offset;
|
||||
let end = offset + buf.len() as u64;
|
||||
let start = start.try_into()?;
|
||||
let end = end.try_into()?;
|
||||
g.get_mut(start..end).context("bug")?.copy_from_slice(buf);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn remove_file(&self, file_id: usize, filename: &Path) -> anyhow::Result<()> {
|
||||
self.fs.remove_file(file_id, filename)
|
||||
}
|
||||
|
||||
fn ensure_file_length(&self, file_id: usize, len: u64) -> anyhow::Result<()> {
|
||||
self.fs.ensure_file_length(file_id, len)
|
||||
}
|
||||
|
||||
fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>> {
|
||||
Ok(Box::new(Self {
|
||||
opened_mmaps: self
|
||||
.opened_mmaps
|
||||
.iter()
|
||||
.map(|m| {
|
||||
let d = dummy_mmap()?;
|
||||
let mut g = m.write();
|
||||
Ok::<_, anyhow::Error>(RwLock::new(std::mem::replace(&mut *g, d)))
|
||||
})
|
||||
.collect::<anyhow::Result<_>>()?,
|
||||
fs: self.fs.take_fs()?,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
mod fs;
|
||||
mod mmap;
|
||||
mod opened_file;
|
||||
|
||||
pub use fs::{FilesystemStorage, FilesystemStorageFactory};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue