Skip to content

Commit ecd6865

Browse files
committed
Build settings index in parallel for the native server
1 parent 90e9aae commit ecd6865

File tree

3 files changed

+83
-65
lines changed

3 files changed

+83
-65
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ruff_server/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ ruff_workspace = { workspace = true }
2828

2929
anyhow = { workspace = true }
3030
crossbeam = { workspace = true }
31+
ignore = { workspace = true }
3132
jod-thread = { workspace = true }
3233
lsp-server = { workspace = true }
3334
lsp-types = { workspace = true }
@@ -38,7 +39,6 @@ serde_json = { workspace = true }
3839
shellexpand = { workspace = true }
3940
tracing = { workspace = true }
4041
tracing-subscriber = { workspace = true }
41-
walkdir = { workspace = true }
4242

4343
[dev-dependencies]
4444
insta = { workspace = true }

crates/ruff_server/src/session/index/ruff_settings.rs

Lines changed: 81 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
use std::collections::BTreeMap;
2+
use std::path::{Path, PathBuf};
3+
use std::sync::Arc;
4+
5+
use ignore::{WalkBuilder, WalkState};
6+
17
use ruff_linter::{
28
display_settings, fs::normalize_path_to, settings::types::FilePattern,
39
settings::types::PreviewMode,
@@ -8,12 +14,6 @@ use ruff_workspace::{
814
pyproject::{find_user_settings_toml, settings_toml},
915
resolver::{ConfigurationTransformer, Relativity},
1016
};
11-
use std::{
12-
collections::BTreeMap,
13-
path::{Path, PathBuf},
14-
sync::Arc,
15-
};
16-
use walkdir::WalkDir;
1717

1818
use crate::session::settings::{ConfigurationPreference, ResolvedEditorSettings};
1919

@@ -30,7 +30,7 @@ pub struct RuffSettings {
3030
}
3131

3232
pub(super) struct RuffSettingsIndex {
33-
/// Index from folder to the resoled ruff settings.
33+
/// Index from folder to the resolved ruff settings.
3434
index: BTreeMap<PathBuf, Arc<RuffSettings>>,
3535
fallback: Arc<RuffSettings>,
3636
}
@@ -126,70 +126,88 @@ impl RuffSettingsIndex {
126126
}
127127

128128
// Add any settings within the workspace itself
129-
let mut walker = WalkDir::new(root).into_iter();
130-
131-
while let Some(entry) = walker.next() {
132-
let Ok(entry) = entry else {
133-
continue;
134-
};
135-
136-
// Skip non-directories.
137-
if !entry.file_type().is_dir() {
138-
continue;
139-
}
140-
141-
let directory = entry.into_path();
129+
let mut builder = WalkBuilder::new(root);
130+
builder.standard_filters(true);
131+
builder.hidden(false);
132+
builder.threads(
133+
std::thread::available_parallelism()
134+
.map_or(1, std::num::NonZeroUsize::get)
135+
.min(12),
136+
);
137+
let walker = builder.build_parallel();
138+
139+
let index = std::sync::RwLock::new(index);
140+
walker.run(|| {
141+
Box::new(|result| {
142+
let Ok(entry) = result else {
143+
return WalkState::Continue;
144+
};
142145

143-
// If the directory is excluded from the workspace, skip it.
144-
if let Some(file_name) = directory.file_name() {
145-
if let Some((_, settings)) = index
146-
.range(..directory.clone())
147-
.rfind(|(path, _)| directory.starts_with(path))
146+
// Skip non-directories.
147+
if !entry
148+
.file_type()
149+
.is_some_and(|file_type| file_type.is_dir())
148150
{
149-
if match_exclusion(&directory, file_name, &settings.file_resolver.exclude) {
150-
tracing::debug!("Ignored path via `exclude`: {}", directory.display());
151-
152-
walker.skip_current_dir();
153-
continue;
154-
} else if match_exclusion(
155-
&directory,
156-
file_name,
157-
&settings.file_resolver.extend_exclude,
158-
) {
159-
tracing::debug!(
160-
"Ignored path via `extend-exclude`: {}",
161-
directory.display()
162-
);
163-
164-
walker.skip_current_dir();
165-
continue;
151+
return WalkState::Continue;
152+
}
153+
154+
let directory = entry.into_path();
155+
tracing::debug!("Visiting: {}", directory.display());
156+
157+
// If the directory is excluded from the workspace, skip it.
158+
if let Some(file_name) = directory.file_name() {
159+
if let Some((_, settings)) = index
160+
.read()
161+
.unwrap()
162+
.range(..directory.clone())
163+
.rfind(|(path, _)| directory.starts_with(path))
164+
{
165+
if match_exclusion(&directory, file_name, &settings.file_resolver.exclude) {
166+
tracing::debug!("Ignored path via `exclude`: {}", directory.display());
167+
return WalkState::Continue;
168+
} else if match_exclusion(
169+
&directory,
170+
file_name,
171+
&settings.file_resolver.extend_exclude,
172+
) {
173+
tracing::debug!(
174+
"Ignored path via `extend-exclude`: {}",
175+
directory.display()
176+
);
177+
return WalkState::Continue;
178+
}
166179
}
167180
}
168-
}
169181

170-
if let Some(pyproject) = settings_toml(&directory).ok().flatten() {
171-
let Ok(settings) = ruff_workspace::resolver::resolve_root_settings(
172-
&pyproject,
173-
Relativity::Parent,
174-
&EditorConfigurationTransformer(editor_settings, root),
175-
) else {
176-
continue;
177-
};
178-
index.insert(
179-
directory,
180-
Arc::new(RuffSettings {
181-
path: Some(pyproject),
182-
file_resolver: settings.file_resolver,
183-
linter: settings.linter,
184-
formatter: settings.formatter,
185-
}),
186-
);
187-
}
188-
}
182+
if let Some(pyproject) = settings_toml(&directory).ok().flatten() {
183+
let Ok(settings) = ruff_workspace::resolver::resolve_root_settings(
184+
&pyproject,
185+
Relativity::Parent,
186+
&EditorConfigurationTransformer(editor_settings, root),
187+
) else {
188+
return WalkState::Continue;
189+
};
190+
index.write().unwrap().insert(
191+
directory,
192+
Arc::new(RuffSettings {
193+
path: Some(pyproject),
194+
file_resolver: settings.file_resolver,
195+
linter: settings.linter,
196+
formatter: settings.formatter,
197+
}),
198+
);
199+
}
200+
201+
WalkState::Continue
202+
})
203+
});
189204

190205
let fallback = Arc::new(RuffSettings::fallback(editor_settings, root));
191206

192-
Self { index, fallback }
207+
Self {
208+
index: index.into_inner().unwrap(),
209+
fallback,
210+
}
193211
}
194212

195213
pub(super) fn get(&self, document_path: &Path) -> Arc<RuffSettings> {

0 commit comments

Comments
 (0)