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

Commit 270bb1b

Browse files
author
Hendrik van Antwerpen
authored
Merge pull request #346 from github/leaner-similar-paths-detection
Reduce stored similar paths and checked cycles
2 parents d39ca5e + cd58abb commit 270bb1b

7 files changed

Lines changed: 202 additions & 69 deletions

File tree

‎languages/tree-sitter-stack-graphs-javascript/rust/npm_package.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ impl FileAnalyzer for NpmPackageAnalyzer {
115115
EXPORTS_GUARD,
116116
"exports_guard_pop",
117117
);
118-
replace_edge(graph, pkg_name_pop, exports_guard_pop, 1);
118+
set_edge_precedence(graph, pkg_name_pop, exports_guard_pop, 1);
119119
let main = Some(npm_pkg.main)
120120
.filter(|main| !main.is_empty())
121121
.and_then(|main| NormalizedRelativePath::from_str(&main))

‎languages/tree-sitter-stack-graphs-javascript/rust/util.rs‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,16 @@ pub fn add_edge(graph: &mut StackGraph, from: Handle<Node>, to: Handle<Node>, pr
6161
graph.add_edge(from, to, precedence);
6262
}
6363

64-
pub fn replace_edge(graph: &mut StackGraph, from: Handle<Node>, to: Handle<Node>, precedence: i32) {
64+
pub fn set_edge_precedence(
65+
graph: &mut StackGraph,
66+
from: Handle<Node>,
67+
to: Handle<Node>,
68+
precedence: i32,
69+
) {
6570
if from == to {
6671
return;
6772
}
68-
graph.remove_edge(from, to);
69-
graph.add_edge(from, to, precedence);
73+
graph.set_edge_precedence(from, to, precedence);
7074
}
7175

7276
pub fn add_module_pops(

‎stack-graphs/src/cycles.rs‎

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ use crate::stitching::ToAppendable;
4949

5050
/// Helps detect similar paths in the path-finding algorithm.
5151
pub struct SimilarPathDetector<P> {
52-
paths: HashMap<PathKey, SmallVec<[P; 8]>>,
52+
paths: HashMap<PathKey, SmallVec<[P; 4]>>,
5353
}
5454

5555
#[doc(hidden)]
@@ -110,11 +110,26 @@ where
110110
{
111111
let key = path.key();
112112

113+
// Iterate through the bucket to determine if this paths is better than any already known
114+
// path. Note that the bucket might be modified during the loop if a path is removed which
115+
// is shadowed by the new path!
113116
let possibly_similar_paths = self.paths.entry(key).or_default();
114-
for other_path in possibly_similar_paths.iter() {
115-
match cmp(arena, path, other_path) {
116-
Some(ord) if ord != Ordering::Less => return true,
117-
_ => continue,
117+
let mut idx = 0;
118+
while idx < possibly_similar_paths.len() {
119+
match cmp(arena, path, &possibly_similar_paths[idx]) {
120+
Some(Ordering::Less) => {
121+
// the new path is better, remove the old one
122+
possibly_similar_paths.remove(idx);
123+
// keep `idx` which now points to the next element
124+
continue;
125+
}
126+
Some(_) => {
127+
// the new path is equal or worse, and ignored
128+
return true;
129+
}
130+
None => {
131+
idx += 1;
132+
}
118133
}
119134
}
120135

‎stack-graphs/src/graph.rs‎

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,14 +1303,20 @@ impl StackGraph {
13031303
let edges = &mut self.outgoing_edges[source];
13041304
if let Err(index) = edges.binary_search_by_key(&sink, |o| o.sink) {
13051305
edges.insert(index, OutgoingEdge { sink, precedence });
1306+
self.incoming_edges[sink] += Degree::One;
13061307
}
13071308
}
13081309

13091310
/// Removes an edge from the stack graph.
1310-
pub fn remove_edge(&mut self, source: Handle<Node>, sink: Handle<Node>) {
1311+
pub fn set_edge_precedence(
1312+
&mut self,
1313+
source: Handle<Node>,
1314+
sink: Handle<Node>,
1315+
precedence: i32,
1316+
) {
13111317
let edges = &mut self.outgoing_edges[source];
13121318
if let Ok(index) = edges.binary_search_by_key(&sink, |o| o.sink) {
1313-
edges.remove(index);
1319+
edges[index].precedence = precedence;
13141320
}
13151321
}
13161322

@@ -1325,6 +1331,11 @@ impl StackGraph {
13251331
None => Either::Left(std::iter::empty()),
13261332
}
13271333
}
1334+
1335+
/// Returns the number of edges that end at a particular sink node.
1336+
pub fn incoming_edge_degree(&self, sink: Handle<Node>) -> Degree {
1337+
self.incoming_edges[sink]
1338+
}
13281339
}
13291340

13301341
//-------------------------------------------------------------------------------------------------
@@ -1430,6 +1441,36 @@ impl StackGraph {
14301441
//-------------------------------------------------------------------------------------------------
14311442
// Stack graphs
14321443

1444+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1445+
#[repr(u8)]
1446+
pub enum Degree {
1447+
Zero,
1448+
One,
1449+
Multiple,
1450+
}
1451+
1452+
impl Default for Degree {
1453+
fn default() -> Self {
1454+
Self::Zero
1455+
}
1456+
}
1457+
1458+
impl std::ops::Add for Degree {
1459+
type Output = Self;
1460+
fn add(self, rhs: Self) -> Self::Output {
1461+
match (self, rhs) {
1462+
(Self::Zero, result) | (result, Self::Zero) => result,
1463+
_ => Self::Multiple,
1464+
}
1465+
}
1466+
}
1467+
1468+
impl std::ops::AddAssign for Degree {
1469+
fn add_assign(&mut self, rhs: Self) {
1470+
*self = *self + rhs;
1471+
}
1472+
}
1473+
14331474
/// Contains all of the nodes and edges that make up a stack graph.
14341475
pub struct StackGraph {
14351476
interned_strings: InternedStringArena,
@@ -1442,9 +1483,10 @@ pub struct StackGraph {
14421483
pub(crate) nodes: Arena<Node>,
14431484
pub(crate) source_info: SupplementalArena<Node, SourceInfo>,
14441485
node_id_handles: NodeIDHandles,
1445-
outgoing_edges: SupplementalArena<Node, SmallVec<[OutgoingEdge; 8]>>,
1486+
outgoing_edges: SupplementalArena<Node, SmallVec<[OutgoingEdge; 4]>>,
1487+
incoming_edges: SupplementalArena<Node, Degree>,
14461488
pub(crate) node_debug_info: SupplementalArena<Node, DebugInfo>,
1447-
pub(crate) edge_debug_info: SupplementalArena<Node, SmallVec<[(Handle<Node>, DebugInfo); 8]>>,
1489+
pub(crate) edge_debug_info: SupplementalArena<Node, SmallVec<[(Handle<Node>, DebugInfo); 4]>>,
14481490
}
14491491

14501492
impl StackGraph {
@@ -1625,6 +1667,7 @@ impl Default for StackGraph {
16251667
source_info: SupplementalArena::new(),
16261668
node_id_handles: NodeIDHandles::new(),
16271669
outgoing_edges: SupplementalArena::new(),
1670+
incoming_edges: SupplementalArena::new(),
16281671
node_debug_info: SupplementalArena::new(),
16291672
edge_debug_info: SupplementalArena::new(),
16301673
}

0 commit comments

Comments
 (0)