Arena

Struct Arena 

Source
pub struct Arena<T: Sized> { /* private fields */ }
Expand description

An arena

It can be sent to other threads but is not Sync.
Pointers to the elements in the Arena are shareable between threads.

use shared_arena::Arena;

let arena = Arena::new();
let foo = arena.alloc(1);

let bar = std::thread::spawn(move || {
    let bar = arena.alloc(100);
    std::mem::drop(arena);
    bar
});

// The values are still valid, even if the arena has been dropped
// in the other thread
assert_eq!(*bar.join().unwrap() + *foo, 101);

Implementations§

Source§

impl<T: Sized> Arena<T>

Source

pub fn with_capacity(cap: usize) -> Arena<T>

Constructs a new Arena capable of holding at least cap elements

Because the arena allocate by page of 63 elements, it might be able to hold more elements than cap.

The Arena will reallocate itself if there is not enough space when allocating (with alloc* functions)

§Example
let arena = Arena::with_capacity(2048);
Source

pub fn new() -> Arena<T>

Constructs a new Arena capable of holding exactly 63 elements

The Arena will reallocate itself if there is not enough space when allocating (with alloc* functions)

§Example
let arena = Arena::new();
Source

pub fn alloc(&self, value: T) -> ArenaBox<T>

Writes a value in the arena, and returns an ArenaBox pointing to that value.

§Example
let arena = Arena::new();
let my_num: ArenaBox<u8> = arena.alloc(0xFF);

assert_eq!(*my_num, 255);
Source

pub fn alloc_with<F>(&self, initializer: F) -> ArenaBox<T>
where F: Fn(&mut MaybeUninit<T>) -> &T,

Finds an empty space in the arena and calls the function initializer with its argument pointing to that space. It returns an ArenaBox pointing to the newly initialized value.

The difference with alloc is that it has the benefit of avoiding intermediate copies of the value.

§Safety

It is the caller responsability to initialize properly the value.
initializer must return &T, this is a way to ensure that its parameter &mut MaybeUninit<T> has been “consumed”.

If initializer returns a different reference than its parameter, the function will panic.

When the ArenaBox is dropped, the value is also dropped. If the value is not initialized correctly, it will drop an unitialized value, which is undefined behavior.

§Example
struct MyData {
    a: usize
}

fn initialize_data<'a>(uninit: &'a mut MaybeUninit<MyData>, source: &MyData) -> &'a MyData {
    unsafe {
        let ptr = uninit.as_mut_ptr();
        ptr::copy(source, ptr, 1);
        &*ptr
    }
}

let arena = Arena::<MyData>::new();
let source = MyData { a: 101 };

let data = arena.alloc_with(|uninit| {
    initialize_data(uninit, &source)
});
assert!(data.a == 101);
Source

pub fn alloc_arc(&self, value: T) -> ArenaArc<T>

Writes a value in the arena, and returns an ArenaArc pointing to that value.

§Example
let arena = Arena::new();
let my_num: ArenaArc<u8> = arena.alloc_arc(0xFF);

assert_eq!(*my_num, 255);
Source

pub fn alloc_arc_with<F>(&self, initializer: F) -> ArenaArc<T>
where F: Fn(&mut MaybeUninit<T>) -> &T,

Finds an empty space in the arena and calls the function initializer with its argument pointing to that space. It returns an ArenaArc pointing to the newly initialized value.

The difference with alloc_arc is that it has the benefit of avoiding intermediate copies of the value.

§Safety

It is the caller responsability to initialize properly the value.
initializer must return &T, this is a way to ensure that its parameter &mut MaybeUninit<T> has been “consumed”.

If initializer returns a different reference than its parameter, the function will panic.

When all ArenaArc pointing that value are dropped, the value is also dropped. If the value is not initialized correctly, it will drop an unitialized value, which is undefined behavior.

§Example
struct MyData {
    a: usize
}

fn initialize_data<'a>(uninit: &'a mut MaybeUninit<MyData>, source: &MyData) -> &'a MyData {
    unsafe {
        let ptr = uninit.as_mut_ptr();
        ptr::copy(source, ptr, 1);
        &*ptr
    }
}

let arena = Arena::<MyData>::new();
let source = MyData { a: 101 };

let data = arena.alloc_arc_with(|uninit| {
    initialize_data(uninit, &source)
});
assert!(data.a == 101);
Source

pub fn alloc_rc(&self, value: T) -> ArenaRc<T>

Writes a value in the arena, and returns an ArenaRc pointing to that value.

§Example
let arena = Arena::new();
let my_num: ArenaRc<u8> = arena.alloc_rc(0xFF);

assert_eq!(*my_num, 255);
Source

pub fn alloc_rc_with<F>(&self, initializer: F) -> ArenaRc<T>
where F: Fn(&mut MaybeUninit<T>) -> &T,

Finds an empty space in the arena and calls the function initializer with its argument pointing to that space. It returns an ArenaRc pointing to the newly initialized value.

The difference with alloc_rc is that it has the benefit of avoiding intermediate copies of the value.

§Safety

It is the caller responsability to initialize properly the value.
initializer must return &T, this is a way to ensure that its parameter &mut MaybeUninit<T> has been “consumed”.

If initializer returns a different reference than its parameter, the function will panic.

When all ArenaRc pointing that value are dropped, the value is also dropped. If the value is not initialized correctly, it will drop an unitialized value, which is undefined behavior.

§Example
struct MyData {
    a: usize
}

fn initialize_data<'a>(uninit: &'a mut MaybeUninit<MyData>, source: &MyData) -> &'a MyData {
    unsafe {
        let ptr = uninit.as_mut_ptr();
        ptr::copy(source, ptr, 1);
        &*ptr
    }
}

let arena = Arena::<MyData>::new();
let source = MyData { a: 101 };

let data = arena.alloc_rc_with(|uninit| {
    initialize_data(uninit, &source)
});
assert!(data.a == 101);
Source

pub fn shrink_to_fit(&self) -> bool

Shrinks the capacity of the arena as much as possible.

It will drop all pages that are unused (no Arena{Box,Arc,Rc} points to it).
If there is still one or more references to a page, the page won’t be dropped.

This is a slow function and it should not be called in a hot path.

The dedicated memory will be deallocated during this call.

§Example
let mut arena = Arena::with_capacity(2048);
let mut values = Vec::new();

assert_eq!(arena.stats(), (0, 2079));

for _ in 0..80 {
    values.push(arena.alloc(0xFF));
}

arena.shrink_to_fit();

let (used, free) = arena.stats();
assert!(used == 80, free == 46);
Source

pub fn stats(&self) -> (usize, usize)

Returns a tuple of non-free and free spaces in the arena

This is a slow function and it should not be called in a hot path.

§Example
let arena = Arena::new();
let item = arena.alloc(1);
let (used, free) = arena.stats();
assert!(used == 1 && free == 62);

Trait Implementations§

Source§

impl<T> Debug for Arena<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Sized> Default for Arena<T>

Source§

fn default() -> Arena<T>

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

impl<T: Sized> Drop for Arena<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<T: Sized> Send for Arena<T>

Auto Trait Implementations§

§

impl<T> !Freeze for Arena<T>

§

impl<T> !RefUnwindSafe for Arena<T>

§

impl<T> !Sync for Arena<T>

§

impl<T> Unpin for Arena<T>

§

impl<T> !UnwindSafe for Arena<T>

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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.