perf(state): exclude cron sessions from trigram FTS

This commit is contained in:
fangliquanflq
2026-09-02 19:56:54 +08:00
committed by kshitij
parent 57162d0cc1
commit ea65fcd980
4 changed files with 248 additions and 18 deletions
+47
View File
@@ -414,6 +414,44 @@ class SessionSchemaMixin:
exc_info=True,
)
def _migrate_trigram_cron_exclusion(self, cursor: sqlite3.Cursor) -> bool:
"""Install the cron-filtered trigram view and purge historical rows.
Legacy inline indexes remain opt-in: their content is private to the
virtual table and cannot adopt this external-content view. For an
external layout, replacing the view and triggers is cheap, but the
existing inverted index still contains cron rows until FTS5 rebuilds
from the new view. Run that rebuild under the shared cross-process
admission gate used by every startup FTS repair.
"""
if self._db_has_legacy_inline_fts(cursor):
return True
trigram_exists = self._fts_table_probe(cursor, "messages_fts_trigram")
if trigram_exists is not True:
# Let the normal ensure path create/backfill a missing optional
# trigram table. ``None`` means this runtime cannot safely inspect
# an existing one, so leave the schema version behind for retry.
return trigram_exists is False
for name in _FTS_TRIGRAM_TRIGGERS:
cursor.execute(f"DROP TRIGGER IF EXISTS {name}")
cursor.execute("DROP VIEW IF EXISTS messages_fts_trigram_src")
if not self._ensure_fts_schema(
cursor, "messages_fts_trigram", FTS_TRIGRAM_SQL
):
return False
# Always rebuild while schema_version is behind, even if the view
# already has the new predicate. A process can die after replacing the
# view but before rebuilding/stamping; view text alone cannot prove the
# old cron postings were purged.
self._run_admitted_startup_rebuild(
cursor,
lambda: cursor.execute(
"INSERT INTO messages_fts_trigram(messages_fts_trigram) "
"VALUES('rebuild')"
),
)
return True
@staticmethod
def _rebuild_fts_indexes(
@@ -1490,6 +1528,15 @@ class SessionSchemaMixin:
# rows, but clear migrated rows so future writes do not keep
# one large prompt copy per session.
self._dedupe_legacy_system_prompts(cursor)
if current_version < 29 and fts5_available:
# v29 (was v27 in the original PR; main had already reached
# v28 with column-reconciliation bumps, so a `< 27` gate would
# never fire on existing installs): cron sessions remain canonical and stay in the standard
# word index, but no longer inflate the trigram substring index.
# Rebuild once so rows indexed by older trigger/view definitions
# do not survive indefinitely as stale matches and disk usage.
if not self._migrate_trigram_cron_exclusion(cursor):
fts_migrations_complete = False
# The FTS storage layout is versioned independently of the main
# schema (see the v23 note above). Stamp the current layout so the