Skip to main content

grafeo_common/
collections.rs

1//! Standard collection type aliases for Grafeo.
2//!
3//! Use these instead of direct HashMap/HashSet to allow future optimization
4//! and ensure consistent hashing across the codebase.
5//!
6//! # Type Aliases
7//!
8//! | Type | Use Case |
9//! |------|----------|
10//! | [`GrafeoMap`] | Single-threaded hash map |
11//! | [`GrafeoSet`] | Single-threaded hash set |
12//! | [`GrafeoConcurrentMap`] | Multi-threaded hash map |
13//! | [`GrafeoConcurrentSet`] | Multi-threaded hash set |
14//! | [`GrafeoIndexMap`] | Insertion-order preserving map |
15//! | [`GrafeoIndexSet`] | Insertion-order preserving set |
16//!
17//! # Example
18//!
19//! ```rust
20//! use grafeo_common::collections::{GrafeoMap, GrafeoSet};
21//!
22//! let mut map: GrafeoMap<String, i32> = GrafeoMap::default();
23//! map.insert("key".to_string(), 42);
24//!
25//! let mut set: GrafeoSet<i32> = GrafeoSet::default();
26//! set.insert(1);
27//! ```
28
29use crate::utils::hash::FxBuildHasher;
30
31/// Standard HashMap with FxHash (fast, non-cryptographic).
32///
33/// FxHash is optimized for small keys and provides excellent performance
34/// for integer and string keys common in graph databases.
35pub type GrafeoMap<K, V> = hashbrown::HashMap<K, V, FxBuildHasher>;
36
37/// Standard HashSet with FxHash.
38pub type GrafeoSet<T> = hashbrown::HashSet<T, FxBuildHasher>;
39
40/// Concurrent HashMap for multi-threaded access.
41///
42/// Uses fine-grained locking for high concurrent throughput.
43/// Prefer this over `Arc<Mutex<HashMap>>` for shared mutable state.
44pub type GrafeoConcurrentMap<K, V> = dashmap::DashMap<K, V, FxBuildHasher>;
45
46/// Concurrent HashSet for multi-threaded access.
47pub type GrafeoConcurrentSet<T> = dashmap::DashSet<T, FxBuildHasher>;
48
49/// Ordered map preserving insertion order.
50///
51/// Useful when iteration order matters (e.g., property serialization).
52pub type GrafeoIndexMap<K, V> = indexmap::IndexMap<K, V, FxBuildHasher>;
53
54/// Ordered set preserving insertion order.
55pub type GrafeoIndexSet<T> = indexmap::IndexSet<T, FxBuildHasher>;
56
57/// Create a new empty [`GrafeoMap`].
58#[inline]
59#[must_use]
60pub fn grafeo_map<K, V>() -> GrafeoMap<K, V> {
61    GrafeoMap::with_hasher(FxBuildHasher::default())
62}
63
64/// Create a new [`GrafeoMap`] with the specified capacity.
65#[inline]
66#[must_use]
67pub fn grafeo_map_with_capacity<K, V>(capacity: usize) -> GrafeoMap<K, V> {
68    GrafeoMap::with_capacity_and_hasher(capacity, FxBuildHasher::default())
69}
70
71/// Create a new empty [`GrafeoSet`].
72#[inline]
73#[must_use]
74pub fn grafeo_set<T>() -> GrafeoSet<T> {
75    GrafeoSet::with_hasher(FxBuildHasher::default())
76}
77
78/// Create a new [`GrafeoSet`] with the specified capacity.
79#[inline]
80#[must_use]
81pub fn grafeo_set_with_capacity<T>(capacity: usize) -> GrafeoSet<T> {
82    GrafeoSet::with_capacity_and_hasher(capacity, FxBuildHasher::default())
83}
84
85/// Create a new empty [`GrafeoConcurrentMap`].
86#[inline]
87#[must_use]
88pub fn grafeo_concurrent_map<K, V>() -> GrafeoConcurrentMap<K, V>
89where
90    K: Eq + std::hash::Hash,
91{
92    GrafeoConcurrentMap::with_hasher(FxBuildHasher::default())
93}
94
95/// Create a new [`GrafeoConcurrentMap`] with the specified capacity.
96#[inline]
97#[must_use]
98pub fn grafeo_concurrent_map_with_capacity<K, V>(capacity: usize) -> GrafeoConcurrentMap<K, V>
99where
100    K: Eq + std::hash::Hash,
101{
102    GrafeoConcurrentMap::with_capacity_and_hasher(capacity, FxBuildHasher::default())
103}
104
105/// Create a new empty [`GrafeoIndexMap`].
106#[inline]
107#[must_use]
108pub fn grafeo_index_map<K, V>() -> GrafeoIndexMap<K, V> {
109    GrafeoIndexMap::with_hasher(FxBuildHasher::default())
110}
111
112/// Create a new [`GrafeoIndexMap`] with the specified capacity.
113#[inline]
114#[must_use]
115pub fn grafeo_index_map_with_capacity<K, V>(capacity: usize) -> GrafeoIndexMap<K, V> {
116    GrafeoIndexMap::with_capacity_and_hasher(capacity, FxBuildHasher::default())
117}
118
119#[cfg(test)]
120mod tests {
121    use super::*;
122
123    #[test]
124    fn test_grafeo_map() {
125        let mut map = grafeo_map::<String, i32>();
126        map.insert("key".to_string(), 42);
127        assert_eq!(map.get("key"), Some(&42));
128    }
129
130    #[test]
131    fn test_grafeo_set() {
132        let mut set = grafeo_set::<i32>();
133        set.insert(1);
134        set.insert(2);
135        assert!(set.contains(&1));
136        assert!(!set.contains(&3));
137    }
138
139    #[test]
140    fn test_grafeo_concurrent_map() {
141        let map = grafeo_concurrent_map::<String, i32>();
142        map.insert("key".to_string(), 42);
143        assert_eq!(*map.get("key").unwrap(), 42);
144    }
145
146    #[test]
147    fn test_grafeo_index_map_preserves_order() {
148        let mut map = grafeo_index_map::<&str, i32>();
149        map.insert("c", 3);
150        map.insert("a", 1);
151        map.insert("b", 2);
152
153        let keys: Vec<_> = map.keys().copied().collect();
154        assert_eq!(keys, vec!["c", "a", "b"]);
155    }
156}