use super::RecordThroughput;
use crate::{
clear::Clear,
hdr_histogram::HdrHistogram,
time_source::{Instant, StdInstant},
};
use serde::{Serialize, Serializer};
pub struct TxPerSec<T: Instant = StdInstant> {
pub hdr_histogram: HdrHistogram,
last: Option<T>,
count: u64,
time_source: std::marker::PhantomData<T>,
}
impl<T: Instant> Default for TxPerSec<T> {
fn default() -> Self {
TxPerSec {
hdr_histogram: HdrHistogram::with_bound(100_000),
last: None,
count: 0,
time_source: std::marker::PhantomData,
}
}
}
impl<T: Instant> RecordThroughput for std::cell::RefCell<TxPerSec<T>> {
#[inline]
fn on_result(&self) {
self.borrow_mut().on_result()
}
}
impl<T: Instant> Clear for std::cell::RefCell<TxPerSec<T>> {
fn clear(&self) {
self.borrow_mut().clear();
}
}
impl<T: Instant> TxPerSec<T> {
pub(crate) fn on_result(&mut self) {
if let Some(ref last) = self.last {
let elapsed = last.elapsed_time();
if elapsed > T::ONE_SEC {
self.hdr_histogram.record(self.count);
self.count = 0;
self.last = Some(T::now());
}
} else {
self.last = Some(T::now());
};
self.count += 1;
}
pub(crate) fn clear(&mut self) {
self.hdr_histogram.clear();
self.last = None;
self.count = 0;
}
}
impl<T: Instant> Serialize for TxPerSec<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
Serialize::serialize(&self.hdr_histogram, serializer)
}
}
use std::{fmt, fmt::Debug};
impl<T: Instant> Debug for TxPerSec<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", &self.hdr_histogram)
}
}