Pesquisa de AST em cache
A pesquisa de AST em cache é um modo complementar de cache aquecido ao índice de fatos. Em vez de armazenar fatos extraídos e analisar novamente os arquivos correspondentes, o cache armazena árvores analisadas serializadas em disco. Nas consultas seguintes, as árvores são desserializadas e o mecanismo de correspondência é executado diretamente, ignorando completamente o pipeline PHP-Parser.
O cache está disponível pelo subcomando greph-index ast-cache CLI e pelos métodos de fachada Greph::buildAstCache() / Greph::searchAstCached(). Ele também oferece pesquisa em vários índices e conjuntos respaldados por manifestos.
Criar o 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
Por padrão, o cache é armazenado em <root>/.greph-ast-cache/. A criação do cache costuma ser a mais lenta entre os três modos de indexação, pois cada arquivo precisa ser analisado uma vez.
Uma criação bem-sucedida exibe um resumo de uma linha:
Built AST cache for 2547 files in .greph-ast-cache (2541 cached trees, +2541 ~0 -0 =0)
A quantidade de árvores em cache costuma ser um pouco menor que a quantidade de arquivos porque arquivos cuja análise falha (e são ignorados silenciosamente) não geram uma entrada no cache. Passe --strict-parse no comando de pesquisa se quiser que os erros de análise sejam exibidos.
Atualizar o cache
./vendor/bin/greph-index ast-cache refresh .
refresh percorre novamente a raiz indexada, analisa outra vez os arquivos alterados e regrava apenas as árvores em cache que mudaram.
Os perfis de ciclo de vida são iguais aos dos outros modos aquecidos:
static: nunca verifica a atualidade nem modifica automaticamentemanual-refresh: informa o estado obsoleto emstats, mas nunca atualiza durante a pesquisaopportunistic-refresh: atualiza durante a pesquisa somente quando o conjunto de alterações fica abaixo dos limites configuradosstrict-stale-check: rejeita pesquisas obsoletas em vez de atualizar
Consultar o 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
O conjunto de opções é idêntico ao de ast-index search, incluindo --fallback scan para caches ausentes.
Pesquisa em vários caches
Repita --index-dir para pesquisar em vários caches aquecidos em uma chamada:
./vendor/bin/greph-index ast-cache search \
--index-dir ../wordpress/.greph-ast-cache \
--index-dir ./.greph-ast-cache \
--show-index-origin \
'array($$$ITEMS)' .
Conjuntos de caches respaldados por manifesto
Se você já mantém conjuntos aquecidos nomeados, o mesmo manifesto pode executar a pesquisa de AST em 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)' .
Diagnósticos do planejador
--trace-plan informa as decisões do planejador de AST em cache em stderr, incluindo:
- quais caches aquecidos foram pesquisados
- se a lógica de atualização de itens obsoletos foi executada
- quantidades de arquivos candidatos após a redução no nível dos arquivos
- quantas árvores em cache foram desserializadas para a correspondência estrutural exata
Cache versus índice de fatos
Ambos os modos aceleram a pesquisa de AST, mas são otimizados para tipos diferentes de trabalho.
| Aspecto | Índice de fatos (ast-index) |
Cache (ast-cache) |
|---|---|---|
| O que é armazenado | Fatos extraídos (nomes de chamadas, nomes de classes, declarações) | Árvores analisadas serializadas |
| Custo de criação | Menor | Maior (analisa tudo) |
| Tamanho da criação | Menor | Maior |
| Caminho da consulta | Filtra pelos fatos e, em seguida, analisa e compara os candidatos | Desserializa a árvore e, em seguida, faz a comparação |
| Ideal para | Padrões com um início reconhecível (nome de chamada, nome de classe) | Padrões cujo recurso distintivo é estrutural, não nominal |
| Pior para | Padrões cujo início é uma metavariável | Consultas frias em uma árvore que já não cabe no cache de páginas do SO |
Na prática, o índice de fatos oferece a consulta fria mais rápida, e o cache, a consulta aquecida mais rápida. Use o que melhor se adaptar à sua carga de trabalho ou crie ambos e deixe suas ferramentas escolherem.
Uso programático
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 aceita o mesmo AstSearchOptions da pesquisa AST nativa e retorna a mesma estrutura de list<AstMatch>. A única diferença é que o pipeline do analisador é ignorado para arquivos que já estão no cache. Para fluxos com vários índices ou baseados em manifestos, use searchAstCachedMany(...) e searchAstCachedSet(...).
Quando usar
O modo AST em cache é a ferramenta certa quando:
- Você executa consultas estruturais repetidas na mesma base de código.
- O gargalo nas execuções anteriores era PHP-Parser (visível nos perfis como tempo gasto no lexer e no analisador).
- Você pode reservar espaço em disco para o armazenamento da árvore serializada.
Se suas consultas costumam abranger uma pequena parte da base de código e as correspondências se concentram em nomes de chamadas ou classes reconhecíveis, o índice de fatos costuma ser mais adequado. Se suas consultas abrangem boa parte da base de código e você pode pagar o custo único da análise, o cache é melhor.