use hashbrown::HashMap;
use std::collections::VecDeque;
#[derive(Clone, Debug)]
pub struct EventData {
pub data: HashMap<String, VecDeque<u64>>,
pub max_data_size: usize,
}
fn vec_deque_truncate_extend_with_zeros(vd: &mut VecDeque<u64>, len: usize) {
vd.truncate(len);
vd.reserve(len);
while vd.len() < len {
vd.push_front(0);
}
}
impl EventData {
pub fn new(max_data_size: usize) -> EventData {
Self {
data: HashMap::new(),
max_data_size,
}
}
pub fn initialize_events(&mut self, events: &[&str]) {
for event in events {
self.event_data(event);
}
}
pub fn event_data_mut(&mut self, event: &str) -> &mut VecDeque<u64> {
self.data
.raw_entry_mut()
.from_key(event)
.or_insert_with(|| {
(event.to_string(), {
let mut vd = VecDeque::new();
vec_deque_truncate_extend_with_zeros(&mut vd, self.max_data_size);
vd
})
})
.1
}
pub fn event_data(&mut self, event: &str) -> &VecDeque<u64> {
self.event_data_mut(event)
}
pub fn zero_event(&mut self, event: &str) {
for val in self.event_data_mut(event) {
*val = 0;
}
}
pub fn set_max_size(&mut self, max_data_size: usize) {
self.max_data_size = max_data_size;
for event_data in self.data.values_mut() {
vec_deque_truncate_extend_with_zeros(event_data, self.max_data_size);
}
}
pub fn clear_event(&mut self, event: &str) {
self.data.remove(event);
}
pub fn clear(&mut self) {
self.data.clear();
}
pub fn event_data_immut(&self, event: &str) -> Vec<u64> {
if let Some(vs) = self.data.get(event) {
vs.iter().copied().collect()
} else {
Vec::new()
}
}
pub fn add_event_data(&mut self, event: &str, val: u64) {
let size = self.max_data_size;
let data = self.event_data_mut(event);
if data.len() == size {
data.pop_front();
}
data.push_back(val);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let event_data = EventData::new(10);
assert_eq!(event_data.max_data_size, 10);
assert!(event_data.data.is_empty());
}
#[test]
fn test_initialize_events() {
let mut event_data = EventData::new(5);
let events = vec!["event1", "event2", "event3"];
event_data.initialize_events(&events);
assert_eq!(event_data.data.len(), 3);
for event in &events {
assert!(event_data.data.contains_key(*event));
let data = event_data.data.get(*event).unwrap();
assert_eq!(data.len(), 5);
for &val in data {
assert_eq!(val, 0);
}
}
}
#[test]
fn test_event_data_mut_creates_new_entry() {
let mut event_data = EventData::new(3);
let data = event_data.event_data_mut("new_event");
assert_eq!(data.len(), 3);
for &val in data.iter() {
assert_eq!(val, 0);
}
assert!(event_data.data.contains_key("new_event"));
}
#[test]
fn test_event_data_mut_returns_existing_entry() {
let mut event_data = EventData::new(3);
let data1 = event_data.event_data_mut("existing_event");
data1[0] = 42;
let data2 = event_data.event_data_mut("existing_event");
assert_eq!(data2[0], 42);
}
#[test]
fn test_event_data() {
let mut event_data = EventData::new(3);
let data = event_data.event_data("test_event");
assert_eq!(data.len(), 3);
for &val in data {
assert_eq!(val, 0);
}
}
#[test]
fn test_zero_event() {
let mut event_data = EventData::new(3);
event_data.add_event_data("test_event", 10);
event_data.add_event_data("test_event", 20);
event_data.add_event_data("test_event", 30);
let data = event_data.event_data("test_event");
assert!(data.iter().any(|&x| x != 0));
event_data.zero_event("test_event");
let data = event_data.event_data("test_event");
for &val in data {
assert_eq!(val, 0);
}
}
#[test]
fn test_set_max_size_increase() {
let mut event_data = EventData::new(3);
event_data.add_event_data("test_event", 10);
event_data.add_event_data("test_event", 20);
event_data.add_event_data("test_event", 30);
event_data.set_max_size(5);
assert_eq!(event_data.max_data_size, 5);
let data = event_data.event_data("test_event");
assert_eq!(data.len(), 5);
let vec_data: Vec<u64> = data.iter().copied().collect();
assert_eq!(vec_data[vec_data.len() - 3..], [10, 20, 30]);
}
#[test]
fn test_set_max_size_decrease() {
let mut event_data = EventData::new(5);
for i in 1..=5 {
event_data.add_event_data("test_event", i * 10);
}
event_data.set_max_size(3);
assert_eq!(event_data.max_data_size, 3);
let data = event_data.event_data("test_event");
assert_eq!(data.len(), 3);
}
#[test]
fn test_clear_event() {
let mut event_data = EventData::new(3);
event_data.add_event_data("event1", 10);
event_data.add_event_data("event2", 20);
assert!(event_data.data.contains_key("event1"));
assert!(event_data.data.contains_key("event2"));
event_data.clear_event("event1");
assert!(!event_data.data.contains_key("event1"));
assert!(event_data.data.contains_key("event2"));
}
#[test]
fn test_clear() {
let mut event_data = EventData::new(3);
event_data.add_event_data("event1", 10);
event_data.add_event_data("event2", 20);
assert_eq!(event_data.data.len(), 2);
event_data.clear();
assert!(event_data.data.is_empty());
}
#[test]
fn test_event_data_immut_existing_event() {
let mut event_data = EventData::new(3);
event_data.add_event_data("test_event", 10);
event_data.add_event_data("test_event", 20);
event_data.add_event_data("test_event", 30);
let data = event_data.event_data_immut("test_event");
assert_eq!(data.len(), 3);
assert_eq!(data[data.len() - 3..], [10, 20, 30]);
}
#[test]
fn test_event_data_immut_nonexistent_event() {
let event_data = EventData::new(5);
let data = event_data.event_data_immut("nonexistent");
assert_eq!(data, Vec::<u64>::new());
}
#[test]
fn test_add_event_data_basic() {
let mut event_data = EventData::new(3);
event_data.add_event_data("test_event", 10);
let data = event_data.event_data("test_event");
assert_eq!(data.back(), Some(&10));
event_data.add_event_data("test_event", 20);
let data = event_data.event_data("test_event");
assert_eq!(data.back(), Some(&20));
}
#[test]
fn test_add_event_data_overflow() {
let mut event_data = EventData::new(3);
for i in 1..=3 {
event_data.add_event_data("test_event", i * 10);
}
let data = event_data.event_data("test_event");
assert_eq!(data.len(), 3);
event_data.add_event_data("test_event", 40);
let data = event_data.event_data("test_event");
assert_eq!(data.len(), 3);
let vec_data: Vec<u64> = data.iter().copied().collect();
assert_eq!(vec_data[vec_data.len() - 3..], [20, 30, 40]);
}
#[test]
fn test_add_event_data_multiple_events() {
let mut event_data = EventData::new(2);
event_data.add_event_data("event1", 10);
event_data.add_event_data("event2", 20);
event_data.add_event_data("event1", 30);
let data1 = event_data.event_data_immut("event1");
let data2 = event_data.event_data_immut("event2");
assert_eq!(data1[data1.len() - 2..], [10, 30]);
assert_eq!(data2[data2.len() - 1..], [20]);
}
#[test]
fn test_complex_workflow() {
let mut event_data = EventData::new(4);
event_data.initialize_events(&["cpu_usage", "memory_usage", "disk_io"]);
for i in 1..=5 {
event_data.add_event_data("cpu_usage", i * 10);
event_data.add_event_data("memory_usage", i * 20);
}
let cpu_data = event_data.event_data_immut("cpu_usage");
assert_eq!(cpu_data.len(), 4);
assert_eq!(cpu_data[cpu_data.len() - 4..], [20, 30, 40, 50]);
let mem_data = event_data.event_data_immut("memory_usage");
assert_eq!(mem_data.len(), 4);
assert_eq!(mem_data[mem_data.len() - 4..], [40, 60, 80, 100]);
let disk_data = event_data.event_data_immut("disk_io");
assert_eq!(disk_data.len(), 4);
assert_eq!(disk_data, vec![0, 0, 0, 0]);
event_data.clear_event("memory_usage");
let cleared_data = event_data.event_data_immut("memory_usage");
assert_eq!(cleared_data, Vec::<u64>::new()); }
}