memtrack-utils 0.1.0

A library with utils for parsing heap tracing files
Documentation
use std::fs::File;
use std::io::{BufWriter, Write};

pub struct Output {
    buffer: BufWriter<File>,
}

pub enum Frame {
    Single {
        function_idx: usize,
    },
    Multiple {
        function_idx: usize,
        file_idx: usize,
        line_number: u32,
    },
}

impl Output {
    pub fn new(out: File) -> Self {
        Self {
            buffer: BufWriter::with_capacity(4096, out),
        }
    }

    pub fn write_version(&mut self, version: u16, file_version: u16) -> std::io::Result<()> {
        writeln!(self.buffer, "v {:x} {:x}", version, file_version)
    }

    pub fn write_page_info(&mut self, page_size: usize, pages: u64) -> std::io::Result<()> {
        writeln!(self.buffer, "I {:x} {:x}", page_size, pages)
    }

    pub fn write_exec(&mut self, command: &str) -> std::io::Result<()> {
        writeln!(self.buffer, "X {}", command)
    }

    pub fn write_string(&mut self, value: &str) -> std::io::Result<()> {
        let size = value.len();
        writeln!(self.buffer, "s {:x} {}", size, value)
    }

    pub fn write_instruction(
        &mut self,
        ip: u64,
        module_idx: usize,
        frames: &[Frame],
    ) -> std::io::Result<()> {
        write!(self.buffer, "i {:x} {:x}", ip, module_idx)?;
        for frame in frames {
            match frame {
                Frame::Single { function_idx } => write!(self.buffer, " {:x}", function_idx)?,
                Frame::Multiple {
                    function_idx,
                    file_idx,
                    line_number,
                } => write!(
                    self.buffer,
                    " {:x} {:x} {:x}",
                    function_idx, file_idx, line_number
                )?,
            }
        }

        writeln!(self.buffer)
    }

    pub fn write_trace(&mut self, ip_id: usize, parent_idx: u64) -> std::io::Result<()> {
        writeln!(self.buffer, "t {:x} {:x}", ip_id, parent_idx)
    }

    pub fn write_trace_alloc(&mut self, size: u64, idx: usize) -> std::io::Result<()> {
        writeln!(self.buffer, "a {:x} {:x}", size, idx)
    }

    pub fn write_alloc(&mut self, idx: usize) -> std::io::Result<()> {
        writeln!(self.buffer, "+ {:x}", idx)
    }

    pub fn write_free(&mut self, idx: usize) -> std::io::Result<()> {
        writeln!(self.buffer, "- {:x}", idx)
    }

    pub fn write_duration(&mut self, duration: u128) -> std::io::Result<()> {
        writeln!(self.buffer, "c {:x}", duration)
    }

    pub fn write_rss(&mut self, rss: usize) -> std::io::Result<()> {
        writeln!(self.buffer, "R {:x}", rss)
    }

    pub fn write(&mut self, value: &str) -> std::io::Result<()> {
        writeln!(self.buffer, "{}", value)
    }

    pub fn write_comment(&mut self, comment: &str) -> std::io::Result<()> {
        writeln!(self.buffer, "# {}", comment)
    }

    pub fn flush(&mut self) -> std::io::Result<()> {
        self.buffer.flush()
    }
}