Přejít k obsahu

Vyhledávání AST z mezipaměti

Vyhledávání AST z mezipaměti je doplňkový režim s připravenou mezipamětí k indexu faktů. Místo ukládání extrahovaných faktů a opětovného parsování odpovídajících souborů ukládá mezipaměť serializované parsované stromy na disk. Následné dotazy stromy deserializují a spustí přímo porovnávání, čímž zcela přeskočí zpracování PHP-Parser.

Mezipaměť je dostupná v dílčím příkazu greph-index ast-cache CLI a metodách fasády Greph::buildAstCache() / Greph::searchAstCached(). Podporuje také vyhledávání ve více indexech a sadách založených na manifestu.

Vytvoření mezipaměti

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

Mezipaměť se ve výchozím nastavení ukládá do <root>/.greph-ast-cache/. Vytvoření této ze tří variant indexu bývá nejpomalejší, protože každý soubor se musí jednou parsovat.

Úspěšné vytvoření vypíše jednořádkové shrnutí:

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

Počet stromů v mezipaměti bývá o něco nižší než počet souborů, protože soubory, které nelze parsovat (a tiše se přeskočí), nevytvoří položku mezipaměti. Pokud chcete zobrazovat chyby parsování, zadejte v příkazu vyhledávání --strict-parse.

Obnovení mezipaměti

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

refresh znovu projde indexovaný kořen, znovu zpracuje změněné soubory a přepíše pouze změněné stromy v mezipaměti.

Profily životního cyklu odpovídají ostatním připraveným režimům:

  • static: nikdy automaticky nekontroluje aktuálnost ani nemění mezipaměť
  • manual-refresh: hlásí zastaralý stav v stats, ale během vyhledávání mezipaměť nikdy neobnovuje
  • opportunistic-refresh: obnovuje mezipaměť během vyhledávání, pouze pokud je změněná sada menší než nakonfigurované limity
  • strict-stale-check: místo obnovy odmítne zastaralé vyhledávání

Dotazování mezipaměti

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

Sada příznaků je totožná s příkazy ast-index search včetně --fallback scan pro případ chybějících mezipamětí.

Opakováním --index-dir prohledáte několik připravených mezipamětí v jednom volání:

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

Sady mezipamětí založené na manifestu

Pokud už používáte pojmenované připravené sady, stejný manifest může řídit vyhledávání AST v mezipaměti:

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

Diagnostika plánovače

--trace-plan zaznamenává rozhodnutí plánovače AST v mezipaměti do stderr, včetně:

  • toho, které připravené mezipaměti se prohledaly
  • zda proběhlo obnovování zastaralých dat
  • počtu souborů kandidátů po zúžení na úrovni souborů
  • počtu deserializovaných stromů v mezipaměti pro přesné strukturální porovnání

Mezipaměť a index faktů

Oba režimy urychlují vyhledávání AST, ale každý je optimalizovaný pro jiný typ práce.

Vlastnost Faktový index (ast-index) Mezipaměť (ast-cache)
Co se ukládá Extrahovaná fakta (názvy volání, názvy tříd, deklarace) Serializované parsované stromy
Náklady na sestavení Nižší Vyšší (parsuje se vše)
Velikost sestavení Menší Větší
Cesta dotazu Filtrování podle faktů, poté parsování a porovnání kandidátů Deserializace stromu, poté porovnání
Nejvhodnější pro Vzory s rozpoznatelnou hlavičkou (název volání, název třídy) Vzory, jejichž rozlišovací znak je strukturální, nikoli pojmenovací
Nejméně vhodné pro Vzory, jejichž hlavička je metavariable Studené dotazy nad stromem, který se už nevejde do mezipaměti stránek OS

V praxi má faktový index nejrychlejší studený dotaz a mezipaměť nejrychlejší zahřátý dotaz. Použijte to, co vyhovuje vašemu pracovnímu zatížení, nebo vytvořte obojí a nechte výběr na svých nástrojích.

Programové použití

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 přijímá stejné AstSearchOptions jako nativní vyhledávání AST a vrací stejný tvar list<AstMatch>. Jediný rozdíl spočívá v tom, že se u souborů, které už jsou v mezipaměti, přeskočí proces parsování. Pro práci s více indexy nebo manifestem použijte searchAstCachedMany(...) a searchAstCachedSet(...).

Kdy jej použít

Režim AST z mezipaměti je vhodný, když:

  • Opakovaně spouštíte strukturální dotazy nad stejnou kódovou základnou.
  • Úzkým hrdlem při předchozích spuštěních bylo PHP-Parser (v profilech je vidět čas strávený v lexeru a parseru).
  • Můžete vyhradit místo na disku pro úložiště serializovaných stromů.

Pokud vaše dotazy obvykle zasáhnou jen malou část kódové základny a shody se soustředí kolem rozpoznatelných názvů volání nebo tříd, je faktový index obvykle vhodnější. Pokud dotazy procházejí širokou část kódové základny a můžete jednorázově zaplatit náklady na parsování, vítězí mezipaměť.