refactored to hashmaps
This commit is contained in:
parent
fbdcdaefbb
commit
579bccb35c
|
@ -4,7 +4,7 @@ use hash::H96;
|
||||||
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
|
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
|
||||||
use Error;
|
use Error;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, Hash, Eq)]
|
||||||
pub struct Command(H96);
|
pub struct Command(H96);
|
||||||
|
|
||||||
impl str::FromStr for Command {
|
impl str::FromStr for Command {
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
use message::Command;
|
||||||
|
use std::collections::hash_map::Entry;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct MessageStats {
|
pub struct MessageStats {
|
||||||
pub addr: u64,
|
pub addr: u64,
|
||||||
|
@ -13,61 +17,72 @@ pub struct MessageStats {
|
||||||
pub version: u64,
|
pub version: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub struct RunningAverage {
|
||||||
|
count: u64,
|
||||||
|
bytes: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RunningAverage {
|
||||||
|
fn new(initial: usize) -> Self {
|
||||||
|
RunningAverage { count: 1, bytes: initial as u64 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&mut self, bytes: usize) {
|
||||||
|
self.count += 1;
|
||||||
|
// self.count guaranteed to be at least 1, since self.count min value is 0 and we just added 1 above
|
||||||
|
// so division by zero is impossible; qed
|
||||||
|
//
|
||||||
|
// let x = self.bytes, x >= 0
|
||||||
|
// let y = bytes, y >= 0
|
||||||
|
// to not overflow, this following be true:
|
||||||
|
// x + (y - x) / c >= 0
|
||||||
|
// so
|
||||||
|
// y / c >= 0
|
||||||
|
// which is true by u64 definition;
|
||||||
|
// qed
|
||||||
|
self.bytes += (bytes as u64 - self.bytes) / self.count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct PeerStats {
|
pub struct PeerStats {
|
||||||
pub last_send: u32,
|
pub last_send: u32,
|
||||||
pub last_recv: u32,
|
pub last_recv: u32,
|
||||||
|
|
||||||
pub total_send: u64,
|
pub total_send: u64,
|
||||||
pub total_recv: u64,
|
pub total_recv: u64,
|
||||||
|
|
||||||
pub avg_ping: f64,
|
pub avg_ping: f64,
|
||||||
pub min_ping: f64,
|
pub min_ping: f64,
|
||||||
|
pub total_ping: u64,
|
||||||
|
|
||||||
pub synced_blocks: u32,
|
pub synced_blocks: u32,
|
||||||
pub synced_headers: u32,
|
pub synced_headers: u32,
|
||||||
pub counter_send: MessageStats,
|
pub send_avg: HashMap<Command, RunningAverage>,
|
||||||
pub counter_recv: MessageStats,
|
pub recv_avg: HashMap<Command, RunningAverage>,
|
||||||
pub bytes_send: MessageStats,
|
|
||||||
pub bytes_recv: MessageStats,
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_send {
|
|
||||||
($msg: ident, $method_name: ident) => {
|
|
||||||
pub fn $method_name(&mut self, bytes: usize) {
|
|
||||||
self.last_send = ::time::get_time().sec as u32;
|
|
||||||
self.total_send += bytes as u64;
|
|
||||||
self.bytes_send.$msg += bytes as u64;
|
|
||||||
self.counter_send.$msg += bytes as u64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_recv {
|
|
||||||
($msg: ident, $method_name: ident) => {
|
|
||||||
pub fn $method_name(&mut self, bytes: usize) {
|
|
||||||
self.last_recv = ::time::get_time().sec as u32;
|
|
||||||
self.total_recv += bytes as u64;
|
|
||||||
self.bytes_recv.$msg += bytes as u64;
|
|
||||||
self.counter_recv.$msg += bytes as u64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_both {
|
|
||||||
($msg: ident, $method_send: ident, $method_recv: ident) => {
|
|
||||||
impl_send!($msg, $method_send);
|
|
||||||
impl_recv!($msg, $method_recv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PeerStats {
|
impl PeerStats {
|
||||||
impl_both!(addr, send_addr, recv_addr);
|
pub fn report_send(&mut self, command: Command, bytes: usize) {
|
||||||
impl_both!(getdata, send_getdata, recv_getdata);
|
match self.send_avg.entry(command) {
|
||||||
impl_both!(getheaders, send_getheaders, recv_getheaders);
|
Entry::Occupied(mut avg) => {
|
||||||
impl_both!(headers, send_headers, recv_headers);
|
avg.get_mut().add(bytes);
|
||||||
impl_both!(reject, send_reject, recv_reject);
|
},
|
||||||
impl_both!(tx, send_tx, recv_tx);
|
Entry::Vacant(entry) => {
|
||||||
impl_both!(inv, send_inv, recv_inv);
|
entry.insert(RunningAverage::new(bytes));
|
||||||
impl_both!(ping, send_ping, recv_ping);
|
},
|
||||||
impl_both!(pong, send_pong, recv_pong);
|
}
|
||||||
impl_both!(verack, send_verack, recv_verack);
|
}
|
||||||
impl_both!(version, send_version, recv_version);
|
|
||||||
|
pub fn report_recv(&mut self, command: Command, bytes: usize) {
|
||||||
|
match self.recv_avg.entry(command) {
|
||||||
|
Entry::Occupied(mut avg) => {
|
||||||
|
avg.get_mut().add(bytes);
|
||||||
|
},
|
||||||
|
Entry::Vacant(entry) => {
|
||||||
|
entry.insert(RunningAverage::new(bytes));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue