mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-12 12:47:25 +08:00
peer_center is used to collect peer info into one peer node. the center node is selected with the following rules: 1. has smallest peer id 2. TODO: has allow_to_be_center peer feature peer center is not guaranteed to be stable and can be changed when peer enter or leave. it's used to reduce the cost to exchange infos between peers.
96 lines
2.4 KiB
Rust
96 lines
2.4 KiB
Rust
use std::sync::atomic::{AtomicU32, AtomicU64, Ordering::Relaxed};
|
|
|
|
pub struct WindowLatency {
|
|
latency_us_window: Vec<AtomicU32>,
|
|
latency_us_window_index: AtomicU32,
|
|
latency_us_window_size: u32,
|
|
|
|
sum: AtomicU32,
|
|
count: AtomicU32,
|
|
}
|
|
|
|
impl WindowLatency {
|
|
pub fn new(window_size: u32) -> Self {
|
|
Self {
|
|
latency_us_window: (0..window_size).map(|_| AtomicU32::new(0)).collect(),
|
|
latency_us_window_index: AtomicU32::new(0),
|
|
latency_us_window_size: window_size,
|
|
|
|
sum: AtomicU32::new(0),
|
|
count: AtomicU32::new(0),
|
|
}
|
|
}
|
|
|
|
pub fn record_latency(&self, latency_us: u32) {
|
|
let index = self.latency_us_window_index.fetch_add(1, Relaxed);
|
|
if self.count.load(Relaxed) < self.latency_us_window_size {
|
|
self.count.fetch_add(1, Relaxed);
|
|
}
|
|
|
|
let index = index % self.latency_us_window_size;
|
|
let old_lat = self.latency_us_window[index as usize].swap(latency_us, Relaxed);
|
|
|
|
if old_lat < latency_us {
|
|
self.sum.fetch_add(latency_us - old_lat, Relaxed);
|
|
} else {
|
|
self.sum.fetch_sub(old_lat - latency_us, Relaxed);
|
|
}
|
|
}
|
|
|
|
pub fn get_latency_us<T: From<u32> + std::ops::Div<Output = T>>(&self) -> T {
|
|
let count = self.count.load(Relaxed);
|
|
let sum = self.sum.load(Relaxed);
|
|
if count == 0 {
|
|
0.into()
|
|
} else {
|
|
(T::from(sum)) / T::from(count)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct Throughput {
|
|
tx_bytes: AtomicU64,
|
|
rx_bytes: AtomicU64,
|
|
|
|
tx_packets: AtomicU64,
|
|
rx_packets: AtomicU64,
|
|
}
|
|
|
|
impl Throughput {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
tx_bytes: AtomicU64::new(0),
|
|
rx_bytes: AtomicU64::new(0),
|
|
|
|
tx_packets: AtomicU64::new(0),
|
|
rx_packets: AtomicU64::new(0),
|
|
}
|
|
}
|
|
|
|
pub fn tx_bytes(&self) -> u64 {
|
|
self.tx_bytes.load(Relaxed)
|
|
}
|
|
|
|
pub fn rx_bytes(&self) -> u64 {
|
|
self.rx_bytes.load(Relaxed)
|
|
}
|
|
|
|
pub fn tx_packets(&self) -> u64 {
|
|
self.tx_packets.load(Relaxed)
|
|
}
|
|
|
|
pub fn rx_packets(&self) -> u64 {
|
|
self.rx_packets.load(Relaxed)
|
|
}
|
|
|
|
pub fn record_tx_bytes(&self, bytes: u64) {
|
|
self.tx_bytes.fetch_add(bytes, Relaxed);
|
|
self.tx_packets.fetch_add(1, Relaxed);
|
|
}
|
|
|
|
pub fn record_rx_bytes(&self, bytes: u64) {
|
|
self.rx_bytes.fetch_add(bytes, Relaxed);
|
|
self.rx_packets.fetch_add(1, Relaxed);
|
|
}
|
|
}
|