
# Căutare AST memorată în cache

Căutarea AST memorată în cache este un mod complementar cu cache încălzit pentru [indexul de fapte](https://greph.inline0.dev/ro/docs/indexed/ast). În loc să stocheze fapte extrase și să analizeze din nou fișierele potrivite, cache-ul stochează pe disc arbori analizați serializați. Interogările ulterioare deserializa arborii și rulează direct potrivitorul, omițând complet fluxul PHP-Parser.

Cache-ul este disponibil prin subcomanda `greph-index ast-cache` CLI și metodele fațadei `Greph::buildAstCache()` / `Greph::searchAstCached()`. Permite și căutarea în mai multe indexuri și seturi susținute de manifest.

## Construirea cache-ului

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

În mod implicit, cache-ul este stocat în `<root>/.greph-ast-cache/`. Construirea cache-ului este, de regulă, cea mai lentă dintre cele trei moduri de indexare, deoarece fiecare fișier trebuie analizat o dată.

O construire reușită afișează un rezumat pe o singură linie:

```text
Built AST cache for 2547 files in .greph-ast-cache (2541 cached trees, +2541 ~0 -0 =0)
```

Numărul arborilor din cache este de obicei puțin mai mic decât numărul fișierelor, deoarece fișierele care nu pot fi analizate (și sunt omise fără notificare) nu generează o intrare în cache. Transmiteți `--strict-parse` în comanda de căutare dacă doriți să fie afișate erorile de analizare.

## Reîmprospătarea cache-ului

```bash
./vendor/bin/greph-index ast-cache refresh .
```

`refresh` parcurge din nou rădăcina indexată, analizează din nou fișierele modificate și rescrie doar arborii din cache care s-au schimbat.

Profilurile ciclului de viață sunt identice cu celelalte moduri încălzite:

- `static`: nu verifică niciodată actualitatea și nu modifică automat
- `manual-refresh`: raportează starea învechită în `stats`, dar nu reîmprospătează niciodată în timpul căutării
- `opportunistic-refresh`: reîmprospătează în timpul căutării doar când setul modificat este sub pragurile configurate
- `strict-stale-check`: respinge căutările învechite în loc să reîmprospăteze

## Interogarea cache-ului

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

Setul de opțiuni este identic cu [`ast-index search`](https://greph.inline0.dev/ro/docs/indexed/ast#querying-the-index), inclusiv `--fallback scan` pentru cache-urile lipsă.

### Căutare în mai multe cache-uri

Repetați `--index-dir` pentru a căuta în mai multe cache-uri încălzite printr-un singur apel:

```bash
./vendor/bin/greph-index ast-cache search \
  --index-dir ../wordpress/.greph-ast-cache \
  --index-dir ./.greph-ast-cache \
  --show-index-origin \
  'array($$$ITEMS)' .
```

### Seturi de cache susținute de manifest

Dacă folosiți deja seturi încălzite cu nume, același manifest poate ghida căutarea AST memorată în 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)' .
```

### Diagnosticarea planificatorului

`--trace-plan` raportează deciziile planificatorului AST memorat în cache către `stderr`, inclusiv:

- ce cache-uri încălzite au fost căutate
- dacă a rulat logica de reîmprospătare a datelor învechite
- numărul de fișiere candidate după restrângerea la nivel de fișier
- câte arbori din cache au fost deserializați pentru potrivirea structurală exactă

## Indexul de fapte vs. cache

Ambele moduri accelerează căutarea AST, dar optimizează tipuri diferite de sarcini.

| Aspect | Index de fapte (`ast-index`) | Cache (`ast-cache`) |
|---|---|---|
| Ce se stochează | Fapte extrase (nume de apeluri, nume de clase, declarații) | Arbori analizați serializați |
| Costul construirii | Mai mic | Mai mare (analizează tot) |
| Dimensiunea construirii | Mai mică | Mai mare |
| Fluxul interogării | Filtrează după fapte, apoi analizează și compară candidații | Deserializați arborele, apoi comparați |
| Potrivit pentru | Tipare cu un început recognoscibil (nume de apel, nume de clasă) | Tipare a căror caracteristică distinctivă este structurală, nu nominală |
| Cel mai puțin potrivit pentru | Tipare al căror început este o metavariabilă | Interogări la rece pe un arbore care nu mai încape în cache-ul de pagini al sistemului de operare |

În practică, indexul de fapte oferă cea mai rapidă interogare la rece, iar cache-ul oferă cea mai rapidă interogare la cald. Folosiți-l pe cel care se potrivește sarcinilor dvs. sau construiți-le pe ambele și lăsați instrumentele dvs. să aleagă.

## Utilizare programatică

```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` acceptă aceleași `AstSearchOptions` ca și căutarea AST nativă și returnează aceeași structură `list<AstMatch>`. Singura diferență este că fluxul parserului este ocolit pentru fișierele care se află deja în cache. Pentru fluxuri cu mai mulți indici sau bazate pe manifest, folosiți `searchAstCachedMany(...)` și `searchAstCachedSet(...)`.

## Când să îl folosiți

Modul AST din cache este potrivit când:

- Rulați interogări structurale repetate asupra aceleiași baze de cod.
- Blocajul în rulările anterioare a fost PHP-Parser (vizibil în profiluri ca timp petrecut în lexer și parser).
- Aveți suficient spațiu pe disc pentru stocarea arborilor serializați.

Dacă interogările dvs. vizează de obicei o mică parte a bazei de cod, iar potrivirile se concentrează în jurul unor nume de apeluri sau de clase recognoscibile, [indexul de fapte](https://greph.inline0.dev/ro/docs/indexed/ast) este de obicei o alegere mai potrivită. Dacă interogările dvs. acoperă o mare parte a bazei de cod, dar puteți suporta costul unei analize inițiale, cache-ul este alegerea mai bună.
