1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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(())
}