slicedvec/
lib.rs

1#![allow(dead_code)]
2//! Two structs are provided: `SlicedVec` and `SlicedSlab`. The target use-case is a need to repeatedly
3//! construct and drop short, run-time sized sequences of floats. Using a `Vec<Vec<T>>` may cause allocator thrashing,
4//! unless a pool or some other mechanism is used. `SlicedVec` stores a
5//! collection of run-time sized slices in a single vector. It emulates a `Vec<&[T]>` but owns and manages
6//! its own storage. Methods are available for constant-time, non-order-preserving insertion and deletion.
7//! Repeated generations of `push` and `swap_remove` (or `swap_truncate`) will not allocate because the capacity
8//! of the storage will grow as needed.
9//!
10//! `SlicedSlab` is built on `SlicedVec` and returns stable keys to allocated sequences of values. When a sequence
11//! is inserted into the slab, it returns a key. The sequence can be retrieved or removed from the slab using the key.
12//! Removal simply marks the slot as unoccupied and it will be overwritten by subsequent inserts without allocation.
13//! Note that dropping elements of the removed sequence is deferred until an insert into that location. Methods are
14//! provided for re-keying and compacting the slab if it becomes too sparse. Open slots are stored in a `BTreeSet`, so
15//! most operations have complexity in the logarithm of the number of open slots. In most cases, the open slot set
16//! will be very small and entirely sit in cache. If it grows excessively large, compaction is needed to improve
17//! performance. The advantage of always inserting into the lowest-rank available slot outweighs the small cost of
18//! the `BTreeSet` as it reduces fragmentation.
19//!
20//! # Example
21//!
22//! ```
23//! use rand::{rngs::SmallRng, Rng, SeedableRng};
24//! use slicedvec::SlicedVec;
25//! let mut rng = SmallRng::from_entropy();
26//! let mut x1 = SlicedVec::with_capacity(1000, 20);
27//! x1.push_vec(
28//!     std::iter::repeat_with(|| rng.gen())
29//!     .take(20 * 1000)
30//!     .collect::<Vec<_>>(),
31//! );
32//! let x1_insert: Vec<Vec<usize>> =
33//!     std::iter::repeat_with(|| std::iter::repeat_with(|| rng.gen()).take(20).collect())
34//!         .take(500)
35//!         .collect();
36//! for i in 0..500 { x1.swap_truncate(i) }
37//! for i in 0..500 { x1.push(&x1_insert[i]) }
38//! ```
39
40use std::{
41    collections::BTreeSet,
42    ops::{Index, IndexMut, Range},
43    ptr,
44};
45
46/// A segmented vector for iterating over slices of constant length.
47#[derive(Debug)]
48pub struct SlicedVec<T>
49where
50    T: Copy + Clone,
51{
52    storage: Vec<T>,
53    segment_len: usize,
54}
55
56impl<T> SlicedVec<T>
57where
58    T: Copy + Clone,
59{
60    /// Initialize a `SlicedVec` and set the segment size.
61    ///
62    /// Panics if `segment_len` is zero.
63    pub fn new(segment_len: usize) -> Self {
64        assert_ne!(segment_len, 0);
65        Self {
66            storage: Vec::new(),
67            segment_len,
68        }
69    }
70    /// Initialize a `SlicedVec` and set the capacity and segment size.
71    ///
72    /// Panics if `segment_len` is zero.
73    pub fn with_capacity(size: usize, segment_len: usize) -> Self {
74        assert_ne!(segment_len, 0);
75        Self {
76            storage: Vec::with_capacity(size * segment_len),
77            segment_len,
78        }
79    }
80    /// Initialize a `SlicedVec` from a vector.
81    ///
82    /// Panics if `segment_len` is zero or the length of `data`
83    /// is not a multiple of `segment_len`.
84    ///
85    /// # Example
86    /// ```
87    /// use slicedvec::SlicedVec;
88    /// let sv = SlicedVec::from_vec(3, (1..=9).collect());
89    /// assert_eq!(sv[0], [1, 2, 3]);
90    /// ```
91    pub fn from_vec(segment_len: usize, data: Vec<T>) -> Self {
92        assert_ne!(segment_len, 0);
93        assert_eq!(data.len() % segment_len, 0);
94        Self {
95            storage: data,
96            segment_len,
97        }
98    }
99    /// Get the internal segment length
100    pub fn segment_len(&self) -> usize {
101        self.segment_len
102    }
103    /// Returns the number of internal segments
104    pub fn len(&self) -> usize {
105        self.storage.len() / self.segment_len
106    }
107    /// Get the capacity in number of segments
108    pub fn capacity(&self) -> usize {
109        self.storage_capacity() / self.segment_len
110    }
111    /// Returns the length of the underlying storage
112    pub fn storage_len(&self) -> usize {
113        self.storage.len()
114    }
115    /// Get the capacity of the underlying storage
116    pub fn storage_capacity(&self) -> usize {
117        self.storage.capacity()
118    }
119    /// Append the contents of another `SlicedVec`.
120    ///
121    /// Complexity is the length of `other`, plus any
122    /// allocation required. `other` is drained after call.
123    ///
124    /// # Example
125    ///
126    /// ```
127    /// use slicedvec::{slicedvec, SlicedVec};
128    /// let mut a = slicedvec![[1, 2, 3], [4, 5, 6]];
129    /// let mut b = slicedvec![[7, 8, 9], [3, 2, 1]];
130    /// a.append(&mut b);
131    /// assert_eq!(a.len(), 4);
132    /// assert_eq!(b.len(), 0);
133    /// ```
134    ///
135    ///  Panics if the segment size of `other` is different.
136    pub fn append(&mut self, other: &mut Self) {
137        assert_eq!(other.segment_len, self.segment_len);
138        self.storage.append(&mut other.storage)
139    }
140    /// Insert a slice at position `index`.
141    ///
142    /// Complexity is linear in `storage_len`.
143    ///
144    /// Panics if `index` is out of bounds or if the
145    /// length of `segment` is not the native segment
146    /// size of the `SlicedVec`.
147    ///
148    /// # Example
149    /// ```
150    /// use slicedvec::{slicedvec, SlicedVec};
151    /// let mut sv = slicedvec![[1, 2],[3, 4]];
152    /// // [1,2][3,4]
153    /// sv.insert(0, &[5, 6]);
154    /// // [5,6][1,2][3,4]
155    /// assert_eq!(sv.len(), 3);
156    /// assert_eq!(sv[0], [5, 6]);
157    /// ```
158    pub fn insert(&mut self, index: usize, segment: &[T]) {
159        assert!(index < self.len());
160        assert_eq!(segment.len(), self.segment_len);
161        let orig_last_index = self.last_index();
162        self.storage.extend_from_within(self.storage_range_last());
163        if index < orig_last_index {
164            let src = self.storage_range_range(index, orig_last_index - 1);
165            let dst = self.storage_begin(index + 1);
166            self.storage.copy_within(src, dst);
167        }
168        // Requires index in bounds
169        unsafe { self.overwrite(index, segment) }
170    }
171    /// Add one or more segments to the end.
172    ///
173    /// Complexity is amortized the segment size.
174    ///
175    /// Panics if the length of the slice is not
176    /// a multiple of the segment length.
177    ///
178    /// # Example
179    ///
180    /// ```
181    /// use slicedvec::*;
182    /// let mut a = slicedvec![[1, 2, 3]];
183    /// a.push(&[4, 5, 6, 7, 8, 9]); // any multiple of segment length
184    /// assert_eq!(a.len(), 3);
185    /// assert_eq!(a.storage_len(), 9);
186    /// ```
187    ///
188    pub fn push(&mut self, segment: &[T]) {
189        assert!(self.is_valid_length(segment));
190        self.storage.extend_from_slice(segment)
191    }
192    /// Add one or more segments contained in a `Vec`.
193    ///
194    /// Complexity is amortized the length of
195    /// the slice.
196    ///
197    /// Panics if the length of the slice is not
198    /// a multiple of the segment length.
199    pub fn push_vec(&mut self, segment: Vec<T>) {
200        self.push(segment.as_slice())
201    }
202    /// Get a reference to a segment.
203    ///
204    /// Returns `None` if `index` is out of range.
205    pub fn get(&self, index: usize) -> Option<&[T]> {
206        self.storage.get(self.storage_range(index))
207    }
208    /// Get a mutable reference to a segment.
209    ///
210    /// Returns `None` if `index` is out of range.
211    pub fn get_mut(&mut self, index: usize) -> Option<&mut [T]> {
212        let range = self.storage_range(index);
213        self.storage.get_mut(range)
214    }
215    /// Get a reference to the first segment.
216    ///
217    /// Returns `None` if `index` is out of range.
218    pub fn first(&self) -> Option<&[T]> {
219        self.get(0)
220    }
221    /// Get a mutable reference to the first segment.
222    ///
223    /// Returns `None` if `index` is out of range.
224    pub fn first_mut(&mut self) -> Option<&mut [T]> {
225        self.get_mut(0)
226    }
227    /// Get a reference to the last segment.
228    ///
229    /// Returns `None` if `index` is out of range.
230    pub fn last(&self) -> Option<&[T]> {
231        self.get(self.last_index())
232    }
233    /// Get a mutable reference to the last segment.
234    ///
235    /// Returns `None` if `index` is out of range.
236    pub fn last_mut(&mut self) -> Option<&mut [T]> {
237        self.get_mut(self.last_index())
238    }
239    /// Remove and return a segment.
240    ///
241    /// Does not preserve the order of segments.
242    /// Complexity is the segment length.
243    ///
244    /// Panics if index is out of range.
245    ///
246    /// # Example
247    /// ```
248    /// use slicedvec::{slicedvec, SlicedVec};
249    /// let mut sv = slicedvec![[1, 2, 3], [4, 5, 6, 7, 8, 9]];
250    /// let first = sv.swap_remove(0);
251    /// assert_eq!(first, vec![1, 2, 3]);
252    /// assert_eq!(sv[0], [7, 8, 9]);
253    /// ```
254    pub fn swap_remove(&mut self, index: usize) -> Vec<T> {
255        assert!(index < self.len());
256        if index != self.last_index() {
257            self.storage_range(index)
258                .zip(self.storage_range_last())
259                .for_each(|(i, j)| self.storage.swap(i, j))
260        }
261        self.storage
262            .drain(self.storage_range_last())
263            .as_slice()
264            .into()
265    }
266    /// Swap a segment and truncate its storage.
267    ///
268    /// Does not preserve the order of segments. The
269    /// `SlicedVec` length will be reduced by one segment.
270    /// Complexity is the segment length.
271    ///
272    /// Panics if `index` is out of bounds.
273    ///
274    /// # Example
275    /// ```
276    /// use slicedvec::{slicedvec, SlicedVec};
277    /// let mut sv = slicedvec![[1, 2, 3], [4, 5, 6, 7, 8, 9]];
278    /// sv.swap_truncate(1);
279    /// assert_eq!(sv[1], [7, 8, 9]);
280    /// assert_eq!(sv.len(), 2);
281    /// ```
282    pub fn swap_truncate(&mut self, index: usize) {
283        assert!(index < self.len());
284        if index != self.last_index() {
285            let src = self.storage_range_last();
286            let dst = self.storage_begin(index);
287            self.storage.copy_within(src, dst)
288        }
289        self.truncate(self.last_index());
290    }
291    /// Truncate the storage to `len` segments.
292    ///
293    /// If `len` is greater than the number of
294    /// segments, nothing happens.
295    ///
296    /// # Example
297    /// ```
298    /// use slicedvec::SlicedVec;
299    /// let mut sv = SlicedVec::<i32>::new(3);
300    /// sv.truncate(1);
301    /// assert_eq!(sv.len(), 0);
302    /// sv.push_vec((1..=9).collect());
303    /// sv.truncate(2);
304    /// assert_eq!(sv.last(), Some([4, 5, 6].as_slice()));
305    /// assert_eq!(sv.len(), 2);
306    /// assert_eq!(sv.storage_len(), 6);
307    /// ```
308    pub fn truncate(&mut self, len: usize) {
309        self.storage.truncate(len * self.segment_len);
310    }
311    /// Non-order-preserving, constant-time insert.
312    ///
313    /// Appends the contents of the segment at `index`
314    /// to the end of the storage and then overwrites
315    /// the segment with the new values. If `index` is
316    /// greater than or equal to `self.len()`, then the
317    /// segments is repeatedly pushed until it fills the
318    /// location given by `index`.
319    ///
320    /// Panics if `index` is out of range.
321    ///
322    /// # Example
323    /// ```
324    /// use slicedvec::SlicedVec;
325    /// let mut sv = SlicedVec::from_vec(3, (1..=9).collect());
326    /// sv.relocate_insert(0, &[1, 2, 3]);
327    /// assert_eq!(sv.first(), sv.last());
328    /// ```
329    pub fn relocate_insert(&mut self, index: usize, segment: &[T]) {
330        assert!(index < self.len());
331        assert_eq!(segment.len(), self.segment_len);
332        self.storage.extend_from_within(self.storage_range(index));
333        // Requires index in bounds
334        unsafe { self.overwrite(index, segment) }
335    }
336    /// Return a chunked iterator.
337    ///
338    /// Allows iteration over segments as slices.
339    ///
340    /// # Example
341    /// ```
342    /// use slicedvec::{slicedvec, SlicedVec};
343    /// let sv = slicedvec![[1, 2, 3], [4, 5, 6, 7, 8, 9]];
344    /// for slice in sv.iter() {
345    ///     assert_eq!(slice.len(), 3);
346    /// }
347    /// ```
348    pub fn iter(&self) -> impl Iterator<Item = &[T]> {
349        self.storage.chunks(self.segment_len)
350    }
351    /// Return a mutable chunked iterator.
352    ///
353    /// Allows iteration and modification of segments.
354    ///
355    /// # Example
356    /// ```
357    /// use slicedvec::{slicedvec, SlicedVec};
358    /// let mut sv = slicedvec![[1, 2, 3], [4, 5, 6, 7, 8, 9]];
359    /// sv.iter_mut().for_each(|slice| slice.swap(0, 2));
360    /// assert_eq!(sv[0], [3, 2, 1]);
361    /// ```
362    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut [T]> {
363        self.storage.chunks_mut(self.segment_len)
364    }
365    /// Return a chunked iterator.
366    ///
367    /// Allows iteration over segments as slices.
368    pub fn enumerate(&self) -> impl Iterator<Item = (usize, &[T])> {
369        self.storage.chunks(self.segment_len).enumerate()
370    }
371    /// Iterate over the raw storage.
372    pub fn iter_storage(&self) -> impl Iterator<Item = &T> {
373        self.storage.iter()
374    }
375    /// Mutable iteration over the raw storage.
376    pub fn iter_mut_storage(&mut self) -> impl Iterator<Item = &mut T> {
377        self.storage.iter_mut()
378    }
379    /// Clear the contents.
380    pub fn clear(&mut self) {
381        self.storage.clear()
382    }
383    /// Test if storage length is zero.
384    pub fn is_empty(&self) -> bool {
385        self.len() == 0
386    }
387    fn storage_begin(&self, index: usize) -> usize {
388        index * self.segment_len
389    }
390    fn storage_end(&self, index: usize) -> usize {
391        self.storage_begin(index) + self.segment_len
392    }
393    fn storage_range(&self, index: usize) -> Range<usize> {
394        self.storage_begin(index)..self.storage_end(index)
395    }
396    fn storage_range_range(&self, begin: usize, end: usize) -> Range<usize> {
397        self.storage_begin(begin)..self.storage_end(end)
398    }
399    fn storage_range_last(&self) -> Range<usize> {
400        self.storage_range(self.last_index())
401    }
402    // Caller is responsible for ensuring length is sufficient
403    fn last_index(&self) -> usize {
404        debug_assert!(!self.is_empty());
405        self.len() - 1
406    }
407    // Caller is responsible for ensuring bounds are safe
408    unsafe fn overwrite(&mut self, index: usize, segment: &[T]) {
409        debug_assert!(index < self.len());
410        debug_assert_eq!(self.segment_len, segment.len());
411        ptr::copy(
412            segment.as_ptr(),
413            self.storage.as_mut_ptr().add(self.storage_begin(index)),
414            self.segment_len,
415        )
416    }
417    fn is_valid_length(&self, data: &[T]) -> bool {
418        data.len() % self.segment_len == 0 && !data.is_empty()
419    }
420}
421
422impl<T> Index<usize> for SlicedVec<T>
423where
424    T: Copy + Clone,
425{
426    type Output = [T];
427    fn index(&self, index: usize) -> &Self::Output {
428        &self.storage[self.storage_range(index)]
429    }
430}
431
432impl<T> IndexMut<usize> for SlicedVec<T>
433where
434    T: Copy + Clone,
435{
436    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
437        let range = self.storage_range(index);
438        &mut self.storage[range]
439    }
440}
441
442#[allow(clippy::from_over_into)]
443impl<T> Into<Vec<T>> for SlicedVec<T>
444where
445    T: Copy + Clone,
446{
447    fn into(self) -> Vec<T> {
448        self.storage
449    }
450}
451
452/// Construct a `SlicedVec` from a list of arrays
453///
454/// # Example
455///
456/// ```
457/// use slicedvec::{slicedvec, SlicedVec};
458/// let x = slicedvec![[1, 2, 3], [4, 5, 6]];
459/// assert_eq!(x.get(0), Some([1, 2, 3].as_slice()));
460/// assert_eq!(x.get(2), None);
461/// assert_eq!(x[1], [4, 5, 6]);
462/// assert_eq!(x.len(), 2);
463/// ```
464///
465/// Panics if array lengths do not match.
466#[macro_export]
467macro_rules! slicedvec {
468    ( $first:expr$(, $the_rest:expr )*$(,)? ) => {
469        {
470            let mut temp_vec = SlicedVec::new($first.len());
471            temp_vec.push($first.as_slice());
472            $(
473                temp_vec.push($the_rest.as_slice());
474            )*
475            temp_vec
476        }
477    }
478}
479
480/// A segmented slab with stable keys.
481///
482/// Maintains a `SlicedVec` and a `BTreeSet` of
483/// available slots. Given sufficient capacity, no
484/// allocation will occur on insert or removal. Look
485/// up of available slots is logarithmic in the number
486/// of open slots.
487#[derive(Debug)]
488pub struct SlicedSlab<T>
489where
490    T: Copy + Clone,
491{
492    slots: SlicedVec<T>,
493    open_slots: BTreeSet<usize>,
494}
495
496impl<T> SlicedSlab<T>
497where
498    T: Copy + Clone,
499{
500    /// Construct a new `SlicedSlab`.
501    ///
502    /// Panics if `segment_len` is zero.
503    pub fn new(segment_len: usize) -> Self {
504        assert_ne!(segment_len, 0);
505        Self {
506            slots: SlicedVec::new(segment_len),
507            open_slots: BTreeSet::new(),
508        }
509    }
510    /// Initialize a `SlicedSlab` and set the capacity and segment size.
511    ///
512    /// Panics if `segment_len` is zero.
513    ///
514    /// # Example
515    /// ```
516    /// use slicedvec::SlicedSlab;
517    /// let mut ss = SlicedSlab::from_vec(3, (1..=9).collect());
518    /// ss.release(1);
519    /// assert_eq!(ss.get_keys(), vec![0, 2]);
520    /// ```
521    pub fn from_vec(segment_len: usize, data: Vec<T>) -> Self {
522        assert_ne!(segment_len, 0);
523        Self {
524            slots: SlicedVec::from_vec(segment_len, data),
525            open_slots: BTreeSet::new(),
526        }
527    }
528    /// Iterate over active keys.
529    ///
530    /// # Example
531    /// ```
532    /// use slicedvec::{SlicedVec, SlicedSlab};
533    /// let mut sv = SlicedVec::new(3);
534    /// let mut ss = SlicedSlab::from_vec(3, (1..=9).collect());
535    /// ss.release(1);
536    /// ss.iter_keys().for_each(|key| sv.push(&ss[key]));
537    /// assert_eq!(sv[1], ss[2]);
538    /// ```
539    pub fn iter_keys(&self) -> impl Iterator<Item = usize> + '_ {
540        (0..self.slots.len()).filter(|key| !self.open_slots.contains(key))
541    }
542    /// Get active keys.
543    pub fn get_keys(&self) -> Vec<usize> {
544        self.iter_keys().collect()
545    }
546    /// Insert a segment into the slab.
547    ///
548    /// The first available slot is overwritten
549    /// with the contents of the slice. Otherwise,
550    /// the slice is appended to the storage. Returns
551    /// a key for later retrieval.
552    ///
553    /// Panics if the length of the slice does
554    /// not match the segments size of the slab.
555    pub fn insert(&mut self, segment: &[T]) -> usize {
556        assert_eq!(segment.len(), self.slots.segment_len());
557        match self.open_slots.pop_first() {
558            Some(key) => {
559                debug_assert!(key < self.slots.len());
560                unsafe {
561                    // Requires key is in bounds
562                    self.slots.overwrite(key, segment);
563                }
564                key
565            }
566            None => {
567                let key = self.slots.len();
568                self.slots.push(segment);
569                key
570            }
571        }
572    }
573    /// Insert a vector into the slab.
574    ///
575    /// # Example
576    /// ```
577    /// use slicedvec::SlicedSlab;
578    /// let mut ss = SlicedSlab::new(3);
579    /// assert_eq!(ss.insert_vec((1..=3).collect()), 0);
580    /// ```
581    pub fn insert_vec(&mut self, data: Vec<T>) -> usize {
582        self.insert(data.as_slice())
583    }
584    /// Copy a segment and return a new key.
585    ///
586    /// If there exists an open slot closer to the
587    /// start of the slab, then the data pointed
588    /// to by `oldkey` will be moved there and
589    /// a new key will be returned. Otherwise, no
590    /// action is taken and `oldkey` is returned
591    /// unchanged.
592    ///
593    /// Panics if the old key is unoccupied.
594    ///
595    /// # Example
596    /// ```
597    /// use slicedvec::SlicedSlab;
598    /// let mut ss = SlicedSlab::new(3);
599    /// assert_eq!(ss.insert(&[1, 2, 3]), 0);
600    /// assert_eq!(ss.insert(&[4, 5, 6]), 1);
601    /// // [occ][occ]
602    /// ss.release(0);
603    /// // [vac][occ]
604    /// assert_eq!(ss.rekey(1), 0);
605    /// // [occ][vac]
606    /// assert_eq!(ss[0], [4, 5, 6]);
607    /// ```
608    pub fn rekey(&mut self, oldkey: usize) -> usize {
609        debug_assert!(oldkey < self.slots.len());
610        if self.open_slots.first() < Some(&oldkey) {
611            match self.open_slots.pop_first() {
612                Some(newkey) => {
613                    self.release(oldkey);
614                    debug_assert!(newkey < self.slots.len());
615                    let src = self.slots.storage_range(oldkey);
616                    let dst = self.slots.storage_begin(newkey);
617                    self.slots.storage.copy_within(src, dst);
618                    newkey
619                }
620                None => oldkey,
621            }
622        } else {
623            oldkey
624        }
625    }
626    /// Removes open slots at the end of the slab.
627    ///
628    /// If all key-holders have called rekey, this
629    /// function will remove all open slots, thus
630    /// fully compacting the slab. The storage capacity
631    /// is not affected. This will greatly increase the
632    /// speed of key look-ups as there will be no open
633    /// slots to search. Subsequent insertions will all
634    /// be pushed to the end of the storage. Or if all
635    /// slots are open, the slab will be empty after
636    /// this call.
637    ///
638    /// # Example
639    /// ```
640    /// use slicedvec::SlicedSlab;
641    /// let mut ss = SlicedSlab::new(3);
642    /// assert_eq!(ss.insert(&[1, 2, 3]), 0);
643    /// assert_eq!(ss.insert(&[4, 5, 6]), 1);
644    /// assert_eq!(ss.insert(&[7, 8, 9]), 2);
645    /// // [occ][occ][occ]
646    /// ss.release(1);
647    /// // [occ][vac][occ]
648    /// assert_eq!(ss.sparsity(), 1./3.);
649    /// ss.compact();
650    /// // [occ][vac][occ]
651    /// assert_eq!(ss.sparsity(), 1./3.);
652    /// assert_eq!(ss.get(1), None);
653    /// assert_eq!(ss.rekey(0), 0);
654    /// // [occ][vac][occ]
655    /// assert_eq!(ss.get(2), Some([7, 8, 9].as_slice()));
656    /// assert_eq!(ss.rekey(2), 1);
657    /// // [occ][occ][vac]
658    /// assert_eq!(ss.get(1), Some([7, 8, 9].as_slice()));
659    /// assert_eq!(ss.get(2), None);
660    /// ss.compact();
661    /// // [occ][occ]
662    /// assert_eq!(ss.sparsity(), 0.0);
663    /// ss.release(1);
664    /// ss.compact();
665    /// assert_eq!(ss.get_keys().into_iter().max().unwrap(), 0);
666    /// ss.release(0);
667    /// ss.compact();
668    /// assert!(ss.get_keys().is_empty());
669    /// ```
670    pub fn compact(&mut self) {
671        if self.open_slots.len() == self.slots.len() {
672            // Covers empty case
673            self.open_slots.clear();
674            self.slots.clear()
675        } else {
676            debug_assert!(!self.slots.is_empty());
677            debug_assert!(self.open_slots.len() < self.slots.len());
678            let mut len = self.slots.len();
679            while self.open_slots.last() == Some(&(len - 1)) {
680                self.open_slots.pop_last();
681                debug_assert!(len > 0);
682                len -= 1;
683            }
684            self.slots.storage.truncate(len * self.slots.segment_len);
685            debug_assert!(self.open_slots.len() <= self.slots.len());
686            debug_assert!(self.open_slots.last() < Some(&(self.slots.len())));
687        }
688    }
689    /// Compute the proportion of open slots.
690    ///
691    /// A sparsity of 0.0 indicates no open slots and
692    /// insertions will be pushed at the end of the storage.
693    /// A sparsity of 1.0 indicates only open slots and compaction
694    /// will lead to an empty slab.
695    pub fn sparsity(&self) -> f32 {
696        self.open_slots.len() as f32 / self.slots.len() as f32
697    }
698    /// Mark the slot as open for future overwrite.
699    ///
700    /// Keys are not globally unique. They will be reused.
701    /// Marking the slot unoccupied is logarithmic in the
702    /// number of open slots.
703    ///
704    /// Panics of the slot is already marked as open.
705    pub fn release(&mut self, key: usize) {
706        assert!(key < self.slots.len());
707        // This is the only site where keys are added
708        // The assertion ensures that no key is out of bounds
709        assert!(self.open_slots.insert(key));
710        debug_assert!(self.open_slots.len() <= self.slots.len());
711    }
712    /// Get a reference to a segment.
713    ///
714    /// Returns `None` if `key` is out of range
715    /// or the slot is marked as unoccupied. Key
716    /// look up is logarithmic in the number of
717    /// open slots.
718    pub fn get(&self, key: usize) -> Option<&[T]> {
719        if self.open_slots.contains(&key) {
720            return None;
721        }
722        self.slots.get(key)
723    }
724    /// Get a mutable reference to a segment.
725    ///
726    /// Returns `None` if `key` is out of range
727    /// or the slot is marked as unoccupied. Key
728    /// look up is logarithmic in the number of
729    /// open slots.
730    pub fn get_mut(&mut self, key: usize) -> Option<&mut [T]> {
731        if self.open_slots.contains(&key) {
732            return None;
733        }
734        self.slots.get_mut(key)
735    }
736    /// Iterate over key, slice pairs.
737    ///
738    /// This will be slow if the slab is very sparse.
739    ///
740    /// # Example
741    /// ```
742    /// use slicedvec::SlicedSlab;
743    /// let mut ss = SlicedSlab::from_vec(3, (1..=9).collect());
744    /// ss.release(1);
745    /// let s: usize = ss.enumerate()
746    ///     .map(|(_, slice)| slice.len())
747    ///     .fold(0, |sum, val| sum + val);
748    /// assert_eq!(s, 6);
749    /// ```
750    pub fn enumerate(&self) -> impl Iterator<Item = (usize, &[T])> {
751        self.slots
752            .enumerate()
753            .filter(|(key, _)| !self.open_slots.contains(key))
754    }
755}
756
757/// Get segment from slab.
758///
759/// This will return whatever it finds at index
760/// regardless of whether it is occupied
761/// or released.
762///
763/// Panics if `index` is out of range.
764///
765/// # Example
766/// ```
767/// use slicedvec::SlicedSlab;
768/// let mut ss = SlicedSlab::from_vec(3, (1..=9).collect());
769/// ss.release(1);
770/// assert_eq!(ss[1], [4, 5, 6]);
771/// assert_eq!(ss.insert(&[3, 2, 1]), 1);
772/// assert_eq!(ss[1], [3, 2, 1]);
773/// ```
774impl<T> Index<usize> for SlicedSlab<T>
775where
776    T: Copy + Clone,
777{
778    type Output = [T];
779    fn index(&self, index: usize) -> &Self::Output {
780        &self.slots[index]
781    }
782}
783
784/// Get segment from slab.
785///
786/// This will return whatever it finds at index
787/// regardless of whether it is occupied
788/// or released.
789///
790/// Panics if `index` is out of range.
791/// # Example
792/// ```
793/// use slicedvec::SlicedSlab;
794/// let mut ss = SlicedSlab::from_vec(3, (1..=9).collect());
795/// ss.release(1);
796/// ss[1][1] = 0;
797/// assert_eq!(ss[1], [4, 0, 6]);
798/// ```
799impl<T> IndexMut<usize> for SlicedSlab<T>
800where
801    T: Copy + Clone,
802{
803    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
804        &mut self.slots[index]
805    }
806}
807
808#[cfg(test)]
809mod tests {
810    use super::SlicedVec;
811
812    #[test]
813    fn test_slicedvec() {
814        let mut a = slicedvec!([1, 2, 3], [4, 5, 6], [7, 8, 9]);
815        assert!(a.is_valid_length(&[1, 2, 3, 4, 5, 6]));
816        assert_eq!(a.segment_len(), 3);
817        assert_eq!(&a[0], &[1, 2, 3]);
818        assert_eq!(&a[1], &[4, 5, 6]);
819        assert_eq!(&a[2], &[7, 8, 9]);
820        assert_eq!(a.swap_remove(1), &[4, 5, 6]);
821        assert_eq!(a.len(), 2);
822        assert_eq!(&a[1], &[7, 8, 9]);
823        a.append(&mut slicedvec!(&[3, 6, 9]));
824        assert_eq!(&a[2], &[3, 6, 9]);
825        a.insert(1, &[3, 2, 1]);
826        assert_eq!(&a[3], &[3, 6, 9]);
827        assert_eq!(&a[1], &[3, 2, 1]);
828        a.relocate_insert(1, &[2, 2, 2]);
829        assert_eq!(&a[4], &[3, 2, 1]);
830        assert_eq!(&a[1], &[2, 2, 2]);
831        let mut v: SlicedVec<i32> = SlicedVec::new(3);
832        assert_eq!(v.len(), 0);
833        v.push(&[1, 2, 3]);
834        assert_eq!(v.len(), 1);
835        assert_eq!(v.get(0), Some([1, 2, 3].as_slice()));
836        v.push(&[4, 5, 6]);
837        assert_eq!(v.len(), 2);
838        assert_eq!(v.get(0).unwrap(), &[1, 2, 3]);
839        assert_eq!(v.get(1).unwrap(), &[4, 5, 6]);
840        let s: i32 = v.iter().map(|x| x.iter().sum::<i32>()).sum();
841        assert_eq!(s, 21);
842        let lens = v.iter().map(|x| x.len()).collect::<Vec<_>>();
843        assert_eq!(lens, vec![3, 3]);
844        assert_eq!(v.swap_remove(0), &[1, 2, 3]);
845        assert_eq!(v.get(0).unwrap(), &[4, 5, 6]);
846        v.iter_mut().for_each(|x| x.clone_from_slice(&[7, 8, 9]));
847        assert_eq!(v.get(0).unwrap(), &[7, 8, 9]);
848        let mut w: SlicedVec<i32> = SlicedVec::with_capacity(20, 5);
849        w.push(&[1, 2, 3, 4, 5]);
850        let x = w.get_mut(0).unwrap();
851        assert_eq!(x, &[1, 2, 3, 4, 5]);
852        x.clone_from_slice(&[5, 4, 3, 2, 1]);
853        assert_eq!(x, &[5, 4, 3, 2, 1]);
854        assert_eq!(&w[0], &[5, 4, 3, 2, 1]);
855        assert_eq!(w[0][2], 3);
856        let z = w.get_mut(0).unwrap();
857        z[2] = 0;
858        assert_eq!(z[2], 0);
859        assert_eq!(w.get(0).unwrap()[2], 0);
860        w.push(&[10, 20, 30, 40, 50]);
861        w.push(&[100, 200, 300, 400, 500]);
862        w.swap_truncate(0);
863        assert_eq!(w.len(), 2);
864        assert_eq!(&w[0], &[100, 200, 300, 400, 500]);
865        assert_eq!(&w[1], &[10, 20, 30, 40, 50]);
866        w.swap_truncate(1);
867        assert_eq!(w.len(), 1);
868        assert_eq!(&w[0], &[100, 200, 300, 400, 500]);
869        w.swap_truncate(0);
870        assert_eq!(w.len(), 0);
871        assert!(w.is_empty());
872        let a = slicedvec![[1, 2, 3], [4, 5, 6]];
873        let aa: Vec<_> = a.into();
874        assert_eq!(aa.len(), 6);
875    }
876}