use std::fmt;
use std::sync::atomic::AtomicU64;
use std::sync::atomic::Ordering;
use crate::time::current_millis;
#[derive(Debug)]
pub struct AccAndTimeStamp {
cold_acc: AtomicU64,
last_cold_read_time_millis: AtomicU64,
create_time_millis: u64,
}
impl AccAndTimeStamp {
pub fn new(cold_acc: u64) -> Self {
let current_time = current_millis();
Self {
cold_acc: AtomicU64::new(cold_acc),
last_cold_read_time_millis: AtomicU64::new(current_time),
create_time_millis: current_time,
}
}
pub fn default_new() -> Self {
Self::new(0)
}
#[inline]
pub fn get_cold_acc(&self) -> u64 {
self.cold_acc.load(Ordering::Relaxed)
}
#[inline]
pub fn set_cold_acc(&self, value: u64) {
self.cold_acc.store(value, Ordering::Relaxed);
}
#[inline]
pub fn add_cold_acc(&self, delta: u64) -> u64 {
self.cold_acc.fetch_add(delta, Ordering::Relaxed)
}
#[inline]
pub fn cold_acc_atomic(&self) -> &AtomicU64 {
&self.cold_acc
}
#[inline]
pub fn get_last_cold_read_time_millis(&self) -> u64 {
self.last_cold_read_time_millis.load(Ordering::Relaxed)
}
#[inline]
pub fn set_last_cold_read_time_millis(&self, time_millis: u64) {
self.last_cold_read_time_millis.store(time_millis, Ordering::Relaxed);
}
#[inline]
pub fn update_last_cold_read_time(&self) {
self.set_last_cold_read_time_millis(current_millis());
}
#[inline]
pub fn get_create_time_millis(&self) -> u64 {
self.create_time_millis
}
}
impl Default for AccAndTimeStamp {
fn default() -> Self {
Self::default_new()
}
}
impl fmt::Display for AccAndTimeStamp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"AccAndTimeStamp{{coldAcc={}, lastColdReadTimeMills={}, createTimeMills={}}}",
self.get_cold_acc(),
self.get_last_cold_read_time_millis(),
self.create_time_millis
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn acc_and_time_stamp_new_and_default() {
let acc_and_time_stamp = AccAndTimeStamp::new(100);
assert_eq!(acc_and_time_stamp.get_cold_acc(), 100);
assert!(acc_and_time_stamp.get_last_cold_read_time_millis() > 0);
assert!(acc_and_time_stamp.get_create_time_millis() > 0);
let acc_and_time_stamp = AccAndTimeStamp::default_new();
assert_eq!(acc_and_time_stamp.get_cold_acc(), 0);
let acc_and_time_stamp = AccAndTimeStamp::default();
assert_eq!(acc_and_time_stamp.get_cold_acc(), 0);
}
#[test]
fn acc_and_time_stamp_cold_acc_methods() {
let acc_and_time_stamp = AccAndTimeStamp::default();
acc_and_time_stamp.set_cold_acc(100);
assert_eq!(acc_and_time_stamp.get_cold_acc(), 100);
let previous = acc_and_time_stamp.add_cold_acc(50);
assert_eq!(previous, 100);
assert_eq!(acc_and_time_stamp.get_cold_acc(), 150);
let atomic = acc_and_time_stamp.cold_acc_atomic();
atomic.store(200, Ordering::Relaxed);
assert_eq!(acc_and_time_stamp.get_cold_acc(), 200);
}
#[test]
fn acc_and_time_stamp_last_cold_read_time_methods() {
let acc_and_time_stamp = AccAndTimeStamp::default();
acc_and_time_stamp.set_last_cold_read_time_millis(123456789);
assert_eq!(acc_and_time_stamp.get_last_cold_read_time_millis(), 123456789);
let acc_and_time_stamp = AccAndTimeStamp::default();
let old_time = acc_and_time_stamp.get_last_cold_read_time_millis();
acc_and_time_stamp.update_last_cold_read_time();
let new_time = acc_and_time_stamp.get_last_cold_read_time_millis();
assert!(new_time >= old_time);
}
#[test]
fn acc_and_time_stamp_format() {
let acc_and_time_stamp = AccAndTimeStamp::new(100);
acc_and_time_stamp.set_last_cold_read_time_millis(200);
let display = format!("{}", acc_and_time_stamp);
assert!(display.contains("AccAndTimeStamp{"));
assert!(display.contains("coldAcc=100"));
assert!(display.contains("lastColdReadTimeMills=200"));
assert!(display.contains("createTimeMills="));
let debug = format!("{:?}", acc_and_time_stamp);
assert!(debug.contains("AccAndTimeStamp"));
assert!(debug.contains("cold_acc"));
assert!(debug.contains("last_cold_read_time_millis"));
assert!(debug.contains("create_time_millis"));
}
}