
# Välimuistissa oleva AST-haku

Välimuistissa oleva AST-haku täydentää lämpimän välimuistin tilana [faktaindeksiä](https://greph.inline0.dev/fi/docs/indexed/ast). Poimittujen faktojen tallentamisen ja osumien tiedostojen uudelleenjäsentämisen sijaan välimuisti tallentaa jäsennetyt puut sarjoitettuna levylle. Seuraavissa kyselyissä puut palautetaan sarjoitetusta muodosta, ja hakusovitin käsittelee ne suoraan, jolloin PHP-Parser-työnkulku jää kokonaan väliin.

Välimuisti on käytettävissä alikomennolla `greph-index ast-cache` CLI sekä julkisivun metodeilla `Greph::buildAstCache()` / `Greph::searchAstCached()`. Se tukee myös hakua useasta indeksistä ja manifestiin perustuvista joukoista.

## Välimuistin rakentaminen

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

Välimuisti tallennetaan oletusarvoisesti polkuun `<root>/.greph-ast-cache/`. Välimuistin rakentaminen on yleensä kolmesta indeksointitilasta hitain, koska jokainen tiedosto on jäsennettävä kerran.

Onnistuneesta rakentamisesta tulostetaan yksirivinen yhteenveto:

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

Välimuistiin tallennettujen puiden määrä on yleensä hieman tiedostomäärää pienempi, koska jäsennysvirheen aiheuttaneet (ja hiljaisesti ohitetut) tiedostot eivät tuota välimuistimerkintää. Anna `--strict-parse` hakukomennossa, jos haluat tuoda jäsennysvirheet näkyviin.

## Välimuistin päivittäminen

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

`refresh` käy indeksoidun juurihakemiston uudelleen läpi, jäsentää muuttuneet tiedostot uudelleen ja kirjoittaa uudelleen vain muuttuneet välimuistipuut.

Elinkaariprofiilit vastaavat muita lämpimiä tiloja:

- `static`: älä koskaan tarkista ajantasaisuutta tai muuta automaattisesti
- `manual-refresh`: ilmoita vanhentuneesta tilasta komennossa `stats`, mutta älä koskaan päivitä haun aikana
- `opportunistic-refresh`: päivitä haun aikana vain, jos muutosten määrä alittaa määritetyt kynnysarvot
- `strict-stale-check`: hylkää vanhentuneet haut päivittämisen sijaan

## Välimuistin kyselyt

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

Valitsimet ovat samat kuin komennossa [`ast-index search`](https://greph.inline0.dev/fi/docs/indexed/ast#querying-the-index), mukaan lukien puuttuvien välimuistien `--fallback scan`-valitsin.

### Haku useasta indeksivälimuistista

Hae useasta lämpimästä välimuistista yhdellä kutsulla toistamalla `--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)' .
```

### Manifestiin perustuvat välimuistijoukot

Jos käytät jo nimettyjä lämpimiä joukkoja, sama manifesti voi ohjata välimuistissa olevaa AST-hakua:

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

### Suunnittelijan diagnostiikka

`--trace-plan` raportoi välimuistissa olevan AST-suunnittelijan päätökset kohteeseen `stderr`, mukaan lukien:

- haetut lämpimät välimuistit
- suoritettiinko vanhentuneen välimuistin päivityslogiikka
- ehdokastiedostojen määrät tiedostotason rajauksen jälkeen
- täsmällistä rakenteellista hakua varten sarjoitetusta muodosta palautettujen puiden määrä

## Välimuisti vai faktaindeksi

Molemmat tilat nopeuttavat AST-hakua, mutta ne on optimoitu erilaisiin työkuormiin.

| Ominaisuus | Faktaindeksi (`ast-index`) | Välimuisti (`ast-cache`) |
|---|---|---|
| Mitä tallennetaan | Poimitut faktat (kutsujen nimet, luokkien nimet, määrittelyt) | Sarjoitetut jäsennetyt puut |
| Rakennuskustannus | Pienempi | Suurempi (jäsentää kaiken) |
| Rakennuskoko | Pienempi | Suurempi |
| Kyselypolku | Suodata faktoilla, jäsennä sitten ehdokkaat ja etsi osumat | Sarjoita puu ja etsi sitten osumat |
| Sopii parhaiten | Kuvioille, joissa on tunnistettava alkuosa (kutsun nimi, luokan nimi) | Kuvioille, joiden erottava piirre on rakenteellinen eikä nimellinen |
| Sopii huonoiten | Kuvioille, joiden alkuosa on metamuuttuja | Kylmille kyselyille puussa, joka ei enää mahdu käyttöjärjestelmän sivuvälimuistiin |

Käytännössä faktaindeksillä kylmä kysely on nopein ja välimuistilla lämmin kysely. Valitse työkuormaasi sopiva vaihtoehto tai rakenna molemmat ja anna työkalujesi valita.

## Käyttö ohjelmallisesti

```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` hyväksyy saman `AstSearchOptions` kuin natiivi AST-haku ja palauttaa saman `list<AstMatch>`-rakenteen. Ainoa ero on, että jäsenninputki ohitetaan välimuistissa jo olevien tiedostojen kohdalla. Käytä usean indeksin tai manifestiin perustuvissa työnkuluissa `searchAstCachedMany(...)` ja `searchAstCachedSet(...)`.

## Milloin sitä kannattaa käyttää

Välimuistiin tallennettu AST-tila sopii, kun:

- Teet toistuvasti rakenteellisia kyselyjä samaan koodikantaan.
- Aiemmilla suorituksilla pullonkaulana oli PHP-Parser (profiileissa näkyy leksikossa ja jäsentimessä kuluvana aikana).
- Sinulla on riittävästi levytilaa sarjoitetun puuvaraston tallentamiseen.

Jos kyselysi osuvat yleensä vain pieneen osaan koodikantaa ja osumat keskittyvät tunnistettaviin kutsujen tai luokkien nimiin, [faktaindeksi](https://greph.inline0.dev/fi/docs/indexed/ast) sopii yleensä paremmin. Jos kyselysi kattavat laajasti koodikantaa mutta voit maksaa kertaluonteisen jäsennyskustannuksen, välimuisti on parempi.
