
# Indekseeritud tekstiotsing

Indekseeritud tekstiotsing on [tekstiotsingu](https://greph.inline0.dev/et/docs/modes/text) soojendatud vahemäluga versioon. Esimene väljakutse loob kettale trigrammide ja identifikaatorikirjete hoidla; järgnevad väljakutsed kasutavad seda, et jätta vahele failid, mis ilmselgelt mustrit ei sisalda. Nii väheneb korduvate päringute latentsus suurtes hoidlates märkimisväärselt, ilma et lisanduks deemon- või jälgimisprotsess.

Soojendatud tekstiotsing hõlmab nüüd järgmist:

- ühe indeksi otsing
- korduv `--index-dir` mitme indeksi otsing
- manifestipõhine hulgaotsing
- elutsükliteadlik aegunud andmete käsitlemine
- plaanuri diagnostika `--trace-plan` kaudu

Indeks on saadaval `greph-index` CLI ja `Greph::buildTextIndex()` / `Greph::searchTextIndexed()` fassaadimeetodite kaudu.

## Registri loomine

```bash
# 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
```

Vaikimisi salvestatakse indeks asukohta `<root>/.greph-index/`.

Eduka loomise korral kuvatakse üherealine kokkuvõte:

```text
Built index for 2547 files in .greph-index (193428 trigrams, +2547 ~0 -0 =0)
```

Neli loendurit näitavad lisatud, uuendatud, kustutatud ja muutmata failide arvu. Värske indeksi loomisel võrdub lisatud failide loendur failide arvuga ja kõik ülejäänud loendurid on nullis.

## Registri värskendamine

```bash
./vendor/bin/greph-index refresh .
```

`refresh` käib indekseeritud juure uuesti läbi, räsi arvutatakse iga faili jaoks ning ümber kirjutatakse ainult need kirjed, mille metaandmed on muutunud. Väljundis kasutatakse sama nelja loendurit, et näeksite täpselt, mis muutus:

```text
Refreshed index for 2547 files in .greph-index (193428 trigrams, +3 ~7 -1 =2536)
```

Kui kasutate `manual-refresh`, käivitage pärast jälgitavate failide muutmist `refresh`. `opportunistic-refresh` indeksite korral saab Greph otsingu ajal indeksi automaatselt värskendada, kui muudetud failide hulk on piisavalt väike.

## Elutsükliprofiilid

Greph töötab ilma deemonita. Elutsükliprofiilid määravad, kuidas soojendatud indeks käitub lähtepuu muutumisel:

- `static`: ära kunagi kontrolli värskust ega muuda automaatselt
- `manual-refresh`: kuva aegunud teave `stats`-s, kuid ära värskenda otsingu ajal kunagi
- `opportunistic-refresh`: värskenda otsingu ajal ainult siis, kui muudetud failide hulk jääb seadistatud piirväärtustest allapoole
- `strict-stale-check`: lükka aegunud soojendatud otsingud tagasi, selle asemel et värskendada

Enne soojendatud otsingu käivitamist kasutage `greph-index stats --dry-refresh`, et vaadata, mida see teeks:

```bash
./vendor/bin/greph-index stats . --dry-refresh
```

## Registrist päringute tegemine

```bash
# 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" .
```

Lippude komplekt on sama mis teksti algupärasel otsingul. Täielikku loendit vaadake [CLI viitest](https://greph.inline0.dev/et/docs/cli#greph-index).

Kui indeksit pole soovitud asukohas, annab `greph-index search` vea. See käsk ei lähe automaatselt üle indekseerimata skannimisele (AST-käskudel on valikuline `--fallback scan`, tekstiotsingu käsul aga mitte). Looge indeks enne.

## Nimega indeksikomplektid

Kui otsite korduvalt sama soojendatud paigutuse põhjal, kasutage lippude `--index-dir` kordamise asemel manifesti:

```json
{
  "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
    }
  ]
}
```

Salvestage see nimega `.greph-index-set.json` ja seejärel:

```bash
./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" .
```

## Registri sisu

Tekstiindeks on trigrammide ja identifikaatorikirjete hoidla. Iga indekseeritud faili kohta eraldab Greph järgmist:

- **Trigrammide hulk**: failisisus leiduvate kolmebaidiste jadade hulk. Kasutatakse literaal- ja regulaaravaldispäringute jämedaks eelfiltreerimiseks.
- **Identifikaatorikirjed**: failis leiduvate identifikaatorikujuliste märkide (`[A-Za-z_][A-Za-z0-9_]*`) hulk. Kasutatakse terviksõnapäringute kiirendamiseks.
- **Elutsükli metaandmed**: salvestatud piirväärtused ja aegunud andmete kontrollimise käitumine.
- **Sisu metaandmed**: suurus ja muutmisaeg värskendamisotsuste ning aegunud andmete kontrolli jaoks.

Päringu saabumisel eraldab Greph mustrist samad kujundid (literaalalamosade trigrammid, terviksõnamustrite identifikaatorimärgid), lõikab kirjete hulki ühisosa järgi ning loeb uuesti sisse ainult vastavad failid. Ühisosast läbi pääsenud failides otsitakse sama mootoriga nagu teksti algupärases režiimis.

Mõne soojendatud koondpäringu puhul saab Greph vastata otse kirjete põhjal:

- terviksõna `-l`
- terviksõna `-L`
- terviksõna `-q`

Nii ei pea kandidaatfaile üldse uuesti avama, kui kirjed juba vastuse tõestavad.

See sarnaneb ripgrep valikulise eelindekseerimise ja codesearchi trigrammiindeksiga, kuid on loodud spetsiaalselt kettal salvestatavate kujundite järgi, mida soojendatud PHP kõige kiiremini kasutab.

## Plaanuri diagnostika

`--trace-plan` väljastab soojendatud tekstiotsingu plaanuri otsuse `stderr`-i, jättes tavalise tulemuste voo puutumata.

Jälg sisaldab järgmist:

- elutsükliprofiil
- valitud failide arv
- kandidaatide allikas (`full-scan`, `trigram-postings`, `word-postings` või `invert-scan`)
- kirjete terminite arv
- kandidaatfailide ja kontrollitud failide arv
- otse koondvastamise sobivus
- päringuvälimälu sobivus ja täitmise otsus

## Millal seda kasutada

Indekseeritud režiim sobib, kui:

- Päringute siht on sama hoidla mitu korda järjest (CI-tööd, agentide tsüklid, IDE-integratsioonid).
- Hoidla on piisavalt suur, et algupärane skannimine oleks kitsaskohaks.
- Mustrid sisaldavad literaalalamosi või identifikaatorimärke, mille järgi indeks saab eelfiltreerida.

Algupärane skannimine sobib endiselt, kui:

- Päring teostatakse väikeses hoidlas, kus indeksi loomise kulu on määrav.
- Otsite ühe korra kindlast teest, mida te uuesti ei päri.
- Vajate ühekordse ajutise käivitusega kõiki vasteid ega soovi indeksit hooldada.

Avaldatud võrdlustulemused [README](https://github.com/inline0/greph#performance)-s näitavad, et soojendatud indekseeritud režiim edestab regulaaravaldispäringute ning arvu, vastetega failide ja vasteteta failide päringute puhul nii `rg` kui ka `grep`-i, kui sihtmärk on WordPress korpus. Lihtsate literaalipäringute puhul edestab see `grep`-i, kuid jääb veidi maha `rg`-st.

## Programmipõhine kasutus

```php
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` aktsepteerib samu `TextSearchOptions` nagu teksti algupärane otsing ja tagastab sama kujuga `list<TextFileResult>`. Mitme indeksi või manifestipõhise töövoo jaoks kasutage `searchTextIndexedMany(...)` ja `searchTextIndexedSet(...)`.
