Skip to content

Commit

Permalink
Make all experimental storages optional
Browse files Browse the repository at this point in the history
  • Loading branch information
ikatson committed May 2, 2024
1 parent 0a1d389 commit 0b1499a
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 14 deletions.
7 changes: 4 additions & 3 deletions crates/librqbit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,10 @@ tokio-util = "0.7.10"
bytes = "1.5.0"
rlimit = "0.10.1"
async-stream = "0.3.5"
memmap2 = "0.9.4"
rand_distr = "0.4.3"
lru = "0.12.3"
memmap2 = { version = "0.9.4" }

rand_distr = { version = "0.4.3", optional = true }
lru = { version = "0.12.3", optional = true }

[dev-dependencies]
futures = { version = "0.3" }
Expand Down
52 changes: 48 additions & 4 deletions crates/librqbit/examples/custom_storage.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,55 @@
use std::time::Duration;

use librqbit::{
storage::{examples::mmap::MmapStorageFactory, StorageFactoryExt},
storage::{StorageFactory, StorageFactoryExt, TorrentStorage},
SessionOptions,
};
use tracing::info;

use std::time::Duration;

#[derive(Default, Clone, Copy)]
struct CustomStorageFactory {
_some_state_used_to_create_per_torrent_storage: (),
}

#[derive(Default, Clone, Copy)]
struct CustomStorage {
_some_state_for_per_torrent_storage: (),
}

impl StorageFactory for CustomStorageFactory {
type Storage = CustomStorage;

fn init_storage(&self, _info: &librqbit::ManagedTorrentInfo) -> anyhow::Result<Self::Storage> {
Ok(CustomStorage::default())
}

fn clone_box(&self) -> librqbit::storage::BoxStorageFactory {
self.boxed()
}
}

impl TorrentStorage for CustomStorage {
fn pread_exact(&self, _file_id: usize, _offset: u64, _buf: &mut [u8]) -> anyhow::Result<()> {
anyhow::bail!("not implemented")
}

fn pwrite_all(&self, _file_id: usize, _offset: u64, _buf: &[u8]) -> anyhow::Result<()> {
anyhow::bail!("not implemented")
}

fn remove_file(&self, _file_id: usize, _filename: &std::path::Path) -> anyhow::Result<()> {
anyhow::bail!("not implemented")
}

fn ensure_file_length(&self, _file_id: usize, _length: u64) -> anyhow::Result<()> {
anyhow::bail!("not implemented")
}

fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>> {
anyhow::bail!("not implemented")
}
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Output logs to console.
Expand All @@ -31,7 +75,7 @@ async fn main() -> anyhow::Result<()> {
include_bytes!("../resources/ubuntu-21.04-live-server-amd64.iso.torrent").into(),
),
Some(librqbit::AddTorrentOptions {
storage_factory: Some(MmapStorageFactory::default().boxed()),
storage_factory: Some(CustomStorageFactory::default().boxed()),
paused: false,
..Default::default()
}),
Expand Down
4 changes: 4 additions & 0 deletions crates/librqbit/src/storage/middleware/slow.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
A storage middleware that slows down the underlying storage.
*/

use std::time::Duration;

use rand_distr::Distribution;
Expand Down
4 changes: 4 additions & 0 deletions crates/librqbit/src/storage/middleware/timing.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
A storage middleware that logs the time underlying storage operations took.
*/

use crate::storage::{StorageFactory, StorageFactoryExt, TorrentStorage};

#[derive(Clone)]
Expand Down
7 changes: 7 additions & 0 deletions crates/librqbit/src/storage/middleware/write_through_cache.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/*
A storage middleware that caches pieces in memory, so that subsequent reads (for checksumming) are
free.
An example, untested and unproven to be useful.
*/

use std::num::NonZeroUsize;

use anyhow::Context;
Expand Down
14 changes: 13 additions & 1 deletion crates/librqbit/src/storage/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
pub mod examples;
pub mod filesystem;

#[cfg(feature = "storage_examples")]
pub mod examples;

#[cfg(feature = "storage_middleware")]
pub mod middleware;

use std::{
Expand Down Expand Up @@ -65,14 +69,22 @@ impl<U: StorageFactory + ?Sized> StorageFactory for Box<U> {
}

pub trait TorrentStorage: Send + Sync {
/// Given a file_id (which you can get more info from in init_storage() through torrent info)
/// read buf.len() bytes into buf at offset.
fn pread_exact(&self, file_id: usize, offset: u64, buf: &mut [u8]) -> anyhow::Result<()>;

/// Given a file_id (which you can get more info from in init_storage() through torrent info)
/// write buf.len() bytes into the file at offset.
fn pwrite_all(&self, file_id: usize, offset: u64, buf: &[u8]) -> anyhow::Result<()>;

/// Remove a file from the storage. If not supported, or it doesn't matter, just return Ok(())
fn remove_file(&self, file_id: usize, filename: &Path) -> anyhow::Result<()>;

/// E.g. for filesystem backend ensure that the file has a certain length, and grow/shrink as needed.
fn ensure_file_length(&self, file_id: usize, length: u64) -> anyhow::Result<()>;

/// Replace the current storage with a dummy, and return a new one that should be used instead.
/// This is used to make the underlying object useless when e.g. pausing the torrent.
fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>>;
}

Expand Down
7 changes: 1 addition & 6 deletions crates/librqbit/src/tests/e2e_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ use anyhow::Context;
use tokio::{io::AsyncReadExt, time::timeout};
use tracing::info;

use crate::{
create_torrent,
storage::{examples::inmemory::InMemoryExampleStorageFactory, StorageFactoryExt},
AddTorrent, CreateTorrentOptions, Session,
};
use crate::{create_torrent, AddTorrent, CreateTorrentOptions, Session};

use super::test_util::create_default_random_dir_with_torrents;

Expand Down Expand Up @@ -86,7 +82,6 @@ async fn e2e_stream() -> anyhow::Result<()> {
AddTorrent::from_bytes(torrent.as_bytes()?),
Some(crate::AddTorrentOptions {
paused: false,
storage_factory: Some(InMemoryExampleStorageFactory::default().boxed()),
initial_peers: Some(vec![peer]),
..Default::default()
}),
Expand Down

0 comments on commit 0b1499a

Please sign in to comment.