Skip to main content

osiris/types/
array.rs

1//! This module implements static and dynamic arrays for in-kernel use.
2
3use crate::{error::Result, types::bitset::BitAlloc};
4
5use super::{
6    boxed::Box,
7    traits::{Get, GetMut, ToIndex},
8};
9
10use core::mem::ManuallyDrop;
11use core::ops::{Index, IndexMut};
12use core::{borrow::Borrow, mem::MaybeUninit};
13
14/// This is a fixed-size map that can store up to N consecutive elements.
15#[proc_macros::fmt]
16pub struct IndexMap<K: ?Sized + ToIndex, V, const N: usize> {
17    data: [Option<V>; N],
18    phantom: core::marker::PhantomData<K>,
19}
20
21#[allow(dead_code)]
22impl<K: ?Sized + ToIndex, V, const N: usize> IndexMap<K, V, N> {
23    /// Create a new IndexMap.
24    ///
25    /// Returns a new IndexMap.
26    pub const fn new() -> Self {
27        Self {
28            data: [const { None }; N],
29            phantom: core::marker::PhantomData,
30        }
31    }
32
33    /// Insert a value at the given index.
34    ///
35    /// `index` - The index to insert the value at.
36    /// `value` - The value to insert.
37    ///
38    /// Returns `Ok(())` if the index was in-bounds, otherwise `Err(KernelError::ENOMEM)`.
39    pub fn insert(&mut self, idx: &K, value: V) -> Result<()> {
40        let idx = K::to_index(Some(idx));
41
42        if idx < N {
43            self.data[idx] = Some(value);
44            Ok(())
45        } else {
46            Err(kerr!(ENOMEM))
47        }
48    }
49
50    /// Remove the value at the given index.
51    ///
52    /// `index` - The index to remove the value from.
53    ///
54    /// Returns the value if it was removed, otherwise `None`.
55    pub fn remove(&mut self, idx: &K) -> Option<V> {
56        let idx = K::to_index(Some(idx));
57
58        if idx < N { self.data[idx].take() } else { None }
59    }
60
61    pub fn raw_insert(&mut self, idx: usize, value: V) -> Result<()> {
62        if idx < N {
63            self.data[idx] = Some(value);
64            Ok(())
65        } else {
66            Err(kerr!(ENOMEM))
67        }
68    }
69
70    pub fn raw_remove(&mut self, idx: usize) -> Option<V> {
71        if idx < N { self.data[idx].take() } else { None }
72    }
73
74    pub fn raw_at(&self, idx: usize) -> Option<&V> {
75        if idx < N {
76            self.data[idx].as_ref()
77        } else {
78            None
79        }
80    }
81
82    pub fn raw_at_mut(&mut self, idx: usize) -> Option<&mut V> {
83        if idx < N {
84            self.data[idx].as_mut()
85        } else {
86            None
87        }
88    }
89}
90
91impl<K: Copy + ToIndex, V, const N: usize> Index<K> for IndexMap<K, V, N> {
92    type Output = V;
93
94    fn index(&self, index: K) -> &Self::Output {
95        self.get::<K>(index).unwrap()
96    }
97}
98
99impl<K: Copy + ToIndex, V, const N: usize> IndexMut<K> for IndexMap<K, V, N> {
100    fn index_mut(&mut self, index: K) -> &mut Self::Output {
101        self.get_mut::<K>(index).unwrap()
102    }
103}
104
105impl<K: ?Sized + ToIndex, V, const N: usize> Get<K> for IndexMap<K, V, N> {
106    type Output = V;
107
108    fn get<Q: Borrow<K>>(&self, index: Q) -> Option<&Self::Output> {
109        let idx = K::to_index(Some(index.borrow()));
110        if idx < N {
111            self.data[idx].as_ref()
112        } else {
113            None
114        }
115    }
116}
117
118impl<K: ?Sized + ToIndex, V, const N: usize> GetMut<K> for IndexMap<K, V, N> {
119    fn get_mut<Q: Borrow<K>>(&mut self, index: Q) -> Option<&mut Self::Output> {
120        let idx = K::to_index(Some(index.borrow()));
121        if idx < N {
122            self.data[idx].as_mut()
123        } else {
124            None
125        }
126    }
127
128    fn get2_mut<Q: Borrow<K>>(
129        &mut self,
130        index1: Q,
131        index2: Q,
132    ) -> (Option<&mut Self::Output>, Option<&mut Self::Output>) {
133        let idx1 = K::to_index(Some(index1.borrow()));
134        let idx2 = K::to_index(Some(index2.borrow()));
135
136        if idx1 == idx2 {
137            debug_assert!(false, "get2_mut called with identical indices");
138            return (None, None);
139        }
140
141        if idx1 >= N {
142            return (
143                None,
144                if idx2 < N {
145                    self.data[idx2].as_mut()
146                } else {
147                    None
148                },
149            );
150        }
151        if idx2 >= N {
152            return (self.data[idx1].as_mut(), None);
153        }
154
155        let (left, right) = self.data.split_at_mut(idx1.max(idx2));
156
157        if idx1 < idx2 {
158            let elem1 = left[idx1].as_mut();
159            let elem2 = right[0].as_mut();
160            (elem1, elem2)
161        } else {
162            let elem1 = right[0].as_mut();
163            let elem2 = left[idx2].as_mut();
164            (elem1, elem2)
165        }
166    }
167
168    fn get3_mut<Q: Borrow<K>>(
169        &mut self,
170        index1: Q,
171        index2: Q,
172        index3: Q,
173    ) -> (
174        Option<&mut Self::Output>,
175        Option<&mut Self::Output>,
176        Option<&mut Self::Output>,
177    ) {
178        let idx1 = K::to_index(Some(index1.borrow()));
179        let idx2 = K::to_index(Some(index2.borrow()));
180        let idx3 = K::to_index(Some(index3.borrow()));
181
182        if idx1 == idx2 || idx1 == idx3 || idx2 == idx3 {
183            debug_assert!(false, "get3_mut called with identical indices");
184            return (None, None, None);
185        }
186
187        let ptr1 = if idx1 < N {
188            Some(&mut self.data[idx1] as *mut Option<V>)
189        } else {
190            None
191        };
192        let ptr2 = if idx2 < N {
193            Some(&mut self.data[idx2] as *mut Option<V>)
194        } else {
195            None
196        };
197        let ptr3 = if idx3 < N {
198            Some(&mut self.data[idx3] as *mut Option<V>)
199        } else {
200            None
201        };
202
203        // Safety: each pointer comes from an in-bounds slot in self.data, and the three indices
204        // are pairwise distinct (check above), so the resulting references are disjoint.
205        unsafe {
206            (
207                ptr1.and_then(|p| (*p).as_mut()),
208                ptr2.and_then(|p| (*p).as_mut()),
209                ptr3.and_then(|p| (*p).as_mut()),
210            )
211        }
212    }
213}
214
215/// This is a vector that can store up to N elements inline and will allocate on the heap if more are needed.
216#[proc_macros::fmt]
217pub struct Vec<T, const N: usize> {
218    len: usize,
219    data: [MaybeUninit<T>; N],
220    extra: Box<[MaybeUninit<T>]>,
221}
222
223#[allow(dead_code)]
224impl<T, const N: usize> Vec<T, N> {
225    /// Create a new Vec.
226    ///
227    /// Returns a new Vec.
228    pub const fn new() -> Self {
229        Self {
230            len: 0,
231            data: [const { MaybeUninit::uninit() }; N],
232            extra: Box::new_slice_empty(),
233        }
234    }
235
236    pub const fn from_array(arr: [T; N]) -> Self {
237        let arr = ManuallyDrop::new(arr);
238        let mut data = [const { MaybeUninit::uninit() }; N];
239
240        let src: *const [T; N] = &arr as *const ManuallyDrop<[T; N]> as *const [T; N];
241        let dst: *mut [MaybeUninit<T>; N] = &mut data;
242
243        let mut i = 0;
244        while i < N {
245            unsafe {
246                let value = core::ptr::read((src as *const T).add(i));
247                (dst as *mut MaybeUninit<T>)
248                    .add(i)
249                    .write(MaybeUninit::new(value));
250            }
251            i += 1;
252        }
253
254        Self {
255            len: N,
256            data,
257            extra: Box::new_slice_empty(),
258        }
259    }
260
261    unsafe fn move_from_slice_to_uninit(dst: &mut [MaybeUninit<T>], src: &[MaybeUninit<T>]) {
262        assert_eq!(dst.len(), src.len());
263
264        unsafe {
265            for i in 0..dst.len() {
266                dst[i].write(src[i].as_ptr().read());
267            }
268        }
269    }
270
271    unsafe fn move_within_to_uninit(
272        slice: &mut [MaybeUninit<T>],
273        src_index: usize,
274        dst_index: usize,
275        count: usize,
276    ) {
277        assert!(src_index + count <= slice.len());
278        assert!(dst_index + count <= slice.len());
279
280        unsafe {
281            for i in 0..count {
282                let value = slice[src_index + i].as_ptr().read();
283                slice[dst_index + i].write(value);
284            }
285        }
286    }
287
288    /// Reserve additional space in the Vec.
289    ///
290    /// `additional` - The additional space to reserve.
291    ///
292    /// Returns `Ok(())` if the space was reserved, otherwise `Err(KernelError::ENOMEM)`.
293    pub fn reserve(&mut self, additional: usize) -> Result<()> {
294        let len_extra = self.extra.len();
295
296        // Check if we have enough space in the inline storage.
297        if self.len + additional <= N + len_extra {
298            return Ok(());
299        }
300
301        // If we don't have enough space, we need to grow the extra storage.
302        let grow = self.len + additional - N;
303        let mut new_extra = Box::new_slice_uninit(grow)?;
304
305        // Check that the new extra storage has the requested length.
306        bug_on!(new_extra.len() != grow);
307
308        let len_initialized_extra = self.len.saturating_sub(N);
309
310        // Move the old extra storage into the new one.
311        unsafe {
312            Self::move_from_slice_to_uninit(
313                &mut new_extra[..len_initialized_extra],
314                &self.extra[..len_initialized_extra],
315            );
316        }
317
318        // Replace the old extra storage with the new one. The old one will be dropped.
319        self.extra = new_extra;
320        Ok(())
321    }
322
323    /// Reserve a fixed amount of space in the Vec. Does nothing if enough space is present already.
324    ///
325    /// `total_capacity` - The total space to be reserved.
326    ///
327    /// Returns `Ok(())` if the space was reserved, otherwise `Err(KernelError::ENOMEM)`.
328    pub fn reserve_total_capacity(&mut self, total_capacity: usize) -> Result<()> {
329        // Check if we already have enough space
330        if self.capacity() >= total_capacity {
331            return Ok(());
332        }
333
334        // If we don't have enough space, we need to grow the extra storage.
335        let new_out_of_line_cap = total_capacity - N;
336        let mut new_extra = Box::new_slice_uninit(new_out_of_line_cap)?;
337
338        // Check that the new extra storage has the requested length.
339        bug_on!(new_extra.len() != new_out_of_line_cap);
340
341        let curr_out_of_line_size = self.len.saturating_sub(N);
342        // Move the old extra storage into the new one.
343        unsafe {
344            Self::move_from_slice_to_uninit(
345                &mut new_extra[..curr_out_of_line_size],
346                &self.extra[..curr_out_of_line_size],
347            );
348        }
349
350        // Replace the old extra storage with the new one. The old one will be dropped.
351        self.extra = new_extra;
352        Ok(())
353    }
354
355    /// Create a new Vec with the given length and value.
356    ///
357    /// `length` - The length of the Vec.
358    /// `value` - The value to initialize the elements in the Vec with.
359    ///
360    /// Returns the new Vec or `Err(KernelError::ENOMEM)` if the allocation failed.
361    pub fn new_init(length: usize, value: T) -> Result<Self>
362    where
363        T: Clone,
364    {
365        let mut vec = Self::new();
366
367        // Check if we can fit all elements in the inline storage.
368        if length <= N {
369            // Initialize all elements in the inline storage.
370            for i in 0..length {
371                vec.data[i].write(value.clone());
372                // Bump len after each write so a panicking T::clone leaves Drop able
373                // to clean up the slots that were already initialized.
374                vec.len = i + 1;
375            }
376        } else {
377            // Allocate the extra storage first and install it on `vec` so any later
378            // failure (clone panic) leaves Drop with a consistent (len, extra) view,
379            // and so an OOM here cannot leak inline clones (none have been written yet).
380            let extra_len = length - N;
381            vec.extra = Box::new_slice_uninit(extra_len)?;
382
383            for elem in &mut vec.data {
384                elem.write(value.clone());
385                vec.len += 1;
386            }
387
388            for i in 0..extra_len {
389                vec.extra[i].write(value.clone());
390                vec.len += 1;
391            }
392        }
393
394        vec.len = length;
395        Ok(vec)
396    }
397
398    /// Push a value onto the Vec.
399    ///
400    /// `value` - The value to push.
401    ///
402    /// Returns `Ok(())` if the value was pushed, otherwise `Err(KernelError::ENOMEM)`.
403    pub fn push(&mut self, value: T) -> Result<()> {
404        // Check if we have enough space in the inline storage.
405        if self.len < N {
406            // Push the value into the inline storage.
407            self.data[self.len].write(value);
408            self.len += 1;
409            Ok(())
410        } else {
411            let len_extra = self.extra.len();
412
413            // Check if we have enough space in the extra storage.
414            if self.len < N + len_extra {
415                // Push the value into the extra storage.
416                self.extra[self.len - N].write(value);
417                self.len += 1;
418                Ok(())
419            } else {
420                // We need to grow the extra storage.
421                let grow = (len_extra + 1) * 2;
422                let mut new_extra = Box::new_slice_uninit(grow)?;
423
424                bug_on!(new_extra.len() != grow);
425
426                let len_initialized_extra = self.len - N;
427
428                // Move the old extra storage into the new one.
429                unsafe {
430                    Self::move_from_slice_to_uninit(
431                        &mut new_extra[..len_initialized_extra],
432                        &self.extra[..len_initialized_extra],
433                    );
434                }
435
436                // Replace the old extra storage with the new one. The old one will be dropped.
437                self.extra = new_extra;
438                self.extra[len_extra].write(value);
439                self.len += 1;
440                Ok(())
441            }
442        }
443    }
444
445    /// Pop a value from the Vec.
446    ///
447    /// Returns the value if it was popped, otherwise `None`.
448    pub fn pop(&mut self) -> Option<T> {
449        if self.len == 0 {
450            return None;
451        }
452        self.remove(self.len - 1)
453    }
454
455    /// Remove the value at the given index.
456    ///
457    /// `index` - The index to remove the value from.
458    ///
459    /// Returns the value if it was removed, otherwise `None`.
460    pub fn remove(&mut self, index: usize) -> Option<T> {
461        // Check if the index is in-bounds.
462        if index >= self.len {
463            return None;
464        }
465
466        // Get the value at the given index.
467        let value = unsafe { self.at_mut_unchecked(index).read() };
468
469        // Check if we need to move inline storage elements.
470        if index < N {
471            // Move the elements in the inline storage.
472            let end = core::cmp::min(self.len, N);
473
474            // Safety: index is less than N and min too.
475            unsafe {
476                Self::move_within_to_uninit(&mut self.data, index + 1, index, end - index - 1);
477            }
478
479            // Check if we need to move the first extra storage element into the inline storage.
480            if self.len() > N {
481                let value = unsafe { self.extra[0].as_ptr().read() };
482                self.data[end - 1].write(value);
483            }
484
485            // Move the elements in the extra storage.
486            if self.len() > N {
487                unsafe {
488                    Self::move_within_to_uninit(&mut self.extra, 1, 0, self.len - N - 1);
489                }
490            }
491        } else {
492            // We only need to move the elements in the extra storage.
493
494            let index = index - N;
495            let end = self.len - N;
496
497            // Safety: index is less than N and min too.
498            unsafe {
499                Self::move_within_to_uninit(&mut self.extra, index + 1, index, end - index - 1);
500            }
501        }
502
503        self.len -= 1;
504        Some(value)
505    }
506
507    /// Get the length of the Vec.
508    ///
509    /// Returns the length of the Vec.
510    pub fn len(&self) -> usize {
511        self.len
512    }
513
514    /// Get the value at the given index.
515    ///
516    /// `index` - The index to get the value from.
517    ///
518    /// Returns `Some(&T)` if the index is in-bounds, otherwise `None`.
519    pub fn at(&self, index: usize) -> Option<&T> {
520        // Check if the index is in-bounds.
521        if index >= self.len {
522            return None;
523        }
524
525        if index < N {
526            // Safety: the elements until self.len are initialized.
527            unsafe { Some(self.data[index].assume_init_ref()) }
528        } else {
529            let index = index - N;
530            // Safety: the elements until self.len - N are initialized.
531            unsafe { Some(self.extra[index].assume_init_ref()) }
532        }
533    }
534
535    /// Get a mutable reference to the value at the given index.
536    ///
537    /// `index` - The index to get the value from.
538    ///
539    /// Returns `Some(&mut T)` if the index is in-bounds, otherwise `None`.
540    pub fn at_mut(&mut self, index: usize) -> Option<&mut T> {
541        // Check if the index is in-bounds.
542        if index >= self.len {
543            return None;
544        }
545
546        if index < N {
547            // Safety: the elements until self.len are initialized.
548            unsafe { Some(self.data[index].assume_init_mut()) }
549        } else {
550            let index = index - N;
551            // Safety: the elements until self.len - N are initialized.
552            unsafe { Some(self.extra[index].assume_init_mut()) }
553        }
554    }
555
556    fn at_mut_unchecked(&mut self, index: usize) -> *mut T {
557        if index < N {
558            // Safety: the elements until self.len are initialized.
559            // The element at index is nowhere else borrowed mutably by function contract.
560            self.data[index].as_mut_ptr()
561        } else {
562            let index = index - N;
563            // Safety: the elements until self.len - N are initialized.
564            // The element at index is nowhere else borrowed mutably by function contract.
565            self.extra[index].as_mut_ptr()
566        }
567    }
568
569    /// Get disjoint mutable references to the values at the given indices.
570    ///
571    /// `index1` - The first index.
572    /// `index2` - The second index.
573    ///
574    /// Returns `Some(&mut T, &mut T)` if the indices are in-bounds and disjoint, otherwise `None`.
575    pub fn at2_mut(&mut self, index1: usize, index2: usize) -> (Option<&mut T>, Option<&mut T>) {
576        if index1 == index2 {
577            debug_assert!(false, "at2_mut called with identical indices");
578            return (None, None);
579        }
580
581        let in1 = index1 < self.len;
582        let in2 = index2 < self.len;
583        let ptr1 = if in1 {
584            Some(self.at_mut_unchecked(index1))
585        } else {
586            None
587        };
588        let ptr2 = if in2 {
589            Some(self.at_mut_unchecked(index2))
590        } else {
591            None
592        };
593
594        // Safety: each pointer is only constructed when the corresponding index is < self.len,
595        // so it points to an initialized slot. The two indices are pairwise distinct (check
596        // above), so the resulting references are disjoint.
597        unsafe { (ptr1.map(|p| &mut *p), ptr2.map(|p| &mut *p)) }
598    }
599
600    /// Get disjoint mutable references to the values at the given indices.
601    ///
602    /// `index1` - The first index.
603    /// `index2` - The second index.
604    /// `index3` - The third index.
605    ///
606    /// Returns `Some(&mut T, &mut T, &mut T)` if the indices are in-bounds and disjoint, otherwise `None`.
607    pub fn at3_mut(
608        &mut self,
609        index1: usize,
610        index2: usize,
611        index3: usize,
612    ) -> (Option<&mut T>, Option<&mut T>, Option<&mut T>) {
613        if index1 == index2 || index1 == index3 || index2 == index3 {
614            debug_assert!(false, "at3_mut called with identical indices");
615            return (None, None, None);
616        }
617
618        let in1 = index1 < self.len;
619        let in2 = index2 < self.len;
620        let in3 = index3 < self.len;
621        let ptr1 = if in1 {
622            Some(self.at_mut_unchecked(index1))
623        } else {
624            None
625        };
626        let ptr2 = if in2 {
627            Some(self.at_mut_unchecked(index2))
628        } else {
629            None
630        };
631        let ptr3 = if in3 {
632            Some(self.at_mut_unchecked(index3))
633        } else {
634            None
635        };
636
637        // Safety: each pointer is only constructed when the corresponding index is < self.len,
638        // so it points to an initialized slot. The three indices are pairwise distinct (check
639        // above), so the resulting references are disjoint.
640        unsafe {
641            (
642                ptr1.map(|p| &mut *p),
643                ptr2.map(|p| &mut *p),
644                ptr3.map(|p| &mut *p),
645            )
646        }
647    }
648
649    /// Swap the values at the given indices.
650    ///
651    /// `a` - The first index.
652    /// `b` - The second index.
653    pub fn swap(&mut self, a: usize, b: usize) {
654        // Check if the indices are in-bounds.
655        if a >= self.len || b >= self.len {
656            return;
657        }
658
659        if a < N && b < N {
660            // Both indices are in the inline storage.
661            self.data.swap(a, b);
662        } else if a >= N && b >= N {
663            // Both indices are in the extra storage.
664            self.extra.swap(a - N, b - N);
665        } else if a >= N {
666            // The first index is in the extra storage.
667            core::mem::swap(&mut self.extra[a - N], &mut self.data[b]);
668        } else {
669            // The second index is in the extra storage.
670            core::mem::swap(&mut self.data[a], &mut self.extra[b - N]);
671        }
672    }
673
674    /// Check if the Vec is empty.
675    ///
676    /// Returns `true` if the Vec is empty, otherwise `false`.
677    pub fn is_empty(&self) -> bool {
678        self.len == 0
679    }
680
681    /// Get total amount of space in Vec (in- and out-of-line)
682    ///
683    /// Returns total amount of  reserved space in the vec
684    pub fn capacity(&self) -> usize {
685        N + self.extra.len()
686    }
687}
688
689impl<T, const N: usize> Vec<T, N> {
690    /// Clear the Vec, dropping all elements.
691    pub fn clear(&mut self) {
692        let min = core::cmp::min(self.len, N);
693
694        // Drop all elements in the inline storage.
695        for elem in &mut self.data[0..min] {
696            // Safety: the elements until min are initialized.
697            unsafe {
698                elem.assume_init_drop();
699            }
700        }
701
702        // Drop all elements in the extra storage.
703        for elem in &mut (*self.extra)[0..self.len - min] {
704            // Safety: the elements until self.len - N are initialized.
705            unsafe {
706                elem.assume_init_drop();
707            }
708        }
709
710        self.len = 0;
711    }
712}
713
714impl<T, const N: usize> Drop for Vec<T, N> {
715    fn drop(&mut self) {
716        self.clear();
717    }
718}
719
720impl<T, const N: usize> Clone for Vec<T, N>
721where
722    T: Clone,
723{
724    fn clone(&self) -> Self {
725        let mut new_vec = Self::new();
726        let min = core::cmp::min(self.len, N);
727
728        bug_on!(new_vec.reserve_total_capacity(self.len).is_err());
729
730        // Clone the elements in the inline storage.
731        for i in 0..min {
732            // Safety: the elements until self.len are initialized.
733            let value = unsafe { self.data[i].assume_init_ref() };
734            new_vec.data[i].write(value.clone());
735        }
736
737        // Clone the elements in the extra storage.
738        for i in 0..self.len - min {
739            // Safety: the elements until self.len - N are initialized.
740            let value = unsafe { self.extra[i].assume_init_ref() };
741            new_vec.extra[i].write(value.clone());
742        }
743
744        new_vec.len = self.len;
745        new_vec
746    }
747}
748
749impl<T, const N: usize> Index<usize> for Vec<T, N> {
750    type Output = T;
751
752    fn index(&self, index: usize) -> &Self::Output {
753        self.at(index).unwrap()
754    }
755}
756
757impl<T, const N: usize> IndexMut<usize> for Vec<T, N> {
758    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
759        self.at_mut(index).unwrap()
760    }
761}
762
763impl<T, const N: usize> Get<usize> for Vec<T, N> {
764    type Output = T;
765
766    fn get<Q: Borrow<usize>>(&self, index: Q) -> Option<&Self::Output> {
767        self.at(*index.borrow())
768    }
769}
770
771impl<T, const N: usize> GetMut<usize> for Vec<T, N> {
772    fn get_mut<Q: Borrow<usize>>(&mut self, index: Q) -> Option<&mut Self::Output> {
773        self.at_mut(*index.borrow())
774    }
775
776    fn get2_mut<Q: Borrow<usize>>(
777        &mut self,
778        index1: Q,
779        index2: Q,
780    ) -> (Option<&mut Self::Output>, Option<&mut Self::Output>) {
781        self.at2_mut(*index1.borrow(), *index2.borrow())
782    }
783
784    fn get3_mut<Q: Borrow<usize>>(
785        &mut self,
786        index1: Q,
787        index2: Q,
788        index3: Q,
789    ) -> (
790        Option<&mut Self::Output>,
791        Option<&mut Self::Output>,
792        Option<&mut Self::Output>,
793    ) {
794        self.at3_mut(*index1.borrow(), *index2.borrow(), *index3.borrow())
795    }
796}
797
798/// This is an IndexMap that additionally tracks which indices are occupied through a bitset.
799/// WORDS is the number of usize words needed to track N entries, you should set it to WORDS = N.div_ceil(usize::BITS as usize).
800/// Its currently impossible to set this value automatically because of const generic limitations.
801pub struct BitReclaimMap<K: ?Sized + ToIndex, V, const N: usize> {
802    map: IndexMap<K, V, N>,
803    free: BitAlloc<N>,
804}
805
806impl<K: ?Sized + ToIndex, V, const N: usize> BitReclaimMap<K, V, N> {
807    pub const fn new() -> Self {
808        Self {
809            map: IndexMap::new(),
810            free: BitAlloc::from_array([!0usize; N]),
811        }
812    }
813
814    #[allow(dead_code)]
815    pub fn insert(&mut self, value: V) -> Result<usize> {
816        let idx = self.free.alloc(1).ok_or(kerr!(ENOMEM))?;
817        if let Err(e) = self.map.raw_insert(idx, value) {
818            // BitAlloc<N> exposes more bits than IndexMap has slots; release any index
819            // that raw_insert rejects so a leaked bit can't accumulate across failures.
820            self.free.free(idx, 1);
821            return Err(e);
822        }
823        Ok(idx)
824    }
825
826    pub fn remove(&mut self, idx: &K) -> Option<V> {
827        self.map.remove(idx).inspect(|_| {
828            self.free.free(K::to_index(Some(idx)), 1);
829        })
830    }
831}
832
833impl<K: ?Sized + ToIndex, V, const N: usize> BitReclaimMap<K, V, N> {
834    /// Call `f(slot, value)` for every occupied slot in the map.
835    pub fn for_each<F: FnMut(usize, &V)>(&self, mut f: F) {
836        for slot in 0..N {
837            if let Some(v) = self.map.raw_at(slot) {
838                f(slot, v);
839            }
840        }
841    }
842}
843
844impl<K: Copy + ToIndex, V, const N: usize> BitReclaimMap<K, V, N> {
845    pub fn insert_with(&mut self, f: impl FnOnce(usize) -> Result<(K, V)>) -> Result<K> {
846        let idx = self.free.alloc(1).ok_or(kerr!(ENOMEM))?;
847        // The closure is user-supplied and may return an error; release the bit so a
848        // sustained run of closure failures cannot exhaust the allocator.
849        let (key, value) = match f(idx) {
850            Ok(kv) => kv,
851            Err(e) => {
852                self.free.free(idx, 1);
853                return Err(e);
854            }
855        };
856        if let Err(e) = self.map.raw_insert(idx, value) {
857            self.free.free(idx, 1);
858            return Err(e);
859        }
860        Ok(key)
861    }
862}
863
864impl<K: Copy + ToIndex, V, const N: usize> Index<K> for BitReclaimMap<K, V, N> {
865    type Output = V;
866
867    fn index(&self, index: K) -> &Self::Output {
868        self.get::<K>(index).unwrap()
869    }
870}
871
872impl<K: Copy + ToIndex, V, const N: usize> IndexMut<K> for BitReclaimMap<K, V, N> {
873    fn index_mut(&mut self, index: K) -> &mut Self::Output {
874        self.get_mut::<K>(index).unwrap()
875    }
876}
877
878impl<K: ?Sized + ToIndex, V, const N: usize> Get<K> for BitReclaimMap<K, V, N> {
879    type Output = V;
880
881    fn get<Q: Borrow<K>>(&self, index: Q) -> Option<&Self::Output> {
882        self.map.get(index)
883    }
884}
885
886impl<K: ?Sized + ToIndex, V, const N: usize> GetMut<K> for BitReclaimMap<K, V, N> {
887    fn get_mut<Q: Borrow<K>>(&mut self, index: Q) -> Option<&mut Self::Output> {
888        self.map.get_mut(index)
889    }
890
891    fn get2_mut<Q: Borrow<K>>(
892        &mut self,
893        index1: Q,
894        index2: Q,
895    ) -> (Option<&mut Self::Output>, Option<&mut Self::Output>) {
896        self.map.get2_mut(index1, index2)
897    }
898
899    fn get3_mut<Q: Borrow<K>>(
900        &mut self,
901        index1: Q,
902        index2: Q,
903        index3: Q,
904    ) -> (
905        Option<&mut Self::Output>,
906        Option<&mut Self::Output>,
907        Option<&mut Self::Output>,
908    ) {
909        self.map.get3_mut(index1, index2, index3)
910    }
911}
912
913#[cfg(test)]
914mod tests {
915    use super::Vec;
916    use crate::hal::mem::PhysAddr;
917    use crate::mem::GLOBAL_ALLOCATOR;
918    use core::ops::Range;
919    use core::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
920
921    fn alloc_range(length: usize) -> Range<PhysAddr> {
922        let alloc_range = std::alloc::Layout::from_size_align(length, align_of::<u128>()).unwrap();
923        let ptr = unsafe { std::alloc::alloc(alloc_range) };
924        PhysAddr::new(ptr as usize)..PhysAddr::new(ptr as usize + length)
925    }
926
927    fn setup_memory(mem_size: usize) {
928        unsafe {
929            GLOBAL_ALLOCATOR
930                .lock()
931                .add_range(&alloc_range(mem_size))
932                .unwrap()
933        };
934    }
935
936    #[derive(Debug)]
937    struct Tracker<'a> {
938        id: usize,
939        drops: &'a AtomicUsize,
940        drop_mask: &'a AtomicU64,
941    }
942
943    impl<'a> Tracker<'a> {
944        fn new(id: usize, drops: &'a AtomicUsize, drop_mask: &'a AtomicU64) -> Self {
945            Self {
946                id,
947                drops,
948                drop_mask,
949            }
950        }
951    }
952
953    impl Drop for Tracker<'_> {
954        fn drop(&mut self) {
955            let bit = 1u64 << self.id;
956            let old_mask = self.drop_mask.fetch_or(bit, Ordering::SeqCst);
957            assert_eq!(old_mask & bit, 0, "value {} was dropped twice", self.id);
958            self.drops.fetch_add(1, Ordering::SeqCst);
959        }
960    }
961
962    #[derive(Debug, Eq, PartialEq)]
963    struct NonCopy {
964        value: usize,
965    }
966
967    impl Clone for NonCopy {
968        fn clone(&self) -> Self {
969            Self { value: self.value }
970        }
971    }
972
973    #[test]
974    fn no_length_underflow() {
975        let vec = Vec::<usize, 8>::new();
976        assert!(vec.len() == 0);
977        assert_eq!(vec.at(0), None);
978    }
979
980    #[test]
981    fn reserve_works() {
982        let mut vec = Vec::<usize, 8>::new();
983        for i in 0..7usize {
984            vec.push(i).unwrap();
985        }
986        assert_eq!(vec.len(), 7);
987
988        let _ = vec.reserve(2);
989    }
990
991    #[test]
992    fn drop_underflow() {
993        let mut vec = Vec::<usize, 8>::new();
994        for i in 0..7usize {
995            vec.push(i).unwrap();
996        }
997        drop(vec);
998    }
999
1000    #[test]
1001    fn push_and_index_non_copy_inline() {
1002        let mut vec = Vec::<NonCopy, 4>::new();
1003
1004        for i in 0..4 {
1005            vec.push(NonCopy { value: i }).unwrap();
1006        }
1007
1008        assert_eq!(vec.len(), 4);
1009        for i in 0..4 {
1010            assert_eq!(vec[i].value, i);
1011        }
1012    }
1013
1014    #[test]
1015    fn push_grows_and_keeps_non_copy_values() {
1016        setup_memory(4096);
1017        let mut vec = Vec::<NonCopy, 2>::new();
1018
1019        for i in 0..8 {
1020            vec.push(NonCopy { value: i }).unwrap();
1021        }
1022
1023        assert_eq!(vec.len(), 8);
1024        assert!(vec.capacity() >= 8);
1025        for i in 0..8 {
1026            assert_eq!(vec.at(i).unwrap().value, i);
1027        }
1028    }
1029
1030    #[test]
1031    fn reserve_moves_only_live_extra_values() {
1032        setup_memory(4096);
1033        let drops = AtomicUsize::new(0);
1034        let drop_mask = AtomicU64::new(0);
1035        let mut vec = Vec::<Tracker<'_>, 2>::new();
1036
1037        for i in 0..4 {
1038            vec.push(Tracker::new(i, &drops, &drop_mask)).unwrap();
1039        }
1040
1041        vec.reserve(10).unwrap();
1042
1043        assert_eq!(drops.load(Ordering::SeqCst), 0);
1044        assert_eq!(vec.len(), 4);
1045        for i in 0..4 {
1046            assert_eq!(vec.at(i).unwrap().id, i);
1047        }
1048
1049        drop(vec);
1050        assert_eq!(drops.load(Ordering::SeqCst), 4);
1051        assert_eq!(drop_mask.load(Ordering::SeqCst), 0b1111);
1052    }
1053
1054    #[test]
1055    fn reserve_total_capacity_moves_non_copy_values() {
1056        setup_memory(4096);
1057        let mut vec = Vec::<NonCopy, 2>::new();
1058
1059        for i in 0..5 {
1060            vec.push(NonCopy { value: i }).unwrap();
1061        }
1062
1063        vec.reserve_total_capacity(16).unwrap();
1064
1065        assert!(vec.capacity() >= 16);
1066        assert_eq!(vec.len(), 5);
1067        for i in 0..5 {
1068            assert_eq!(vec.at(i).unwrap().value, i);
1069        }
1070    }
1071
1072    #[test]
1073    fn remove_from_inline_shifts_inline_values() {
1074        let mut vec = Vec::<NonCopy, 5>::new();
1075        for i in 0..5 {
1076            vec.push(NonCopy { value: i }).unwrap();
1077        }
1078
1079        let removed = vec.remove(1).unwrap();
1080
1081        assert_eq!(removed.value, 1);
1082        assert_eq!(vec.len(), 4);
1083        assert_eq!(vec.at(0).unwrap().value, 0);
1084        assert_eq!(vec.at(1).unwrap().value, 2);
1085        assert_eq!(vec.at(2).unwrap().value, 3);
1086        assert_eq!(vec.at(3).unwrap().value, 4);
1087    }
1088
1089    #[test]
1090    fn remove_from_inline_pulls_first_extra_value_inline() {
1091        setup_memory(4096);
1092        let mut vec = Vec::<NonCopy, 3>::new();
1093        for i in 0..7 {
1094            vec.push(NonCopy { value: i }).unwrap();
1095        }
1096
1097        let removed = vec.remove(1).unwrap();
1098
1099        assert_eq!(removed.value, 1);
1100        assert_eq!(vec.len(), 6);
1101        for (idx, expected) in [0, 2, 3, 4, 5, 6].iter().copied().enumerate() {
1102            assert_eq!(vec.at(idx).unwrap().value, expected);
1103        }
1104    }
1105
1106    #[test]
1107    fn remove_from_extra_shifts_extra_values() {
1108        setup_memory(4096);
1109        let mut vec = Vec::<NonCopy, 3>::new();
1110        for i in 0..8 {
1111            vec.push(NonCopy { value: i }).unwrap();
1112        }
1113
1114        let removed = vec.remove(5).unwrap();
1115
1116        assert_eq!(removed.value, 5);
1117        assert_eq!(vec.len(), 7);
1118        for (idx, expected) in [0, 1, 2, 3, 4, 6, 7].iter().copied().enumerate() {
1119            assert_eq!(vec.at(idx).unwrap().value, expected);
1120        }
1121    }
1122
1123    #[test]
1124    fn remove_last_extra_does_not_shift_or_drop_extra_values() {
1125        setup_memory(4096);
1126        let drops = AtomicUsize::new(0);
1127        let drop_mask = AtomicU64::new(0);
1128        let mut vec = Vec::<Tracker<'_>, 2>::new();
1129
1130        for i in 0..5 {
1131            vec.push(Tracker::new(i, &drops, &drop_mask)).unwrap();
1132        }
1133
1134        let removed = vec.remove(4).unwrap();
1135
1136        assert_eq!(removed.id, 4);
1137        assert_eq!(vec.len(), 4);
1138        assert_eq!(drops.load(Ordering::SeqCst), 0);
1139        drop(removed);
1140        assert_eq!(drops.load(Ordering::SeqCst), 1);
1141        drop(vec);
1142        assert_eq!(drops.load(Ordering::SeqCst), 5);
1143        assert_eq!(drop_mask.load(Ordering::SeqCst), 0b1_1111);
1144    }
1145
1146    #[test]
1147    fn pop_moves_value_out_without_copy() {
1148        let drops = AtomicUsize::new(0);
1149        let drop_mask = AtomicU64::new(0);
1150        let mut vec = Vec::<Tracker<'_>, 4>::new();
1151
1152        for i in 0..3 {
1153            vec.push(Tracker::new(i, &drops, &drop_mask)).unwrap();
1154        }
1155
1156        let popped = vec.pop().unwrap();
1157
1158        assert_eq!(popped.id, 2);
1159        assert_eq!(vec.len(), 2);
1160        assert_eq!(drops.load(Ordering::SeqCst), 0);
1161        drop(popped);
1162        assert_eq!(drops.load(Ordering::SeqCst), 1);
1163        drop(vec);
1164        assert_eq!(drops.load(Ordering::SeqCst), 3);
1165        assert_eq!(drop_mask.load(Ordering::SeqCst), 0b111);
1166    }
1167
1168    #[test]
1169    fn clear_drops_each_live_value_once() {
1170        setup_memory(4096);
1171        let drops = AtomicUsize::new(0);
1172        let drop_mask = AtomicU64::new(0);
1173        let mut vec = Vec::<Tracker<'_>, 2>::new();
1174
1175        for i in 0..6 {
1176            vec.push(Tracker::new(i, &drops, &drop_mask)).unwrap();
1177        }
1178
1179        vec.clear();
1180
1181        assert_eq!(vec.len(), 0);
1182        assert_eq!(drops.load(Ordering::SeqCst), 6);
1183        assert_eq!(drop_mask.load(Ordering::SeqCst), 0b11_1111);
1184        drop(vec);
1185        assert_eq!(drops.load(Ordering::SeqCst), 6);
1186    }
1187
1188    #[test]
1189    fn remove_then_drop_drops_every_value_once() {
1190        setup_memory(4096);
1191        let drops = AtomicUsize::new(0);
1192        let drop_mask = AtomicU64::new(0);
1193        let mut vec = Vec::<Tracker<'_>, 3>::new();
1194
1195        for i in 0..7 {
1196            vec.push(Tracker::new(i, &drops, &drop_mask)).unwrap();
1197        }
1198
1199        let removed_inline = vec.remove(1).unwrap();
1200        let removed_extra = vec.remove(4).unwrap();
1201
1202        assert_eq!(removed_inline.id, 1);
1203        assert_eq!(removed_extra.id, 5);
1204        assert_eq!(drops.load(Ordering::SeqCst), 0);
1205
1206        drop(removed_inline);
1207        drop(removed_extra);
1208        assert_eq!(drops.load(Ordering::SeqCst), 2);
1209
1210        drop(vec);
1211        assert_eq!(drops.load(Ordering::SeqCst), 7);
1212        assert_eq!(drop_mask.load(Ordering::SeqCst), 0b111_1111);
1213    }
1214
1215    #[test]
1216    fn clone_works_for_non_copy_values() {
1217        setup_memory(4096);
1218        let mut vec = Vec::<NonCopy, 2>::new();
1219        for i in 0..5 {
1220            vec.push(NonCopy { value: i }).unwrap();
1221        }
1222
1223        let clone = vec.clone();
1224
1225        assert_eq!(clone.len(), 5);
1226        for i in 0..5 {
1227            assert_eq!(clone.at(i).unwrap().value, i);
1228            assert_eq!(vec.at(i).unwrap().value, i);
1229        }
1230    }
1231
1232    #[test]
1233    fn new_init_sets_length_and_initializes_values() {
1234        setup_memory(4096);
1235        let vec = Vec::<NonCopy, 2>::new_init(5, NonCopy { value: 42 }).unwrap();
1236
1237        assert_eq!(vec.len(), 5);
1238        for i in 0..5 {
1239            assert_eq!(vec.at(i).unwrap().value, 42);
1240        }
1241    }
1242
1243    #[test]
1244    fn new_init_oom_does_not_leak() {
1245        struct Counted<'a> {
1246            drops: &'a AtomicUsize,
1247            clones: &'a AtomicUsize,
1248        }
1249        impl Clone for Counted<'_> {
1250            fn clone(&self) -> Self {
1251                self.clones.fetch_add(1, Ordering::SeqCst);
1252                Counted {
1253                    drops: self.drops,
1254                    clones: self.clones,
1255                }
1256            }
1257        }
1258        impl Drop for Counted<'_> {
1259            fn drop(&mut self) {
1260                self.drops.fetch_add(1, Ordering::SeqCst);
1261            }
1262        }
1263
1264        setup_memory(4096);
1265        let drops = AtomicUsize::new(0);
1266        let clones = AtomicUsize::new(0);
1267        let r = Vec::<Counted, 2>::new_init(
1268            1_000_000_000,
1269            Counted {
1270                drops: &drops,
1271                clones: &clones,
1272            },
1273        );
1274        assert!(r.is_err());
1275        let n_clones = clones.load(Ordering::SeqCst);
1276        let n_drops = drops.load(Ordering::SeqCst);
1277        assert_eq!(
1278            n_drops,
1279            n_clones + 1,
1280            "leaked clones (clones={}, drops={})",
1281            n_clones,
1282            n_drops,
1283        );
1284    }
1285
1286    #[test]
1287    fn at2_mut_out_of_bounds_returns_none() {
1288        let mut vec = Vec::<usize, 4>::new();
1289        vec.push(7).unwrap();
1290        let (a, b) = vec.at2_mut(0, 2);
1291        assert!(a.is_some(), "index 0 is in-bounds");
1292        assert!(
1293            b.is_none(),
1294            "index 2 should be out-of-bounds (len=1) and return None, but got {:?}",
1295            b
1296        );
1297    }
1298
1299    #[test]
1300    fn at3_mut_out_of_bounds_returns_none() {
1301        let mut vec = Vec::<usize, 4>::new();
1302        vec.push(7).unwrap();
1303        vec.push(8).unwrap();
1304        let (a, b, c) = vec.at3_mut(0, 1, 3);
1305        assert!(a.is_some());
1306        assert!(b.is_some());
1307        assert!(
1308            c.is_none(),
1309            "index 3 should be out-of-bounds (len=2) and return None, but got {:?}",
1310            c
1311        );
1312    }
1313
1314    use super::IndexMap;
1315    use crate::types::traits::GetMut;
1316
1317    #[test]
1318    fn indexmap_get2_mut_out_of_bounds_returns_none() {
1319        let mut m: IndexMap<usize, u32, 4> = IndexMap::new();
1320        m.raw_insert(0, 10).unwrap();
1321        let (a, b) = m.get2_mut(0usize, 10usize);
1322        assert!(a.is_some());
1323        assert!(b.is_none());
1324    }
1325
1326    #[test]
1327    fn indexmap_get3_mut_out_of_bounds_returns_none() {
1328        let mut m: IndexMap<usize, u32, 4> = IndexMap::new();
1329        m.raw_insert(0, 10).unwrap();
1330        let (a, b, c) = m.get3_mut(0usize, 10usize, 11usize);
1331        assert!(a.is_some());
1332        assert!(b.is_none());
1333        assert!(c.is_none());
1334    }
1335
1336    use super::BitReclaimMap;
1337
1338    #[test]
1339    fn bitreclaim_insert_failure_does_not_leak() {
1340        let mut m: BitReclaimMap<usize, u32, 2> = BitReclaimMap::new();
1341        m.insert(10).unwrap();
1342        m.insert(20).unwrap();
1343        // Third insert allocates bit 2 then fails (raw_insert rejects idx >= N).
1344        assert!(m.insert(30).is_err());
1345        // Probe BitAlloc directly: bit 2 must be free again.
1346        let next_free = m.free.alloc(1);
1347        assert_eq!(
1348            next_free,
1349            Some(2),
1350            "expected bit 2 to be free after failed insert, but BitAlloc returned {:?}",
1351            next_free
1352        );
1353    }
1354
1355    #[test]
1356    fn bitreclaim_insert_with_failed_closure_does_not_leak() {
1357        use crate::error::Result as KResult;
1358        let mut m: BitReclaimMap<usize, u32, 2> = BitReclaimMap::new();
1359        for _ in 0..10 {
1360            let r: KResult<usize> =
1361                m.insert_with(|_idx| -> KResult<(usize, u32)> { Err(kerr!(ENOMEM)) });
1362            assert!(r.is_err());
1363        }
1364        let id0 = m.insert(10).unwrap();
1365        let id1 = m.insert(20).unwrap();
1366        assert!(id0 < 2);
1367        assert!(id1 < 2);
1368        assert_ne!(id0, id1);
1369    }
1370}