deferred_map/
secondary.rs

1use crate::utils::unlikely;
2use std::fmt;
3
4/// 存储值及其所属的代数(generation)。
5/// Internal slot storage for SecondaryMap.
6///
7/// Stores the value and the generation it belongs to.
8///
9/// SecondaryMap 的内部 slot 存储。
10/// 存储值及其所属的代数(generation)。
11#[derive(Clone, Debug)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub(crate) struct Slot<T> {
14    value: T,
15    generation: crate::Generation,
16}
17
18impl<T> Slot<T> {
19    #[inline(always)]
20    fn new(value: T, generation: crate::Generation) -> Self {
21        Self { value, generation }
22    }
23
24    #[inline(always)]
25    fn generation(&self) -> crate::Generation {
26        self.generation
27    }
28}
29
30/// A secondary map that associates data with keys from a `DeferredMap`.
31///
32/// `SecondaryMap` allows you to store additional information for each key in a `DeferredMap`.
33/// It is separate from the primary map and does not affect the primary map's memory layout.
34///
35/// Key Features:
36/// - **Sparse Storage**: Efficiently handles cases where not all keys in the primary map have associated data.
37/// - **Generation Checking**: Automatically validates compatibility with the primary map's keys.
38///   Stale keys (from older generations) will be ignored or overwritten as appropriate.
39/// - **Automatic Expansion**: The map automatically grows to accommodate keys with larger indices.
40///
41///
42/// 一个辅助映射(SecondaryMap),用于将数据与 `DeferredMap` 的 Key 关联。
43///
44/// `SecondaryMap` 允许你为 `DeferredMap` 中的每个 Key 存储额外信息。
45/// 它与主映射分离,不影响主映射的内存布局。
46///
47/// 主要特性:
48/// - **稀疏存储**:高效处理主映射中并非所有 Key 都有关联数据的情况。
49/// - **代数检查**:自动验证与主映射 Key 的兼容性。过期的 Key(来自旧代数)将被忽略或覆盖。
50/// - **自动扩展**:映射会自动增长以适应具有更大索引的 Key。
51///
52/// # Examples (示例)
53///
54/// ```
55/// use deferred_map::{DeferredMap, SecondaryMap};
56///
57/// let mut map = DeferredMap::new();
58/// let handle = map.allocate_handle();
59/// let key = handle.key();
60/// map.insert(handle, "Primary Value");
61///
62/// let mut sec_map = SecondaryMap::new();
63/// sec_map.insert(key, 100);
64///
65/// assert_eq!(sec_map.get(key), Some(&100));
66/// ```
67#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
68#[derive(Clone)]
69pub struct SecondaryMap<T, K: crate::Key = crate::DefaultKey> {
70    // We use Option to represent presence.
71    // None means no value associated with this index for the stored generation.
72    // Even if Some is present, we must check generation matching.
73    slots: Vec<Option<Slot<T>>>,
74    num_elems: usize,
75    #[cfg(debug_assertions)]
76    map_id: Option<u64>,
77    #[cfg_attr(feature = "serde", serde(skip))]
78    _marker: std::marker::PhantomData<K>,
79}
80
81impl<T, K: crate::Key> Default for SecondaryMap<T, K> {
82    fn default() -> Self {
83        Self::new()
84    }
85}
86
87impl<T, K: crate::Key> SecondaryMap<T, K> {
88    /// Create a new empty SecondaryMap
89    ///
90    /// 创建一个新的空 SecondaryMap
91    #[inline]
92    pub fn new() -> Self {
93        Self {
94            slots: Vec::new(),
95            num_elems: 0,
96            #[cfg(debug_assertions)]
97            map_id: None,
98            _marker: std::marker::PhantomData,
99        }
100    }
101
102    /// Create a SecondaryMap with specified capacity
103    ///
104    /// 创建一个指定容量的 SecondaryMap
105    #[inline]
106    pub fn with_capacity(capacity: usize) -> Self {
107        Self {
108            slots: Vec::with_capacity(capacity),
109            num_elems: 0,
110            #[cfg(debug_assertions)]
111            map_id: None,
112            _marker: std::marker::PhantomData,
113        }
114    }
115
116    /// Insert a value for a specific key
117    ///
118    /// If the key belongs to an older generation than what is currently stored, the insertion is ignored.
119    /// If the key is newer, it overwrites the existing value.
120    ///
121    /// 为特定 Key 插入值
122    ///
123    /// 如果 Key 的代数(generation)老于当前存储的代数,插入将被忽略。
124    /// 如果 Key 是新的,它将覆盖现有值。
125    ///
126    /// # Returns
127    /// - `Some(old_value)` if a value existed for the EXACT same key (same index and generation).
128    /// - `None` otherwise.
129    pub fn insert(&mut self, key: K, value: T) -> Option<T> {
130        #[cfg(debug_assertions)]
131        {
132            if let Some(id) = self.map_id {
133                debug_assert_eq!(
134                    id,
135                    key.map_id(),
136                    "Key used with wrong map instance in SecondaryMap"
137                );
138            } else {
139                self.map_id = Some(key.map_id());
140            }
141        }
142
143        let index = key.index();
144        let generation = key.generation();
145        let index = index as usize;
146
147        // Ensure we have enough slots
148        // 确保有足够的 slot
149        if index >= self.slots.len() {
150            let required_additional = index - self.slots.len() + 1;
151            self.slots.reserve(required_additional);
152            self.slots.resize_with(index + 1, || None);
153        }
154
155        let slot_opt = unsafe { self.slots.get_unchecked_mut(index) };
156
157        match slot_opt {
158            Some(slot) => {
159                if slot.generation() == generation {
160                    // Exact match, replace value
161                    // 完全匹配,替换值
162                    Some(std::mem::replace(&mut slot.value, value))
163                } else if slot.generation() < generation {
164                    // Stale slot (older generation), overwrite with new data
165                    // 槽位过期(旧代数),用新数据覆盖
166                    // Note: We don't return the old value because it belongs to a different entity (older gen)
167                    *slot = Slot::new(value, generation);
168                    None
169                } else {
170                    // Incoming key is older than stored data, ignore insert
171                    // 传入的 Key 比存储的数据旧,忽略插入
172                    None
173                }
174            }
175            None => {
176                // Empty slot, insert new
177                // 空槽位,插入新值
178                *slot_opt = Some(Slot::new(value, generation));
179                self.num_elems += 1;
180                None
181            }
182        }
183    }
184
185    /// Remove value by key
186    ///
187    /// Only removes if both index and generation match.
188    ///
189    /// 通过 Key 移除值
190    ///
191    /// 仅当索引和代数都匹配时才移除。
192    pub fn remove(&mut self, key: K) -> Option<T> {
193        #[cfg(debug_assertions)]
194        if let Some(id) = self.map_id {
195            debug_assert_eq!(
196                id,
197                key.map_id(),
198                "Key used with wrong map instance in SecondaryMap"
199            );
200        }
201
202        let index = key.index();
203        let generation = key.generation();
204        let index = index as usize;
205
206        if unlikely(index >= self.slots.len()) {
207            return None;
208        }
209
210        let slot_opt = unsafe { self.slots.get_unchecked_mut(index) };
211
212        if let Some(slot) = slot_opt {
213            if slot.generation() == generation {
214                self.num_elems -= 1;
215                return slot_opt.take().map(|s| s.value);
216            }
217        }
218
219        None
220    }
221
222    /// Get reference to value by key
223    ///
224    /// 通过 Key 获取值的引用
225    #[inline]
226    pub fn get(&self, key: K) -> Option<&T> {
227        #[cfg(debug_assertions)]
228        if let Some(id) = self.map_id {
229            debug_assert_eq!(
230                id,
231                key.map_id(),
232                "Key used with wrong map instance in SecondaryMap"
233            );
234        }
235
236        let index = key.index();
237        let generation = key.generation();
238        let index = index as usize;
239
240        if unlikely(index >= self.slots.len()) {
241            return None;
242        }
243
244        // SAFETY: Bounds checked above
245        match unsafe { self.slots.get_unchecked(index) } {
246            Some(slot) if slot.generation() == generation => Some(&slot.value),
247            _ => None,
248        }
249    }
250
251    /// Get mutable reference to value by key
252    ///
253    /// 通过 Key 获取值的可变引用
254    #[inline]
255    pub fn get_mut(&mut self, key: K) -> Option<&mut T> {
256        #[cfg(debug_assertions)]
257        if let Some(id) = self.map_id {
258            debug_assert_eq!(
259                id,
260                key.map_id(),
261                "Key used with wrong map instance in SecondaryMap"
262            );
263        }
264
265        let index = key.index();
266        let generation = key.generation();
267        let index = index as usize;
268
269        if unlikely(index >= self.slots.len()) {
270            return None;
271        }
272
273        // SAFETY: Bounds checked above
274        match unsafe { self.slots.get_unchecked_mut(index) } {
275            Some(slot) if slot.generation() == generation => Some(&mut slot.value),
276            _ => None,
277        }
278    }
279
280    /// Check if key exists
281    ///
282    /// 检查 Key 是否存在
283    #[inline]
284    pub fn contains_key(&self, key: K) -> bool {
285        self.get(key).is_some()
286    }
287
288    /// Return the number of elements
289    ///
290    /// 返回元素数量
291    #[inline]
292    pub fn len(&self) -> usize {
293        self.num_elems
294    }
295
296    /// Check if empty
297    ///
298    /// 检查是否为空
299    #[inline]
300    pub fn is_empty(&self) -> bool {
301        self.num_elems == 0
302    }
303
304    /// Capacity of the underlying vector
305    ///
306    /// 底层 vector 的容量
307    #[inline]
308    pub fn capacity(&self) -> usize {
309        self.slots.capacity()
310    }
311
312    /// Clear all elements
313    ///
314    /// Does not deallocate memory, but clears validity.
315    ///
316    /// 清空所有元素
317    /// 不会释放内存,但会清除有效性。
318    pub fn clear(&mut self) {
319        self.slots.clear();
320        self.num_elems = 0;
321        #[cfg(debug_assertions)]
322        {
323            self.map_id = None;
324        }
325    }
326
327    /// Retains only the elements specified by the predicate.
328    ///
329    /// 只保留满足谓词的元素。
330    pub fn retain<F>(&mut self, mut f: F)
331    where
332        F: FnMut(K, &mut T) -> bool,
333    {
334        for (index, slot_opt) in self.slots.iter_mut().enumerate() {
335            if let Some(slot) = slot_opt {
336                let key = K::from_parts(
337                    index as u32,
338                    slot.generation,
339                    #[cfg(debug_assertions)]
340                    self.map_id.unwrap_or(0),
341                );
342
343                if !f(key, &mut slot.value) {
344                    *slot_opt = None;
345                    self.num_elems -= 1;
346                }
347            }
348        }
349    }
350
351    /// Iterator over all (key, value) pairs
352    ///
353    /// 遍历所有 (key, value) 对的迭代器
354    pub fn iter(&self) -> impl Iterator<Item = (K, &T)> {
355        self.slots
356            .iter()
357            .enumerate()
358            .filter_map(move |(index, slot_opt)| {
359                slot_opt.as_ref().map(|slot| {
360                    let key = K::from_parts(
361                        index as u32,
362                        slot.generation,
363                        #[cfg(debug_assertions)]
364                        self.map_id.unwrap_or(0),
365                    );
366                    (key, &slot.value)
367                })
368            })
369    }
370
371    /// Mutable iterator over all (key, value) pairs
372    ///
373    /// 遍历所有 (key, value) 对的可变迭代器
374    pub fn iter_mut(&mut self) -> impl Iterator<Item = (K, &mut T)> {
375        #[cfg(debug_assertions)]
376        let map_id = self.map_id;
377
378        self.slots
379            .iter_mut()
380            .enumerate()
381            .filter_map(move |(index, slot_opt)| {
382                slot_opt.as_mut().map(|slot| {
383                    let key = K::from_parts(
384                        index as u32,
385                        slot.generation,
386                        #[cfg(debug_assertions)]
387                        map_id.unwrap_or(0),
388                    );
389                    (key, &mut slot.value)
390                })
391            })
392    }
393}
394
395impl<T: fmt::Debug> fmt::Debug for SecondaryMap<T> {
396    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
397        f.debug_map().entries(self.iter()).finish()
398    }
399}
400
401#[cfg(test)]
402mod tests {
403    use super::*;
404    use std::mem::size_of;
405
406    #[test]
407    fn test_slot_niche_optimization() {
408        // Slot<u32> layout:
409        // value: u32 (4 bytes)
410        // value: u32 (4 bytes)
411        // generation_p1: Generation (4 bytes)
412        // Total: 8 bytes
413        // Option<Slot<u32>>: Should be 8 bytes because strict NonZeroU32 allows 0 to be None.
414        assert_eq!(size_of::<Slot<u32>>(), 8);
415        assert_eq!(
416            size_of::<Option<Slot<u32>>>(),
417            8,
418            "Niche optimization failed for Slot<u32>"
419        );
420
421        // Slot<u64> layout:
422        // value: u64 (8 bytes)
423        // generation: Generation (4 bytes)
424        // padding: 4 bytes
425        // Total: 16 bytes. Alignment 8.
426        // Option<Slot<u64>>: Should use the niche in generation.
427        assert_eq!(size_of::<Slot<u64>>(), 16);
428        assert_eq!(
429            size_of::<Option<Slot<u64>>>(),
430            16,
431            "Niche optimization failed for Slot<u64>"
432        );
433    }
434}