
# Vyhľadávanie v AST s vyrovnávacou pamäťou

Vyhľadávanie v AST s vyrovnávacou pamäťou dopĺňa režim [indexu faktov](https://greph.inline0.dev/sk/docs/indexed/ast) ako režim so zahriatou vyrovnávacou pamäťou. Namiesto ukladania extrahovaných faktov a opätovného parsovania zodpovedajúcich súborov sa na disk ukladajú serializované parsované stromy. Pri ďalších dopytoch sa stromy deserializujú a porovnávač sa spustí priamo nad nimi, pričom sa úplne preskočí proces PHP-Parser.

Vyrovnávacia pamäť je dostupná cez podpríkaz `greph-index ast-cache` CLI a metódy fasády `Greph::buildAstCache()` / `Greph::searchAstCached()`. Podporuje aj vyhľadávanie vo viacerých indexoch a súpravách založených na manifeste.

## Zostavenie vyrovnávacej pamäte

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

Vyrovnávacia pamäť sa predvolene ukladá do `<root>/.greph-ast-cache/`. Jej zostavenie zvyčajne trvá najdlhšie z troch režimov indexovania, pretože každý súbor treba raz parsovať.

Úspešné zostavenie vypíše súhrn v jednom riadku:

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

Počet stromov vo vyrovnávacej pamäti býva o niečo nižší než počet súborov, pretože súbory, ktoré sa nepodarí parsovať (a potichu sa preskočia), nevytvoria položku vo vyrovnávacej pamäti. Ak chcete zobraziť chyby parsovania, zadajte pri vyhľadávaní `--strict-parse`.

## Obnovenie vyrovnávacej pamäte

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

`refresh` znova prejde indexovaný koreňový adresár, opätovne spracuje zmenené súbory a prepíše iba zmenené stromy vo vyrovnávacej pamäti.

Profily životného cyklu zodpovedajú ostatným zahriatym režimom:

- `static`: nikdy automaticky nekontrolovať aktuálnosť ani nič nemeniť
- `manual-refresh`: uvádzať zastaraný stav v `stats`, ale počas vyhľadávania nikdy neobnovovať
- `opportunistic-refresh`: obnovovať počas vyhľadávania iba vtedy, keď je množina zmien pod nakonfigurovanými limitmi
- `strict-stale-check`: odmietnuť zastarané vyhľadávania namiesto obnovovania

## Vyhľadávanie v 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
```

Množina príznakov je totožná s [`ast-index search`](https://greph.inline0.dev/sk/docs/indexed/ast#querying-the-index) vrátane `--fallback scan` pre chýbajúce cache.

### Vyhľadávanie vo viacerých indexoch cache

Opakujte `--index-dir` a vyhľadajte viacero prednačítaných cache jedným volaním:

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

### Množiny cache podložené manifestom

Ak už uchovávate pomenované prednačítané množiny, ten istý manifest môže riadiť vyhľadávanie v cache AST:

```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)' .
```

### Diagnostika plánovača

`--trace-plan` odovzdáva rozhodnutia plánovača cache AST do `stderr` vrátane:

- v ktorých prednačítaných cache sa vyhľadávalo
- či sa spustila logika obnovy zastaraných údajov
- počtu kandidátnych súborov po zúžení na úrovni súborov
- počtu deserializovaných stromov z cache na presné štrukturálne porovnanie

## Cache verzus index faktov

Oba režimy zrýchľujú vyhľadávanie v AST, ale sú optimalizované pre odlišné typy úloh.

| Aspekt | Index faktov (`ast-index`) | Cache (`ast-cache`) |
|---|---|---|
| Čo sa ukladá | Extrahované fakty (názvy volaní, názvy tried, deklarácie) | Serializované parsované stromy |
| Náklady na zostavenie | Nižšie | Vyššie (parsuje sa všetko) |
| Veľkosť po zostavení | Menšia | Väčšia |
| Postup pri vyhľadávaní | Filtrovanie podľa faktov, potom parsovanie a porovnanie kandidátov | Deserializácia stromu, potom porovnanie |
| Najvhodnejšie pre | Vzory s rozpoznateľnou hlavičkou (názov volania, názov triedy) | Vzory, ktorých rozlišovacia vlastnosť je štrukturálna, nie názvová |
| Najhoršie pre | Vzory, ktorých hlavička je metavariabilná | Studené vyhľadávania v strome, ktorý sa už nezmestí do vyrovnávacej pamäte stránok OS |

V praxi má index faktov najrýchlejšie studené vyhľadávanie a cache najrýchlejšie prednačítané vyhľadávanie. Použite ten, ktorý vyhovuje vašej záťaži, alebo zostavte oba a nechajte svoje nástroje vybrať.

## Programové použitie

```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` prijíma rovnaké `AstSearchOptions` ako natívne vyhľadávanie v AST a vracia výsledok v rovnakom tvare `list<AstMatch>`. Jediným rozdielom je, že pri súboroch, ktoré už sú v cache, sa obíde proces parsovania. Pri práci s viacerými indexmi alebo manifestom použite `searchAstCachedMany(...)` a `searchAstCachedSet(...)`.

## Kedy ho použiť

Režim AST s cache je vhodný, keď:

- Opakovane spúšťate štrukturálne vyhľadávania v tej istej kódovej základni.
- Úzkym miestom pri predchádzajúcich spusteniach bolo PHP-Parser (v profiloch je viditeľný čas strávený v lexikálnom a syntaktickom analyzátore).
- Môžete si dovoliť miesto na disku pre úložisko serializovaných stromov.

Ak vaše vyhľadávania zvyčajne zasahujú len malú časť kódovej základne a zhody sa sústreďujú okolo rozpoznateľných názvov volaní alebo tried, zvyčajne sa viac hodí [index faktov](https://greph.inline0.dev/sk/docs/indexed/ast). Ak vaše vyhľadávania pokrývajú širokú časť kódovej základne, ale môžete zaplatiť jednorazové náklady na parsovanie, vyhráva cache.
