@@ -197,6 +197,23 @@ impl VectorDatabase {
Ok(())
}
+ pub fn worktree_previously_indexed(&self, worktree_root_path: &Path) -> Result<bool> {
+ let mut worktree_query = self
+ .db
+ .prepare("SELECT id FROM worktrees WHERE absolute_path = ?1")?;
+ let worktree_id = worktree_query
+ .query_row(params![worktree_root_path.to_string_lossy()], |row| {
+ Ok(row.get::<_, i64>(0)?)
+ })
+ .map_err(|err| anyhow!(err));
+
+ if worktree_id.is_ok() {
+ return Ok(true);
+ } else {
+ return Ok(false);
+ }
+ }
+
pub fn find_or_create_worktree(&self, worktree_root_path: &Path) -> Result<i64> {
// Check that the absolute path doesnt exist
let mut worktree_query = self
@@ -34,7 +34,7 @@ use util::{
ResultExt,
};
-const SEMANTIC_INDEX_VERSION: usize = 5;
+const SEMANTIC_INDEX_VERSION: usize = 6;
const EMBEDDINGS_BATCH_SIZE: usize = 80;
pub fn init(
@@ -161,6 +161,10 @@ enum DbOperation {
worktree_id: i64,
sender: oneshot::Sender<Result<HashMap<PathBuf, SystemTime>>>,
},
+ WorktreePreviouslyIndexed {
+ path: Arc<Path>,
+ sender: oneshot::Sender<Result<bool>>,
+ },
}
enum EmbeddingJob {
@@ -327,6 +331,10 @@ impl SemanticIndex {
let file_mtimes = db.get_file_mtimes(worktree_db_id);
sender.send(file_mtimes).ok();
}
+ DbOperation::WorktreePreviouslyIndexed { path, sender } => {
+ let worktree_indexed = db.worktree_previously_indexed(path.as_ref());
+ sender.send(worktree_indexed).ok();
+ }
}
}
@@ -479,6 +487,49 @@ impl SemanticIndex {
async move { rx.await? }
}
+ fn worktree_previously_indexed(&self, path: Arc<Path>) -> impl Future<Output = Result<bool>> {
+ let (tx, rx) = oneshot::channel();
+ self.db_update_tx
+ .try_send(DbOperation::WorktreePreviouslyIndexed { path, sender: tx })
+ .unwrap();
+ async move { rx.await? }
+ }
+
+ pub fn project_previously_indexed(
+ &mut self,
+ project: ModelHandle<Project>,
+ cx: &mut ModelContext<Self>,
+ ) -> Task<Result<bool>> {
+ let worktree_scans_complete = project
+ .read(cx)
+ .worktrees(cx)
+ .map(|worktree| {
+ let scan_complete = worktree.read(cx).as_local().unwrap().scan_complete();
+ async move {
+ scan_complete.await;
+ }
+ })
+ .collect::<Vec<_>>();
+
+ let worktrees_indexed_previously = project
+ .read(cx)
+ .worktrees(cx)
+ .map(|worktree| self.worktree_previously_indexed(worktree.read(cx).abs_path()))
+ .collect::<Vec<_>>();
+
+ cx.spawn(|this, mut cx| async move {
+ futures::future::join_all(worktree_scans_complete).await;
+
+ let worktree_indexed_previously =
+ futures::future::join_all(worktrees_indexed_previously).await;
+
+ Ok(worktree_indexed_previously
+ .iter()
+ .filter(|worktree| worktree.is_ok())
+ .all(|v| v.as_ref().log_err().is_some_and(|v| v.to_owned())))
+ })
+ }
+
pub fn index_project(
&mut self,
project: ModelHandle<Project>,