Skip to content
This repository was archived by the owner on Sep 9, 2025. It is now read-only.

Commit c28ca80

Browse files
author
Hendrik van Antwerpen
committed
Add stitcher stats
1 parent a2ce328 commit c28ca80

3 files changed

Lines changed: 191 additions & 34 deletions

File tree

‎stack-graphs/src/graph.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ impl Handle<File> {
425425
/// Each node (except for the _root node_ and _jump to scope_ node) lives in a file, and has a
426426
/// _local ID_ that must be unique within its file.
427427
#[repr(C)]
428-
#[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
428+
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
429429
pub struct NodeID {
430430
file: ControlledOption<Handle<File>>,
431431
local_id: u32,

‎stack-graphs/src/stitching.rs‎

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ use crate::partial::PartialPaths;
6666
use crate::partial::PartialSymbolStack;
6767
use crate::paths::Extend;
6868
use crate::paths::PathResolutionError;
69+
use crate::stats::FrequencyDistribution;
6970
use crate::CancellationError;
7071
use crate::CancellationFlag;
7172

@@ -839,6 +840,7 @@ pub struct ForwardPartialPathStitcher<H> {
839840
similar_path_detector: Option<SimilarPathDetector<PartialPath>>,
840841
check_only_join_nodes: bool,
841842
max_work_per_phase: usize,
843+
stats: Stats,
842844
#[cfg(feature = "copious-debugging")]
843845
phase_number: usize,
844846
}
@@ -876,6 +878,7 @@ impl<H> ForwardPartialPathStitcher<H> {
876878
check_only_join_nodes: false,
877879
// By default, there's no artificial bound on the amount of work done per phase
878880
max_work_per_phase: usize::MAX,
881+
stats: Stats::default(),
879882
#[cfg(feature = "copious-debugging")]
880883
phase_number: 1,
881884
}
@@ -909,6 +912,10 @@ impl<H> ForwardPartialPathStitcher<H> {
909912
pub fn set_max_work_per_phase(&mut self, max_work_per_phase: usize) {
910913
self.max_work_per_phase = max_work_per_phase;
911914
}
915+
916+
pub fn into_stats(self) -> Stats {
917+
self.stats
918+
}
912919
}
913920

914921
impl<H: Clone> ForwardPartialPathStitcher<H> {
@@ -1056,6 +1063,21 @@ impl<H: Clone> ForwardPartialPathStitcher<H> {
10561063
self.next_iteration.2.push(new_has_split);
10571064
}
10581065

1066+
let (graph, _, _) = candidates.get_graph_partials_and_db();
1067+
let end_node = &graph[partial_path.end_node];
1068+
if end_node.is_root() {
1069+
self.stats.candidates_per_root_path += candidate_count;
1070+
self.stats.extensions_per_root_path += extension_count;
1071+
self.stats.root_visits += 1;
1072+
} else {
1073+
self.stats.candidates_per_node_path += candidate_count;
1074+
self.stats.extensions_per_node_path += extension_count;
1075+
self.stats.node_visits += end_node.id();
1076+
}
1077+
1078+
if extension_count == 0 {
1079+
self.stats.maximal_path_lengh += partial_path.edges.len();
1080+
}
10591081
candidate_count
10601082
}
10611083

@@ -1089,6 +1111,7 @@ impl<H: Clone> ForwardPartialPathStitcher<H> {
10891111
self.next_iteration.1.drain(..),
10901112
self.next_iteration.2.drain(..),
10911113
));
1114+
self.stats.queued_paths_per_phase += self.queue.len();
10921115
let mut work_performed = 0;
10931116
while let Some((partial_path, cycle_detector, has_split)) = self.queue.pop_front() {
10941117
let (graph, partials, _) = candidates.get_graph_partials_and_db();
@@ -1110,6 +1133,7 @@ impl<H: Clone> ForwardPartialPathStitcher<H> {
11101133
break;
11111134
}
11121135
}
1136+
self.stats.processed_paths_per_phase += work_performed;
11131137

11141138
#[cfg(feature = "copious-debugging")]
11151139
{
@@ -1149,7 +1173,7 @@ impl ForwardPartialPathStitcher<Edge> {
11491173
config: StitcherConfig,
11501174
cancellation_flag: &dyn CancellationFlag,
11511175
mut visit: F,
1152-
) -> Result<(), CancellationError>
1176+
) -> Result<Stats, CancellationError>
11531177
where
11541178
F: FnMut(&StackGraph, &mut PartialPaths, &PartialPath),
11551179
{
@@ -1168,6 +1192,8 @@ impl ForwardPartialPathStitcher<Edge> {
11681192
ForwardPartialPathStitcher::from_partial_paths(graph, partials, initial_paths);
11691193
config.apply(&mut stitcher);
11701194
stitcher.set_check_only_join_nodes(true);
1195+
1196+
let mut accepted_path_length = FrequencyDistribution::default();
11711197
while !stitcher.is_complete() {
11721198
cancellation_flag.check("finding complete partial paths")?;
11731199
stitcher.process_next_phase(
@@ -1176,11 +1202,16 @@ impl ForwardPartialPathStitcher<Edge> {
11761202
);
11771203
for path in stitcher.previous_phase_partial_paths() {
11781204
if as_complete_as_necessary(graph, path) {
1205+
accepted_path_length += path.edges.len();
11791206
visit(graph, partials, path);
11801207
}
11811208
}
11821209
}
1183-
Ok(())
1210+
1211+
Ok(Stats {
1212+
accepted_path_length,
1213+
..stitcher.stats
1214+
})
11841215
}
11851216
}
11861217

@@ -1202,7 +1233,7 @@ impl<H: Clone> ForwardPartialPathStitcher<H> {
12021233
config: StitcherConfig,
12031234
cancellation_flag: &dyn CancellationFlag,
12041235
mut visit: F,
1205-
) -> Result<(), Err>
1236+
) -> Result<Stats, Err>
12061237
where
12071238
I: IntoIterator<Item = Handle<Node>>,
12081239
A: Appendable,
@@ -1225,6 +1256,8 @@ impl<H: Clone> ForwardPartialPathStitcher<H> {
12251256
ForwardPartialPathStitcher::from_partial_paths(graph, partials, initial_paths);
12261257
config.apply(&mut stitcher);
12271258
stitcher.set_check_only_join_nodes(true);
1259+
1260+
let mut accepted_path_length = FrequencyDistribution::default();
12281261
while !stitcher.is_complete() {
12291262
cancellation_flag.check("finding complete partial paths")?;
12301263
for path in stitcher.previous_phase_partial_paths() {
@@ -1234,11 +1267,55 @@ impl<H: Clone> ForwardPartialPathStitcher<H> {
12341267
let (graph, partials, _) = candidates.get_graph_partials_and_db();
12351268
for path in stitcher.previous_phase_partial_paths() {
12361269
if path.is_complete(graph) {
1270+
accepted_path_length += path.edges.len();
12371271
visit(graph, partials, path);
12381272
}
12391273
}
12401274
}
1241-
Ok(())
1275+
1276+
Ok(Stats {
1277+
accepted_path_length,
1278+
..stitcher.stats
1279+
})
1280+
}
1281+
}
1282+
1283+
#[derive(Clone, Debug, Default)]
1284+
pub struct Stats {
1285+
/// The distribution of the number of queued paths per stitching phase
1286+
pub queued_paths_per_phase: FrequencyDistribution<usize>,
1287+
/// The distribution of the number of processed paths per stitching phase
1288+
pub processed_paths_per_phase: FrequencyDistribution<usize>,
1289+
/// The distribution of the length of accepted paths
1290+
pub accepted_path_length: FrequencyDistribution<usize>,
1291+
/// The distribution of the maximal length of paths (when they cannot be extended more)
1292+
pub maximal_path_lengh: FrequencyDistribution<usize>,
1293+
/// The distribution of the number of candidates for paths ending in a regular node
1294+
pub candidates_per_node_path: FrequencyDistribution<usize>,
1295+
/// The distribution of the number of candidates for paths ending in the root node
1296+
pub candidates_per_root_path: FrequencyDistribution<usize>,
1297+
/// The distribution of the number of extensions (accepted candidates) for paths ending in a regular node
1298+
pub extensions_per_node_path: FrequencyDistribution<usize>,
1299+
/// The distribution of the number of extensions (accepted candidates) for paths ending in the root node
1300+
pub extensions_per_root_path: FrequencyDistribution<usize>,
1301+
/// The number of times the root node is visited
1302+
pub root_visits: usize,
1303+
/// The distribution of the number of times a regular node is visited
1304+
pub node_visits: FrequencyDistribution<crate::graph::NodeID>,
1305+
}
1306+
1307+
impl std::ops::AddAssign<&Self> for Stats {
1308+
fn add_assign(&mut self, rhs: &Self) {
1309+
self.queued_paths_per_phase += &rhs.queued_paths_per_phase;
1310+
self.processed_paths_per_phase += &rhs.processed_paths_per_phase;
1311+
self.accepted_path_length += &rhs.accepted_path_length;
1312+
self.maximal_path_lengh += &rhs.maximal_path_lengh;
1313+
self.candidates_per_node_path += &rhs.candidates_per_node_path;
1314+
self.candidates_per_root_path += &rhs.candidates_per_root_path;
1315+
self.extensions_per_node_path += &rhs.extensions_per_node_path;
1316+
self.extensions_per_root_path += &rhs.extensions_per_root_path;
1317+
self.root_visits += rhs.root_visits;
1318+
self.node_visits += &rhs.node_visits;
12421319
}
12431320
}
12441321

0 commit comments

Comments
 (0)