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}