
# Kešota AST meklēšana

Kešota AST meklēšana ir papildinošs uzsildītās kešatmiņas režīms līdzās [faktu indeksam](https://greph.inline0.dev/lv/docs/indexed/ast). Tā vietā, lai saglabātu izgūtos faktus un atkārtoti parsētu atbilstošos failus, kešatmiņā diskā tiek glabāti serializēti parsētie koki. Turpmākajos vaicājumos koki tiek deserializēti un atbilstības meklētājs tiek palaists tieši, pilnībā izlaižot PHP-Parser konveijeru.

Kešatmiņa ir pieejama apakškomandā `greph-index ast-cache` CLI un fasādes metodēs `Greph::buildAstCache()` / `Greph::searchAstCached()`. Tā atbalsta arī vairāku indeksu un uz manifestiem balstītu kopu meklēšanu.

## Kešatmiņas izveide

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

Pēc noklusējuma kešatmiņa tiek glabāta mapē `<root>/.greph-ast-cache/`. Kešatmiņas izveide parasti ir lēnākā no trim indeksēšanas režīmiem, jo katrs fails ir jāparsē vienu reizi.

Pēc veiksmīgas izveides tiek parādīts kopsavilkums vienā rindā:

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

Kešoto koku skaits parasti ir nedaudz mazāks nekā failu skaits, jo faili, kurus neizdodas parsēt un kuri tiek klusi izlaisti, kešā netiek ierakstīti. Meklēšanas komandai pievienojiet `--strict-parse`, ja vēlaties, lai parsēšanas kļūdas tiktu parādītas.

## Kešatmiņas atsvaidzināšana

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

`refresh` atkārtoti pārstaigā indeksēto saknes direktoriju, parsē izmainītos failus no jauna un pārraksta tikai tos kešotos kokus, kas ir mainījušies.

Dzīves cikla profili atbilst citiem režīmiem ar iesildītu kešatmiņu:

- `static`: nekad automātiski nepārbauda, vai dati ir aktuāli, un neveic izmaiņas
- `manual-refresh`: ziņo par novecojušiem datiem laukā `stats`, bet meklēšanas laikā nekad neatsvaidzina
- `opportunistic-refresh`: meklēšanas laikā atsvaidzina tikai tad, ja izmainīto failu skaits nepārsniedz konfigurētos sliekšņus
- `strict-stale-check`: noraida novecojušus meklēšanas pieprasījumus, nevis atsvaidzina datus

## Vaicājumi kešatmiņai

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

Karodziņu kopa ir identiska [`ast-index search`](https://greph.inline0.dev/lv/docs/indexed/ast#querying-the-index), tostarp `--fallback scan` trūkstošām kešatmiņām.

### Meklēšana vairākos indeksos kešatmiņā

Atkārtojiet `--index-dir`, lai vienā izsaukumā meklētu vairākās kešatmiņās ar iesildītiem datiem:

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

### Kešatmiņas kopas, kuru pamatā ir manifests

Ja jau uzturat nosauktas kopas ar iesildītiem datiem, to pašu manifestu var izmantot kešotai AST meklēšanai:

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

### Plānotāja diagnostika

`--trace-plan` nosūta kešotā AST plānotāja lēmumus uz `stderr`, tostarp:

- kurās kešatmiņās ar iesildītiem datiem tika meklēts
- vai tika izpildīta novecojušu datu atsvaidzināšanas loģika
- kandidātfailu skaits pēc failu līmeņa filtrēšanas
- cik kešoto koku tika deserializēti precīzai strukturālajai salīdzināšanai

## Kešatmiņa un faktu indekss

Abi režīmi paātrina AST meklēšanu, taču ir optimizēti atšķirīgiem darba veidiem.

| Aspekts | Faktu indekss (`ast-index`) | Kešatmiņa (`ast-cache`) |
|---|---|---|
| Kas tiek glabāts | Izgūtie fakti (izsaukumu nosaukumi, klašu nosaukumi, deklarācijas) | Serializēti parsēti koki |
| Izveides izmaksas | Zemākas | Augstākas (tiek parsēts viss) |
| Izveides apjoms | Mazāks | Lielāks |
| Vaicājuma izpilde | Filtrē pēc faktiem, pēc tam parsē un salīdzina kandidātus | Deserializē koku, pēc tam to salīdzina |
| Vispiemērotākais | Rakstiem ar atpazīstamu sākumu (izsaukuma nosaukumu, klases nosaukumu) | Rakstiem, kuru atšķirīgā iezīme ir strukturāla, nevis saistīta ar nosaukumu |
| Vismazāk piemērots | Rakstiem, kuru sākums ir metavariabls | Vaicājumiem ar neiesildītu kešatmiņu, ja koks vairs neietilpst OS lapu kešatmiņā |

Praksē faktu indekss nodrošina ātrāko vaicājumu ar neiesildītu kešatmiņu, bet kešatmiņa — ātrāko vaicājumu ar iesildītu kešatmiņu. Izmantojiet to, kas labāk atbilst jūsu darba slodzei, vai izveidojiet abus un ļaujiet rīkiem izvēlēties.

## Izmantošana programmā

```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` pieņem tādus pašus `AstSearchOptions` kā vietējā AST meklēšana un atgriež tādas pašas formas `list<AstMatch>`. Vienīgā atšķirība ir tā, ka failiem, kuri jau atrodas kešatmiņā, parsētāja konveijers tiek izlaists. Vairāku indeksu vai manifestā balstītām darbplūsmām izmantojiet `searchAstCachedMany(...)` un `searchAstCachedSet(...)`.

## Kad to izmantot

AST režīms ar kešatmiņu ir piemērots, ja:

- Atkārtoti veicat strukturālus vaicājumus tai pašai koda bāzei.
- Iepriekšējās izpildēs šaurā vieta bija PHP-Parser (profilos redzams laiks, kas pavadīts leksiskajā un sintaktiskajā analīzē).
- Varat atvēlēt vietu diskā serializēto koku krātuvei.

Ja vaicājumi parasti skar nelielu koda bāzes daļu un atbilstības galvenokārt saistītas ar atpazīstamiem izsaukumu vai klašu nosaukumiem, parasti piemērotāks ir [faktu indekss](https://greph.inline0.dev/lv/docs/indexed/ast). Ja vaicājumi aptver plašu koda bāzes daļu, bet varat samaksāt vienreizējās parsēšanas izmaksas, labāk noderēs kešatmiņa.
