Skip to content

Commit

Permalink
Make nameattr an optional feature
Browse files Browse the repository at this point in the history
This makes `indexmap` an optional dependency.
  • Loading branch information
jasonrhansen authored Sep 11, 2019
1 parent af3c68b commit ce4ca10
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 34 deletions.
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ cirrus-ci = { repository = "jonhoo/inferno" }
codecov = { repository = "jonhoo/inferno", branch = "master", service = "github" }

[features]
default = ["cli", "multithreaded"]
default = ["cli", "multithreaded", "nameattr"]
cli = ["structopt", "env_logger"]
multithreaded = ["chashmap", "crossbeam", "num_cpus"]
nameattr = ["indexmap"]

[dependencies]
chashmap = { version = "2.2", optional = true }
crossbeam = { version = "0.7", optional = true }
env_logger = { version = "0.6.0", optional = true }
fnv = "1.0.3"
indexmap = "1.0"
indexmap = { version = "1.0", optional = true }
itoa = "0.4.3"
lazy_static = "1.3.0"
log = "0.4"
Expand Down
33 changes: 24 additions & 9 deletions src/bin/flamegraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use std::path::{Path, PathBuf};

use env_logger::Env;
use inferno::flamegraph::color::{BackgroundColor, PaletteMap, SearchColor};
use inferno::flamegraph::{self, defaults, Direction, FuncFrameAttrsMap, Options, Palette};
use inferno::flamegraph::{self, defaults, Direction, Options, Palette};

#[cfg(feature = "nameattr")]
use inferno::flamegraph::FuncFrameAttrsMap;

use structopt::StructOpt;

#[derive(Debug, StructOpt)]
Expand Down Expand Up @@ -133,6 +137,7 @@ struct Opt {
/// File containing attributes to use for the SVG frames of particular functions.
/// Each line in the file should be a function name followed by a tab,
/// then a sequence of tab separated name=value pairs
#[cfg(feature = "nameattr")]
#[structopt(long = "nameattr", value_name = "PATH")]
nameattr: Option<PathBuf>,

Expand Down Expand Up @@ -187,14 +192,9 @@ impl<'a> Opt {
options.colors = self.colors;
options.bgcolors = self.bgcolors;
options.hash = self.hash;
if let Some(file) = self.nameattr {
match FuncFrameAttrsMap::from_file(&file) {
Ok(m) => {
options.func_frameattrs = m;
}
Err(e) => panic!("Error reading {}: {:?}", file.display(), e),
}
};

self.set_func_frameattrs(&mut options);

if self.inverted {
options.direction = Direction::Inverted;
if self.title == defaults::TITLE {
Expand Down Expand Up @@ -226,6 +226,21 @@ impl<'a> Opt {
options.search_color = self.search_color;
(self.infiles, options)
}

#[cfg(feature = "nameattr")]
fn set_func_frameattrs(&self, options: &mut Options) {
if let Some(file) = &self.nameattr {
match FuncFrameAttrsMap::from_file(&file) {
Ok(m) => {
options.func_frameattrs = m;
}
Err(e) => panic!("Error reading {}: {:?}", file.display(), e),
}
};
}

#[cfg(not(feature = "nameattr"))]
fn set_func_frameattrs(&self, _: &mut Options) {}
}

const PALETTE_MAP_FILE: &str = "palette.map"; // default name for the palette map file
Expand Down
93 changes: 70 additions & 23 deletions src/flamegraph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ macro_rules! args {
}};
}

#[cfg(feature = "nameattr")]
mod attrs;

pub mod color;
mod merge;
mod rand;
Expand All @@ -23,8 +25,12 @@ use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
use quick_xml::Writer;
use str_stack::StrStack;

#[cfg(feature = "nameattr")]
use self::attrs::FrameAttrs;

#[cfg(feature = "nameattr")]
pub use self::attrs::FuncFrameAttrsMap;

pub use self::color::Palette;
use self::color::{Color, SearchColor};
use self::svg::{Dimension, StyleOptions};
Expand Down Expand Up @@ -115,6 +121,7 @@ pub struct Options<'a> {
///
/// In particular, if a function appears in the given map, it will have extra attributes set in
/// the resulting SVG based on its value in the map.
#[cfg(feature = "nameattr")]
pub func_frameattrs: FuncFrameAttrsMap,

/// Whether to plot a plot that grows top-to-bottom or bottom-up (the default).
Expand Down Expand Up @@ -254,13 +261,15 @@ impl<'a> Default for Options<'a> {
bgcolors: Default::default(),
hash: Default::default(),
palette_map: Default::default(),
func_frameattrs: Default::default(),
direction: Default::default(),
negate_differentials: Default::default(),
pretty_xml: Default::default(),
no_sort: Default::default(),
reverse_stack_order: Default::default(),
no_javascript: Default::default(),

#[cfg(feature = "nameattr")]
func_frameattrs: Default::default(),
}
}
}
Expand Down Expand Up @@ -521,28 +530,14 @@ where
}
};

let frame_attributes = opt
.func_frameattrs
.frameattrs_for_func(frame.location.function);

