#[derive(Debug, Default, Clone)]
pub struct LockStats {
pub lock_requests: u64,
pub lock_waits: u64,
pub n_owners: u64,
pub n_waiters: u64,
pub n_total_locks: u64,
pub n_read_locks: u64,
pub n_write_locks: u64,
pub n_lock_timeouts: u64,
}
impl LockStats {
pub fn new() -> Self {
Self::default()
}
pub fn reset(&mut self) {
*self = Self::default();
}
pub fn wait_percentage(&self) -> f64 {
if self.lock_requests == 0 {
0.0
} else {
(self.lock_waits as f64 / self.lock_requests as f64) * 100.0
}
}
pub fn add(&mut self, other: &LockStats) {
self.lock_requests += other.lock_requests;
self.lock_waits += other.lock_waits;
self.n_owners += other.n_owners;
self.n_waiters += other.n_waiters;
self.n_total_locks += other.n_total_locks;
self.n_read_locks += other.n_read_locks;
self.n_write_locks += other.n_write_locks;
self.n_lock_timeouts += other.n_lock_timeouts;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let stats = LockStats::new();
assert_eq!(stats.lock_requests, 0);
assert_eq!(stats.lock_waits, 0);
assert_eq!(stats.n_owners, 0);
assert_eq!(stats.n_waiters, 0);
assert_eq!(stats.n_total_locks, 0);
assert_eq!(stats.n_read_locks, 0);
assert_eq!(stats.n_write_locks, 0);
}
#[test]
fn test_reset() {
let mut stats = LockStats::new();
stats.lock_requests = 100;
stats.lock_waits = 10;
stats.n_owners = 5;
stats.reset();
assert_eq!(stats.lock_requests, 0);
assert_eq!(stats.lock_waits, 0);
assert_eq!(stats.n_owners, 0);
}
#[test]
fn test_wait_percentage() {
let mut stats = LockStats::new();
assert_eq!(stats.wait_percentage(), 0.0);
stats.lock_requests = 100;
stats.lock_waits = 10;
assert_eq!(stats.wait_percentage(), 10.0);
stats.lock_requests = 200;
stats.lock_waits = 50;
assert_eq!(stats.wait_percentage(), 25.0);
}
#[test]
fn test_add() {
let mut stats1 = LockStats::new();
stats1.lock_requests = 100;
stats1.lock_waits = 10;
stats1.n_owners = 5;
stats1.n_waiters = 2;
stats1.n_total_locks = 50;
stats1.n_read_locks = 30;
stats1.n_write_locks = 20;
stats1.n_lock_timeouts = 3;
let mut stats2 = LockStats::new();
stats2.lock_requests = 50;
stats2.lock_waits = 5;
stats2.n_owners = 3;
stats2.n_waiters = 1;
stats2.n_total_locks = 25;
stats2.n_read_locks = 15;
stats2.n_write_locks = 10;
stats2.n_lock_timeouts = 2;
stats1.add(&stats2);
assert_eq!(stats1.lock_requests, 150);
assert_eq!(stats1.lock_waits, 15);
assert_eq!(stats1.n_owners, 8);
assert_eq!(stats1.n_waiters, 3);
assert_eq!(stats1.n_total_locks, 75);
assert_eq!(stats1.n_read_locks, 45);
assert_eq!(stats1.n_write_locks, 30);
assert_eq!(stats1.n_lock_timeouts, 5);
}
#[test]
fn test_lock_timeout_counter() {
let mut stats = LockStats::new();
assert_eq!(stats.n_lock_timeouts, 0);
stats.n_lock_timeouts = 7;
assert_eq!(stats.n_lock_timeouts, 7);
stats.reset();
assert_eq!(stats.n_lock_timeouts, 0);
}
}