Added `From<impl DurationProvider> for SingleThrottleProvider`

Attempted, multiple times, to impl `UniformSample<T>` for `UniformDurationProvider<T, R>`... None have worked yet. Figure this out, so we can have `UniformThrottleProvider<UniformDurationProvider, R>`.

Fortune for throttle's current commit: Middle blessing − 中吉
master
Avril 2 years ago
parent 07c4817a53
commit 5867c5ce39
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -0,0 +1,37 @@
//! Extension
use std::ops::{
RangeBounds,
Bound
};
pub trait BoundExt<T>
{
fn map_impl<U, F>(self, f: F) -> Bound<U>
where F: FnOnce(T) -> U;
}
impl<T> BoundExt<T> for Bound<T>
{
#[inline(always)]
fn map_impl<U, F>(self, f: F) -> Bound<U>
where F: FnOnce(T) -> U {
//! Copied from stdlib
use Bound::*;
match self {
Unbounded => Unbounded,
Included(x) => Included(f(x)),
Excluded(x) => Excluded(f(x)),
}
}
}
#[inline(always)] pub fn erase<T>(_: T) -> () {}
/// Get the memory address this reference points to.
///
/// # Note
/// If `T` is a fat pointer, it is cast to a thin-pointer first.
#[inline(always)]
pub fn into_addr<T: ?Sized>(r: &T) -> usize
{
r as *const T as *const std::convert::Infallible as usize
}

