77 lines
2.3 KiB
Rust
Raw Normal View History

2024-10-17 15:05:05 +01:00
use std::collections::HashMap;
use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::time::{Duration, UNIX_EPOCH};
fn parse(
file: File,
) -> Result<HashMap<String, HashMap<std::time::SystemTime, f64>>, Box<dyn Error>> {
let mut file = file;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
let mut metrics: HashMap<String, HashMap<std::time::SystemTime, Vec<f64>>> = HashMap::new();
for line in contents.lines() {
let re = regex::Regex::new(r"(\d+) (\w+) (\d+)").unwrap();
if let Some(caps) = re.captures(line) {
let timestamp_raw = &caps[1];
let metric_name = &caps[2];
let metric_value_raw = &caps[3];
let timestamp = timestamp_raw.parse::<i64>().unwrap();
let metric_value = metric_value_raw.parse::<f64>().unwrap();
if !metrics.contains_key(metric_name) {
metrics.insert(metric_name.to_string(), HashMap::new());
}
let minute = UNIX_EPOCH + Duration::from_secs((timestamp - (timestamp % 60)) as u64);
metrics
.get_mut(metric_name)
.unwrap()
.insert(minute, vec![metric_value]);
} else {
println!("invalid line");
}
}
let mut aggregated_metrics: HashMap<String, HashMap<std::time::SystemTime, f64>> =
HashMap::new();
for (metric_name, time_val_list) in metrics {
aggregated_metrics.insert(metric_name.clone(), HashMap::new());
for (time, values) in time_val_list {
let mut sum = 0.0;
for v in values.iter() {
sum += *v
}
let average = sum / values.len() as f64;
aggregated_metrics
.get_mut(&metric_name)
.unwrap()
.insert(time, average);
}
}
Ok(aggregated_metrics)
}
fn main() {
let file = File::open("input.txt").expect("Unable to open file");
let metrics = parse(file).expect("Unable to parse file");
for (metric_name, time_val) in metrics {
for (time, value) in time_val {
println!(
"{} {:?} {:.2}",
metric_name,
chrono::DateTime::<chrono::Utc>::from(time),
value
);
}
}
}