Hoppa till innehåll

Cachad AST-sökning

Cachad AST-sökning är ett kompletterande läge med uppvärmd cache som fungerar tillsammans med faktindexet. I stället för att lagra extraherade fakta och tolka matchande filer på nytt lagrar cachen serialiserade, tolkade träd på disk. Efterföljande frågor avserialiserar träden och kör matcharen direkt, så att hela PHP-Parser-processen hoppas över.

Cachen exponeras via underkommandot greph-index ast-cache CLI och fasadmetoderna Greph::buildAstCache() / Greph::searchAstCached(). Den stöder även sökning med flera index och manifestbaserade uppsättningar.

Bygga cachen

Shell
# 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

Som standard lagras cachen i <root>/.greph-ast-cache/. Cachebyggen är vanligtvis de långsammaste av de tre indexlägena eftersom varje fil måste tolkas en gång.

Ett lyckat bygge skriver ut en sammanfattning på en rad:

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

Antalet cachade träd är vanligtvis något lägre än antalet filer, eftersom filer som inte kan tolkas (och därför hoppas över utan meddelande) inte skapar någon cachepost. Ange --strict-parse i sökkommandot om du vill att tolkningsfel ska visas.

Uppdatera cachen

Shell
./vendor/bin/greph-index ast-cache refresh .

refresh går igenom den indexerade roten på nytt, tolkar ändrade filer igen och skriver endast om de cachade träd som har ändrats.

Livscykelprofilerna motsvarar de andra uppvärmda lägena:

  • static: kontrollera aldrig aktualiteten eller ändra automatiskt
  • manual-refresh: rapportera inaktuellt tillstånd i stats, men uppdatera aldrig under sökning
  • opportunistic-refresh: uppdatera under sökning endast om mängden ändrade filer ligger under de konfigurerade tröskelvärdena
  • strict-stale-check: avvisa inaktuella sökningar i stället för att uppdatera

Söka i cachen

Shell
./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

Uppsättningen flaggor är identisk med ast-index search, inklusive --fallback scan för cachar som saknas.

Upprepa --index-dir för att söka i flera uppvärmda cachar i ett anrop:

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

Manifestbaserade cacheuppsättningar

Om du redan har namngivna uppvärmda uppsättningar kan samma manifest användas för cachad AST-sökning:

Shell
./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)' .

Planeringsdiagnostik

--trace-plan rapporterar den cachade AST-planerarens beslut till stderr, bland annat:

  • vilka uppvärmda cachar som genomsöktes
  • om logiken för uppdatering av inaktuella data kördes
  • antal kandidatfiler efter begränsning på filnivå
  • hur många cachade träd som avserialiserades för exakt strukturell matchning

Cache jämfört med faktindex

Båda lägena snabbar upp AST-sökning, men är optimerade för olika typer av arbetsbelastning.

Aspekt Faktindex (ast-index) Cache (ast-cache)
Vad som lagras Extraherade fakta (anropsnamn, klassnamn, deklarationer) Serialiserade parsade träd
Byggkostnad Lägre Högre (parsar allt)
Storlek på bygget Mindre Större
Söksökväg Filtrera efter fakta, parsa och matcha sedan kandidaterna Deserialisera trädet och matcha sedan
Bäst för Mönster med ett igenkännbart huvud (anropsnamn, klassnamn) Mönster vars särskiljande egenskap är strukturell, inte nominell
Sämst för Mönster där huvudet är en metavariabel Kalla sökningar i ett träd som inte längre ryms i operativsystemets sidcache

I praktiken ger faktindexet den snabbaste kalla sökningen och cachen den snabbaste varma sökningen. Välj det som passar din arbetsbelastning, eller bygg båda och låt dina verktyg välja.

Programmatisk användning

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 tar emot samma AstSearchOptions som inbyggd AST-sökning och returnerar samma list<AstMatch>-format. Den enda skillnaden är att parserkedjan hoppas över för filer som redan finns i cachen. För flöden med flera index eller manifest, använd searchAstCachedMany(...) och searchAstCachedSet(...).

När du ska använda det

Läge för cachad AST är rätt verktyg när:

  • Du kör upprepade strukturella sökningar mot samma kodbas.
  • Flaskhalsen vid dina tidigare körningar var PHP-Parser (synligt i profiler som tid åtgången i lexern och parsern).
  • Du har utrymme på disken för det serialiserade trädlagret.

Om dina sökningar vanligtvis träffar en liten del av kodbasen och matchningarna koncentreras kring igenkännbara anropsnamn eller klassnamn passar faktindex oftast bättre. Om dina sökningar täcker stora delar av kodbasen men du kan betala engångskostnaden för parsning är cachen snabbare.