Μετάβαση στο περιεχόμενο

Αναζήτηση κειμένου με ευρετήριο

Η αναζήτηση κειμένου με ευρετήριο είναι η εκδοχή της αναζήτησης κειμένου με θερμό cache. Η πρώτη κλήση δημιουργεί ένα αποθηκευτικό χώρο στον δίσκο με τριγράμματα και καταχωρίσεις αναγνωριστικών· οι επόμενες κλήσεις τον χρησιμοποιούν για να παραλείπουν αρχεία που προφανώς δεν μπορούν να περιέχουν το μοτίβο. Έτσι, μειώνεται σημαντικά η καθυστέρηση σε επαναλαμβανόμενα ερωτήματα σε μεγάλα αποθετήρια, χωρίς να χρειάζεται διεργασία δαίμονα ή παρακολούθησης.

Η αναζήτηση κειμένου με θερμό cache περιλαμβάνει πλέον:

  • αναζήτηση σε ένα ευρετήριο
  • επαναλαμβανόμενη αναζήτηση --index-dir σε πολλαπλά ευρετήρια
  • αναζήτηση σε σύνολο βάσει manifest
  • διαχείριση παρωχημένων δεδομένων με επίγνωση του κύκλου ζωής
  • διαγνωστικά σχεδιασμού μέσω του --trace-plan

Το ευρετήριο είναι διαθέσιμο μέσω του greph-index CLI και των μεθόδων facade Greph::buildTextIndex() / Greph::searchTextIndexed().

Δημιουργία του ευρετηρίου

Κέλυφος
# 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

Από προεπιλογή, το ευρετήριο αποθηκεύεται στο <root>/.greph-index/.

Μια επιτυχής δημιουργία εκτυπώνει μια σύνοψη μίας γραμμής:

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

Οι τέσσερις μετρητές αντιστοιχούν στον αριθμό των αρχείων που προστέθηκαν, ενημερώθηκαν, διαγράφηκαν και παρέμειναν αμετάβλητα. Σε μια νέα δημιουργία, ο μετρητής προσθηκών ισούται με τον αριθμό των αρχείων και όλοι οι υπόλοιποι είναι μηδέν.

Ανανέωση του ευρετηρίου

Κέλυφος
./vendor/bin/greph-index refresh .

Το refresh διατρέχει ξανά τη ρίζα του ευρετηρίου, κατακερματίζει κάθε αρχείο και ξαναγράφει μόνο τις καταχωρίσεις των οποίων άλλαξαν τα μεταδεδομένα. Η έξοδος χρησιμοποιεί τους ίδιους τέσσερις μετρητές, ώστε να βλέπετε ακριβώς τι άλλαξε:

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

Εκτελέστε το refresh αφού επεξεργαστείτε τα παρακολουθούμενα αρχεία, όταν χρησιμοποιείτε το manual-refresh. Για ευρετήρια opportunistic-refresh, το Greph μπορεί να ανανεώσει αυτόματα το ευρετήριο κατά την αναζήτηση, αν το σύνολο των αλλαγών παραμένει αρκετά μικρό.

Προφίλ κύκλου ζωής

Το Greph λειτουργεί χωρίς διεργασία δαίμονα. Τα προφίλ κύκλου ζωής καθορίζουν τη συμπεριφορά ενός θερμού ευρετηρίου όταν αλλάζει το δέντρο πηγαίου κώδικα:

  • static: να μην ελέγχει ποτέ τη φρεσκάδα ούτε να κάνει αυτόματες αλλαγές
  • manual-refresh: να εμφανίζει πληροφορίες παρωχημένων δεδομένων στο stats, αλλά να μην ανανεώνει ποτέ κατά την αναζήτηση
  • opportunistic-refresh: να ανανεώνει κατά την αναζήτηση μόνο όταν το σύνολο των αλλαγών είναι κάτω από τα διαμορφωμένα όρια
  • strict-stale-check: να απορρίπτει αναζητήσεις σε θερμό ευρετήριο με παρωχημένα δεδομένα, αντί να το ανανεώνει

Χρησιμοποιήστε το greph-index stats --dry-refresh για να ελέγξετε τι θα έκανε η αναζήτηση με θερμό cache πριν την εκτελέσετε:

Κέλυφος
./vendor/bin/greph-index stats . --dry-refresh

Εκτέλεση ερωτημάτων στο ευρετήριο

Κέλυφος
# 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" .

Το σύνολο σημαιών είναι ίδιο με αυτό της εγγενούς αναζήτησης κειμένου. Δείτε την αναφοράCLI για τον πλήρη κατάλογο.

Αν το ευρετήριο δεν υπάρχει στην καθορισμένη θέση, το greph-index search εμφανίζει σφάλμα. Αυτή η εντολή δεν κάνει αυτόματη εφεδρική σάρωση χωρίς ευρετήριο (οι εντολές AST έχουν την προαιρετική επιλογή --fallback scan, αλλά η εντολή κειμένου δεν την έχει). Δημιουργήστε πρώτα το ευρετήριο.

Επώνυμα σύνολα ευρετηρίων

Αν αναζητάτε επανειλημμένα στην ίδια διάταξη θερμού cache, χρησιμοποιήστε ένα manifest αντί να επαναλαμβάνετε τις σημαίες --index-dir:

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
    }
  ]
}

Αποθηκεύστε το ως .greph-index-set.json και, στη συνέχεια:

Κέλυφος
./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" .

Τι αποθηκεύει το ευρετήριο