let mut has_href = false;
let mut title = &buffer[info];
if let Some(frame_attributes) = frame_attributes {
if frame_attributes.attrs.contains_key("xlink:href") {
write_container_attributes(&mut cache_a, &frame_attributes);
svg.write_event(&cache_a)?;
has_href = true;
} else {
write_container_attributes(&mut cache_g, &frame_attributes);
svg.write_event(&cache_g)?;
}
if let Some(ref t) = frame_attributes.title {
title = t.as_str();
}
} else if let Event::Start(ref mut c) = cache_g {
c.clear_attributes();
svg.write_event(&cache_g)?;
}
let (has_href, title) = write_container_start(
opt,
&mut svg,
&mut cache_a,
&mut cache_g,
&frame,
&buffer[info],
)?;

svg.write_event(Event::Start(BytesStart::borrowed_name(b"title")))?;
svg.write_event(Event::Text(BytesText::from_plain_str(title)))?;
Expand Down Expand Up @@ -627,7 +622,59 @@ where
Ok(())
}

#[cfg(feature = "nameattr")]
fn write_container_start<'a, W: Write>(
opt: &'a Options<'a>,
svg: &mut Writer<W>,
cache_a: &mut Event<'_>,
cache_g: &mut Event<'_>,
frame: &merge::TimedFrame<'_>,
mut title: &'a str,
) -> quick_xml::Result<(bool, &'a str)> {
let frame_attributes = opt
.func_frameattrs
.frameattrs_for_func(frame.location.function);

let mut has_href = false;
if let Some(frame_attributes) = frame_attributes {
if frame_attributes.attrs.contains_key("xlink:href") {
write_container_attributes(cache_a, &frame_attributes);
svg.write_event(&cache_a)?;
has_href = true;
} else {
write_container_attributes(cache_g, &frame_attributes);
svg.write_event(&cache_g)?;
}
if let Some(ref t) = frame_attributes.title {
title = t.as_str();
}
} else if let Event::Start(ref mut c) = cache_g {
c.clear_attributes();
svg.write_event(&cache_g)?;
}

Ok((has_href, title))
}

#[cfg(not(feature = "nameattr"))]
fn write_container_start<'a, W: Write>(
_opt: &Options<'_>,
svg: &mut Writer<W>,
_cache_a: &mut Event<'_>,
cache_g: &mut Event<'_>,
_frame: &merge::TimedFrame<'_>,
title: &'a str,
) -> quick_xml::Result<(bool, &'a str)> {
if let Event::Start(ref mut c) = cache_g {
c.clear_attributes();
svg.write_event(&cache_g)?;
}

Ok((false, title))
}

/// Writes atributes to the container, container could be g or a
#[cfg(feature = "nameattr")]
fn write_container_attributes(event: &mut Event<'_>, frame_attributes: &FrameAttrs) {
if let Event::Start(ref mut c) = event {
c.clear_attributes();
Expand Down
6 changes: 6 additions & 0 deletions tests/flamegraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ fn flamegraph_factor() {
}

#[test]
#[cfg(feature = "nameattr")]
fn flamegraph_nameattr() {
let input_file = "./flamegraph/test/results/perf-cycles-instructions-01-collapsed-all.txt";
let expected_result_file = "./tests/data/flamegraph/nameattr/nameattr.svg";
Expand All @@ -201,6 +202,7 @@ fn flamegraph_nameattr() {
}

#[test]
#[cfg(feature = "nameattr")]
fn flamegraph_nameattr_empty_line() {
let input_file = "./flamegraph/test/results/perf-cycles-instructions-01-collapsed-all.txt";
let expected_result_file = "./tests/data/flamegraph/nameattr/nameattr.svg";
Expand All @@ -217,6 +219,7 @@ fn flamegraph_nameattr_empty_line() {
}

#[test]
#[cfg(feature = "nameattr")]
fn flamegraph_nameattr_empty_attribute() {
let input_file = "./flamegraph/test/results/perf-cycles-instructions-01-collapsed-all.txt";
let expected_result_file = "./tests/data/flamegraph/nameattr/nameattr.svg";
Expand All @@ -233,6 +236,7 @@ fn flamegraph_nameattr_empty_attribute() {
}

#[test]
#[cfg(feature = "nameattr")]
fn flamegraph_nameattr_duplicate_attributes() {
let input_file = "./flamegraph/test/results/perf-cycles-instructions-01-collapsed-all.txt";
let expected_result_file = "./tests/data/flamegraph/nameattr/nameattr_duplicate_attributes.svg";
Expand All @@ -249,6 +253,7 @@ fn flamegraph_nameattr_duplicate_attributes() {
}

#[test]
#[cfg(feature = "nameattr")]
fn flamegraph_nameattr_should_warn_about_duplicate_attributes() {
test_logger::init();
let nameattr_file = "./tests/data/flamegraph/nameattr/nameattr_duplicate_attributes.txt";
Expand All @@ -267,6 +272,7 @@ fn flamegraph_nameattr_should_warn_about_duplicate_attributes() {
}

#[test]
#[cfg(feature = "nameattr")]
fn flamegraph_nameattr_should_warn_about_invalid_attribute() {
test_logger::init();
let nameattr_file = "./tests/data/flamegraph/nameattr/nameattr_invalid_attribute.txt";
Expand Down

0 comments on commit ce4ca10

Please sign in to comment.