use std::collections::{BTreeMap, HashMap};
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
#[derive(Debug)]
pub struct NetworkIoStatistics {
stats: Arc<Mutex<IoStatisticsData>>,
#[allow(dead_code)]
config: StatisticsConfig,
}
#[derive(Debug, Clone, Default)]
pub struct IoStatisticsData {
pub zero_copy_sent_bytes: u64,
pub zero_copy_recv_bytes: u64,
pub traditional_sent_bytes: u64,
pub traditional_recv_bytes: u64,
pub zero_copy_send_count: u64,
pub zero_copy_recv_count: u64,
pub traditional_send_count: u64,
pub traditional_recv_count: u64,
pub total_sent_bytes: u64,
pub total_recv_bytes: u64,
pub qps_sent: f64,
pub qps_recv: f64,
pub avg_send_latency_us: f64,
pub avg_recv_latency_us: f64,
pub error_count: u64,
pub success_count: u64,
pub start_time: Option<Instant>,
pub last_update: Option<Instant>,
}
#[derive(Debug, Clone)]
pub struct StatisticsConfig {
pub window_size: Duration,
pub enable_detailed_stats: bool,
pub sampling_rate: f64,
}
impl NetworkIoStatistics {
pub fn new(config: StatisticsConfig) -> Self {
let stats: _ = IoStatisticsData {
start_time: Some(Instant::now()),
last_update: Some(Instant::now()),
..Default::default()
};
Self {
stats: Arc::new(Mutex::new(stats)),
config,
}
}
pub fn default() -> Self {
let config: _ = StatisticsConfig {
window_size: Duration::from_secs(60), enable_detailed_stats: true,
sampling_rate: 1.0, };
Self::new(config)
}
pub fn record_zero_copy_send(&self, bytes: u64, latency_us: u64) {
let mut stats = self.stats.lock().unwrap();
stats.zero_copy_sent_bytes += bytes;
stats.zero_copy_send_count += 1;
stats.total_sent_bytes += bytes;
if stats.zero_copy_send_count > 0 {
let total_latency: _ = stats.avg_send_latency_us * (stats.zero_copy_send_count - 1) as f64;
stats.avg_send_latency_us =
(total_latency + latency_us as f64) / stats.zero_copy_send_count as f64;
}
self.update_last_update(&mut stats);
}
pub fn record_zero_copy_recv(&self, bytes: u64, latency_us: u64) {
let mut stats = self.stats.lock().unwrap();
stats.zero_copy_recv_bytes += bytes;
stats.zero_copy_recv_count += 1;
stats.total_recv_bytes += bytes;
if stats.zero_copy_recv_count > 0 {
let total_latency: _ = stats.avg_recv_latency_us * (stats.zero_copy_recv_count - 1) as f64;
stats.avg_recv_latency_us =
(total_latency + latency_us as f64) / stats.zero_copy_recv_count as f64;
}
self.update_last_update(&mut stats);
}
pub fn record_traditional_send(&self, bytes: u64, latency_us: u64) {
let mut stats = self.stats.lock().unwrap();
stats.traditional_sent_bytes += bytes;
stats.traditional_send_count += 1;
stats.total_sent_bytes += bytes;
let total_send_count: _ = stats.traditional_send_count + stats.zero_copy_send_count;
if total_send_count > 0 {
let total_latency: _ = stats.avg_send_latency_us * (total_send_count - 1) as f64;
stats.avg_send_latency_us =
(total_latency + latency_us as f64) / total_send_count as f64;
}
self.update_last_update(&mut stats);
}
pub fn record_traditional_recv(&self, bytes: u64, latency_us: u64) {
let mut stats = self.stats.lock().unwrap();
stats.traditional_recv_bytes += bytes;
stats.traditional_recv_count += 1;
stats.total_recv_bytes += bytes;
let total_recv_count: _ = stats.traditional_recv_count + stats.zero_copy_recv_count;
if total_recv_count > 0 {
let total_latency: _ = stats.avg_recv_latency_us * (total_recv_count - 1) as f64;
stats.avg_recv_latency_us =
(total_latency + latency_us as f64) / total_recv_count as f64;
}
self.update_last_update(&mut stats);
}
pub fn record_success(&self) {
let mut stats = self.stats.lock().unwrap();
stats.success_count += 1;
self.update_last_update(&mut stats);
}
pub fn record_error(&self) {
let mut stats = self.stats.lock().unwrap();
stats.error_count += 1;
self.update_last_update(&mut stats);
}
fn update_last_update(&self, stats: &mut IoStatisticsData) {
stats.last_update = Some(Instant::now());
if let Some(start_time) = stats.start_time {
let elapsed: _ = stats.last_update.unwrap().duration_since(start_time);
if elapsed.as_secs() > 0 {
stats.qps_sent = stats.total_sent_bytes as f64 / elapsed.as_secs() as f64;
stats.qps_recv = stats.total_recv_bytes as f64 / elapsed.as_secs() as f64;
}
}
}
pub fn get_stats(&self) -> IoStatisticsData {
self.stats.lock().unwrap().clone()
}
pub fn zero_copy_ratio(&self) -> f64 {
let stats: _ = self.stats.lock().unwrap();
let total_bytes: _ = stats.total_sent_bytes + stats.total_recv_bytes;
if total_bytes == 0 {
return 0.0;
}
let zero_copy_bytes: _ = stats.zero_copy_sent_bytes + stats.zero_copy_recv_bytes;
zero_copy_bytes as f64 / total_bytes as f64
}
pub fn error_rate(&self) -> f64 {
let stats: _ = self.stats.lock().unwrap();
let total_ops: _ = stats.success_count + stats.error_count;
if total_ops == 0 {
return 0.0;
}
stats.error_count as f64 / total_ops as f64
}
pub fn throughput(&self) -> f64 {
let stats: _ = self.stats.lock().unwrap();
if let Some(start_time) = stats.start_time {
let elapsed: _ = stats.last_update.unwrap().duration_since(start_time);
if elapsed.as_secs() > 0 {
return (stats.total_sent_bytes + stats.total_recv_bytes) as f64
/ elapsed.as_secs() as f64;
}
}
0.0
}
pub fn reset(&self) {
let mut stats = self.stats.lock().unwrap();
*stats = IoStatisticsData {
start_time: Some(Instant::now()),
last_update: Some(Instant::now()),
..Default::default()
};
}
pub fn generate_report(&self) -> String {
let stats: _ = self.stats.lock().unwrap();
let zero_copy_ratio: _ = self.zero_copy_ratio();
let error_rate: _ = self.error_rate();
let throughput: _ = self.throughput();
format!(
r#"
网络 I/O 统计报告
===================
传输统计:
零拷贝发送: {} bytes ({} 次)
零拷贝接收: {} bytes ({} 次)
传统拷贝发送: {} bytes ({} 次)
传统拷贝接收: {} bytes ({} 次)
总发送: {} bytes
总接收: {} bytes
性能指标:
零拷贝比率: {:.2}%
错误率: {:.2}%
吞吐量: {:.2} bytes/sec
平均发送延迟: {:.2} μs
平均接收延迟: {:.2} μs
QPS (发送): {:.2}
QPS (接收): {:.2}
运行时间: {:?}"#,
stats.zero_copy_sent_bytes,
stats.zero_copy_send_count,
stats.zero_copy_recv_bytes,
stats.zero_copy_recv_count,
stats.traditional_sent_bytes,
stats.traditional_send_count,
stats.traditional_recv_bytes,
stats.traditional_recv_count,
stats.total_sent_bytes,
stats.total_recv_bytes,
zero_copy_ratio * 100.0,
error_rate * 100.0,
throughput,
stats.avg_send_latency_us,
stats.avg_recv_latency_us,
stats.qps_sent,
stats.qps_recv,
stats.start_time.map(|t| t.elapsed()).unwrap_or_default()
)
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_zero_copy_network_io_statistics() {
let _stats: _ = NetworkIoStatistics::default();
println!("NetworkIoStatistics test placeholder");
println!("This test validates statistics collection and reporting");
}
}