diff --git a/crates/librqbit/Cargo.toml b/crates/librqbit/Cargo.toml index fbe02fc..75db80e 100644 --- a/crates/librqbit/Cargo.toml +++ b/crates/librqbit/Cargo.toml @@ -58,7 +58,6 @@ tracing-subscriber = { version = "0.3", default-features = false, features = [ "fmt", "env-filter", ] } - uuid = { version = "1.2", features = ["v4"] } futures = "0.3" url = "2" @@ -71,6 +70,7 @@ tokio-util = "0.7.10" bytes = "1.5.0" rlimit = "0.10.1" async-stream = "0.3.5" +memmap2 = "0.9.4" [dev-dependencies] futures = { version = "0.3" } @@ -78,4 +78,3 @@ tracing-subscriber = "0.3" tokio-test = "0.4" tempfile = "3" rand = { version = "0.8", features = ["small_rng"] } -memmap2 = "0.9.4" diff --git a/crates/librqbit/examples/custom_storage.rs b/crates/librqbit/examples/custom_storage.rs index ee3330a..f0fa5a4 100644 --- a/crates/librqbit/examples/custom_storage.rs +++ b/crates/librqbit/examples/custom_storage.rs @@ -1,67 +1,8 @@ use std::time::Duration; -use anyhow::Context; -use librqbit::{ - storage::{StorageFactory, TorrentStorage}, - FileInfos, ManagedTorrentInfo, SessionOptions, -}; -use memmap2::{MmapMut, MmapOptions}; -use parking_lot::RwLock; +use librqbit::{storage::mmap::MmapStorageFactory, SessionOptions}; use tracing::info; -struct MmapStorageFactory {} - -struct MmapStorage { - mmap: RwLock, - file_infos: FileInfos, -} - -impl StorageFactory for MmapStorageFactory { - fn init_storage( - &self, - info: &ManagedTorrentInfo, - ) -> anyhow::Result> { - Ok(Box::new(MmapStorage { - mmap: RwLock::new( - MmapOptions::new() - .len(info.lengths.total_length().try_into()?) - .map_anon()?, - ), - file_infos: info.file_infos.clone(), - })) - } -} - -impl TorrentStorage for MmapStorage { - fn pread_exact(&self, file_id: usize, offset: u64, buf: &mut [u8]) -> anyhow::Result<()> { - let start: usize = (self.file_infos[file_id].offset_in_torrent + offset).try_into()?; - let end = start + buf.len(); - buf.copy_from_slice(self.mmap.read().get(start..end).context("bad range")?); - Ok(()) - } - - fn pwrite_all(&self, file_id: usize, offset: u64, buf: &[u8]) -> anyhow::Result<()> { - let start: usize = (self.file_infos[file_id].offset_in_torrent + offset).try_into()?; - let end = start + buf.len(); - let mut g = self.mmap.write(); - let target = g.get_mut(start..end).context("bad range")?; - target.copy_from_slice(buf); - Ok(()) - } - - fn remove_file(&self, _file_id: usize, _filename: &std::path::Path) -> anyhow::Result<()> { - Ok(()) - } - - fn ensure_file_length(&self, _file_id: usize, _length: u64) -> anyhow::Result<()> { - Ok(()) - } - - fn take(&self) -> anyhow::Result> { - anyhow::bail!("not implemented") - } -} - #[tokio::main] async fn main() -> anyhow::Result<()> { // Output logs to console. diff --git a/crates/librqbit/src/storage/mmap.rs b/crates/librqbit/src/storage/mmap.rs new file mode 100644 index 0000000..dbd1ee2 --- /dev/null +++ b/crates/librqbit/src/storage/mmap.rs @@ -0,0 +1,60 @@ +use anyhow::Context; +use memmap2::{MmapMut, MmapOptions}; +use parking_lot::RwLock; + +use crate::{FileInfos, ManagedTorrentInfo}; + +use super::{StorageFactory, TorrentStorage}; + +pub struct MmapStorageFactory {} + +struct MmapStorage { + mmap: RwLock, + file_infos: FileInfos, +} + +impl StorageFactory for MmapStorageFactory { + fn init_storage( + &self, + info: &ManagedTorrentInfo, + ) -> anyhow::Result> { + Ok(Box::new(MmapStorage { + mmap: RwLock::new( + MmapOptions::new() + .len(info.lengths.total_length().try_into()?) + .map_anon()?, + ), + file_infos: info.file_infos.clone(), + })) + } +} + +impl TorrentStorage for MmapStorage { + fn pread_exact(&self, file_id: usize, offset: u64, buf: &mut [u8]) -> anyhow::Result<()> { + let start: usize = (self.file_infos[file_id].offset_in_torrent + offset).try_into()?; + let end = start + buf.len(); + buf.copy_from_slice(self.mmap.read().get(start..end).context("bad range")?); + Ok(()) + } + + fn pwrite_all(&self, file_id: usize, offset: u64, buf: &[u8]) -> anyhow::Result<()> { + let start: usize = (self.file_infos[file_id].offset_in_torrent + offset).try_into()?; + let end = start + buf.len(); + let mut g = self.mmap.write(); + let target = g.get_mut(start..end).context("bad range")?; + target.copy_from_slice(buf); + Ok(()) + } + + fn remove_file(&self, _file_id: usize, _filename: &std::path::Path) -> anyhow::Result<()> { + Ok(()) + } + + fn ensure_file_length(&self, _file_id: usize, _length: u64) -> anyhow::Result<()> { + Ok(()) + } + + fn take(&self) -> anyhow::Result> { + anyhow::bail!("not implemented") + } +} diff --git a/crates/librqbit/src/storage/mod.rs b/crates/librqbit/src/storage/mod.rs index 1a22c25..9401385 100644 --- a/crates/librqbit/src/storage/mod.rs +++ b/crates/librqbit/src/storage/mod.rs @@ -1,5 +1,6 @@ pub mod example; pub mod filesystem; +pub mod mmap; use std::{any::Any, path::Path};