cfx_storage/impls/delta_mpt/slab/mod.rs
1// Copyright 2019 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4
5//! Pre-allocated storage for a uniform data type.
6//!
7//! `Slab` provides pre-allocated storage for a single data type. If many values
8//! of a single type are being allocated, it can be more efficient to
9//! pre-allocate the necessary storage. Since the size of the type is uniform,
10//! memory fragmentation can be avoided. Storing, clearing, and lookup
11//! operations become very cheap.
12//!
13//! While `Slab` may look like other Rust collections, it is not intended to be
14//! used as a general purpose collection. The primary difference between `Slab`
15//! and `Vec` is that `Slab` returns the key when storing the value.
16//!
17//! It is important to note that keys may be reused. In other words, once a
18//! value associated with a given key is removed from a slab, that key may be
19//! returned from future calls to `insert`.
20//!
21//! # Examples
22//!
23//! Basic storing and retrieval.
24//!
25//! ```
26//! use cfx_storage::Slab;
27//! let mut slab: Slab<&str> = Slab::with_capacity(10);
28//!
29//! let hello = slab.insert("hello").unwrap();
30//! let world = slab.insert("world").unwrap();
31//!
32//! assert_eq!(slab[hello], "hello");
33//! assert_eq!(slab[world], "world");
34//!
35//! // Cannot IndexMut
36//! // slab[world] = "earth";
37//! // assert_eq!(slab[world], "earth");
38//! ```
39//!
40//! Sometimes it is useful to be able to associate the key with the value being
41//! inserted in the slab. This can be done with the `vacant_entry` API as such:
42//!
43//! ```
44//! use cfx_storage::Slab;
45//! let mut slab: Slab<(usize, &str)> = Slab::with_capacity(10);
46//!
47//! let hello = {
48//! let entry = slab.vacant_entry().unwrap();
49//! let key = entry.key();
50//! // this line prevents buggy doc test from triggering.
51//! entry.insert((key, "hello"));
52//! key
53//! };
54//!
55//! assert_eq!(hello, slab[hello].0);
56//! assert_eq!("hello", slab[hello].1);
57//! ```
58//!
59//! It is generally a good idea to specify the desired capacity of a slab at
60//! creation time. Note that `Slab` will grow the internal capacity when
61//! attempting to insert a new value once the existing capacity has been
62//! reached. To avoid this, add a check.
63//!
64//! ```
65//! use cfx_storage::Slab;
66//! let mut slab: Slab<&str> = Slab::with_capacity(1024);
67//!
68//! // ... use the slab
69//!
70//! if slab.len() == slab.capacity() {
71//! panic!("slab full");
72//! }
73//!
74//! slab.insert("the slab is not at capacity yet");
75//! ```
76//!
77//! # Capacity and reallocation
78//!
79//! The capacity of a slab is the amount of space allocated for any future
80//! values that will be inserted in the slab. This is not to be confused with
81//! the *length* of the slab, which specifies the number of actual values
82//! currently being inserted. If a slab's length is equal to its capacity, the
83//! next value inserted into the slab will require growing the slab by
84//! reallocating.
85//!
86//! For example, a slab with capacity 10 and length 0 would be an empty slab
87//! with space for 10 more stored values. Storing 10 or fewer elements into the
88//! slab will not change its capacity or cause reallocation to occur. However,
89//! if the slab length is increased to 11 (due to another `insert`), it will
90//! have to reallocate, which can be slow. For this reason, it is recommended to
91//! use [`Slab::with_capacity`] whenever possible to specify how many values the
92//! slab is expected to store.
93//!
94//! # Implementation
95//!
96//! `Slab` is backed by a `Vec` of slots. Each slot is either occupied or
97//! vacant. `Slab` maintains a stack of vacant slots using a linked list. To
98//! find a vacant slot, the stack is popped. When a slot is released, it is
99//! pushed onto the stack.
100//!
101//! If there are no more available slots in the stack, then `Vec::reserve(1)` is
102//! called and a new slot is created.
103//!
104//! [`Slab::with_capacity`]: struct.Slab.html#with_capacity
105
106#![allow(unknown_lints, missing_safety_doc)]
107#![deny(warnings, missing_debug_implementations)]
108
109use super::super::{
110 super::utils::{UnsafeCellExtension, WrappedCreateFrom},
111 errors::*,
112};
113use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
114use parking_lot::Mutex;
115use std::{
116 cell::UnsafeCell, fmt, iter::IntoIterator, marker::PhantomData, ops, ptr,
117 slice,
118};
119
120/// Pre-allocated storage for a uniform data type.
121/// The modified slab offers thread-safety without giant lock by mimicking the
122/// behavior of independent pointer at best.
123///
124/// Resizing the slab itself requires &mut, other operations can be done with &.
125///
126/// Getting reference to allocated slot doesn't conflict with any other
127/// operations. Slab doesn't check if user get &mut and & for the same slot.
128/// User should maintain a layer which controls the mutability of each specific
129/// slot. It can be done through the wrapper around the slot index, or in the
130/// type which implements `EntryTrait<T>`.
131///
132/// Allocation and Deallocation are serialized by mutex because they modify the
133/// slab link-list.
134pub struct Slab<T, E: EntryTrait<EntryType = T> = Entry<T>> {
135 /// Chunk of memory
136 // entries is always kept full in order to prevent changing vector
137 // when allocating space for new element. We would like to keep the size of
138 // initialized entry in AllocRelatedFields#size_initialized instead of
139 // vector.
140 entries: Vec<UnsafeCell<E>>,
141
142 /// Fields which are modified when allocate / delete an entry.
143 alloc_fields: Mutex<AllocRelatedFields>,
144
145 value_type: PhantomData<T>,
146}
147
148impl<T, E: EntryTrait<EntryType = T> + MallocSizeOf> MallocSizeOf
149 for Slab<T, E>
150{
151 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
152 self.entries.size_of(ops)
153 }
154}
155
156unsafe impl<T, E: EntryTrait<EntryType = T>> Sync for Slab<T, E> {}
157
158#[derive(Default)]
159struct AllocRelatedFields {
160 // Number of Filled elements currently in the slab
161 used: usize,
162 // Size of the memory where it's initialized with data or offset to next
163 // available slot.
164 size_initialized: usize,
165 // Offset of the next available slot in the slab. Set to the slab's
166 // capacity when the slab is full.
167 next: usize,
168}
169
170/// Slab physically stores a concrete type which implements `EntryTrait<T>` for
171/// value type T. The `EntryTrait<T>` is responsible to hold the value type and
172/// the next vacant link list for slab.
173pub trait EntryTrait: Sized + Default {
174 type EntryType;
175
176 fn from_value(value: Self::EntryType) -> Self;
177
178 fn from_vacant_index(next: usize) -> Self;
179
180 fn is_vacant(&self) -> bool;
181
182 fn take_occupied_and_replace_with_vacant_index(
183 &mut self, next: usize,
184 ) -> Self::EntryType {
185 unsafe {
186 let ret = ptr::read(self.get_occupied_mut());
187 // Semantically, val is moved into ret and self is dropped.
188
189 ptr::write(self, Self::from_vacant_index(next));
190 // Semantically, new is dropped, self now holds new.
191
192 ret
193 }
194 }
195
196 fn get_next_vacant_index(&self) -> usize;
197 fn get_occupied_ref(&self) -> &Self::EntryType;
198 fn get_occupied_mut(&mut self) -> &mut Self::EntryType;
199}
200
201impl<T: EntryTrait<EntryType = T>> EntryTrait for UnsafeCell<T> {
202 type EntryType = UnsafeCell<T>;
203
204 fn from_value(value: UnsafeCell<T>) -> Self {
205 UnsafeCell::new(T::from_value(value.into_inner()))
206 }
207
208 fn from_vacant_index(next: usize) -> Self {
209 UnsafeCell::new(T::from_vacant_index(next))
210 }
211
212 fn is_vacant(&self) -> bool { self.get_ref().is_vacant() }
213
214 fn take_occupied_and_replace_with_vacant_index(
215 &mut self, next: usize,
216 ) -> UnsafeCell<T> {
217 unsafe {
218 let ret = ptr::read(self.get_occupied_mut());
219 // Semantically, val is moved into ret and self is dropped.
220
221 ptr::write(self.get_mut(), T::from_vacant_index(next));
222 // Semantically, new is dropped, self now holds new.
223
224 ret
225 }
226 }
227
228 fn get_next_vacant_index(&self) -> usize {
229 self.get_ref().get_next_vacant_index()
230 }
231
232 fn get_occupied_ref(&self) -> &UnsafeCell<T> { self }
233
234 fn get_occupied_mut(&mut self) -> &mut UnsafeCell<T> { self }
235}
236
237impl<T> EntryTrait for Entry<T> {
238 type EntryType = T;
239
240 fn from_value(value: T) -> Self { Entry::Occupied(value) }
241
242 fn from_vacant_index(index: usize) -> Self { Entry::Vacant(index) }
243
244 fn is_vacant(&self) -> bool { matches!(self, Entry::Vacant(_)) }
245
246 fn get_next_vacant_index(&self) -> usize {
247 match *self {
248 Entry::Vacant(index) => index,
249 _ => unreachable!(),
250 }
251 }
252
253 fn get_occupied_ref(&self) -> &T {
254 match self {
255 Entry::Occupied(val) => val,
256 _ => unreachable!(),
257 }
258 }
259
260 fn get_occupied_mut(&mut self) -> &mut T {
261 match self {
262 Entry::Occupied(val) => val,
263 _ => unreachable!(),
264 }
265 }
266}
267
268impl<E: EntryTrait> WrappedCreateFrom<E::EntryType, E> for E {
269 fn take(val: E::EntryType) -> E { E::from_value(val) }
270}
271
272// TODO: Check future rust compiler support. It's quite unfortunate that the
273// TODO: current rust compiler think that the commented out code conflict with
274// TODO: the one above. We implemented UnsafeCell EntryTrait in
275// TODO: super::merkle_patricia_trie.
276/*
277impl<'x, E: EntryTrait> WrappedCreateFrom<&'x E::EntryType, E> for E where E::EntryType : Clone {
278 fn take(val: &'x E::EntryType) -> E {
279 E::from_value(val.clone())
280 }
281}
282*/
283
284impl<'x, T: Clone> WrappedCreateFrom<&'x T, Entry<T>> for Entry<T> {
285 fn take(val: &'x T) -> Self { Entry::Occupied(val.clone()) }
286
287 fn take_from(dest: &mut Entry<T>, val: &'x T) {
288 match dest {
289 Entry::Occupied(t_dest) => {
290 t_dest.clone_from(val);
291 }
292 Entry::Vacant(_) => {
293 *dest = Entry::Occupied(val.clone());
294 }
295 }
296 }
297}
298
299impl<'x, T: Clone> WrappedCreateFrom<&'x T, Entry<UnsafeCell<T>>>
300 for Entry<UnsafeCell<T>>
301{
302 fn take(val: &'x T) -> Self {
303 Entry::Occupied(UnsafeCell::new(val.clone()))
304 }
305
306 fn take_from(dest: &mut Entry<UnsafeCell<T>>, val: &'x T) {
307 match dest {
308 Entry::Occupied(unsafecell_dest) => {
309 unsafecell_dest.get_mut().clone_from(val);
310 }
311 Entry::Vacant(_) => {
312 *dest = Entry::Occupied(UnsafeCell::new(val.clone()));
313 }
314 }
315 }
316}
317
318/// A handle to a vacant entry in a `Slab`.
319///
320/// `VacantEntry` allows constructing values with the key that they will be
321/// assigned to.
322///
323/// # Examples
324/// ```
325/// # use cfx_storage::Slab;
326/// let mut slab: Slab<(usize, &str)> = Slab::with_capacity(10);
327///
328/// let hello = {
329/// let entry = slab.vacant_entry().unwrap();
330/// let key = entry.key();
331/// // this line prevents buggy doc test from triggering.
332/// entry.insert((key, "hello"));
333/// key
334/// };
335///
336/// assert_eq!(hello, slab[hello].0);
337/// assert_eq!("hello", slab[hello].1);
338/// ```
339#[derive(Debug)]
340pub struct VacantEntry<'a, T: 'a, E: 'a + EntryTrait<EntryType = T>> {
341 slab: &'a Slab<T, E>,
342 key: usize,
343 // Panic if insert is not called at all because the allocated slot must be
344 // initialized.
345 inserted: bool,
346}
347
348impl<'a, T: 'a, E: 'a + EntryTrait<EntryType = T>> Drop
349 for VacantEntry<'a, T, E>
350{
351 fn drop(&mut self) { assert!(self.inserted) }
352}
353
354/// A mutable iterator over the values stored in the `Slab`
355pub struct IterMut<'a, T: 'a, E: 'a + EntryTrait<EntryType = T>> {
356 entries: slice::IterMut<'a, UnsafeCell<E>>,
357 curr: usize,
358 value_type: PhantomData<T>,
359}
360
361#[derive(Clone, Debug)]
362pub enum Entry<T> {
363 Vacant(usize),
364 Occupied(T),
365}
366
367impl<T: MallocSizeOf> MallocSizeOf for Entry<T> {
368 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
369 match self {
370 Entry::Vacant(_) => 0,
371 Entry::Occupied(e) => e.size_of(ops),
372 }
373 }
374}
375
376impl<T> Default for Entry<T> {
377 fn default() -> Self { Entry::Vacant(0) }
378}
379
380impl<T, E: EntryTrait<EntryType = T>> Default for Slab<T, E> {
381 fn default() -> Self {
382 Self {
383 entries: Default::default(),
384 alloc_fields: Default::default(),
385 value_type: PhantomData,
386 }
387 }
388}
389
390impl<T, E: EntryTrait<EntryType = T>> Slab<T, E> {
391 /// Construct a new, empty `Slab` with the specified capacity.
392 ///
393 /// The returned slab will be able to store exactly `capacity` without
394 /// reallocating. If `capacity` is 0, the slab will not allocate.
395 ///
396 /// It is important to note that this function does not specify the *length*
397 /// of the returned slab, but only the capacity. For an explanation of the
398 /// difference between length and capacity, see [Capacity and
399 /// reallocation](index.html#capacity-and-reallocation).
400 ///
401 /// # Examples
402 ///
403 /// # use cfx_storage::Slab;
404 /// let mut slab = Slab::with_capacity(10);
405 ///
406 /// // The slab contains no values, even though it has capacity for more
407 /// assert_eq!(slab.len(), 0);
408 ///
409 /// // These are all done without reallocating...
410 /// for i in 0..10 {
411 /// slab.insert(i);
412 /// }
413 ///
414 /// // ...but this may make the slab reallocate
415 /// slab.insert(11);
416 pub fn with_capacity(capacity: usize) -> Self {
417 let mut new = Slab::default();
418 new.reserve(capacity).unwrap();
419 new
420 }
421
422 /// Return the number of values the slab can store without reallocating.
423 ///
424 /// # Examples
425 ///
426 /// # use cfx_storage::Slab;
427 /// ```
428 /// use cfx_storage::Slab;
429 /// let slab: Slab<i32> = Slab::with_capacity(10);
430 /// assert_eq!(slab.capacity(), 10);
431 /// ```
432 pub fn capacity(&self) -> usize { self.entries.capacity() }
433
434 /// Reserve capacity for at least `additional` more values to be stored
435 /// without allocating.
436 ///
437 /// `reserve` does nothing if the slab already has sufficient capacity for
438 /// `additional` more values. If more capacity is required, a new segment of
439 /// memory will be allocated and all existing values will be copied into it.
440 /// As such, if the slab is already very large, a call to `reserve` can end
441 /// up being expensive.
442 ///
443 /// The slab may reserve more than `additional` extra space in order to
444 /// avoid frequent reallocations. Use `reserve_exact` instead to guarantee
445 /// that only the requested space is allocated.
446 ///
447 /// # Panics
448 ///
449 /// Panics if the new capacity overflows `usize`.
450 ///
451 /// # Examples
452 ///
453 /// # use cfx_storage::Slab;
454 /// let mut slab = Slab::with_capacity(10);
455 /// slab.insert("hello");
456 /// slab.reserve(10);
457 /// assert!(slab.capacity() >= 11);
458 pub fn reserve(&mut self, additional: usize) -> Result<()> {
459 let old_capacity = self.capacity();
460 if old_capacity - self.len() >= additional {
461 return Ok(());
462 }
463 let need_add = self.len() + additional - old_capacity;
464 self.entries.reserve(need_add);
465 // TODO(yz): should return error instead of panic, however, try_reserve*
466 // is only in nightly.
467 // self.entries.
468 // try_reserve(need_add).chain_err(|| ErrorKind::OutOfMem)?;
469 let capacity = self.capacity();
470 self.resize_up(old_capacity, capacity);
471 Ok(())
472 }
473
474 /// Reserve the minimum capacity required to store exactly `additional`
475 /// more values.
476 ///
477 /// `reserve_exact` does nothing if the slab already has sufficient capacity
478 /// for `additional` more values. If more capacity is required, a new
479 /// segment of memory will be allocated and all existing values will be
480 /// copied into it. As such, if the slab is already very large, a call
481 /// to `reserve` can end up being expensive.
482 ///
483 /// Note that the allocator may give the slab more space than it requests.
484 /// Therefore capacity can not be relied upon to be precisely minimal.
485 /// Prefer `reserve` if future insertions are expected.
486 ///
487 /// # Panics
488 ///
489 /// Panics if the new capacity overflows `usize`.
490 ///
491 /// # Examples
492 ///
493 /// # use cfx_storage::Slab;
494 /// let mut slab = Slab::with_capacity(10);
495 /// slab.insert("hello");
496 /// slab.reserve_exact(10);
497 /// assert!(slab.capacity() >= 11);
498 pub fn reserve_exact(&mut self, additional: usize) -> Result<()> {
499 let old_capacity = self.capacity();
500 if old_capacity - self.len() >= additional {
501 return Ok(());
502 }
503 let need_add = self.len() + additional - old_capacity;
504 // TODO(yz): should return error instead of panic, however, try_reserve*
505 // is only in nightly.
506 // self.entries.
507 // try_reserve_exact(need_add).chain_err(|| ErrorKind::OutOfMem)?;
508 self.entries.reserve_exact(need_add);
509 let capacity = self.capacity();
510 self.resize_up(old_capacity, capacity);
511 Ok(())
512 }
513
514 // TODO(yz): resize_default is nightly only.
515 fn resize_up(&mut self, capacity: usize, new_capacity: usize) {
516 for _i in capacity..new_capacity {
517 self.entries.push(Default::default());
518 }
519 }
520
521 fn resize_down(&mut self, capacity: usize, new_capacity: usize) {
522 for _i in new_capacity..capacity {
523 self.entries.pop();
524 }
525 }
526
527 /// Shrink the capacity of the slab as much as possible.
528 ///
529 /// It will drop down as close as possible to the length but the allocator
530 /// may still inform the vector that there is space for a few more elements.
531 /// Also, since values are not moved, the slab cannot shrink past any stored
532 /// values.
533 ///
534 /// # Examples
535 ///
536 /// # use cfx_storage::Slab;
537 /// let mut slab = Slab::with_capacity(10);
538 ///
539 /// for i in 0..3 {
540 /// slab.insert(i);
541 /// }
542 ///
543 /// assert_eq!(slab.capacity(), 10);
544 /// slab.shrink_to_fit();
545 /// assert!(slab.capacity() >= 3);
546 ///
547 /// In this case, even though two values are removed, the slab cannot shrink
548 /// past the last value.
549 ///
550 /// # use cfx_storage::Slab;
551 /// let mut slab = Slab::with_capacity(10);
552 ///
553 /// for i in 0..3 {
554 /// slab.insert(i);
555 /// }
556 ///
557 /// slab.remove(0);
558 /// slab.remove(1);
559 ///
560 /// assert_eq!(slab.capacity(), 10);
561 /// slab.shrink_to_fit();
562 /// assert!(slab.capacity() >= 3);
563 pub fn shrink_to_fit(&mut self) {
564 let capacity = self.capacity();
565 let new_capacity = self.alloc_fields.get_mut().size_initialized;
566
567 self.resize_down(capacity, new_capacity);
568 self.entries.shrink_to_fit();
569 }
570
571 /// Clear the slab of all values.
572 ///
573 /// # Examples
574 ///
575 /// # use cfx_storage::Slab;
576 /// let mut slab = Slab::with_capacity(10);
577 ///
578 /// for i in 0..3 {
579 /// slab.insert(i);
580 /// }
581 ///
582 /// slab.clear();
583 /// assert!(slab.is_empty());
584 pub fn clear(&mut self) { std::mem::take(self); }
585
586 /// Return the number of stored values.
587 ///
588 /// # Examples
589 ///
590 /// # use cfx_storage::Slab;
591 /// let mut slab = Slab::with_capacity(10);
592 ///
593 /// for i in 0..3 {
594 /// slab.insert(i);
595 /// }
596 ///
597 /// assert_eq!(3, slab.len());
598 pub fn len(&self) -> usize { self.alloc_fields.lock().used }
599
600 /// Return `true` if there are no values stored in the slab.
601 ///
602 /// # Examples
603 ///
604 /// # use cfx_storage::Slab;
605 /// let mut slab = Slab::with_capacity(10);
606 /// assert!(slab.is_empty());
607 ///
608 /// slab.insert(1);
609 /// assert!(!slab.is_empty());
610 pub fn is_empty(&self) -> bool { self.len() == 0 }
611
612 /// Return an iterator that allows modifying each value.
613 ///
614 /// This function should generally be **avoided** as it is not efficient.
615 /// Iterators must iterate over every slot in the slab even if it is
616 /// vacant. As such, a slab with a capacity of 1 million but only one
617 /// stored value must still iterate the million slots.
618 ///
619 /// # Examples
620 ///
621 /// ```
622 /// # use cfx_storage::Slab;
623 /// let mut slab: Slab<usize> = Slab::with_capacity(10);
624 ///
625 /// let key1 = slab.insert(0).unwrap();
626 /// let key2 = slab.insert(1).unwrap();
627 ///
628 /// for (key, val) in slab.iter_mut() {
629 /// if key == key1 {
630 /// *val += 2;
631 /// }
632 /// }
633 ///
634 /// assert_eq!(slab[key1], 2);
635 /// assert_eq!(slab[key2], 1);
636 /// ```
637 pub fn iter_mut(&mut self) -> IterMut<'_, T, E> {
638 IterMut {
639 entries: self.entries
640 [0..self.alloc_fields.get_mut().size_initialized]
641 .iter_mut(),
642 curr: 0,
643 value_type: PhantomData,
644 }
645 }
646
647 /// Return a reference to the value associated with the given key.
648 ///
649 /// If the given key is not associated with a value, then `None` is
650 /// returned.
651 ///
652 /// # Examples
653 ///
654 /// # use cfx_storage::Slab;
655 /// let mut slab = Slab::with_capacity(10);
656 /// let key = slab.insert("hello");
657 ///
658 /// assert_eq!(slab.get(key), Some(&"hello"));
659 /// assert_eq!(slab.get(123), None);
660 pub fn get(&self, key: usize) -> Option<&T> {
661 self.entries.get(key).and_then(|entry| {
662 if entry.get_ref().is_vacant() {
663 None
664 } else {
665 Some(entry.get_ref().get_occupied_ref())
666 }
667 })
668 }
669
670 /// Return a mutable reference to the value associated with the given key.
671 ///
672 /// If the given key is not associated with a value, then `None` is
673 /// returned.
674 ///
675 /// # Examples
676 ///
677 /// ```
678 /// use cfx_storage::Slab;
679 /// let mut slab: Slab<&str> = Slab::with_capacity(10);
680 /// let key = slab.insert("hello").unwrap();
681 ///
682 /// *slab.get_mut(key).unwrap() = "world";
683 ///
684 /// assert_eq!(slab[key], "world");
685 /// assert_eq!(slab.get_mut(123), None);
686 /// ```
687 // This method is unsafe because user may pass the same key to get_mut at
688 // the same time.
689 pub fn get_mut(&mut self, key: usize) -> Option<&mut T> {
690 self.entries.get_mut(key).and_then(|entry| {
691 if entry.get_ref().is_vacant() {
692 None
693 } else {
694 Some(entry.get_mut().get_occupied_mut())
695 }
696 })
697 }
698
699 /// Return a reference to the value associated with the given key without
700 /// performing bounds checking.
701 ///
702 /// This function should be used with care.
703 ///
704 /// # Examples
705 ///
706 /// # use cfx_storage::Slab;
707 /// let mut slab = Slab::with_capacity(10);
708 /// let key = slab.insert(2);
709 ///
710 /// unsafe {
711 /// assert_eq!(slab.get_unchecked(key), &2);
712 /// }
713 pub unsafe fn get_unchecked(&self, key: usize) -> &T {
714 self.entries.get_unchecked(key).get_ref().get_occupied_ref()
715 }
716
717 /// Return a mutable reference to the value associated with the given key
718 /// without performing bounds checking.
719 ///
720 /// This function should be used with care.
721 ///
722 /// # Examples
723 ///
724 /// ```
725 /// use cfx_storage::Slab;
726 /// let mut slab: Slab<u32> = Slab::with_capacity(10);
727 /// let key = slab.insert(2).unwrap();
728 ///
729 /// unsafe {
730 /// let val = slab.get_unchecked_mut(key);
731 /// *val = 13;
732 /// }
733 ///
734 /// assert_eq!(slab[key], 13);
735 /// ```
736 pub unsafe fn get_unchecked_mut(&mut self, key: usize) -> &mut T {
737 self.entries
738 .get_unchecked_mut(key)
739 .get_mut()
740 .get_occupied_mut()
741 }
742
743 /// Insert a value in the slab, returning key assigned to the value.
744 ///
745 /// The returned key can later be used to retrieve or remove the value using
746 /// indexed lookup and `remove`. Additional capacity is allocated if
747 /// needed. See [Capacity and
748 /// reallocation](index.html#capacity-and-reallocation).
749 ///
750 /// # Panics
751 ///
752 /// Panics if the number of elements in the vector overflows a `usize`.
753 ///
754 /// # Examples
755 /// ```
756 /// use cfx_storage::Slab;
757 /// let mut slab: Slab<&str> = Slab::with_capacity(10);
758 /// let key = slab.insert("hello").unwrap();
759 /// assert_eq!(slab[key], "hello");
760 /// ```
761 pub fn insert<U>(&self, val: U) -> Result<usize>
762 where E: WrappedCreateFrom<U, E> {
763 let key = self.allocate()?;
764 self.insert_at(key, val);
765 Ok(key)
766 }
767
768 pub fn allocate(&self) -> Result<usize> {
769 let mut alloc_fields = self.alloc_fields.lock();
770 let key = alloc_fields.next;
771 if key == self.entries.capacity() {
772 Err(Error::OutOfMem)
773 } else {
774 alloc_fields.used += 1;
775 if key == alloc_fields.size_initialized {
776 alloc_fields.next = key + 1;
777 alloc_fields.size_initialized = alloc_fields.next;
778 } else {
779 alloc_fields.next =
780 self.entries[key].get_ref().get_next_vacant_index();
781 }
782 Ok(key)
783 }
784 }
785
786 /// Cast an entry to ref mut when creating value into the slot or freeing
787 /// value from the slot.
788 fn cast_entry_ref_mut(&self, key: usize) -> &mut E {
789 unsafe { self.entries.get_unchecked(key).get_as_mut() }
790 }
791
792 fn insert_at<U>(&self, key: usize, val: U) -> &mut T
793 where E: WrappedCreateFrom<U, E> {
794 let entry = self.cast_entry_ref_mut(key);
795 E::take_from(entry, val);
796 entry.get_occupied_mut()
797 }
798
799 /// Return a handle to a vacant entry allowing for further manipulation.
800 ///
801 /// This function is useful when creating values that must contain their
802 /// slab key. The returned `VacantEntry` reserves a slot in the slab and is
803 /// able to query the associated key.
804 ///
805 /// # Examples
806 ///
807 /// ```
808 /// use cfx_storage::Slab;
809 /// let mut slab: Slab<(usize, &str)> = Slab::with_capacity(10);
810 ///
811 /// let hello = {
812 /// let entry = slab.vacant_entry().unwrap();
813 /// let key = entry.key();
814 /// // this line prevents buggy doc test from triggering.
815 /// entry.insert((key, "hello"));
816 /// key
817 /// };
818 ///
819 /// assert_eq!(hello, slab[hello].0);
820 /// assert_eq!("hello", slab[hello].1);
821 /// ```
822 pub fn vacant_entry(&self) -> Result<VacantEntry<'_, T, E>> {
823 Ok(VacantEntry {
824 key: self.allocate()?,
825 slab: self,
826 inserted: false,
827 })
828 }
829
830 /// Remove and return the value associated with the given key.
831 ///
832 /// The key is then released and may be associated with future stored
833 /// values.
834 ///
835 /// # Panics
836 ///
837 /// Panics if `key` is not associated with a value.
838 ///
839 /// # Examples
840 ///
841 /// # use cfx_storage::Slab;
842 /// let mut slab = Slab::with_capacity(10);
843 ///
844 /// let hello = slab.insert("hello");
845 ///
846 /// assert_eq!(slab.remove(hello), "hello");
847 /// assert!(!slab.contains(hello));
848 pub fn remove(&self, key: usize) -> Result<T> {
849 if key > self.entries.len() {
850 // Index out of range.
851 return Err(Error::SlabKeyError);
852 }
853 let mut alloc_fields = self.alloc_fields.lock();
854 let next = alloc_fields.next;
855 let entry = self.cast_entry_ref_mut(key);
856 if entry.is_vacant() {
857 // Trying to free unallocated space.
858 Err(Error::SlabKeyError)
859 } else {
860 alloc_fields.used -= 1;
861 alloc_fields.next = key;
862 Ok(entry.take_occupied_and_replace_with_vacant_index(next))
863 }
864 }
865
866 /// Return `true` if a value is associated with the given key.
867 ///
868 /// # Examples
869 ///
870 /// # use cfx_storage::Slab;
871 /// let mut slab = Slab::with_capacity(10);
872 ///
873 /// let hello = slab.insert("hello");
874 /// assert!(slab.contains(hello));
875 ///
876 /// slab.remove(hello);
877 ///
878 /// assert!(!slab.contains(hello));
879 pub fn contains(&self, key: usize) -> bool { self.get(key).is_some() }
880
881 /// Retain only the elements specified by the predicate.
882 ///
883 /// In other words, remove all elements `e` such that `f(usize, &mut e)`
884 /// returns false. This method operates in place and preserves the key
885 /// associated with the retained values.
886 ///
887 /// # Examples
888 ///
889 /// # use cfx_storage::Slab;
890 /// let mut slab = Slab::with_capacity(10);
891 ///
892 /// let k1 = slab.insert(0);
893 /// let k2 = slab.insert(1);
894 /// let k3 = slab.insert(2);
895 ///
896 /// slab.retain(|key, val| key == k1 || *val == 1);
897 ///
898 /// assert!(slab.contains(k1));
899 /// assert!(slab.contains(k2));
900 /// assert!(!slab.contains(k3));
901 ///
902 /// assert_eq!(2, slab.len());
903 pub fn retain<F>(&mut self, mut f: F)
904 where F: FnMut(usize, &mut T) -> bool {
905 for i in 0..self.entries.len() {
906 let keep = self.get_mut(i).is_none_or(|v| f(i, v));
907
908 if !keep {
909 self.remove(i).unwrap();
910 }
911 }
912 }
913}
914
915impl<T, E: EntryTrait<EntryType = T>> ops::Index<usize> for Slab<T, E> {
916 type Output = T;
917
918 fn index(&self, key: usize) -> &T {
919 self.entries[key].get_ref().get_occupied_ref()
920 }
921}
922
923impl<'a, T, E: EntryTrait<EntryType = T>> IntoIterator for &'a mut Slab<T, E> {
924 type IntoIter = IterMut<'a, T, E>;
925 type Item = (usize, &'a mut T);
926
927 fn into_iter(self) -> IterMut<'a, T, E> { self.iter_mut() }
928}
929
930impl<T, E: EntryTrait<EntryType = T>> fmt::Debug for Slab<T, E>
931where T: fmt::Debug
932{
933 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
934 write!(
935 fmt,
936 "Slab {{ len: {}, cap: {} }}",
937 self.len(),
938 self.capacity()
939 )
940 }
941}
942
943impl<'a, T: 'a, E: EntryTrait<EntryType = T>> fmt::Debug for IterMut<'a, T, E>
944where T: fmt::Debug
945{
946 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
947 fmt.debug_struct("IterMut")
948 .field("curr", &self.curr)
949 .field("remaining", &self.entries.len())
950 .finish()
951 }
952}
953
954// ===== VacantEntry =====
955
956impl<'a, T, E: EntryTrait<EntryType = T>> VacantEntry<'a, T, E> {
957 /// Insert a value in the entry, returning a mutable reference to the value.
958 ///
959 /// To get the key associated with the value, use `key` prior to calling
960 /// `insert`.
961 ///
962 /// # Examples
963 ///
964 /// ```
965 /// use cfx_storage::Slab;
966 /// let mut slab: Slab<(usize, &str)> = Slab::with_capacity(10);
967 ///
968 /// let hello = {
969 /// let entry = slab.vacant_entry().unwrap();
970 /// let key = entry.key();
971 /// // this line prevents buggy doc test from triggering.
972 /// entry.insert((key, "hello"));
973 /// key
974 /// };
975 ///
976 /// assert_eq!(hello, slab[hello].0);
977 /// assert_eq!("hello", slab[hello].1);
978 /// ```
979 pub fn insert<U>(mut self, val: U) -> &'a mut T
980 where E: WrappedCreateFrom<U, E> {
981 self.inserted = true;
982 self.slab.insert_at(self.key, val)
983 }
984
985 /// Return the key associated with this entry.
986 ///
987 /// A value stored in this entry will be associated with this key.
988 ///
989 /// # Examples
990 ///
991 /// ```
992 /// use cfx_storage::Slab;
993 /// let mut slab: Slab<(usize, &str)> = Slab::with_capacity(10);
994 ///
995 /// let hello = {
996 /// let entry = slab.vacant_entry().unwrap();
997 /// let key = entry.key();
998 /// // this line prevents buggy doc test from triggering.
999 /// entry.insert((key, "hello"));
1000 /// key
1001 /// };
1002 ///
1003 /// assert_eq!(hello, slab[hello].0);
1004 /// assert_eq!("hello", slab[hello].1);
1005 /// ```
1006 pub fn key(&self) -> usize { self.key }
1007}
1008
1009// ===== IterMut =====
1010
1011impl<'a, T, E: EntryTrait<EntryType = T>> Iterator for IterMut<'a, T, E> {
1012 type Item = (usize, &'a mut T);
1013
1014 fn next(&mut self) -> Option<(usize, &'a mut T)> {
1015 for entry in &mut self.entries {
1016 let curr = self.curr;
1017 self.curr += 1;
1018
1019 if !entry.get_ref().is_vacant() {
1020 return Some((curr, entry.get_mut().get_occupied_mut()));
1021 }
1022 }
1023
1024 None
1025 }
1026}