DashMap في Rust: الدليل الكامل للخريطة التشاركية (Concurrent HashMap)
1. ما هي DashMap ولماذا تحتاجها؟
DashMap هي خريطة تجزئة (hash map) عالية الأداء ومتزامنة (concurrent) للغة Rust، مصممة خصيصًا للاستخدام في التطبيقات متعددة الخيوط (multithreaded). في المكتبة القياسية لـ Rust، لدينا HashMap، لكنها ليست آمنة للخيوط (thread-safe). إذا حاولت استخدام HashMap من عدة خيوط دون مزامنة خارجية (مثل Mutex أو RwLock)، فسيُصدر مترجم Rust خطأ. DashMap تحل هذه المشكلة بتوفير هيكل بيانات جاهز يمكن استخدامه بأمان من عدة خيوط في وقت واحد دون الحاجة إلى لفّه يدويًا بأقفال.
لماذا تحتاجها؟ في التطبيقات الحديثة متعددة الخيوط، غالبًا ما نحتاج إلى حالة مشتركة (shared state) تصل إليها عدة خيوط. المثال الكلاسيكي هو ذاكرة التخزين المؤقت (cache)، أو خادم ويب يعالج الطلبات في مجموعة خيوط (thread pool)، أو قاعدة بيانات داخل الذاكرة (in-memory database). استخدام Mutex<HashMap> قد يصبح عنق زجاجة (bottleneck)، لأن Mutex يقفل الخريطة بأكملها، حتى لو كانت الخيوط المختلفة تعمل على مفاتيح مختلفة. DashMap تستخدم تقنية "التقسيم" (sharding): حيث يتم تقسيم جدول التجزئة الداخلي إلى عدة أجزاء مستقلة (shards)، كل جزء محمي بقفل RwLock خاص به. هذا يسمح بتنفيذ عمليات قراءة وكتابة متزامنة على أجزاء مختلفة دون حجب متبادل، مما يُحقق زيادة كبيرة في الأداء على المعالجات متعددة النوى.
DashMap ليست مجرد غلاف آمن للخيوط. إنها توفر واجهة برمجة تطبيقات (API) غنية، تشمل التكرارات (iterators)، والعمليات الشرطية (compare-and-swap)، والإدراج مع الإرجاع، وغيرها الكثير. صُممت لتكون مريحة وبديهية للمطورين المعتادين على HashMap القياسية. إنها واحدة من أشهر المكتبات وأكثرها نضجًا في نظام Rust البيئي للعمل مع البيانات التشاركية.
2. التثبيت
لإضافة DashMap إلى مشروعك في Rust، استخدم مدير الحزم cargo. نفّذ الأمر التالي في الدليل الجذر لمشروعك:
cargo add dashmap
سيُضيف هذا الأمر أحدث إصدار من المكتبة إلى ملف Cargo.toml الخاص بك. إذا كنت تفضل القيام بذلك يدويًا، أضف السطر التالي إلى قسم [dependencies]:
[dependencies]
dashmap = "6.1"
وقت كتابة هذا الدليل، أحدث إصدار مستقر هو 6.1. يُنصح باستخدام الإصدار الأحدث، حيث أن المكتبة في تطور نشط.
3. البداية السريعة
فيما يلي مثال عملي بسيط يوضح كيفية إنشاء DashMap، وإدراج البيانات، وقراءتها، وحذفها.
use dashmap::DashMap;
fn main() {
// إنشاء خريطة تجزئة جديدة وفارغة
let map = DashMap::new();
// إدراج أزواج مفتاح-قيمة
map.insert("key1", 10);
map.insert("key2", 20);
// قراءة قيمة باستخدام المفتاح
if let Some(value) = map.get("key1") {
println!("قيمة 'key1' هي: {}", *value);
}
// تحديث قيمة
map.insert("key1", 100);
// حذف عنصر
map.remove("key2");
// التحقق من الطول
println!("عدد العناصر: {}", map.len());
}
يتم تجميع هذا المثال وتشغيله دون أي أقفال إضافية، وهذه هي الميزة الرئيسية لـ DashMap.
4. أهم الدوال (Methods)
دعنا نستعرض 8 دوال رئيسية في DashMap. جميع الأمثلة تفترض وجود use dash