70 lines
3.9 KiB
Markdown
70 lines
3.9 KiB
Markdown
# #86 — Optimisation globale des performances (phase 3)
|
|
|
|
> **Statut :** ✅ livré | **Zone :** backend (`indexer.py`, `mutations.py`)
|
|
> **Prérequis déjà livrés :** BUG-033 (recherche via inverted index), BUG-040 (PDF lazy),
|
|
> BUG-025 (caps regex).
|
|
|
|
## Contexte
|
|
|
|
La roadmap #86 demandait : recherche simple + tool IA via l'inverted index, indexation
|
|
incrémentale + scan différentiel au démarrage, extraction PDF/excalidraw différée et caps
|
|
CPU sur les opérations regex. Trois de ces cinq points étaient déjà couverts par des
|
|
correctifs antérieurs ; cette livraison ferme les deux points restants.
|
|
|
|
## Ce qui était déjà livré (rappel)
|
|
|
|
| Point #86 | Livré par | État |
|
|
|---|---|---|
|
|
| Recherche simple + `search_fulltext` via inverted index | BUG-033 | `search()` récupère ses candidats via l'inverted index (intersection + expansion de préfixes), repli scan pendant la construction |
|
|
| Extraction PDF différée | BUG-040 | `_scan_vault` ne lit que les métadonnées ; `enrich_pdf_texts()` extrait après index |
|
|
| Caps CPU regex | BUG-025 | `validate_regex` (longueur ≤ 500, rejet quantificateurs imbriqués), contenu tronqué à 200 kio, matchs plafonnés à 1 000 |
|
|
|
|
## Livré ici
|
|
|
|
### 1. Scan différentiel au démarrage (`backend/indexer.py`)
|
|
|
|
- `_scan_vault(..., previous_files)` : quand un snapshot `{relative_path: file_info}` est
|
|
fourni, toute entrée dont `size` **et** `modified` sont inchangés est réutilisée sans
|
|
lecture disque ni re-parse (copie du dict, tags recomptés, wikilinks ré-enregistrés
|
|
depuis le contenu caché pour reconstruire l'index de backlinks).
|
|
- `build_index()` capture le snapshot précédent avant le `clear()` et le transmet à
|
|
chaque scan de vault (via `functools.partial` pour l'executor) ; `reload_single_vault()`
|
|
fait de même pour son vault. Seuls le `os.walk` + `stat` (bon marché) tournent à
|
|
chaque passe ; le retour inclut `reused` (hits différentiels, loggé par vault).
|
|
- Premier démarrage (aucun snapshot) : comportement identique à avant.
|
|
|
|
### 2. Extraction excalidraw différée (`backend/indexer.py`)
|
|
|
|
- Le scan ne lit plus les `.excalidraw` / `.excalidraw.md` : titre dérivé du nom de
|
|
fichier, `content` vide, flag `excalidraw_text_pending` (plus de décompression
|
|
lz-string pendant le scan).
|
|
- `enrich_pdf_texts()` traite désormais les deux flags (`pdf` + `excalidraw`) via
|
|
`_read_excalidraw_indexable_text()` exécuté dans l'executor, avec notification du hook
|
|
d'index incrémental comme pour les PDF. Nom conservé pour compatibilité (tests,
|
|
`main.py`, `reload_index`, `reload_single_vault` inchangés côté appel).
|
|
- Le chemin incrémental fichier-à-fichier (`_index_single_file_sync`, watcher) reste
|
|
immédiat : un seul fichier ne justifie pas le différé.
|
|
|
|
### 3. Garde-fou taille sur `replace_in_files` (`backend/services/mutations.py`)
|
|
|
|
- Nouvelle constante `MAX_REPLACE_FILE_BYTES` (5 Mio) : tout fichier dépassant le plafond
|
|
est sauté (warning loggé) au lieu d'être lu intégralement puis balayé par le pattern
|
|
utilisateur. Complète les caps BUG-025 (qui couvrent la recherche, pas le remplacement
|
|
qui opère sur le contenu disque complet par nature).
|
|
|
|
## Tests
|
|
|
|
`tests/test_perf_phase3.py` (9 tests) : différé excalidraw au scan (`.excalidraw` +
|
|
`.excalidraw.md`), remplissage par l'enrichissement, `reused == 0` au premier scan,
|
|
réutilisation à l'identique, re-parse du fichier modifié, ajout/suppression, skip
|
|
`replace` sur fichier surdimensionné + cas passant nominal.
|
|
|
|
## Limites connues
|
|
|
|
- Pas de persistance disque de l'index : le différentiel joue sur les rebuilds dans le
|
|
même processus (`reload_index`, `reload_single_vault`), pas entre deux redémarrages
|
|
(persistance = #85, phase 2).
|
|
- La comparaison `size + mtime` ne détecte pas une modification qui conserverait taille
|
|
et mtime à la milliseconde près (cas pathologique, le watcher temps réel couvre les
|
|
modifications en cours d'exécution).
|