MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / update_content_index_paths

Function update_content_index_paths

atomic-repository/src/content_search.rs:98–155  ·  view source on GitHub ↗

Incrementally refresh the content index for a set of repo-relative paths that changed (e.g. the files touched by a recorded change) and persist the result to disk. Each path is re-read from disk: added/modified files are re-indexed and deleted files are removed, keeping the index in sync with the working copy without re-walking the whole tree. Ignored and Atomic-internal paths are skipped so buil

(
    repo_root: &Path,
    paths: I,
)

Source from the content-addressed store, hash-verified

96/// No-op when the content index does not yet exist — building it is the job of
97/// [`build_content_index`]; this only maintains an existing index.
98pub fn update_content_index_paths<I, P>(
99 repo_root: &Path,
100 paths: I,
101) -> Result<(), ContentSearchError>
102where
103 I: IntoIterator<Item = P>,
104 P: AsRef<Path>,
105{
106 if !has_content_index(repo_root) {
107 return Ok(());
108 }
109
110 // The open + compact below race syntext's own lock-downgrade windows and
111 // any concurrent reader/writer on the same index dir, so retry the whole
112 // update on a lock conflict rather than treating it as a hard failure.
113 // Collect the paths once: the retry closure may run multiple times.
114 let paths: Vec<std::path::PathBuf> = paths
115 .into_iter()
116 .map(|p| p.as_ref().to_path_buf())
117 .collect();
118 with_lock_retry(|| {
119 let ignore_rules = crate::ignore::IgnoreRules::load_for_enrichment(repo_root);
120 let config = content_config(repo_root);
121 let index = Index::open(config)?;
122
123 let mut any = false;
124 for path in &paths {
125 let rel = path.as_path();
126 if crate::ignore::is_enrichment_internal(rel) || ignore_rules.is_ignored(rel, false) {
127 continue;
128 }
129 // syntext strips `repo_root` to derive the relative path, so hand it an
130 // absolute path. The file need not exist — a missing file is treated as
131 // a deletion and removed from the index.
132 let absolute = repo_root.join(rel);
133 index.notify_change(&absolute)?;
134 any = true;
135 }
136
137 if !any {
138 return Ok(());
139 }
140
141 // Commit the pending overlay and fold it into on-disk base segments so the
142 // change survives to the next `Index::open`. When the changed set is large
143 // relative to the index (syntext caps the overlay at 50% of base docs),
144 // `compact` reports `OverlayFull`; the sanctioned recovery is a full
145 // (filtered) rebuild.
146 match index.compact() {
147 Ok(()) => Ok(()),
148 Err(IndexError::OverlayFull { .. }) => {
149 drop(index);
150 build_content_index(repo_root)
151 }
152 Err(e) => Err(e.into()),
153 }
154 })
155}

Callers 3

enrich_changeMethod · 0.85
recordMethod · 0.85

Calls 8

has_content_indexFunction · 0.85
with_lock_retryFunction · 0.85
content_configFunction · 0.85
is_enrichment_internalFunction · 0.85
build_content_indexFunction · 0.85
as_refMethod · 0.80
into_iterMethod · 0.45
is_ignoredMethod · 0.45