From c118736c9c78ebea2adfa04b3777c004d07ff402 Mon Sep 17 00:00:00 2001 From: Christian Schwarz Date: Sat, 14 Sep 2024 12:48:23 +0000 Subject: [PATCH] draw-timeline-dir: ability to draw line --- pageserver/ctl/src/draw_timeline_dir.rs | 58 +++++++++++++++++++------ 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/pageserver/ctl/src/draw_timeline_dir.rs b/pageserver/ctl/src/draw_timeline_dir.rs index bc939f9688..f103be93b8 100644 --- a/pageserver/ctl/src/draw_timeline_dir.rs +++ b/pageserver/ctl/src/draw_timeline_dir.rs @@ -108,6 +108,7 @@ fn parse_filename(name: &str) -> (Range, Range) { enum LineKind { GcCutoff, Branch, + KeyVertical, } impl From for Fill { @@ -115,6 +116,7 @@ impl From for Fill { match value { LineKind::GcCutoff => Fill::Color(rgb(255, 0, 0)), LineKind::Branch => Fill::Color(rgb(0, 255, 0)), + LineKind::KeyVertical => Fill::Color(rgb(0, 0, 255)), } } } @@ -126,6 +128,7 @@ impl FromStr for LineKind { Ok(match s { "gc_cutoff" => LineKind::GcCutoff, "branch" => LineKind::Branch, + "key" => LineKind::KeyVertical, _ => anyhow::bail!("unsupported linekind: {s}"), }) } @@ -142,25 +145,31 @@ pub fn main() -> Result<()> { let stdin = io::stdin(); let mut lines: Vec<(Lsn, LineKind)> = vec![]; + let mut vertical_lines: Vec<(Key, LineKind)> = vec![]; for (lineno, line) in stdin.lock().lines().enumerate() { let lineno = lineno + 1; let line = line.unwrap(); - if let Some((kind, lsn)) = line.split_once(':') { - let (kind, lsn) = LineKind::from_str(kind) - .context("parse kind") - .and_then(|kind| { - if lsn.contains('/') { - Lsn::from_str(lsn) - } else { - Lsn::from_hex(lsn) + if let Some((kind, what)) = line.split_once(':') { + (|| { + match LineKind::from_str(kind).context("parse kind")? { + kind @ LineKind::Branch | kind @ LineKind::GcCutoff => { + let lsn = if what.contains('/') { + Lsn::from_str(what)? + } else { + Lsn::from_hex(what)? + }; + lines.push((lsn, kind)); } - .map(|lsn| (kind, lsn)) - .context("parse lsn") - }) - .with_context(|| format!("parse {line:?} on {lineno}"))?; - lines.push((lsn, kind)); + kind @ LineKind::KeyVertical => { + let key = Key::from_hex(what).context("parse key")?; + vertical_lines.push((key, kind)); + } + } + anyhow::Ok(()) + })() + .with_context(|| format!("parse {line:?} on {lineno}"))?; continue; } let line = PathBuf::from_str(&line).unwrap(); @@ -175,7 +184,7 @@ pub fn main() -> Result<()> { } // Collect all coordinates - let mut keys: Vec = Vec::with_capacity(files.len()); + let mut keys: Vec = Vec::with_capacity(files.len() + vertical_lines.len()); let mut lsns: Vec = Vec::with_capacity(files.len() + lines.len()); for Layer { @@ -192,6 +201,8 @@ pub fn main() -> Result<()> { lsns.extend(lines.iter().map(|(lsn, _)| *lsn)); + keys.extend(vertical_lines.iter().map(|(key, _)| *key)); + // Analyze let key_map = build_coordinate_compression_map(keys); let lsn_map = build_coordinate_compression_map(lsns); @@ -283,6 +294,25 @@ pub fn main() -> Result<()> { ); } + for (key, kind) in vertical_lines { + let key = *key_map.get(&key).unwrap(); + let stretch = 2.0; + let xmargin = 0.05; + let ymargin = 0.05; + let lsn_diff = 0.3; + let lsn_offset = -lsn_diff / 2.0; + println!( + "{}", + rectangle( + 5.0 + key as f32, + 0.0, + (key_map.len() + 10) as f32, + lsn_map.len() as f32, + ) + .fill(kind) + ); + } + println!("{}", EndSvg); eprintln!("num_images: {}", num_images);