
# Vahemällu salvestatud AST-otsing

Vahemällu salvestatud AST-otsing on täiendav soojendatud vahemäluga režiim, mis täiendab [faktiregistrit](https://greph.inline0.dev/et/docs/indexed/ast). Selle asemel et salvestada eraldatud fakte ja parsida leitud faile uuesti, salvestab vahemälu kettale parsitud puude serialiseeritud kujud. Järgnevad päringud deserialiseerivad puud ja käivitavad vastemootori otse, jättes PHP-Parser töövoo täielikult vahele.

Vahemälule pääseb ligi alamkäsuga `greph-index ast-cache` CLI ning fassaadi meetoditega `Greph::buildAstCache()` / `Greph::searchAstCached()`. See toetab ka mitme registri ja manifestipõhist komplektiotsingut.

## Vahemälu loomine

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

Vaikimisi salvestatakse vahemälu asukohta `<root>/.greph-ast-cache/`. Kolmest registrirežiimist on vahemälu loomine tavaliselt kõige aeglasem, sest iga fail tuleb üks kord parsida.

Eduka loomise korral kuvatakse üherealine kokkuvõte:

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

Vahemällu salvestatud puude arv on tavaliselt failide arvust veidi väiksem, sest parsimisel nurjunud failid (mis jäetakse vaikselt vahele) ei saa vahemälukirjet. Kui soovite parsimisvigu näha, edastage selle asemel otsingukäsule `--strict-parse`.

## Vahemälu värskendamine

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

`refresh` käib indekseeritud juurkausta uuesti läbi, parsib muudetud failid uuesti ja kirjutab ümber ainult muutunud vahemällu salvestatud puud.

Elutsükli profiilid on samad mis muudes soojendatud režiimides:

- `static`: ära kontrolli automaatselt ajakohasust ega muuda andmeid
- `manual-refresh`: teavita aegunud olekust käsus `stats`, kuid ära värskenda otsingu ajal kunagi
- `opportunistic-refresh`: värskenda otsingu ajal ainult siis, kui muudetud failide arv jääb konfigureeritud piiridest allapoole
- `strict-stale-check`: lükka aegunud otsingud tagasi, selle asemel et neid värskendada

## Vahemälust päringute tegemine

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

Lippude kogum on identne valikuga [`ast-index search`](https://greph.inline0.dev/et/docs/indexed/ast#querying-the-index), sealhulgas valikuga `--fallback scan` puuduva vahemälu korral.

### Vahemäluotsing mitmest registrist

Mitmest soojendatud vahemälust korraga otsimiseks korrake valikut `--index-dir`:

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

### Manifestipõhised vahemälukomplektid

Kui kasutate juba nimega soojendatud komplekte, saab sama manifesti abil teha vahemällu salvestatud AST-otsingut:

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

### Plaanuri diagnostika

`--trace-plan` väljastab vahemällu salvestatud AST-plaanuri otsused asukohta `stderr`, sealhulgas:

- millistest soojendatud vahemäludest otsiti
- kas käivitati aegunud andmete värskendamise loogika
- failide arv pärast failitaseme kitsendamist
- mitu vahemällu salvestatud puud deserialiseeriti täpseks struktuurivastete leidmiseks

## Vahemälu ja faktiregister

Mõlemad režiimid kiirendavad AST-otsingut, kuid sobivad erinevat tüüpi töökoormustele.

| Aspekt | Faktide indeks (`ast-index`) | Vahemälu (`ast-cache`) |
|---|---|---|
| Mida salvestatakse | Väljavõetud faktid (väljakutsete nimed, klasside nimed, deklaratsioonid) | Serialiseeritud parsitud puud |
| Koostamise kulu | Väiksem | Suurem (parsib kõik) |
| Koostamise maht | Väiksem | Suurem |
| Päringu töövoog | Filtreeri faktide järgi, seejärel parsi ja sobita kandidaadid | Deserialiseeri puu, seejärel sobita |
| Sobib kõige paremini | Mustritele, millel on äratuntav päis (väljakutse nimi, klassi nimi) | Mustritele, mille eristav tunnus on struktuurne, mitte nimepõhine |
| Sobib kõige halvemini | Mustritele, mille päis on metamärgis | Külmadele päringutele puus, mis ei mahu enam OS-i lehevahemällu |

Praktikas annab faktide indeks kiireima külma päringu ja vahemälu kiireima sooja päringu. Kasutage seda, mis teie töökoormusega sobib, või looge mõlemad ja laske tööriistadel valida.

## Programmipõhine kasutus

```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` aktsepteerib samu `AstSearchOptions` nagu AST-i algupärane otsing ja tagastab sama kujuga `list<AstMatch>`. Ainus erinevus on see, et parsija töövoog jäetakse vahele nende failide puhul, mis on juba vahemälus. Mitme indeksi või manifestipõhise töövoo jaoks kasutage `searchAstCachedMany(...)` ja `searchAstCachedSet(...)`.

## Millal seda kasutada

Vahemällu salvestatud AST-režiim sobib, kui:

- Käivitate sama koodibaasi vastu korduvalt struktuuripäringuid.
- Varasemate käivituste kitsaskoht oli PHP-Parser (profiilides paistab see leksimisele ja parsimisele kulunud ajana).
- Teil on piisavalt kettaruumi serialiseeritud puuhoidla jaoks.

Kui päringud hõlmavad tavaliselt väikest osa koodibaasist ning vasted koonduvad äratuntavate väljakutsete või klasside nimede ümber, sobib [faktide indeks](https://greph.inline0.dev/et/docs/indexed/ast) tavaliselt paremini. Kui päringud hõlmavad laialdaselt koodibaasi, kuid saate tasuda ühekordse parsimiskulu, on vahemälu parem.
