Improve local filetree view state and sidebar performance

This commit is contained in:
lix-2026
2026-05-27 11:31:12 +08:00
parent 58e2fdb5d8
commit 3ae33cc21d
56 changed files with 8614 additions and 461 deletions
@@ -56,7 +56,7 @@ pub(crate) fn query_local_search_index(
title_only: bool,
exact: bool,
) -> Result<Value, WebError> {
let index = rebuild_local_search_index(root_path, root_uri, workspace_id)?;
let index = load_or_rebuild_local_search_index(root_path, root_uri, workspace_id)?;
let normalized_query = normalize_search_text(query);
let page_id = page_id.map(str::trim).filter(|value| !value.is_empty());
let recent_changes = local_recent_changes_projection(&index.documents, root_uri);
@@ -294,6 +294,23 @@ fn rebuild_local_search_index(
Ok(index)
}
fn load_or_rebuild_local_search_index(
root_path: &Path,
root_uri: &str,
workspace_id: &str,
) -> Result<LocalSearchIndex, WebError> {
match read_local_search_index(root_path) {
Ok(Some(index))
if index.version == LOCAL_SEARCH_INDEX_VERSION
&& index.root_uri == root_uri
&& index.workspace_id == workspace_id =>
{
Ok(index)
}
Ok(_) | Err(_) => rebuild_local_search_index(root_path, root_uri, workspace_id),
}
}
fn read_local_search_index(root_path: &Path) -> Result<Option<LocalSearchIndex>, WebError> {
let index_path = root_path
.join(".mnote")
@@ -999,4 +1016,74 @@ mod tests {
.any(|document| document.path == "README.md"));
let _ = fs::remove_dir_all(&root);
}
#[test]
fn local_search_query_reads_existing_index_without_rebuilding() {
let root = temp_root("mnote-local-search-query-cache");
let root_uri = format!("file://{}", root.display());
let workspace_id = "local-ws-query-cache";
let child_path = root.join("docs").join("child.md");
fs::write(
&child_path,
"---\ntitle: Child\n---\n# Child\nOriginalToken body.\n",
)
.expect("write child");
let first_projection = query_local_search_index(
&root,
&root_uri,
workspace_id,
"OriginalToken",
None,
10,
false,
false,
)
.expect("first query");
assert_eq!(
first_projection["results"].as_array().map(Vec::len),
Some(1)
);
fs::write(
&child_path,
"---\ntitle: Child\n---\n# Child\nUnindexedToken body.\n",
)
.expect("update child without refresh");
let stale_projection = query_local_search_index(
&root,
&root_uri,
workspace_id,
"UnindexedToken",
None,
10,
false,
false,
)
.expect("query existing index");
assert_eq!(
stale_projection["results"].as_array().map(Vec::len),
Some(0)
);
refresh_local_search_index_for_path(&root, &root_uri, workspace_id, "docs/child.md")
.expect("incremental refresh");
let refreshed_projection = query_local_search_index(
&root,
&root_uri,
workspace_id,
"UnindexedToken",
None,
10,
false,
false,
)
.expect("query refreshed index");
assert_eq!(
refreshed_projection["results"].as_array().map(Vec::len),
Some(1)
);
let _ = fs::remove_dir_all(&root);
}
}