pub mod layout;
pub mod trace;
use self::trace::{Packet, Parser};
use anyhow::{bail, Result};
use std::{collections::BTreeMap, fs::File};
pub type TraceMap = BTreeMap<u32, TraceEntry>;
#[derive(Default)]
pub struct TraceEntry {
pub cur: u32,
pub max: u32,
pub total: u32,
}
pub fn read_trace(trace: &mut TraceMap, trace_file: File, max_size: u32) -> Result<()> {
let parser = Parser::new(trace_file)?;
for packet in parser {
let packet = packet?;
match packet {
Packet::Alloc { size } => {
alloc(trace, size, max_size)?;
}
Packet::Dealloc { size } => {
dealloc(trace, size)?;
}
Packet::Grow { old_size, new_size } | Packet::Shrink { old_size, new_size } => {
dealloc(trace, old_size)?;
alloc(trace, new_size, max_size)?;
}
}
}
Ok(())
}
fn alloc(trace: &mut TraceMap, size: u32, max_size: u32) -> Result<()> {
if size > max_size {
bail!("Trace file is corrupted");
}
let entry = trace.entry(size).or_default();
entry.cur += 1;
entry.total += 1;
if entry.max < entry.cur {
entry.max = entry.cur;
}
Ok(())
}
fn dealloc(trace: &mut TraceMap, size: u32) -> Result<()> {
let entry = trace.entry(size).or_default();
if entry.cur == 0 {
bail!("Trace file is corrupted");
}
entry.cur -= 1;
Ok(())
}