İçeriğe geç

Önbelleğe Alınmış AST Araması

Önbelleğe alınmış AST araması, olgu dizinini tamamlayan bir ısıtılmış önbellek modudur. Çıkarılmış olguları saklayıp eşleşen dosyaları yeniden ayrıştırmak yerine önbellek, ayrıştırılmış ağaçların serileştirilmiş hâllerini diskte saklar. Sonraki sorgularda ağaçların serileştirilmiş hâli çözülür ve eşleştirici doğrudan çalıştırılarak PHP-Parser işlem hattı tamamen atlanır.

Önbelleğe greph-index ast-cache CLI alt komutundan ve Greph::buildAstCache() / Greph::searchAstCached() arayüz yöntemlerinden erişilir. Ayrıca çoklu dizin aramasını ve bildirim dosyası destekli küme aramasını da destekler.

Önbelleği oluşturma

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

Önbellek varsayılan olarak <root>/.greph-ast-cache/ konumunda saklanır. Üç dizin modu arasında önbellek oluşturma genellikle en yavaş olanıdır; çünkü her dosyanın bir kez ayrıştırılması gerekir.

Başarılı bir oluşturma işlemi tek satırlık bir özet yazdırır:

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

Ayrıştırma başarısız olan dosyalar (ve sessizce atlananlar) önbellek girdisi oluşturmadığından, önbelleğe alınmış ağaç sayısı genellikle dosya sayısından biraz düşüktür. Ayrıştırma hatalarını görmek istiyorsanız arama komutuna --strict-parse ekleyin.

Önbelleği yenileme

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

refresh dizinlenen kökü yeniden tarar, değişen dosyaları yeniden ayrıştırır ve yalnızca değişen önbellek ağaçlarını yeniden yazar.

Yaşam döngüsü profilleri diğer ısıtılmış modlarla aynıdır:

  • static: güncelliği hiçbir zaman denetleme veya otomatik olarak değiştirme
  • manual-refresh: eski durumu stats içinde bildir, ancak arama sırasında hiçbir zaman yenileme
  • opportunistic-refresh: yalnızca değişen küme yapılandırılan eşiklerin altındaysa arama sırasında yenile
  • strict-stale-check: eski aramaları yenilemek yerine reddet

Önbellekte sorgu yapma

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

Seçenek kümesi, eksik önbellekler için --fallback scan dahil olmak üzere ast-index search ile aynıdır.

Tek bir çağrıda birden çok ısıtılmış önbellekte arama yapmak için --index-dir seçeneğini tekrarlayın:

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

Bildirim dosyası destekli önbellek kümeleri

Adlandırılmış ısıtılmış kümeleri zaten tutuyorsanız, aynı bildirim dosyası önbelleğe alınmış AST aramasını çalıştırabilir:

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

Planlayıcı tanılamaları

--trace-plan, önbelleğe alınmış AST planlayıcı kararlarını stderr konumuna bildirir. Bunlar şunları içerir:

  • Hangi ısıtılmış önbelleklerde arama yapıldığı
  • Eski verileri yenileme mantığının çalışıp çalışmadığı
  • Dosya düzeyinde daraltmanın ardından kalan aday dosya sayısı
  • Tam yapısal eşleştirme için serileştirilmiş hâli çözülen önbelleğe alınmış ağaç sayısı

Önbellek ve olgu dizini karşılaştırması

Her iki mod da AST aramasını hızlandırır, ancak farklı iş yükleri için optimize edilmiştir.

Özellik Olgu dizini (ast-index) Önbellek (ast-cache)
Saklanan Çıkarılmış olgular (çağrı adları, sınıf adları, bildirimler) Serileştirilmiş ayrıştırılmış ağaçlar
Oluşturma maliyeti Daha düşük Daha yüksek (her şeyi ayrıştırır)
Oluşturma boyutu Daha küçük Daha büyük
Sorgu yolu Olgulara göre filtrele, ardından adayları ayrıştır ve eşleştir Ağacı serileştirilmiş hâlinden çöz, ardından eşleştir
En uygun olduğu durum Tanınabilir bir başlığı olan örüntüler (çağrı adı, sınıf adı) Ayırt edici özelliği ad değil yapı olan örüntüler
En az uygun olduğu durum Başlığı bir metadeğişken olan örüntüler Artık işletim sistemi sayfa önbelleğine sığmayan bir ağaçta yapılan soğuk sorgular

Uygulamada olgu dizini soğuk sorgularda, önbellek ise sıcak sorgularda en hızlıdır. İş yükünüze uyanı kullanın veya ikisini de oluşturup hangi yöntemin kullanılacağını araçlarınızın seçmesini sağlayın.

Programatik kullanım

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, yerel AST aramasıyla aynı AstSearchOptions değerini kabul eder ve aynı list<AstMatch> yapısını döndürür. Tek fark, önbellekte bulunan dosyalar için ayrıştırıcı işlem hattının atlanmasıdır. Çoklu dizin veya bildirim dosyası destekli iş akışları için searchAstCachedMany(...) ve searchAstCachedSet(...) kullanın.

Ne zaman kullanılır?

Önbelleğe alınmış AST modu şu durumlarda doğru araçtır:

  • Aynı kod tabanında yapısal sorguları tekrar tekrar çalıştırıyorsanız.
  • Önceki çalıştırmalarınızda darboğaz PHP-Parser ise (profillerde sözcük çözümleyici ve ayrıştırıcıda harcanan süre olarak görünür).
  • Serileştirilmiş ağaç deposu için gereken disk alanını ayırabiliyorsanız.

Sorgularınız genellikle kod tabanının küçük bir bölümünde sonuç veriyor ve eşleşmeler tanınabilir çağrı adları veya sınıf adları çevresinde yoğunlaşıyorsa, olgu dizini genellikle daha uygundur. Sorgularınız kod tabanının geneline yayılıyorsa ancak tek seferlik ayrıştırma maliyetini karşılayabiliyorsanız önbellek daha iyi sonuç verir.