Indexerad textsökning
Indexerad textsökning är den cacheförvärmda versionen av textsökning. Det första anropet bygger ett index på disk över trigram och identifierarpostningar. Efterföljande anrop använder indexet för att hoppa över filer som uppenbart inte kan innehålla mönstret. Resultatet är mycket lägre fördröjning vid upprepade sökningar i stora kodförråd, utan att någon daemon- eller bevakarprocess tillkommer.
Den förvärmda textsökningen omfattar nu:
- sökning i ett enda index
- upprepad sökning i
--index-dirflera index - sökning i en manifestbaserad mängd
- hantering av inaktuella index med hänsyn till deras livscykel
- diagnostik av sökplaneraren via
--trace-plan
Indexet exponeras via greph-index CLI och fasadmetoderna Greph::buildTextIndex() / Greph::searchTextIndexed().
Bygga indexet
# Full build at the current directory
./vendor/bin/greph-index build .
# Full build at an explicit root
./vendor/bin/greph-index build path/to/repo
# Use a non-default index directory
./vendor/bin/greph-index build . --index-dir /tmp/greph-index
# Build with an explicit lifecycle policy
./vendor/bin/greph-index build . \
--lifecycle opportunistic-refresh \
--auto-refresh-max-files 32 \
--auto-refresh-max-bytes 1048576
Indexet lagras som standard på <root>/.greph-index/.
Ett lyckat bygge skriver ut en sammanfattning på en rad:
Built index for 2547 files in .greph-index (193428 trigrams, +2547 ~0 -0 =0)
De fyra räknarna visar antalet tillagda, uppdaterade, borttagna och oförändrade filer. Vid en nybyggnad motsvarar räknaren för tillagda antalet filer, och alla andra räknare är noll.
Uppdatera indexet
./vendor/bin/greph-index refresh .
refresh går igenom den indexerade roten igen, hashar varje fil och skriver endast om poster vars metadata har ändrats. Resultatet använder samma fyra räknare så att du kan se exakt vad som ändrats:
Refreshed index for 2547 files in .greph-index (193428 trigrams, +3 ~7 -1 =2536)
Kör refresh efter att du redigerat spårade filer när du använder manual-refresh. För index med opportunistic-refresh kan Greph automatiskt uppdatera indexet under sökning om mängden ändrade filer fortfarande är tillräckligt liten.
Livscykelprofiler
Greph körs utan daemon. Livscykelprofiler styr hur ett förvärmt index beter sig när källträdet ändras:
static: kontrollera aldrig aktualitet eller ändra automatisktmanual-refresh: visa information om inaktuella index istats, men uppdatera aldrig under sökningopportunistic-refresh: uppdatera under sökning endast när mängden ändrade filer ligger under de konfigurerade tröskelvärdenastrict-stale-check: avvisa inaktuella förvärmda sökningar i stället för att uppdatera
Använd greph-index stats --dry-refresh för att se vad en förvärmd sökning skulle göra innan du kör den:
./vendor/bin/greph-index stats . --dry-refresh
Söka i indexet
# Fixed-string search
./vendor/bin/greph-index search -F "function" .
# Case-insensitive whole-word
./vendor/bin/greph-index search -F -i -w "function" .
# Counts
./vendor/bin/greph-index search -F -c "function" .
# Files only
./vendor/bin/greph-index search -F -l "function" .
# Multi-index search
./vendor/bin/greph-index search -F "apply_filters" . \
--index-dir wordpress/.greph-index \
--index-dir wp-content/plugins/my-plugin/.greph-index \
--show-index-origin
# Regex search
./vendor/bin/greph-index search "function\s+\w+" .
# JSON output
./vendor/bin/greph-index search --json -F "function" .
# Planner trace to stderr
./vendor/bin/greph-index search --trace-plan -F "function" .
Flaggorna är desamma som för inbyggd textsökning. Se referensen CLI för hela listan.
Om indexet inte finns på den angivna platsen ger greph-index search ett fel. Det här kommandot faller inte automatiskt tillbaka på en oindexerad genomsökning (AST-kommandona har ett valfritt --fallback scan, men textkommandot har inte det). Bygg indexet först.
Namngivna indexmängder
Om du upprepade gånger söker i samma förvärmda layout kan du använda ett manifest i stället för att upprepa flaggorna --index-dir:
{
"name": "wordpress-local",
"indexes": [
{
"name": "core-text",
"root": "wordpress",
"mode": "text",
"lifecycle": "static",
"priority": 100
},
{
"name": "plugin-text",
"root": "wp-content/plugins/my-plugin",
"mode": "text",
"lifecycle": "opportunistic-refresh",
"max_changed_files": 16,
"max_changed_bytes": 262144,
"priority": 200
}
]
}
Spara det som .greph-index-set.json och kör sedan:
./vendor/bin/greph-index set build
./vendor/bin/greph-index set stats --dry-refresh
./vendor/bin/greph-index set search --show-index-origin -F "apply_filters" .
Vad indexet lagrar
Textindexet är ett lager med trigram och identifierarpostningar. För varje indexerad fil extraherar Greph:
- Trigramuppsättning: uppsättningen av sekvenser med tre byte som finns i filinnehållet. Används som ett grovt förfilter för både literal- och regexsökningar.
- Identifierarpostningar: uppsättningen av identifierarliknande token (
[A-Za-z_][A-Za-z0-9_]*) som finns i filen. Används för att snabba upp sökningar efter hela ord. - Livscykelmetadata: lagrade tröskelvärden och beteende vid kontroll av inaktualitet.
- Innehållsmetadata: storlek och mtime för beslut om uppdatering och granskning av inaktualitet.
När en sökfråga kommer extraherar Greph samma former från mönstret (trigram från litterala delsträngar, identifierartoken från mönster för hela ord), skär mängderna av postningar med varandra och läser endast om de matchande filerna. Filerna som återstår efter snittet söks igenom med samma motor som i inbyggt textläge.
För vissa förvärmda sammanfattningssökningar kan Greph svara direkt från postningarna:
- hela ordet
-l - hela ordet
-L - hela ordet
-q
Då behöver kandidatfilerna inte öppnas igen när postningarna redan bevisar svaret.
Det här bygger på samma idé som den valfria förindexeringen i ripgrep och trigramindexet i codesearch, men är särskilt utformat för de diskbaserade former som förvärmd PHP kan träffa snabbast.
Diagnostik av sökplaneraren
--trace-plan skriver beslutet från den förvärmda textsökningens sökplanerare till stderr, utan att påverka den vanliga resultatströmmen.
Spårningen innehåller:
- livscykelprofil
- antal valda filer
- kandidatkälla (
full-scan,trigram-postings,word-postingsellerinvert-scan) - antal postningstermer
- antal kandidatfiler och verifierade filer
- om direkt sammanfattning är möjlig
- om frågecache är möjlig och beslut om att fylla den
När du ska använda det
Indexerad sökning är rätt verktyg när:
- Du söker i samma kodförråd många gånger i följd (CI-jobb, agentloopar, IDE-integrationer).
- Kodförrådet är tillräckligt stort för att inbyggd genomsökning ska bli flaskhalsen.
- Mönstren innehåller litterala delsträngar eller identifierartoken som indexet kan förfiltrera efter.
Inbyggd genomsökning är fortfarande rätt verktyg när:
- Du söker i ett litet kodförråd där byggkostnaden dominerar.
- Du söker i en engångssökväg som du inte kommer att söka i igen.
- Du behöver varje träff i en enstaka tillfällig körning och inte vill underhålla ett index.
De publicerade benchmarkresultaten i README visar att det förvärmt indexerade läget presterar bättre än både rg och grep vid regexsökningar och sökningar efter antal, filer med träffar och filer utan träffar i korpusen WordPress. Vid vanliga litterala sökningar slår det grep men är fortfarande något långsammare än rg.
Programmatisk användning
use Greph\Greph;
use Greph\Text\TextSearchOptions;
use Greph\Index\IndexLifecycleProfile;
// Build once
Greph::buildTextIndex('.', lifecycle: IndexLifecycleProfile::OpportunisticRefresh);
// Refresh after edits
Greph::refreshTextIndex('.');
// Query
$results = Greph::searchTextIndexed(
'function',
'src',
new TextSearchOptions(fixedString: true),
);
searchTextIndexed tar emot samma TextSearchOptions som inbyggd textsökning och returnerar samma list<TextFileResult>-format. För flöden med flera index eller manifest, använd searchTextIndexedMany(...) och searchTextIndexedSet(...).