
# Pesquisa de AST em cache

A pesquisa de AST em cache é um modo complementar de cache aquecido ao [índice de fatos](https://greph.inline0.dev/pt/docs/indexed/ast). 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

```bash
# 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:

```text
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

```bash
./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 automaticamente
- `manual-refresh`: informa o estado obsoleto em `stats`, mas nunca atualiza durante a pesquisa
- `opportunistic-refresh`: atualiza durante a pesquisa somente quando o conjunto de alterações fica abaixo dos limites configurados
- `strict-stale-check`: rejeita pesquisas obsoletas em vez de atualizar

## Consultar o cache

```bash
./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`](https://greph.inline0.dev/pt/docs/indexed/ast#querying-the-index), incluindo `--fallback scan` para caches ausentes.

### Pesquisa em vários caches

Repita `--index-dir` para pesquisar em vários caches aquecidos em uma chamada:

```bash
./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:

```bash
./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

```php
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](https://greph.inline0.dev/pt/docs/indexed/ast) 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.
