All storage factories are generic now

This commit is contained in:
Igor Katson 2024-05-01 22:14:34 +01:00
parent e4adfa569a
commit 5027d8ccd1
12 changed files with 88 additions and 52 deletions

View file

@ -19,21 +19,21 @@ impl InMemoryPiece {
}
}
#[derive(Default)]
pub struct InMemoryExampleStorageFactory {}
impl StorageFactory for InMemoryExampleStorageFactory {
type Storage = InMemoryExampleStorage;
fn init_storage(
&self,
info: &crate::torrent_state::ManagedTorrentInfo,
) -> anyhow::Result<Box<dyn TorrentStorage>> {
Ok(Box::new(InMemoryExampleStorage::new(
info.lengths,
info.file_infos.clone(),
)?))
) -> anyhow::Result<InMemoryExampleStorage> {
InMemoryExampleStorage::new(info.lengths, info.file_infos.clone())
}
}
struct InMemoryExampleStorage {
pub struct InMemoryExampleStorage {
lengths: Lengths,
file_infos: FileInfos,
map: RwLock<HashMap<ValidPieceIndex, InMemoryPiece>>,

View file

@ -18,7 +18,9 @@ use super::{StorageFactory, TorrentStorage};
pub struct FilesystemStorageFactory {}
impl StorageFactory for FilesystemStorageFactory {
fn init_storage(&self, meta: &ManagedTorrentInfo) -> anyhow::Result<Box<dyn TorrentStorage>> {
type Storage = FilesystemStorage;
fn init_storage(&self, meta: &ManagedTorrentInfo) -> anyhow::Result<FilesystemStorage> {
let mut files = Vec::<OpenedFile>::new();
let output_folder = &meta.options.output_folder;
for file_details in meta.info.iter_file_details(&meta.lengths)? {
@ -54,10 +56,10 @@ impl StorageFactory for FilesystemStorageFactory {
};
files.push(OpenedFile::new(file));
}
Ok(Box::new(FilesystemStorage {
Ok(FilesystemStorage {
output_folder: output_folder.clone(),
opened_files: files,
}))
})
}
}

View file

@ -6,26 +6,26 @@ use crate::{FileInfos, ManagedTorrentInfo};
use super::{StorageFactory, TorrentStorage};
#[derive(Default)]
pub struct MmapStorageFactory {}
struct MmapStorage {
pub struct MmapStorage {
mmap: RwLock<MmapMut>,
file_infos: FileInfos,
}
impl StorageFactory for MmapStorageFactory {
fn init_storage(
&self,
info: &ManagedTorrentInfo,
) -> anyhow::Result<Box<dyn crate::storage::TorrentStorage>> {
Ok(Box::new(MmapStorage {
type Storage = MmapStorage;
fn init_storage(&self, info: &ManagedTorrentInfo) -> anyhow::Result<Self::Storage> {
Ok(MmapStorage {
mmap: RwLock::new(
MmapOptions::new()
.len(info.lengths.total_length().try_into()?)
.map_anon()?,
),
file_infos: info.file_infos.clone(),
}))
})
}
}

View file

@ -9,11 +9,40 @@ use std::{any::Any, path::Path};
use crate::torrent_state::ManagedTorrentInfo;
pub trait StorageFactory: Send + Sync + Any {
fn init_storage(&self, info: &ManagedTorrentInfo) -> anyhow::Result<Box<dyn TorrentStorage>>;
type Storage: TorrentStorage;
fn init_storage(&self, info: &ManagedTorrentInfo) -> anyhow::Result<Self::Storage>;
}
pub type BoxStorageFactory = Box<dyn StorageFactory<Storage = Box<dyn TorrentStorage>>>;
pub trait StorageFactoryExt {
fn boxed(self) -> BoxStorageFactory;
}
impl<SF: StorageFactory> StorageFactoryExt for SF {
fn boxed(self) -> BoxStorageFactory {
struct BoxFactory<SF> {
sf: SF,
}
impl<SF: StorageFactory> StorageFactory for BoxFactory<SF> {
type Storage = Box<dyn TorrentStorage>;
fn init_storage(&self, info: &ManagedTorrentInfo) -> anyhow::Result<Self::Storage> {
let s = self.sf.init_storage(info)?;
Ok(Box::new(s))
}
}
Box::new(BoxFactory { sf: self })
}
}
impl<U: StorageFactory + ?Sized> StorageFactory for Box<U> {
fn init_storage(&self, info: &ManagedTorrentInfo) -> anyhow::Result<Box<dyn TorrentStorage>> {
type Storage = U::Storage;
fn init_storage(&self, info: &ManagedTorrentInfo) -> anyhow::Result<U::Storage> {
(**self).init_storage(info)
}
}

View file

@ -17,17 +17,16 @@ impl<U: StorageFactory> SlowStorageFactory<U> {
}
impl<U: StorageFactory> StorageFactory for SlowStorageFactory<U> {
fn init_storage(
&self,
info: &crate::ManagedTorrentInfo,
) -> anyhow::Result<Box<dyn TorrentStorage>> {
Ok(Box::new(SlowStorage {
type Storage = SlowStorage<U::Storage>;
fn init_storage(&self, info: &crate::ManagedTorrentInfo) -> anyhow::Result<Self::Storage> {
Ok(SlowStorage {
underlying: self.underlying_factory.init_storage(info)?,
}))
})
}
}
struct SlowStorage<U> {
pub struct SlowStorage<U> {
underlying: U,
}

View file

@ -15,18 +15,17 @@ impl<U> TimingStorageFactory<U> {
}
impl<U: StorageFactory> StorageFactory for TimingStorageFactory<U> {
fn init_storage(
&self,
info: &crate::ManagedTorrentInfo,
) -> anyhow::Result<Box<dyn TorrentStorage>> {
Ok(Box::new(TimingStorage {
type Storage = TimingStorage<U::Storage>;
fn init_storage(&self, info: &crate::ManagedTorrentInfo) -> anyhow::Result<Self::Storage> {
Ok(TimingStorage {
name: self.name.clone(),
underlying: self.underlying_factory.init_storage(info)?,
}))
})
}
}
struct TimingStorage<U> {
pub struct TimingStorage<U> {
name: String,
underlying: U,
}