تقوم الأداة المساعدة ugrep-indexer بفهرسة الملفات بشكل متكرر لتسريع عملية الالتقاط العودي.
تتم أيضًا فهرسة محتويات الأرشيفات والملفات المضغوطة عند تحديدها باستخدام خيار سطر الأوامر. وهذا يلغي البحث عنها عندما لا يتطابق أي من محتوياتها مع الأنماط المحددة.
ugrep هو باحث سريع عن الملفات متوافق مع grep ويدعم البحث المستند إلى الفهرس. يمكن أن يكون البحث المعتمد على الفهرس أسرع بشكل ملحوظ في أنظمة الملفات البطيئة وعندما يكون التخزين المؤقت لنظام الملفات غير فعال: إذا لم يتم تخزين نظام الملفات الموجود على محرك الأقراص الذي تم البحث فيه مؤقتًا في ذاكرة الوصول العشوائي (RAM)، أي أنه "بارد"، فإن الفهرسة ستؤدي إلى تسريع البحث. فهو يبحث فقط في تلك الملفات التي قد تتطابق مع نمط regex محدد باستخدام فهرس الملف. يسمح هذا الفهرس بالتحقق السريع من وجود تطابق محتمل، وبالتالي نتجنب البحث في جميع الملفات.
يعد البحث المفهرس باستخدام ugrep آمنًا ولا يتخطى أبدًا الملفات المحدثة التي قد تتطابق الآن. إذا تمت إضافة أو تغيير أي ملفات وأدلة بعد الفهرسة، فسيقوم البحث دائمًا بالبحث في هذه الإضافات والتغييرات التي تم إجراؤها على نظام الملفات من خلال مقارنة الطوابع الزمنية للملفات والدليل بالطابع الزمني للفهرسة.
عند إضافة العديد من الملفات أو تغييرها بعد الفهرسة، فقد نرغب في إعادة الفهرسة لتحديث الفهارس. تتم عملية إعادة الفهرسة بشكل تدريجي، لذا فهي لن تستغرق وقتًا طويلاً مثل عملية الفهرسة الأولية.
مثال نموذجي ولكن صغير للبحث المعتمد على الفهرس، على سبيل المثال في مستودع ugrep v3.12.6 الموجود على محرك أقراص منفصل:
$ cd drive/ugrep
$ ugrep-indexer -I
12247077 bytes scanned and indexed with 19% noise on average
1317 files indexed in 28 directories
28 new directories indexed
1317 new files indexed
0 modified files indexed
0 deleted files removed from indexes
128 binary files ignored with --ignore-binary
0 symbolic links skipped
0 devices skipped
5605227 bytes indexing storage increase at 4256 bytes/file
يستغرق البحث العادي على نظام ملفات بارد بدون فهرسة 1.02 ثانية بعد إلغاء تحميل drive
وتثبيته مرة أخرى لمسح ذاكرة التخزين المؤقت FS لتسجيل تأثير الفهرسة:
$ ugrep -I -l 'std::chrono' --stats
src/ugrep.cpp
Searched 1317 files in 28 directories in 1.02 seconds with 8 threads: 1 matching (0.07593%)
يستغرق Ripgrep 13.0.0 وقتًا أطول بمقدار 1.18 ثانية لنفس البحث البارد (يتخطى ripgrep الملفات الثنائية افتراضيًا، لذلك لم يتم تحديد الخيار -I
):
$ time rg -l 'std::chrono'
src/ugrep.cpp
1.18 real 0.01 user 0.06 sys
على النقيض من ذلك، مع الفهرسة، يستغرق البحث في نظام الملفات الباردة 0.0487 ثانية فقط باستخدام ugrep، وهو أسرع 21 مرة، بعد إلغاء تحميل drive
وتثبيته مرة أخرى لمسح ذاكرة التخزين المؤقت FS لتسجيل تأثير الفهرسة:
$ ugrep --index -I -l 'std::chrono' --stats
src/ugrep.cpp
Searched 1317 files in 28 directories in 0.0487 seconds with 8 threads: 1 matching (0.07593%)
Skipped 1316 of 1317 files with non-matching indexes
يوجد دائمًا بعض التباين في الوقت المنقضي، حيث كان 0.0487 ثانية هو أفضل وقت من بين أربع عمليات بحث أنتجت نطاقًا زمنيًا للبحث يتراوح بين 0.0487 (سرعة تصل إلى 21x) إلى 0.0983 ثانية (سرعة تصل إلى 10x).
قد تكون زيادة السرعة أعلى بكثير بشكل عام مقارنة بهذا العرض التوضيحي الصغير، اعتمادًا على عدة عوامل، حجم الملفات المفهرسة، وسرعة قراءة نظام الملفات، وبافتراض أن معظم الملفات باردة.
من المؤكد أن خوارزمية الفهرسة التي صممتها رتيبة : فالدقة الأعلى تضمن زيادة أداء البحث عن طريق تقليل المعدل الإيجابي الخاطئ، ولكنها تزيد أيضًا من حمل تخزين الفهرس. وبالمثل، تؤدي الدقة المنخفضة إلى تقليل أداء البحث، ولكنها تقلل أيضًا من الحمل الزائد لتخزين الفهرس. لذلك، قمت بتسمية المفهرس الخاص بي باسم المفهرس الرتيب .
إذا كانت مساحة تخزين الملفات مرتفعة، فيمكننا تقليل حجم تخزين الفهرس عن طريق تحديد دقة فهرسة أقل.
تؤدي فهرسة المثال أعلاه بالمستوى 0 (الخيار -0
) إلى تقليل حمل تخزين الفهرسة بمقدار 8.6 مرات، من 4256 بايت لكل ملف إلى 490 بايت لكل ملف:
12247077 bytes scanned and indexed with 42% noise on average
1317 files indexed in 28 directories
0 new directories indexed
1317 new files indexed
0 modified files indexed
0 deleted files removed from indexes
128 binary files ignored with --ignore-binary
0 symbolic links skipped
0 devices skipped
646123 bytes indexing storage increase at 490 bytes/file
لا يزال البحث المفهرس أسرع بكثير بمقدار 12x من البحث غير المفهرس في هذا المثال، مع البحث فعليًا في 16 ملفًا (15 نتيجة إيجابية خاطئة):
Searched 1317 files in 28 directories in 0.0722 seconds with 8 threads: 1 matching (0.07593%)
Skipped 1301 of 1317 files with non-matching indexes
أنماط Regex الأكثر تعقيدًا من هذا المثال قد يكون لها معدل إيجابي كاذب أعلى بشكل طبيعي، وهو معدل الملفات التي تعتبر متطابقة على الرغم من أنها ليست كذلك. قد يؤدي المعدل الإيجابي الكاذب المرتفع إلى تقليل سرعات البحث عندما يكون المعدل كبيرًا بما يكفي ليكون مؤثرًا.
يوضح الجدول التالي كيفية تأثير دقة الفهرسة على تخزين الفهرسة ومتوسط الضوضاء لكل ملف مفهرس. تُظهر الأعمدة الموجودة في أقصى اليمين سرعة البحث والمعدل الإيجابي الخاطئ لـ ugrep --index -I -l 'std::chrono'
:
لجنة التنسيق الإدارية. | تخزين الفهرس (كيلو بايت) | متوسط الضوضاء | ايجابيات كاذبة | وقت البحث (ق) |
---|---|---|---|---|
-0 | 631 | 42% | 15 | 0.0722 |
-1 | 1276 | 39% | 1 | 0.0506 |
-2 | 1576 | 36% | 0 | 0.0487 |
-3 | 2692 | 31% | 0 | Unch |
-4 | 2966 | 28% | 0 | Unch |
-5 | 4953 | 23% | 0 | Unch |
-6 | 5474 | 19% | 0 | Unch |
-7 | 9513 | 15% | 0 | Unch |
-8 | 10889 | 11% | 0 | Unch |
-9 | 13388 | 7% | 0 | Unch |
إذا كان التعبير العادي المحدد يتطابق مع العديد من الأنماط المحتملة، على سبيل المثال مع البحث ugrep --index -I -l '(todo|TODO)[: ]'
، فقد نلاحظ معدلًا أعلى من النتائج الإيجابية الخاطئة بين الملفات الـ 1317 التي تم البحث عنها، مما يؤدي إلى أوقات بحث أطول قليلاً:
لجنة التنسيق الإدارية. | ايجابيات كاذبة | وقت البحث (ق) |
---|---|---|
-0 | 189 | 0.292 |
-1 | 69 | 0.122 |
-2 | 43 | 0.103 |
-3 | 19 | 0.101 |
-4 | 16 | 0.097 |
-5 | 2 | 0.096 |
-6 | 1 | Unch |
-7 | 0 | Unch |
-8 | 0 | Unch |
-9 | 0 | Unch |
الدقة -4
هي القيمة الافتراضية (من -5
سابقًا في الإصدارات الأقدم)، والتي تميل إلى العمل بشكل جيد جدًا للبحث باستخدام أنماط التعبير العادي ذات التعقيد المتواضع.
كلمة واحدة من الحذر. هناك دائمًا القليل من النفقات العامة للتحقق من الفهارس. هذا يعني أنه إذا كانت جميع الملفات مخزنة مؤقتًا بالفعل في ذاكرة الوصول العشوائي (RAM)، لأنه تم البحث عن الملفات أو قراءتها مؤخرًا، فمن الواضح أن الفهرسة لن تؤدي بالضرورة إلى تسريع البحث. وفي هذه الحالة قد يكون البحث غير المفهرس أسرع. علاوة على ذلك، فإن البحث المستند إلى الفهرس يستغرق وقتًا أطول لبدء التشغيل. يزداد وقت بدء التشغيل هذا عند استخدام فئات أحرف Unicode وأحرف البدل التي يجب تحويلها إلى جداول التجزئة.
للتلخيص، يكون البحث المستند إلى الفهرس أكثر فاعلية عند البحث في الكثير من الملفات الباردة وعندما لا تتطابق أنماط التعبير العادي كثيرًا، أي أننا نريد الحد من استخدام عدد غير محدود من التكرارات *
و +
والحد من استخدام فئات أحرف Unicode عندما ممكن. يؤدي هذا إلى تقليل وقت بدء تشغيل ugrep ويحد من معدل تطابقات الأنماط الإيجابية الخاطئة (راجع أيضًا الأسئلة والأجوبة أدناه).
قم بفهرسة جميع الملفات غير الثنائية بشكل متكرر وتدريجي لإظهار التقدم:
ugrep-indexer -I -v
قم بفهرسة جميع الملفات غير الثنائية بشكل متكرر وتدريجي، بما في ذلك الملفات غير الثنائية المخزنة في الأرشيفات وفي الملفات المضغوطة، مع إظهار التقدم:
ugrep-indexer -z -I -v
قم بفهرسة جميع الملفات غير الثنائية بشكل متزايد، بما في ذلك الأرشيفات والملفات المضغوطة، وإظهار التقدم، واتبع الروابط الرمزية للملفات (ولكن ليس للأدلة)، ولكن لا تقم بفهرسة الملفات والأدلة التي تطابق الكرات الموجودة في .gitignore:
ugrep-indexer -z -I -v -S -X
فرض إعادة الفهرسة لجميع الملفات غير الثنائية، بما في ذلك الأرشيفات والملفات المضغوطة، واتباع الروابط الرمزية للملفات (ولكن ليس للأدلة)، ولكن لا تقم بفهرسة الملفات والأدلة التي تطابق الكرات الموجودة في .gitignore:
ugrep-indexer -f -z -I -v -S -X
نفس الشيء، ولكن قم بتقليل تخزين ملف الفهرس إلى الحد الأدنى عن طريق تقليل دقة الفهرسة من 5 (افتراضي) إلى 0:
ugrep-indexer -f -0 -z -I -v -S -X
زيادة أداء البحث عن طريق زيادة دقة الفهرسة من 5 (افتراضي) إلى 7 بتكلفة ملفات الفهرس الأكبر:
ugrep-indexer -f7zIvSX
قم بحذف كافة ملفات الفهرس المخفية ._UG#_Store
بشكل متكرر لاستعادة شجرة الدليل إلى حالة غير مفهرسة:
ugrep-indexer -d
تكوين وتجميع مع:
./build.sh
إذا رغبت في ذلك ولكن ليس مطلوبًا، قم بالتثبيت باستخدام:
sudo make install
أضف خيارًا لإنشاء ملف فهرس واحد، على سبيل المثال، محدد بشكل صريح لـ ugrep. قد يؤدي هذا إلى تحسين سرعة البحث المفهرس بشكل أكبر إذا كان ملف الفهرس موجودًا على نظام ملفات سريع. بخلاف ذلك، لا تتوقع الكثير من التحسن أو حتى التباطؤ المحتمل، نظرًا لأنه لا يمكن البحث في ملف فهرس واحد بشكل متزامن وسيتم فحص المزيد من إدخالات الفهرس عندما يتم في الواقع تخطي الدلائل (تخطي فهارسها أيضًا). التجارب سوف تخبرنا. التحذير المهم لهذا الأسلوب هو أن البحث المعتمد على الفهرس باستخدام ugrep --index
لم يعد آمنًا: لن يتم البحث في الملفات الجديدة والمعدلة التي لم تتم فهرستها بعد.
يحتوي كل مرشح N-gram Bloom على "طبقة بت" خاصة به في جدول التجزئة لتجنب تعارضات التجزئة. على سبيل المثال، لا يتشارك 2 جرام أي بتات مع 3 جرام. وهذا يضمن عدم وجود أي نتائج إيجابية كاذبة أبدًا مع الأحرف التي تتم مطابقتها بشكل خاطئ والتي ليست في الواقع جزءًا من النمط. ومع ذلك، فإن مساحة البت التي تبلغ 1 جرام (حرف واحد) صغيرة (256 بت على الأكثر). لذلك، فإننا نهدر بعض البتات عندما تكون جداول التجزئة أكبر. أحد الأساليب الممكنة لتقليل الفاقد هو الجمع بين 1 جرام و2 جرام لمشاركة نفس مساحة البت. من السهل القيام بذلك إذا اعتبرنا أن 1 جرام يساوي 2 جرام مع تعيين الحرف الثاني على