Cachelagret AST-søgning
Cachelagret AST-søgning er en supplerende tilstand med opvarmet cache, der bruges sammen med faktaindekset. I stedet for at gemme udtrukne fakta og parse matchede filer på ny gemmer cachen serialiserede parsetræer på disken. Efterfølgende forespørgsler deserialiserer træerne og kører matcheren direkte, så hele PHP-Parser-forløbet springes over.
Cachen er tilgængelig via underkommandoen greph-index ast-cache CLI og facademetoderne Greph::buildAstCache() / Greph::searchAstCached(). Den understøtter også søgning på tværs af flere indekser og manifestbaserede sæt.
Oprettelse af cachen
# 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
Cachen gemmes som standard på <root>/.greph-ast-cache/. Cacheoprettelse er typisk den langsomste af de tre indekstilstande, fordi hver fil skal parses én gang.
En vellykket oprettelse udskriver en oversigt på én linje:
Built AST cache for 2547 files in .greph-ast-cache (2541 cached trees, +2541 ~0 -0 =0)
Antallet af cachelagrede træer er som regel lidt lavere end antallet af filer, fordi filer, der ikke kan parses (og derfor springes over uden besked), ikke får en cachepost. Angiv --strict-parse i søgekommandoen, hvis parsefejl skal vises.
Opdatering af cachen
./vendor/bin/greph-index ast-cache refresh .
refresh gennemgår den indekserede rod igen, parser ændrede filer på ny og omskriver kun de cachelagrede træer, der er ændret.
Livscyklusprofilerne svarer til profilerne i de andre tilstande med opvarmede indekser:
static: kontrollér aldrig automatisk, om dataene er aktuelle, og foretag aldrig automatiske ændringermanual-refresh: rapportér forældet tilstand istats, men opdatér aldrig under søgningopportunistic-refresh: opdatér under søgning, kun når ændringerne holder sig under de konfigurerede grænserstrict-stale-check: afvis forældede søgninger i stedet for at opdatere
Forespørgsler i cachen
./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
Flagene er identiske med dem i ast-index search, herunder --fallback scan til manglende cacher.
Cache-søgning på tværs af flere indekser
Gentag --index-dir for at søge i flere opvarmede cacher i én omgang:
./vendor/bin/greph-index ast-cache search \
--index-dir ../wordpress/.greph-ast-cache \
--index-dir ./.greph-ast-cache \
--show-index-origin \
'array($$$ITEMS)' .
Manifestbaserede cachesæt
Hvis du allerede bruger navngivne sæt med opvarmede indekser, kan det samme manifest bruges til cachelagret AST-søgning:
./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)' .
Diagnostik fra planlæggeren
--trace-plan rapporterer planlæggerens beslutninger for den cachelagrede AST til stderr, herunder:
- hvilke opvarmede cacher der blev søgt i
- om logikken til opdatering af forældede data blev kørt
- antal kandidatfiler efter indsnævring på filniveau
- hvor mange cachelagrede træer der blev deserialiseret til præcis strukturel matching
Cache kontra faktaindeks
Begge tilstande gør AST-søgning hurtigere, men optimerer til forskellige typer arbejde.
| Aspekt | Faktindeks (ast-index) |
Cache (ast-cache) |
|---|---|---|
| Hvad gemmes | Udtrukne fakta (kaldnavne, klassenavne, deklarationer) | Serialiserede parsede træer |
| Byggeomkostning | Lavere | Højere (parser alt) |
| Størrelse | Mindre | Større |
| Forespørgselsforløb | Filtrér efter fakta, og parse og match derefter kandidaterne | Deserialisér træet, og match derefter |
| Bedst til | Mønstre med et genkendeligt hoved (kaldnavn, klassenavn) | Mønstre, hvis særkende er strukturelt, ikke navnebaseret |
| Dårligst til | Mønstre, hvis hoved er en metavariabel | Kolde forespørgsler på et træ, der ikke længere passer i OS'ets sidecache |
I praksis har faktindekset den hurtigste kolde forespørgsel, mens cachen har den hurtigste varme forespørgsel. Brug den løsning, der passer til din arbejdsbelastning, eller byg begge, og lad dine værktøjer vælge.
Programmatisk brug
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 accepterer de samme AstSearchOptions som indbygget AST-søgning og returnerer samme list<AstMatch>-struktur. Den eneste forskel er, at parserforløbet springes over for filer, der allerede er i cachen. Brug searchAstCachedMany(...) og searchAstCachedSet(...) til forløb med flere indeks eller manifestunderstøttelse.
Hvornår skal den bruges
Cached AST-tilstand er det rette værktøj, når:
- Du kører gentagne strukturelle forespørgsler mod den samme kodebase.
- Flaskehalsen i dine tidligere kørsler var PHP-Parser (synligt i profiler som tid brugt i lexer og parser).
- Du har diskplads nok til det serialiserede trælager.
Hvis dine forespørgsler normalt rammer en lille del af kodebasen, og resultaterne samler sig omkring genkendelige kaldnavne eller klassenavne, er faktindekset som regel et bedre valg. Hvis dine forespørgsler dækker store dele af kodebasen, men du kan betale engangsomkostningen ved parsing, er cachen bedst.