Skip to content

Commit 67684bb

Browse files
committed
Indexing: Periodically vacuum DB
So that the DB doesn't grow too big.
1 parent d125a24 commit 67684bb

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

apps/desktop/src-tauri/src/indexing/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2114,6 +2114,10 @@ pub fn start_indexing(app: &AppHandle) -> Result<(), String> {
21142114

21152115
let scan_result = manager.resume_or_scan();
21162116

2117+
// Clone the writer before moving manager into the state machine, so we
2118+
// can hand it to the vacuum timer if startup succeeds.
2119+
let writer_for_vacuum = manager.writer.clone();
2120+
21172121
// Re-lock and check: if someone called stop_indexing() while we were
21182122
// inside resume_or_scan(), the phase is now Disabled. Respect that —
21192123
// shut down the manager instead of overwriting with Running.
@@ -2122,6 +2126,17 @@ pub fn start_indexing(app: &AppHandle) -> Result<(), String> {
21222126
(IndexPhase::Initializing { .. }, Ok(())) => {
21232127
*guard = IndexPhase::Running(Box::new(manager));
21242128
log::info!("start_indexing: done — IndexManager is Running");
2129+
2130+
// Periodic incremental vacuum: reclaim free pages from deletes/rescans
2131+
// every 30s. Stops automatically when the writer channel closes.
2132+
tauri::async_runtime::spawn(async move {
2133+
loop {
2134+
tokio::time::sleep(Duration::from_secs(30)).await;
2135+
if writer_for_vacuum.send(WriteMessage::IncrementalVacuum).is_err() {
2136+
break;
2137+
}
2138+
}
2139+
});
21252140
}
21262141
(IndexPhase::Initializing { .. }, Err(e)) => {
21272142
*guard = IndexPhase::Disabled;

apps/desktop/src-tauri/src/indexing/writer.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ pub enum WriteMessage {
9898
BeginTransaction,
9999
/// Commit the current explicit transaction.
100100
CommitTransaction,
101+
/// Periodic housekeeping: reclaim free pages from deletes/rescans.
102+
/// Sent by a background timer, not counted in WriterStats.
103+
IncrementalVacuum,
101104
/// Shut down the writer thread.
102105
Shutdown,
103106
}
@@ -381,7 +384,9 @@ fn writer_loop(
381384
let mut accumulator = AccumulatorMaps::new();
382385

383386
for msg in &receiver {
384-
stats.record(&msg);
387+
if !matches!(msg, WriteMessage::IncrementalVacuum) {
388+
stats.record(&msg);
389+
}
385390
if process_message(
386391
&conn,
387392
msg,
@@ -628,6 +633,19 @@ fn process_message(
628633
}
629634
log::debug!("Writer: COMMIT transaction ({}ms)", t.elapsed().as_millis());
630635
}
636+
WriteMessage::IncrementalVacuum => {
637+
match conn.pragma_query_value(None, "freelist_count", |row| row.get::<_, i64>(0)) {
638+
Ok(free) if free > 0 => {
639+
if let Err(e) = conn.execute_batch("PRAGMA incremental_vacuum(2000)") {
640+
log::warn!("Writer: incremental_vacuum failed: {e}");
641+
} else {
642+
log::debug!("Writer: incremental_vacuum reclaimed up to 2000 of {free} free pages");
643+
}
644+
}
645+
Ok(_) => {} // No free pages, nothing to do
646+
Err(e) => log::warn!("Writer: freelist_count query failed: {e}"),
647+
}
648+
}
631649
WriteMessage::Shutdown => return true,
632650
}
633651
false

0 commit comments

Comments
 (0)