Ö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
# 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:
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
./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ştirmemanual-refresh: eski durumustatsiçinde bildir, ancak arama sırasında hiçbir zaman yenilemeopportunistic-refresh: yalnızca değişen küme yapılandırılan eşiklerin altındaysa arama sırasında yenilestrict-stale-check: eski aramaları yenilemek yerine reddet
Önbellekte sorgu yapma
./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.
Çoklu dizin önbellek araması
Tek bir çağrıda birden çok ısıtılmış önbellekte arama yapmak için --index-dir seçeneğini tekrarlayın:
./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:
./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
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.