@ -1,12 +1,27 @@
use std::io;
mod ext; use ext::*;
mod conf;
mod prov;
mod stream;
fn main() -> io::Result<()> {
let mut input = io::stdin().lock();
let mut output = stream::ThrottleAdaptor::new(prov::UniformThrottleProvider::from(prov::Duration::from_millis(5)..prov::Duration::from_millis(50)), prov::UniformBufferProvider::from(0usize..=10), io::stdout().lock());
let mut output = stream::ThrottleAdaptor
/*::new(prov::UniformThrottleProvider::from(
prov::UniformDurationProvider::from(
prov::Duration::from_millis(5)
..prov::Duration::from_millis(50)
)
..prov::UniformDurationProvider::from(
prov::Duration::from_millis(10)
..prov::Duration::from_millis(100)
))*/ //TODO: Figure out how to fucking implement that god-damn uniform sampler for `UniformDurationProvider`. Ugh...
::new( prov::SingleThrottleProvider::from(prov::UniformDurationProvider::from(prov::Duration::from_millis(5)..prov::Duration::from_millis(10)))
, prov::UniformBufferProvider::from(0usize..=20)
, io::stdout().lock());
let copied = io::copy(&mut input, &mut output)?;
if cfg!(debug_assertions) {
eprintln!("Copied {copied} bytes from input -{output:?}> output");

@ -286,6 +286,116 @@ where T: BufferProvider + rand::distributions::uniform::SampleUniform,
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
pub struct UniformDurationProvider<T: ?Sized, R: std::ops::RangeBounds<T>>(R, std::marker::PhantomData<T>);
#[cfg(feature="none")]
const _:() = {
use rand::distributions::uniform::{
self,
UniformSampler,
SampleUniform,
SampleRange,
Uniform,
};
use std::{
ops::{
RangeBounds,
Bound,
},
};
#[derive(Debug)]
struct UniformDurationProviderSampler<T:?Sized, R: std::ops::RangeBounds<T>>(UniformDurationProvider<T, R>);
impl<T: ?Sized, R: RangeBounds<T>> UniformSampler for UniformDurationProviderSampler<T, R>
where R: SampleRange<T>,
T: SampleUniform,
{
type X = UniformDurationProvider<T, R>;
fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
where
B1: uniform::SampleBorrow<Self::X> + Sized,
B2: uniform::SampleBorrow<Self::X> + Sized {
Self(<Self::X as UniformSampler>::X::new_inclusive(low, high))
}
fn sample<Rng: rand::Rng + ?Sized>(&self, rng: &mut Rng) -> Self::X {
//use rand::prelude::*;
//UniformDurationProvider(self.0.sample(rng))
todo!()
}
fn new<B1, B2>(low: B1, high: B2) -> Self
where
B1: uniform::SampleBorrow<Self::X> + Sized,
B2: uniform::SampleBorrow<Self::X> + Sized {
<Self::X as UniformSampler>::new(low, high)
}
}
};
#[cfg(feature="FUCK THIS")]
const _:() = {
use rand::distributions::uniform::{
self,
UniformSampler,
SampleUniform,
SampleRange,
Uniform,
};
use std::{
ops::{
RangeBounds,
Bound,
},
marker::PhantomData
};
use crate::ext::*;
#[derive(Debug, Clone, Copy)]
struct UDPSampler<R>(uniform::UniformDuration, PhantomData<R>);
impl<D> UniformSampler for UDPSampler<D>
where D: RangeBounds<Duration>
{
type X = UniformDurationProvider<Duration, D>;
fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
where
B1: uniform::SampleBorrow<Self::X> + Sized,
B2: uniform::SampleBorrow<Self::X> + Sized
{
Self(uniform::UniformDuration::new_inclusive(low.borrow().0.start_bound(), high.borrow().0.end_bound()), PhantomData)
}
fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
todo!()
}
fn new<B1, B2>(low: B1, high: B2) -> Self
where
B1: uniform::SampleBorrow<Self::X> + Sized,
B2: uniform::SampleBorrow<Self::X> + Sized
{
Self(uniform::UniformDuration::new(low, high), PhantomData)
}
}
impl<R> SampleUniform for UniformDurationProvider<Duration, R>
where R: RangeBounds<Duration> + SampleRange<Duration>
{
type Sampler = UDPSampler<R>;
}
};
impl<T, R> rand::distributions::uniform::SampleRange<T> for UniformDurationProvider<T, R>
where R: std::ops::RangeBounds<T> + rand::distributions::uniform::SampleRange<T>,
T: rand::distributions::uniform::SampleUniform
{
#[inline(always)]
fn sample_single<Rng: rand::RngCore + ?Sized>(self, rng: &mut Rng) -> T {
self.0.sample_single(rng)
}
#[inline]
fn is_empty(&self) -> bool {
use super::ext::*;
self.0.start_bound().map_impl(into_addr) == self.0.end_bound().map_impl(into_addr)
}
}
impl<T: ?Sized, R> From<R> for UniformDurationProvider<T, R>
where T: DurationProvider,
R: std::ops::RangeBounds<T>
@ -316,7 +426,18 @@ pub struct UniformThrottleProvider<T: ?Sized, R: std::ops::RangeBounds<T>>(R, st
/// Provides a single `DurationProvider` on each call to `get_timeout()`.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct SingleThrottleProvider<D>(D);
pub struct SingleThrottleProvider<D: ?Sized>(D);
impl<D: DurationProvider> From<D> for SingleThrottleProvider<D>
{
#[inline(always)]
fn from(from: D) -> Self
{
Self(from)
}
}
/// Always provides no timeout duration.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@ -352,16 +473,21 @@ impl<D: Clone + DurationProvider> ThrottleProvider for SingleThrottleProvider<D>
}
}
impl From<Duration> for SingleThrottleProvider<Duration>
/*impl From<Duration> for SingleThrottleProvider<Duration>
{
#[inline(always)]
fn from(from: Duration) -> Self
{
Self(from)
}
}
}*/
//TODO: Split this into multiple: From<Range/Inclusive>: same.
// And From<x..>,From<..{,=}x>: x..BUFFER_MAX_LEN, 0..{,=}x
// (seperate impls needed for type signature. which is annoying...)
//
// XXX: Alternatively, we could add `new_from_range<R2>(range: R2)` methods for UniformThrottleProvider<_, R> where R determines which we use. This is probably the better way of doing it.
impl<T: ?Sized, R> From<R> for UniformThrottleProvider<T, R>
where T: DurationProvider,
R: std::ops::RangeBounds<T>

Loading…
Cancel
Save