mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
Reduce path storage in the file-search index (#55351)
## What changed Reuse the matcher column for ASCII paths instead of storing a separate full path for every indexed entry. Store the selected search root and entry type alongside each entry so snapshots can build results without resolving the root again. Retain the original relative path for Unicode entries because matcher columns keep only one code point per grapheme. GitOrigin-RevId: 1e931482c9a656970e2eeaaade02f19063464f12
This commit is contained in:
@@ -72,9 +72,19 @@ pub enum MatchType {
|
||||
Directory,
|
||||
}
|
||||
|
||||
/// Carries the entry type observed by the walker so matched paths are not restatted.
|
||||
struct IndexedEntry {
|
||||
full_path: Arc<str>,
|
||||
/// Carries the selected root and entry type without duplicating ASCII matcher paths.
|
||||
enum IndexedEntry {
|
||||
Ascii {
|
||||
root_idx: usize,
|
||||
match_type: MatchType,
|
||||
},
|
||||
Unicode(Box<UnicodeEntry>),
|
||||
}
|
||||
|
||||
// Unicode matcher columns retain only one codepoint per grapheme.
|
||||
struct UnicodeEntry {
|
||||
root_idx: usize,
|
||||
relative_path: Box<str>,
|
||||
match_type: MatchType,
|
||||
}
|
||||
|
||||
@@ -470,23 +480,29 @@ fn walker_worker(
|
||||
Err(_) => return ignore::WalkState::Continue,
|
||||
};
|
||||
let path = entry.path();
|
||||
let Some(full_path) = path.to_str() else {
|
||||
if path.to_str().is_none() {
|
||||
return ignore::WalkState::Continue;
|
||||
};
|
||||
if let Some((_, relative_path)) = get_file_path(path, &search_directories) {
|
||||
}
|
||||
if let Some((root_idx, relative_path)) = get_file_path(path, &search_directories) {
|
||||
let match_type = match entry.file_type() {
|
||||
Some(file_type) if file_type.is_dir() => MatchType::Directory,
|
||||
_ => MatchType::File,
|
||||
};
|
||||
injector.push(
|
||||
IndexedEntry {
|
||||
full_path: Arc::from(full_path),
|
||||
let column = Utf32String::from(relative_path);
|
||||
let indexed_entry = match &column {
|
||||
Utf32String::Ascii(_) => IndexedEntry::Ascii {
|
||||
root_idx,
|
||||
match_type,
|
||||
},
|
||||
|_, cols| {
|
||||
cols[0] = Utf32String::from(relative_path);
|
||||
},
|
||||
);
|
||||
Utf32String::Unicode(_) => IndexedEntry::Unicode(Box::new(UnicodeEntry {
|
||||
root_idx,
|
||||
relative_path: Box::from(relative_path),
|
||||
match_type,
|
||||
})),
|
||||
};
|
||||
injector.push(indexed_entry, |_, cols| {
|
||||
cols[0] = column;
|
||||
});
|
||||
}
|
||||
n += 1;
|
||||
if n >= CHECK_INTERVAL {
|
||||
|
||||
@@ -18,10 +18,9 @@ fn query_update_does_not_relabel_pending_matches() {
|
||||
);
|
||||
let injector = nucleo.injector();
|
||||
for (relative, match_type) in [("", MatchType::Directory), ("beta.txt", MatchType::File)] {
|
||||
let full_path = root.path().join(relative);
|
||||
injector.push(
|
||||
IndexedEntry {
|
||||
full_path: Arc::from(full_path.to_str().unwrap()),
|
||||
IndexedEntry::Ascii {
|
||||
root_idx: 0,
|
||||
match_type,
|
||||
},
|
||||
|_, columns| columns[0] = Utf32String::from(relative),
|
||||
|
||||
@@ -4,10 +4,9 @@ use crate::FileMatch;
|
||||
use crate::FileSearchSnapshot;
|
||||
use crate::IndexedEntry;
|
||||
use crate::SessionInner;
|
||||
use crate::get_file_path;
|
||||
use nucleo::Matcher;
|
||||
use nucleo::Nucleo;
|
||||
use std::path::Path;
|
||||
use nucleo::Utf32String;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub(super) fn for_query(
|
||||
@@ -31,9 +30,22 @@ pub(super) fn for_query(
|
||||
.take(limit)
|
||||
.filter_map(|match_| {
|
||||
let item = snapshot.get_item(match_.idx)?;
|
||||
let full_path = item.data.full_path.as_ref();
|
||||
let (root_idx, relative_path) =
|
||||
get_file_path(Path::new(full_path), &inner.search_directories)?;
|
||||
let (root_idx, relative_path, match_type) = match item.data {
|
||||
IndexedEntry::Ascii {
|
||||
root_idx,
|
||||
match_type,
|
||||
} => {
|
||||
let Utf32String::Ascii(path) = &item.matcher_columns[0] else {
|
||||
return None;
|
||||
};
|
||||
(*root_idx, path.as_ref(), *match_type)
|
||||
}
|
||||
IndexedEntry::Unicode(entry) => (
|
||||
entry.root_idx,
|
||||
entry.relative_path.as_ref(),
|
||||
entry.match_type,
|
||||
),
|
||||
};
|
||||
let indices = if let Some(indices_matcher) = indices_matcher.as_mut() {
|
||||
let mut indices = Vec::<u32>::new();
|
||||
let haystack = item.matcher_columns[0].slice(..);
|
||||
@@ -47,7 +59,7 @@ pub(super) fn for_query(
|
||||
Some(FileMatch {
|
||||
score: match_.score,
|
||||
path: PathBuf::from(relative_path),
|
||||
match_type: item.data.match_type,
|
||||
match_type,
|
||||
root: inner.search_directories[root_idx].clone(),
|
||||
indices,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user