Skip to content

Commit

Permalink
Implement block level flamegraph
Browse files Browse the repository at this point in the history
  • Loading branch information
eyeplum committed May 18, 2021
1 parent 254b4ce commit 8c5b5c1
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 9 deletions.
8 changes: 7 additions & 1 deletion src/cli/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::char;

use clap::ArgMatches;

use super::{Error, Result, FLAG_NAME_CODE_POINT_INPUT_MODE};
use super::{Error, Result, FLAG_NAME_CODE_POINT_INPUT_MODE, FLAG_NAME_GENERATE_FLAMEGRAPH};
use crate::ucd::string_to_code_point;

pub const OPTION_NAME_INPUT_TYPE: &str = "input_type";
Expand All @@ -38,6 +38,7 @@ fn characters_from_input_string(input_string: &str) -> Vec<char> {
pub enum Input {
String(String),
Characters(Vec<char>),
GenerateFlamegraph,
}

impl ToString for Input {
Expand All @@ -52,11 +53,16 @@ impl ToString for Input {
}
string
}
Input::GenerateFlamegraph => String::new(), // This variant is not representable as a string
}
}
}

pub fn parse_input(args: &ArgMatches) -> Result<Input> {
if args.is_present(FLAG_NAME_GENERATE_FLAMEGRAPH) {
return Ok(Input::GenerateFlamegraph);
}

let input_string = args.value_of(ARGUMENT_VALUE_NAME_INPUT).unwrap_or(""); // No input is provided, fallback to an empty string

match args.value_of(OPTION_NAME_INPUT_TYPE) {
Expand Down
72 changes: 72 additions & 0 deletions src/cli/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use clap::ArgMatches;

use super::{parse_input, Error, Result};
use crate::cli::input::Input;
use crate::ucd::GraphemeProperties;

pub const OPTION_NAME_OUTPUT_FORMAT: &str = "output_format";
Expand All @@ -31,6 +32,11 @@ fn graphems_to_string(graphemes: &[GraphemeProperties]) -> String {

pub fn generate_output(args: ArgMatches) -> Result<String> {
let input = parse_input(&args)?;

if let Input::GenerateFlamegraph = input {
return chrome_tracing::describe_unicode_as_events();
}

let graphemes = GraphemeProperties::from_string(&input.to_string());
match args.value_of(OPTION_NAME_OUTPUT_FORMAT) {
Some(output_format) => match output_format {
Expand All @@ -43,3 +49,69 @@ pub fn generate_output(args: ArgMatches) -> Result<String> {
None => Ok(graphems_to_string(&graphemes)),
}
}

// TODO: Should this module be a separate file?
mod chrome_tracing {
use serde::Serialize;
use unic::ucd::{Block, BlockIter};

use super::Result;
use crate::ucd::{Plane, PLANE_COUNT};

#[derive(Serialize)]
struct Event {
name: &'static str,
cat: &'static str,
ph: char,
ts: u32,
pid: u64,
tid: u64,
}

pub fn describe_unicode_as_events() -> Result<String> {
let blocks: Vec<Block> = BlockIter::new().collect();

let mut events = Vec::with_capacity(blocks.len() + PLANE_COUNT as usize);

for i in 0..PLANE_COUNT {
let plane = Plane::at(i as usize);
events.push(Event {
name: plane.name,
cat: "Plane",
ph: 'B',
ts: plane.range.start,
pid: 0,
tid: 0,
});
events.push(Event {
name: plane.name,
cat: "Plane",
ph: 'E',
ts: plane.range.end,
pid: 0,
tid: 0,
});
}

for block in blocks {
events.push(Event {
name: block.name,
cat: "Block",
ph: 'B',
ts: block.range.low as u32,
pid: 0,
tid: 0,
});
events.push(Event {
name: block.name,
cat: "Block",
ph: 'E',
ts: block.range.high as u32,
pid: 0,
tid: 0,
});
}

Ok(serde_json::to_string_pretty(&events)?)
}
}
6 changes: 3 additions & 3 deletions src/ucd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ mod character_properties;
mod plane;

pub use character_properties::{CharacterProperties, GraphemeProperties};
pub use plane::Plane;
pub use plane::{Plane, PLANE_COUNT};

#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
pub struct Range {
start: u32,
end: u32,
pub start: u32,
pub end: u32,
}

pub fn code_point_to_string(chr: char) -> String {
Expand Down
15 changes: 10 additions & 5 deletions src/ucd/plane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

use super::Range;

const PLANE_COUNT: u32 = 17;
pub const PLANE_COUNT: u32 = 17;

const PLANE_SIZE: u32 = 0x1_0000;
const PLANE_NAMES: &[&str] = &[
"Basic Multilingual Plane",
Expand Down Expand Up @@ -51,13 +52,17 @@ impl Plane {
assert_eq!(PLANE_NAMES.len(), PLANE_COUNT as usize);

let plane_index = chr as u32 / PLANE_SIZE;
assert!(plane_index < PLANE_COUNT);
Self::at(plane_index as usize)
}

pub fn at(index: usize) -> Plane {
assert!(index < PLANE_COUNT as usize);

Plane {
name: PLANE_NAMES[plane_index as usize],
name: PLANE_NAMES[index],
range: Range {
start: plane_index * PLANE_SIZE,
end: (plane_index + 1) * PLANE_SIZE - 1,
start: index as u32 * PLANE_SIZE,
end: (index as u32 + 1) * PLANE_SIZE - 1,
},
}
}
Expand Down

0 comments on commit 8c5b5c1

Please sign in to comment.