Recherche AST en cache
La recherche AST en cache complète l’index de faits par un mode avec cache préchauffé. Au lieu de stocker des faits extraits et de réanalyser les fichiers correspondants, le cache stocke sur disque des arbres analysés sérialisés. Les requêtes suivantes désérialisent les arbres et exécutent directement le moteur de correspondance, en ignorant entièrement le processus PHP-Parser.
Le cache est accessible avec la sous-commande greph-index ast-cache CLI et les méthodes de façade Greph::buildAstCache() / Greph::searchAstCached(). Il prend également en charge la recherche multi-index et celle sur des ensembles définis par manifeste.
Création du cache
# Full build at the current directory
./vendor/bin/greph-index ast-cache build .
# Use a non-default cache directory
./vendor/bin/greph-index ast-cache build . --index-dir /tmp/greph-ast-cache
# Build a cache that may refresh automatically for small changes
./vendor/bin/greph-index ast-cache build . \
--lifecycle opportunistic-refresh \
--auto-refresh-max-files 32 \
--auto-refresh-max-bytes 1048576
Par défaut, le cache est stocké dans <root>/.greph-ast-cache/. La création du cache est généralement la plus lente des trois méthodes d’indexation, car chaque fichier doit être analysé une fois.
Une création réussie affiche un résumé sur une seule ligne :
Built AST cache for 2547 files in .greph-ast-cache (2541 cached trees, +2541 ~0 -0 =0)
Le nombre d’arbres en cache est généralement légèrement inférieur au nombre de fichiers, car les fichiers dont l’analyse échoue (et qui sont ignorés sans avertissement) ne génèrent aucune entrée de cache. Passez --strict-parse lors de la recherche pour afficher les erreurs d’analyse.
Actualisation du cache
./vendor/bin/greph-index ast-cache refresh .
refresh reparcourt la racine indexée, analyse à nouveau les fichiers modifiés et ne réécrit que les arbres en cache qui ont changé.
Les profils de cycle de vie sont les mêmes que pour les autres modes préchauffés :
static: ne vérifie jamais la fraîcheur et n’effectue aucune modification automatiquemanual-refresh: signale les données obsolètes dansstats, mais n’actualise jamais le cache pendant la rechercheopportunistic-refresh: actualise le cache pendant la recherche uniquement si l’ensemble des fichiers modifiés reste sous les seuils configurésstrict-stale-check: refuse les recherches sur des données obsolètes au lieu d’actualiser le cache
Interrogation du cache
./vendor/bin/greph-index ast-cache search 'new $CLASS()' src
./vendor/bin/greph-index ast-cache search '$obj->$method($$$ARGS)' src
./vendor/bin/greph-index ast-cache search --json 'array($$$ITEMS)' src
./vendor/bin/greph-index ast-cache search --fallback scan 'new $CLASS()' src
./vendor/bin/greph-index ast-cache search --trace-plan 'array($$$ITEMS)' src
Les options sont identiques à celles de ast-index search, y compris --fallback scan pour les caches manquants.
Recherche dans plusieurs caches
Répétez --index-dir pour rechercher dans plusieurs caches préchauffés en une seule commande :
./vendor/bin/greph-index ast-cache search \
--index-dir ../wordpress/.greph-ast-cache \
--index-dir ./.greph-ast-cache \
--show-index-origin \
'array($$$ITEMS)' .
Ensembles de caches définis par manifeste
Si vous utilisez déjà des ensembles préchauffés nommés, le même manifeste peut piloter la recherche AST en cache :
./vendor/bin/greph-index set build --mode ast-cache
./vendor/bin/greph-index set stats --mode ast-cache --dry-refresh
./vendor/bin/greph-index set search --mode ast-cache --show-index-origin 'array($$$ITEMS)' .
Diagnostics du planificateur
--trace-plan indique les décisions du planificateur AST mis en cache dans stderr, notamment :
- les caches préchauffés parcourus
- l’exécution ou non de l’actualisation des données obsolètes
- le nombre de fichiers candidats après la réduction au niveau des fichiers
- le nombre d’arbres en cache désérialisés pour la correspondance structurelle exacte
Cache ou index de faits
Les deux modes accélèrent la recherche AST, mais sont optimisés pour des types de charge de travail différents.
| Aspect | Index de faits (ast-index) |
Cache (ast-cache) |
|---|---|---|
| Données stockées | Faits extraits (noms d'appels, noms de classes, déclarations) | Arbres analysés sérialisés |
| Coût de création | Plus faible | Plus élevé (analyse tout) |
| Taille créée | Plus petite | Plus grande |
| Parcours de requête | Filtrer par faits, puis analyser et faire correspondre les candidats | Désérialiser l'arbre, puis faire les correspondances |
| Idéal pour | Les motifs avec un en-tête reconnaissable (nom d'appel, nom de classe) | Les motifs dont le trait distinctif est structurel plutôt que nominal |
| À éviter pour | Les motifs dont l'en-tête est une métavariable | Les requêtes à froid sur un arbre qui ne tient plus dans le cache de pages du système d'exploitation |
En pratique, l'index de faits offre les requêtes à froid les plus rapides, et le cache les requêtes à chaud les plus rapides. Choisissez celui qui convient à votre charge de travail, ou créez les deux et laissez vos outils décider.
Utilisation par programmation
use Greph\Greph;
use Greph\Ast\AstSearchOptions;
use Greph\Index\IndexLifecycleProfile;
Greph::buildAstCache('.', lifecycle: IndexLifecycleProfile::Static);
$matches = Greph::searchAstCached(
'array($$$ITEMS)',
'src',
new AstSearchOptions(jobs: 4, tracePlan: true),
);
searchAstCached accepte les mêmes AstSearchOptions que la recherche AST native et renvoie la même structure list<AstMatch>. La seule différence est que le pipeline d'analyse est ignoré pour les fichiers déjà présents dans le cache. Pour les flux multi-index ou reposant sur un manifeste, utilisez searchAstCachedMany(...) et searchAstCachedSet(...).
Quand l’utiliser
Le mode AST mis en cache est adapté lorsque :
- Vous exécutez des requêtes structurelles répétées sur la même base de code.
- Le goulot d'étranglement de vos exécutions précédentes était PHP-Parser (visible dans les profils sous forme de temps passé dans l'analyse lexicale et syntaxique).
- Vous pouvez consacrer de l'espace disque au stockage de l'arbre sérialisé.
Si vos requêtes portent généralement sur une petite partie de la base de code et que les correspondances se concentrent autour de noms d'appels ou de classes reconnaissables, l'index de faits convient généralement mieux. Si vos requêtes couvrent une grande partie de la base de code et que vous pouvez assumer un coût d'analyse initial, le cache est plus avantageux.