Move around storage into folders

This commit is contained in:
Igor Katson 2024-05-02 18:58:54 +01:00
parent 6233cc9d12
commit 2c500049e8
10 changed files with 18 additions and 14 deletions

View file

@ -0,0 +1,2 @@
pub mod slow;
pub mod timing;

View file

@ -0,0 +1,84 @@
use std::time::Duration;
use rand_distr::Distribution;
use crate::storage::{StorageFactory, TorrentStorage};
pub struct SlowStorageFactory<U> {
underlying_factory: U,
}
impl<U: StorageFactory> SlowStorageFactory<U> {
pub fn new(underlying: U) -> Self {
Self {
underlying_factory: underlying,
}
}
}
impl<U: StorageFactory> StorageFactory for SlowStorageFactory<U> {
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)?,
})
}
fn is_type_id(&self, type_id: std::any::TypeId) -> bool {
self.underlying_factory.is_type_id(type_id)
}
}
pub struct SlowStorage<U> {
underlying: U,
}
fn random_duration() -> Duration {
use rand_distr::StandardNormal;
let s = StandardNormal {};
let sl: f64 = s.sample(&mut rand::thread_rng());
// let sl = Duration::from_secs_f64(sl);
// tracing::trace!(duration = ?sl, "sleeping");
// std::thread::sleep(sl)
//
let micros = 340f64 + sl * 200.;
// 16 is max blocking threads
let micros = micros.max(0.001) * 4. * 16.;
#[allow(clippy::cast_possible_truncation)]
Duration::from_micros(micros as u64)
}
fn random_sleep() {
let sl = random_duration();
tracing::trace!(duration = ?sl, "sleeping");
std::thread::sleep(sl)
}
impl<U: TorrentStorage> TorrentStorage for SlowStorage<U> {
fn pread_exact(&self, file_id: usize, offset: u64, buf: &mut [u8]) -> anyhow::Result<()> {
random_sleep();
self.underlying.pread_exact(file_id, offset, buf)
}
fn pwrite_all(&self, file_id: usize, offset: u64, buf: &[u8]) -> anyhow::Result<()> {
random_sleep();
self.underlying.pwrite_all(file_id, offset, buf)
}
fn remove_file(&self, file_id: usize, filename: &std::path::Path) -> anyhow::Result<()> {
self.underlying.remove_file(file_id, filename)
}
fn ensure_file_length(&self, file_id: usize, length: u64) -> anyhow::Result<()> {
self.underlying.ensure_file_length(file_id, length)
}
fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>> {
Ok(Box::new(SlowStorage {
underlying: self.underlying.take()?,
}))
}
}

View file

@ -0,0 +1,90 @@
use crate::storage::{StorageFactory, TorrentStorage};
pub struct TimingStorageFactory<U> {
name: String,
underlying_factory: U,
}
impl<U> TimingStorageFactory<U> {
pub fn new(name: String, underlying: U) -> Self {
Self {
name,
underlying_factory: underlying,
}
}
}
impl<U: StorageFactory> StorageFactory for TimingStorageFactory<U> {
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)?,
})
}
fn is_type_id(&self, type_id: std::any::TypeId) -> bool {
self.underlying_factory.is_type_id(type_id)
}
}
pub struct TimingStorage<U> {
name: String,
underlying: U,
}
macro_rules! timeit {
($name:expr, $op:expr, $($rest:tt),*) => {
{
let start = std::time::Instant::now();
let r = $op;
let elapsed = start.elapsed();
tracing::debug!(name = $name, $($rest),*, elapsed_micros=elapsed.as_micros(), "timeit");
r
}
};
}
impl<U: TorrentStorage> TorrentStorage for TimingStorage<U> {
fn pread_exact(&self, file_id: usize, offset: u64, buf: &mut [u8]) -> anyhow::Result<()> {
let storage = &self.name;
let len = buf.len();
timeit!(
"pread_exact",
self.underlying.pread_exact(file_id, offset, buf),
file_id,
offset,
storage,
len
)
}
fn pwrite_all(&self, file_id: usize, offset: u64, buf: &[u8]) -> anyhow::Result<()> {
let storage = &self.name;
let len = buf.len();
timeit!(
"pwrite_all",
self.underlying.pwrite_all(file_id, offset, buf),
file_id,
offset,
storage,
len
)
}
fn remove_file(&self, file_id: usize, filename: &std::path::Path) -> anyhow::Result<()> {
self.underlying.remove_file(file_id, filename)
}
fn ensure_file_length(&self, file_id: usize, length: u64) -> anyhow::Result<()> {
self.underlying.ensure_file_length(file_id, length)
}
fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>> {
Ok(Box::new(TimingStorage {
underlying: self.underlying.take()?,
name: self.name.clone(),
}))
}
}