Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions crates/no-mistakes/benches/core_analysis/graph_gates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@
//! Sized above the 14-file core-analysis fixture and below the 246-file
//! large-graph-monorepo acceptance fixture so CI benches stay in-process.

#[path = "graph_gates_session.rs"]
mod session;
#[path = "graph_gates_support.rs"]
mod support;

use super::shard;
use criterion::{black_box, BenchmarkId, Criterion, Throughput};
use no_mistakes::codebase::analysis_session::AnalysisSession;
use no_mistakes::codebase::dependencies::graph::DepGraph;
use no_mistakes::codebase::dependencies::NodeId;
use no_mistakes::codebase::ts_resolver::load_tsconfig;
use no_mistakes::codebase::ts_source::facts::{collect_ts_facts, TsFactPlan};
use std::sync::Arc;
use support::{
build_graph, domain_totals, expect_count, expect_kind_counts, fact_totals, file_nodes,
fixture_root, gate_plan, source_files, traversal_snapshot, EXPECTED_BACKEND_ROUTES,
Expand Down Expand Up @@ -173,6 +177,20 @@ pub(super) fn bench_graph_gates(c: &mut Criterion) {
}
build_group.finish();

let session = AnalysisSession::new(None);
let v2 = session
.config(&root, Some(&config_path))
.expect("graph-gates session config");
let _ = session.test_file_filter(&root, v2.as_ref());
session::bench_graph_gates_session(
c,
&root,
&config,
&config_path,
Arc::clone(&session),
&preflight,
);

let mut query_group = c.benchmark_group("graph_gates_query");
query_group.throughput(Throughput::Elements(
(FORWARD_ROOTS.len() + REVERSE_ROOTS.len()) as u64,
Expand Down
57 changes: 57 additions & 0 deletions crates/no-mistakes/benches/core_analysis/graph_gates_session.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use super::support::{traversal_snapshot, EXPECTED_GRAPH_NODES};
use criterion::{black_box, BenchmarkId, Criterion, Throughput};
use no_mistakes::codebase::analysis_session::AnalysisSession;
use no_mistakes::codebase::dependencies::graph::DepGraph;
use no_mistakes::codebase::ts_resolver::TsConfig;
use std::path::Path;
use std::sync::Arc;

pub(super) fn bench_graph_gates_session(
c: &mut Criterion,
root: &Path,
config: &TsConfig,
config_path: &Path,
session: Arc<AnalysisSession>,
unprepared: &DepGraph,
) {
let session_preflight = DepGraph::build_with_plan_and_config_and_session(
root,
config,
super::support::gate_plan(),
Some(config_path),
Arc::clone(&session),
)
.expect("graph-gates session preflight should succeed");
assert_eq!(
traversal_snapshot(&session_preflight),
traversal_snapshot(unprepared),
"session-path graph build must preserve traversal order"
);
drop(session_preflight);

let mut session_group = c.benchmark_group("graph_gates_build_session");
session_group.throughput(Throughput::Elements(EXPECTED_GRAPH_NODES as u64));
for threads in [1usize, 4] {
let pool = rayon::ThreadPoolBuilder::new()
.num_threads(threads)
.build()
.expect("graph-gates rayon pool");
session_group.bench_with_input(BenchmarkId::from_parameter(threads), &threads, |b, _| {
b.iter(|| {
pool.install(|| {
black_box(
DepGraph::build_with_plan_and_config_and_session(
black_box(root),
black_box(config),
black_box(super::support::gate_plan()),
Some(black_box(config_path)),
black_box(Arc::clone(&session)),
)
.expect("graph-gates session build should succeed"),
)
})
});
});
}
session_group.finish();
}
3 changes: 3 additions & 0 deletions crates/no-mistakes/src/codebase/analysis_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub struct AnalysisSession {
registry_extension_reports: DashMap<RegistryExtensionKey, RegistryExtensionCell>,
parse_attempts: Option<DashMap<PathBuf, u64>>,
interner: Arc<PathInterner>,
test_filters: DashMap<PathBuf, Arc<TestFilterCell>>,
}

type AnalysisDataset = crate::codebase::analysis_dataset::AnalysisDataset;
Expand All @@ -39,6 +40,7 @@ type SourceReadResult = Result<Arc<str>, SourceReadError>;
type RegistryExtensionResult =
Result<Arc<crate::registry_extension_query::RegistryExtensionReport>, Arc<str>>;
type RegistryExtensionCell = Arc<OnceLock<RegistryExtensionResult>>;
type TestFilterCell = OnceLock<Arc<crate::codebase::test_filter::TestFileFilter>>;

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
struct RegistryExtensionKey {
Expand Down Expand Up @@ -81,6 +83,7 @@ impl AnalysisSession {
registry_extension_reports: DashMap::new(),
parse_attempts: collect_keyed_work.then(DashMap::new),
interner: Arc::new(PathInterner::new()),
test_filters: DashMap::new(),
})
}

Expand Down
51 changes: 51 additions & 0 deletions crates/no-mistakes/src/codebase/analysis_session/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,55 @@ impl AnalysisSession {
) -> anyhow::Result<Arc<crate::codebase::ts_resolver::TsConfig>> {
self.dataset(root).tsconfig(tsconfig_path)
}

/// Request-scoped filter for `root`. A seeded filter is reused for that root.
#[doc(hidden)]
pub fn test_file_filter(
&self,
root: &Path,
config: &crate::config::v2::NoMistakesConfig,
) -> Arc<crate::codebase::test_filter::TestFileFilter> {
self.test_file_filter_with_visible(root, config, None)
}

pub(crate) fn test_file_filter_with_visible(
&self,
root: &Path,
config: &crate::config::v2::NoMistakesConfig,
visible_paths: Option<&[PathBuf]>,
) -> Arc<crate::codebase::test_filter::TestFileFilter> {
let root = normalize_path(root);
let cell = self.test_filter_cell(&root);
Arc::clone(cell.get_or_init(|| {
Comment thread
jonathanong marked this conversation as resolved.
self.increment("test_filter.builds", 1);
let paths = visible_paths
.map(<[PathBuf]>::to_vec)
.unwrap_or_else(|| self.visible_paths(&root).paths_for(&root).as_ref().clone());
Arc::new(crate::codebase::test_filter::TestFileFilter::from_visible(
&root, config, &paths,
))
}))
}

/// Seed a filter built from prepared project globs. First writer wins.
#[doc(hidden)]
pub fn insert_test_file_filter(
&self,
root: &Path,
filter: crate::codebase::test_filter::TestFileFilter,
) {
let cell = self.test_filter_cell(&normalize_path(root));
let _ = cell.get_or_init(|| Arc::new(filter));
}

fn test_filter_cell(&self, root: &Path) -> Arc<super::TestFilterCell> {
match self.test_filters.entry(root.to_path_buf()) {
Entry::Occupied(entry) => Arc::clone(entry.get()),
Entry::Vacant(entry) => {
let cell = Arc::new(OnceLock::new());
entry.insert(Arc::clone(&cell));
cell
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,12 @@ impl DepGraph {
) -> Result<Self> {
let session =
crate::codebase::analysis_session::AnalysisSession::new(crate::diagnostics::current());
// Interner-only session: graph config still uses TestFileFilter::new.
let config_options = graph_config_options_for_plan_with_config_and_session(
root,
plan,
config_path,
Some(&session),
None,
Some(graph_files.all()),
);
Self::build_with_plan_files_options_and_facts(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,27 @@ impl DepGraph {
)
}

/// Standalone graph build that reuses a request session's TestFileFilter.
#[doc(hidden)]
pub fn build_with_plan_and_config_and_session(
root: &Path,
tsconfig: &TsConfig,
plan: GraphBuildPlan,
config_path: Option<&Path>,
session: std::sync::Arc<crate::codebase::analysis_session::AnalysisSession>,
) -> Result<Self> {
let graph_files = GraphFiles::discover(root);
Self::build_with_plan_files_config_facts_and_session(
root,
tsconfig,
plan,
&graph_files,
config_path,
None,
session,
)
}

pub(crate) fn build_with_plan_and_files(
root: &Path,
tsconfig: &TsConfig,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
impl DepGraph {
pub(crate) fn build_with_plan_files_config_facts_and_session(
root: &Path,
tsconfig: &TsConfig,
plan: GraphBuildPlan,
graph_files: &GraphFiles,
config_path: Option<&Path>,
facts: Option<&dyn TsFactLookup>,
session: std::sync::Arc<crate::codebase::analysis_session::AnalysisSession>,
) -> Result<Self> {
let config_options = graph_config_options_for_plan_with_config_and_session(
root,
plan,
config_path,
Some(&session),
Some(graph_files.all()),
);
Self::build_with_plan_files_options_and_facts(
GraphEdgeBuildInputs {
root,
tsconfig,
tsconfig_catalog: None,
plan,
graph_files,
workspace: None,
config_options: config_options.as_ref(),
playwright_settings: &[],
config_path,
dotnet_facts: None,
swift_facts: None,
import_resolution_cache: None,
visible_paths: None,
workflow_documents: None,
interner: session.interner_arc(),
},
facts,
SuppliedFactPolicy::FillSparse,
session,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn graph_config_options_with_config_and_session(
None => crate::codebase::config::load_config(root),
}
.ok()?;
let v2_config = load_v2_config(root, config_path).ok();
let v2_config = load_v2_config(root, config_path).ok()?;
let snapshot;
let snapshot_paths;
let discovered;
Expand All @@ -43,12 +43,19 @@ fn graph_config_options_with_config_and_session(
discovered = crate::codebase::ts_source::discover_visible_paths(root);
&discovered
};
Some(graph_config_options_from_loaded(
root,
&config,
v2_config.as_ref()?,
visible_paths,
))
Some(match session {
Some(session) => graph_config_options_from_loaded_with_test_filter(
root,
&config,
&v2_config,
visible_paths,
Some(
(*session.test_file_filter_with_visible(root, &v2_config, Some(visible_paths)))
.clone(),
),
),
None => graph_config_options_from_loaded(root, &config, &v2_config, visible_paths),
})
}

fn graph_config_options_for_plan_with_config_and_session(
Expand Down
1 change: 1 addition & 0 deletions crates/no-mistakes/src/codebase/dependencies/graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ include!("edge_maps.rs");
include!("fact_lookup.rs");

include!("builder.rs");
include!("builder_session.rs");
include!("builder_check_facts.rs");
include!("builder_observability.rs");
include!("builder_parse_errors.rs");
Expand Down
Loading
Loading