Το ευρετήριο κειμένου είναι ένα αποθηκευτικό σύνολο τριγραμμάτων και καταχωρίσεων αναγνωριστικών. Για κάθε ευρετηριασμένο αρχείο, το Greph εξάγει:

  • Σύνολο τριγραμμάτων: το σύνολο των ακολουθιών τριών byte που υπάρχουν στο περιεχόμενο του αρχείου. Χρησιμοποιείται ως αρχικό φίλτρο τόσο για κυριολεκτικά ερωτήματα όσο και για ερωτήματα regex.
  • Καταχωρίσεις αναγνωριστικών: το σύνολο των διακριτών ακολουθιών που έχουν μορφή αναγνωριστικού ([A-Za-z_][A-Za-z0-9_]*) και υπάρχουν στο αρχείο. Χρησιμοποιείται για την επιτάχυνση ερωτημάτων που αφορούν ολόκληρες λέξεις.
  • Μεταδεδομένα κύκλου ζωής: αποθηκευμένα όρια και συμπεριφορά ελέγχου παρωχημένων δεδομένων.
  • Μεταδεδομένα περιεχομένου: μέγεθος και χρόνος τελευταίας τροποποίησης για αποφάσεις ανανέωσης και έλεγχο παρωχημένων δεδομένων.

Όταν λαμβάνει ένα ερώτημα, το Greph εξάγει τις ίδιες μορφές από το μοτίβο (τριγράμματα από κυριολεκτικά υποσυμβολοσειρές, διακριτές ακολουθίες αναγνωριστικών από μοτίβα ολόκληρων λέξεων), υπολογίζει την τομή των καταχωρίσεων και ξαναδιαβάζει μόνο τα αρχεία που ταιριάζουν. Τα αρχεία που απομένουν μετά την τομή αναζητούνται με την ίδια μηχανή όπως και στην εγγενή λειτουργία κειμένου.

Για ορισμένα ερωτήματα σύνοψης με θερμό cache, το Greph μπορεί να δώσει απάντηση απευθείας από τις καταχωρίσεις:

  • ολόκληρη λέξη -l
  • ολόκληρη λέξη -L
  • ολόκληρη λέξη -q

Έτσι, αποφεύγεται πλήρως το άνοιγμα υποψήφιων αρχείων, όταν οι καταχωρίσεις αποδεικνύουν ήδη την απάντηση.

Αυτή είναι η ίδια ιδέα με την προαιρετική προευρετηρίαση του ripgrep και το ευρετήριο τριγραμμάτων του codesearch, προσαρμοσμένη όμως στις μορφές στον δίσκο που μπορεί να εντοπίσει ταχύτερα η αναζήτηση PHP με θερμό cache.

Διαγνωστικά σχεδιασμού

Το --trace-plan στέλνει την απόφαση του σχεδιαστή αναζήτησης κειμένου με θερμό cache στο stderr, χωρίς να επηρεάζει την κανονική ροή αποτελεσμάτων.

Το ίχνος περιλαμβάνει:

  • προφίλ κύκλου ζωής
  • αριθμό επιλεγμένων αρχείων
  • πηγή υποψηφίων (full-scan, trigram-postings, word-postings ή invert-scan)
  • αριθμό όρων στις καταχωρίσεις
  • αριθμό υποψήφιων και επαληθευμένων αρχείων
  • καταλληλότητα για απευθείας σύνοψη
  • καταλληλότητα cache ερωτημάτων και απόφαση συμπλήρωσής του

Πότε να το χρησιμοποιήσετε

Η λειτουργία με ευρετήριο είναι η κατάλληλη όταν:

  • Αναζητάτε επανειλημμένα στο ίδιο αποθετήριο (εργασίες CI, βρόχοι πρακτόρων, ενσωματώσεις IDE).
  • Το αποθετήριο είναι αρκετά μεγάλο ώστε η εγγενής σάρωση να αποτελεί το σημείο συμφόρησης.
  • Τα μοτίβα περιλαμβάνουν κυριολεκτικές υποσυμβολοσειρές ή διακριτές ακολουθίες αναγνωριστικών που μπορούν να φιλτραριστούν εκ των προτέρων από το ευρετήριο.

Η εγγενής σάρωση παραμένει η κατάλληλη όταν:

  • Αναζητάτε σε μικρό αποθετήριο, όπου το κόστος δημιουργίας του ευρετηρίου είναι ο κυρίαρχος παράγοντας.
  • Αναζητάτε σε μια διαδρομή μόνο μία φορά και δεν θα την ξαναχρησιμοποιήσετε.
  • Χρειάζεστε κάθε αντιστοιχία σε μία μεμονωμένη, έκτακτη εκτέλεση και δεν θέλετε να συντηρείτε ευρετήριο.

Οι δημοσιευμένοι αριθμοί συγκριτικών δοκιμών στην README δείχνουν ότι η λειτουργία με ευρετήριο και θερμό cache υπερτερεί των rg και grep σε ερωτήματα regex, καθώς και σε ερωτήματα καταμέτρησης, αρχείων με αντιστοιχίες και αρχείων χωρίς αντιστοιχίες, στο σύνολο δεδομένων WordPress. Σε απλά κυριολεκτικά ερωτήματα υπερτερεί του grep, αλλά παραμένει ελαφρώς πιο αργή από το rg.

Προγραμματιστική χρήση

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 δέχεται το ίδιο TextSearchOptions με την εγγενή αναζήτηση κειμένου και επιστρέφει το ίδιο σχήμα list<TextFileResult>. Για ροές εργασίας με πολλαπλά ευρετήρια ή με βάση manifest, χρησιμοποιήστε τα searchTextIndexedMany(...) και searchTextIndexedSet(...).