diff --git a/src/daemon.rs b/src/daemon.rs index 746a8db..20891f6 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -5,7 +5,6 @@ use crate::digest::generate_daily_digest; use crate::discovery_engine::{discover_dependencies, discover_similar_projects}; use crate::health::analyze_repo; use crate::i18n::from_language; -use crate::knowledge_engine::index_repo; use crate::registry::{ HealthEntry, health as reg_health, knowledge as reg_knowledge, relation as reg_relation, repo, }; @@ -111,14 +110,27 @@ impl Daemon { } else { crate::registry::repo::list_repos(&conn)? }; + // Batch-index: reuse a single Tantivy writer across all repos + let (search_index, _reader) = crate::search::init_index()?; + let mut writer = crate::search::get_writer(&search_index)?; + let schema = search_index.schema(); let mut count = 0; for repo in repos { - if let Err(e) = index_repo(&mut conn, &repo, config.as_ref()) { + if let Err(e) = crate::knowledge_engine::index_repo_with_writer( + &mut conn, + &repo, + config.as_ref(), + &mut writer, + &schema, + ) { tracing::warn!("Failed to index {}: {}", repo.id, e); } else { count += 1; } } + if let Err(e) = crate::search::commit_writer(&mut writer) { + tracing::warn!("Failed to commit search index: {}", e); + } Ok::<_, anyhow::Error>(count) }) .await diff --git a/src/knowledge_engine/index.rs b/src/knowledge_engine/index.rs index fb668be..21183b9 100644 --- a/src/knowledge_engine/index.rs +++ b/src/knowledge_engine/index.rs @@ -2,25 +2,14 @@ // Copyright (c) 2026 juice094 use crate::registry::RepoEntry; use std::path::PathBuf; +use tantivy::{IndexWriter, schema::Schema}; -fn index_repo_in_search( - repo: &crate::registry::RepoEntry, - summary: &str, - keywords: &str, -) -> anyhow::Result<()> { - let (index, _reader) = crate::search::init_index()?; - let mut writer = crate::search::get_writer(&index)?; - let schema = index.schema(); - crate::search::delete_repo_doc(&mut writer, &schema, &repo.id)?; - crate::search::add_repo_doc(&mut writer, &schema, &repo.id, summary, keywords, &repo.tags)?; - crate::search::commit_writer(&mut writer)?; - Ok(()) -} - -pub fn index_repo( +fn index_repo_core( conn: &mut rusqlite::Connection, repo: &crate::registry::RepoEntry, config: Option<&crate::config::Config>, + writer: &mut IndexWriter, + schema: &Schema, ) -> anyhow::Result<()> { use tracing::{info, warn}; @@ -37,7 +26,9 @@ pub fn index_repo( crate::registry::knowledge::save_summary(conn, &repo.id, &summary, &keywords)?; - if let Err(e) = index_repo_in_search(repo, &summary, &keywords) { + if let Err(e) = crate::search::delete_repo_doc(writer, schema, &repo.id).and_then(|_| { + crate::search::add_repo_doc(writer, schema, &repo.id, &summary, &keywords, &repo.tags) + }) { warn!("Failed to index repo in search: {}", e); } @@ -57,6 +48,33 @@ pub fn index_repo( Ok(()) } +/// Index a single repo with a standalone Tantivy writer. +/// Suitable for one-off indexing where writer reuse is not needed. +pub fn index_repo( + conn: &mut rusqlite::Connection, + repo: &crate::registry::RepoEntry, + config: Option<&crate::config::Config>, +) -> anyhow::Result<()> { + let (index, _reader) = crate::search::init_index()?; + let mut writer = crate::search::get_writer(&index)?; + let schema = index.schema(); + index_repo_core(conn, repo, config, &mut writer, &schema)?; + crate::search::commit_writer(&mut writer)?; + Ok(()) +} + +/// Index a single repo reusing an existing Tantivy writer. +/// Callers must commit the writer after the batch. +pub fn index_repo_with_writer( + conn: &mut rusqlite::Connection, + repo: &crate::registry::RepoEntry, + config: Option<&crate::config::Config>, + writer: &mut IndexWriter, + schema: &Schema, +) -> anyhow::Result<()> { + index_repo_core(conn, repo, config, writer, schema) +} + /// 兼容旧调用的包装层:执行索引逻辑 pub fn run_index( conn: &mut rusqlite::Connection,