Skip to main content

XArray

Struct XArray 

Source
pub struct XArray<T: ForeignOwnable, const SHIFT: usize, const SIZE: usize> { /* private fields */ }
Expand description

An extensible array backed by a radix tree, mapping usize indices to Entry values.

T must be a ForeignOwnable whose FOREIGN_ALIGN is at least 4. The type can be named with any other T, but constructing a value of it fails to compile.

§Ownership

When an XArray is dropped, all stored Entry::Pointer entries are freed via ForeignOwnable::from_foreign(). This differs from the C xa_destroy(), which only frees internal nodes and requires callers to free stored pointers themselves. Entry::Int entries are encoded integers with no backing allocation and need no cleanup.

§Examples

use kernel::alloc::{flags, KBox};
use kernel::rxarray::{BorrowedEntry, Entry, XArray6};

let mut xa = XArray6::<KBox<u64>>::new();
assert!(xa.is_empty());

// Store a pointer entry at index 1.
let boxed = KBox::new(0xbeef_u64, flags::GFP_KERNEL)?;
xa.store(1, Entry::Pointer(boxed), flags::GFP_KERNEL)?;
match xa.load(1) {
    Some(BorrowedEntry::Pointer(val)) => assert_eq!(*val, 0xbeef_u64),
    _ => panic!("expected Pointer"),
}

// Store a value entry at index 0.
let old = xa.store(0, Entry::int::<0xdead>(), flags::GFP_KERNEL)?;
assert!(old.is_none());
assert!(!xa.is_empty());

match xa.load(0) {
    Some(BorrowedEntry::Int(v)) => assert_eq!(v, 0xdead),
    _ => panic!("expected Int"),
}

let old = xa.store(0, Entry::int::<0xcafe>(), flags::GFP_KERNEL)?;
match old {
    Some(Entry::Int(v)) => assert_eq!(v, 0xdead),
    _ => panic!("expected old Int"),
}

match xa.erase(0) {
    Some(Entry::Int(v)) => assert_eq!(v, 0xcafe),
    _ => panic!("expected erased Int"),
}
assert!(xa.erase(1).is_some());
assert!(xa.is_empty());

§Invariants

  • T::FOREIGN_ALIGN >= 4, ensuring pointer entries do not collide with the integer or internal entry encoding.
  • SHIFT > 0 and SIZE == 1 << SHIFT.
  • Every slot in every node satisfies the Slot invariants.
  • Interior levels (level > 0) contain only empty or node slots. Leaf level (level 0) contains only empty, Int, or Pointer slots.
  • The subtree below every node slot contains at least one of the Entry types (Int or Pointer).

Implementations§

Source§

impl<T: ForeignOwnable, const SHIFT: usize, const SIZE: usize> XArray<T, SHIFT, SIZE>

Source

pub const fn new() -> Self

Creates a new empty XArray.

Source

pub fn is_empty(&self) -> bool

Returns true if the tree contains no entries.

Scanning the root node suffices: by the type invariants, every node slot in it leads to at least one entry.

Source

pub fn erase(&mut self, index: usize) -> Option<Entry<T>>

Erases the entry at index.

Returns the previous entry, or None if the slot was empty. Empty intermediate nodes are freed during traversal.

Source

pub fn store( &mut self, index: usize, entry: Entry<T>, flags: Flags, ) -> Result<Option<Entry<T>>, StoreError<T>>

Stores an entry at index.

Returns the previous entry, or None if the slot was empty.

§Errors

Returns a StoreError carrying the entry back to the caller, with error ENOMEM if a new intermediate node cannot be allocated. A failed stored leaves the tree unchanged. For C callers, EINVAL in case of tree corruption detection.

Source

pub fn load(&self, index: usize) -> Option<BorrowedEntry<'_, T>>

Loads the entry at index.

Returns None if the slot is empty. The returned BorrowedEntry is a value that borrows from the array where pointer entries carry T::Borrowed<'_> (e.g., &T for KBox<T>), and integer entries carry a copy of the Value.

Source

pub fn load_mut(&mut self, index: usize) -> Option<BorrowedEntryMut<'_, T>>

Loads the entry at index for mutation.

Returns None if the slot is empty. The returned BorrowedEntryMut is a value that borrows from the array where pointer entries carry T::BorrowedMut<'_> (e.g., &mut T for KBox<T>), and integer entries carry a copy of the Value.

Trait Implementations§

Source§

impl<T: ForeignOwnable, const SHIFT: usize, const SIZE: usize> Default for XArray<T, SHIFT, SIZE>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<T, const SHIFT: usize, const SIZE: usize> Freeze for XArray<T, SHIFT, SIZE>
where Node<T, SHIFT, SIZE>: Freeze,

§

impl<T, const SHIFT: usize, const SIZE: usize> RefUnwindSafe for XArray<T, SHIFT, SIZE>
where Node<T, SHIFT, SIZE>: RefUnwindSafe,

§

impl<T, const SHIFT: usize, const SIZE: usize> Send for XArray<T, SHIFT, SIZE>
where Node<T, SHIFT, SIZE>: Send,

§

impl<T, const SHIFT: usize, const SIZE: usize> Sync for XArray<T, SHIFT, SIZE>
where Node<T, SHIFT, SIZE>: Sync,

§

impl<T, const SHIFT: usize, const SIZE: usize> Unpin for XArray<T, SHIFT, SIZE>
where Node<T, SHIFT, SIZE>: Unpin,

§

impl<T, const SHIFT: usize, const SIZE: usize> UnsafeUnpin for XArray<T, SHIFT, SIZE>
where Node<T, SHIFT, SIZE>: UnsafeUnpin,

§

impl<T, const SHIFT: usize, const SIZE: usize> UnwindSafe for XArray<T, SHIFT, SIZE>
where Node<T, SHIFT, SIZE>: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Init<T> for T

Source§

fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>
where F: FnOnce(&mut T) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<S, T> IntoSafeCast<T> for S
where T: FromSafeCast<S>,

Source§

fn into_safe_cast(self) -> T

Convert self into a T. This operation is guaranteed to be lossless.
Source§

impl<S, T> IntoSafeCastArch<T> for S
where T: FromSafeCastArch<S>,

Source§

fn into_safe_cast_arch(self) -> T

Convert self into a T. This operation is guaranteed to be lossless.
Source§

impl<T> KnownSize for T

Source§

const MIN_SIZE: usize = const MIN_SIZE: usize = size_of::<T>();

Minimum size of this type known at compile-time.
Source§

const MIN_ALIGN: Alignment = const MIN_ALIGN: Alignment = Alignment::of::<T>();

Minimum alignment of this type known at compile-time.
Source§

fn size(_: *const T) -> usize

Get the size of an object of this type in bytes, with the metadata of the given pointer.
Source§

impl<T> PinInit<T> for T

Source§

unsafe fn __init(self, slot: *mut T) -> Result<(), !>

Initializes slot. Read more
Source§

fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>
where F: FnOnce(Pin<&mut T>) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T, U, const N: u32> TryIntoBounded<T, N> for U
where T: Integer, U: TryInto<T>,

Source§

fn try_into_bounded(self) -> Option<Bounded<T, N>>

Attempts to convert self into a Bounded using N bits. Read more