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}