Struct rarena_allocator::Arena

source ·
pub struct Arena { /* private fields */ }
Expand description

Arena should be lock-free

Implementations§

source§

impl Arena

source

pub const fn version(&self) -> u16

Returns the version of the ARENA.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
let version = arena.version();
source

pub const fn magic_version(&self) -> u16

Returns the magic version of the ARENA. This value can be used to check the compatibility for application using Arena.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
let magic_version = arena.magic_version();
source

pub fn allocated(&self) -> usize

Returns the number of bytes allocated by the ARENA.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
let allocated = arena.allocated();
source

pub const fn capacity(&self) -> usize

Returns the capacity of the ARENA.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
let capacity = arena.capacity();
source

pub fn remaining(&self) -> usize

Returns the number of bytes remaining bytes can be allocated by the ARENA.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
let remaining = arena.remaining();
source

pub fn refs(&self) -> usize

Returns the number of references to the ARENA.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
let refs = arena.refs();
source

pub fn discarded(&self) -> u32

Returns the number of bytes discarded by the ARENA.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
let discarded = arena.discarded();
source

pub fn increase_discarded(&self, size: u32)

Forcelly increases the discarded bytes.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
arena.increase_discarded(100);
source

pub fn minimum_segment_size(&self) -> u32

Returns the minimum segment size of the ARENA.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
let min_segment_size = arena.minimum_segment_size();
source

pub fn set_minimum_segment_size(&self, size: u32)

Sets the minimum segment size of the ARENA.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
arena.set_minimum_segment_size(100);
source

pub const fn data_offset(&self) -> usize

Returns the data offset of the ARENA. The offset is the end of the reserved bytes of the ARENA.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
let data_offset = arena.data_offset();
source

pub fn data(&self) -> &[u8]

Returns the data section of the ARENA as a byte slice, header is not included.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
let data = arena.data();
source

pub const fn memory(&self) -> &[u8]

Returns the whole main memory of the ARENA as a byte slice.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
let memory = arena.memory();
source

pub const fn read_only(&self) -> bool

Returns true if the arena is read-only.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
let read_only = arena.read_only();
source§

impl Arena

source

pub fn new(opts: ArenaOptions) -> Self

Creates a new ARENA with the given options.

§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());
source

pub fn map_mut<P: AsRef<Path>>( path: P, opts: ArenaOptions, open_options: OpenOptions, mmap_options: MmapOptions, ) -> Result<Self>

Creates a new ARENA backed by a mmap with the given options.

§Example
use rarena_allocator::{Arena, ArenaOptions, OpenOptions, MmapOptions};


let open_options = OpenOptions::default().create_new(Some(100)).read(true).write(true);
let mmap_options = MmapOptions::new();
let arena = Arena::map_mut(&path, ArenaOptions::new(), open_options, mmap_options).unwrap();
source

pub fn map<P: AsRef<Path>>( path: P, open_options: OpenOptions, mmap_options: MmapOptions, magic_version: u16, ) -> Result<Self>

Opens a read only ARENA backed by a mmap with the given capacity.

§Example
use rarena_allocator::{Arena, ArenaOptions, OpenOptions, MmapOptions};



let open_options = OpenOptions::default().read(true);
let mmap_options = MmapOptions::new();
let arena = Arena::map(&path, open_options, mmap_options, 0).unwrap();
source

pub fn map_anon(opts: ArenaOptions, mmap_options: MmapOptions) -> Result<Self>

Creates a new ARENA backed by an anonymous mmap with the given capacity.

§Example
use rarena_allocator::{Arena, ArenaOptions, MmapOptions};

let mmap_options = MmapOptions::new().len(100);
let arena = Arena::map_anon(ArenaOptions::new(), mmap_options).unwrap();
source

pub fn flush(&self) -> Result<()>

Flushes the memory-mapped file to disk.

§Example
use rarena_allocator::{Arena, ArenaOptions, OpenOptions, MmapOptions};

let open_options = OpenOptions::default().create_new(Some(100)).read(true).write(true);
let mmap_options = MmapOptions::new();
let mut arena = Arena::map_mut(&path, ArenaOptions::new(), open_options, mmap_options).unwrap();
arena.flush().unwrap();
source

pub fn flush_async(&self) -> Result<()>

Flushes the memory-mapped file to disk asynchronously.

§Example
use rarena_allocator::{Arena, ArenaOptions, OpenOptions, MmapOptions};

let open_options = OpenOptions::default().create(Some(100)).read(true).write(true);
let mmap_options = MmapOptions::new();
let mut arena = Arena::map_mut(&path, ArenaOptions::new(), open_options, mmap_options).unwrap();

arena.flush_async().unwrap();
source

pub fn alloc_bytes_owned(&self, size: u32) -> Result<BytesMut, Error>

Allocates an owned slice of memory in the ARENA.

The cost of this method is an extra atomic operation, compared to alloc_bytes.

source

pub fn alloc_bytes(&self, size: u32) -> Result<BytesRefMut<'_>, Error>

Allocates a slice of memory in the ARENA.

The BytesRefMut is zeroed out.

If you want a BytesMut, see alloc_bytes_owned.

source

pub fn alloc_aligned_bytes_owned<T>(&self, size: u32) -> Result<BytesMut, Error>

Allocates an owned byte slice that can hold a well-aligned T and extra size bytes.

The layout of the allocated memory is:

| T | [u8; size] |
§Example
let mut bytes = arena.alloc_aligned_bytes_owned::<T>(extra).unwrap();
bytes.put(val).unwrap(); // write `T` to the byte slice.
source

pub fn alloc_aligned_bytes<T>( &self, size: u32, ) -> Result<BytesRefMut<'_>, Error>

Allocates a byte slice that can hold a well-aligned T and extra size bytes.

The layout of the allocated memory is:

| T | [u8; size] |
§Example
let mut bytes = arena.alloc_aligned_bytes::<T>(extra).unwrap();
bytes.put(val).unwrap(); // write `T` to the byte slice.
source

pub unsafe fn alloc<T>(&self) -> Result<RefMut<'_, T>, Error>

Allocates a T in the ARENA.

§Safety
  • If T needs to be dropped and callers invoke RefMut::detach, then the caller must ensure that the T is dropped before the ARENA is dropped. Otherwise, it will lead to memory leaks.

  • If this is file backed ARENA, then T must be recoverable from bytes.

    1. Types require allocation are not recoverable.
    2. Pointers are not recoverable, like *const T, *mut T, NonNull and any structs contains pointers, although those types are on stack, but they cannot be recovered, when reopens the file.
§Examples
§Memory leak

The following example demonstrates the memory leak when the T is a heap allocated type and detached.


let arena = Arena::new(ArenaOptions::new());

{
  let mut data = arena.alloc::<Vec<u8>>().unwrap();
  data.detach();
  data.write(vec![1, 2, 3]);
}

drop(arena); // memory leak, the `Vec<u8>` is not dropped.
§Undefined behavior

The following example demonstrates the undefined behavior when the T is not recoverable.


struct TypeOnHeap {
  data: Vec<u8>,
}

let arena = Arena::map_mut("path/to/file", ArenaOptions::new(), OpenOptions::create_new(Some(1000)).read(true).write(true), MmapOptions::default()).unwrap();

let mut data = arena.alloc::<TypeOnHeap>().unwrap();
data.detach();
data.write(TypeOnHeap { data: vec![1, 2, 3] });
let offset = data.offset();
drop(arena);

// reopen the file
let arena = Arena::map("path/to/file", OpenOptions::read(true), MmapOptions::default()).unwrap();

let foo = &*arena.get_aligned_pointer::<TypeOnHeap>(offset as usize);
let b = foo.data[1]; // undefined behavior, the `data`'s pointer stored in the file is not valid anymore.
§Good practice

Some examples about how to use this method correctly.

§Heap allocated type with carefull memory management
let arena = Arena::new(ArenaOptions::new());

// Do not invoke detach, so when the data is dropped, the drop logic will be handled by the ARENA.
// automatically.
{
  let mut data = arena.alloc::<Vec<u8>>().unwrap();
  data.write(vec![1, 2, 3]);
}


let mut detached_data = arena.alloc::<Vec<u8>>().unwrap();
detached_data.detach();
detached_data.write(vec![4, 5, 6]);

// some other logic

core::ptr::drop_in_place(detached_data.as_mut()); // drop the `Vec` manually.

drop(arena); // it is safe, the `Vec` is already dropped.
§Recoverable type with file backed ARENA

struct Recoverable {
  field1: u64,
  field2: AtomicU32,
}

let arena = Arena::map_mut("path/to/file", ArenaOptions::new(), OpenOptions::create_new(Some(1000)).read(true).write(true), MmapOptions::default()).unwrap();

let mut data = arena.alloc::<Recoverable>().unwrap();
data.write(Recoverable { field1: 10, field2: AtomicU32::new(20) });
data.detach();
let offset = data.offset();
drop(arena);

// reopen the file
let arena = Arena::map("path/to/file", OpenOptions::read(true), MmapOptions::default()).unwrap();

let foo = &*arena.get_aligned_pointer::<Recoverable>(offset as usize);

assert_eq!(foo.field1, 10);
assert_eq!(foo.field2.load(Ordering::Acquire), 20);
source

pub unsafe fn alloc_owned<T>(&self) -> Result<Owned<T>, Error>

Allocates a T in the ARENA. Like alloc, but returns an Owned.

The cost is one more atomic operation than alloc.

§Safety
§Example
use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());

unsafe {
  let mut data = arena.alloc_owned::<u64>().unwrap();
  data.write(10);

  assert_eq!(*data.as_ref(), 10);
}
source

pub unsafe fn clear(&self) -> Result<(), Error>

Clear the ARENA.

§Safety
  • The current pointers get from the ARENA cannot be used anymore after calling this method.
  • This method is not thread-safe.
§Examples

Undefine behavior:

let mut data = arena.alloc::<Vec<u8>>().unwrap();

arena.clear();

data.write(vec![1, 2, 3]); // undefined behavior

Good practice:

use rarena_allocator::{Arena, ArenaOptions};

let arena = Arena::new(ArenaOptions::new());

unsafe {
  let mut data = arena.alloc::<Vec<u8>>().unwrap();
  data.write(vec![1, 2, 3]);

  arena.clear().unwrap();
}
source

pub unsafe fn dealloc(&self, offset: u32, size: u32) -> bool

Deallocates the memory at the given offset and size, the offset..offset + size will be made to a segment, returns true if the deallocation is successful.

§Safety
  • you must ensure the same offset..offset + size is not deallocated twice.
  • offset must be larger than the Arena::data_offset.
  • offset + size must be less than the Arena::allocated.
source

pub const unsafe fn get_bytes(&self, offset: usize, size: usize) -> &[u8]

Returns a bytes slice from the ARENA.

§Safety
  • offset..offset + size must be allocated memory.
  • offset must be less than the capacity of the ARENA.
  • size must be less than the capacity of the ARENA.
  • offset + size must be less than the capacity of the ARENA.
source

pub unsafe fn get_bytes_mut(&self, offset: usize, size: usize) -> &mut [u8]

Returns a mutable bytes slice from the ARENA. If the ARENA is read-only, then this method will return an empty slice.

§Safety
  • offset..offset + size must be allocated memory.
  • offset must be less than the capacity of the ARENA.
  • size must be less than the capacity of the ARENA.
  • offset + size must be less than the capacity of the ARENA.
§Panic
  • If the ARENA is read-only, then this method will panic.
source

pub const unsafe fn get_pointer(&self, offset: usize) -> *const u8

Returns a pointer to the memory at the given offset.

§Safety
  • offset must be less than the capacity of the ARENA.
source

pub unsafe fn get_pointer_mut(&self, offset: usize) -> *mut u8

Returns a pointer to the memory at the given offset. If the ARENA is read-only, then this method will return a null pointer.

§Safety
  • offset must be less than the capacity of the ARENA.
§Panic
  • If the ARENA is read-only, then this method will panic.
source

pub unsafe fn get_aligned_pointer<T>(&self, offset: usize) -> *const T

Returns an aligned pointer to the memory at the given offset.

§Safety
  • offset..offset + mem::size_of::<T>() + padding must be allocated memory.
  • offset must be less than the capacity of the ARENA.
source

pub unsafe fn get_aligned_pointer_mut<T>(&self, offset: usize) -> NonNull<T>

Returns an aligned pointer to the memory at the given offset. If the ARENA is read-only, then this method will return a null pointer.

§Safety
  • offset..offset + mem::size_of::<T>() + padding must be allocated memory.
  • offset must be less than the capacity of the ARENA.
§Panic
  • If the ARENA is read-only, then this method will panic.
source

pub unsafe fn offset(&self, ptr: *const u8) -> usize

Returns the offset to the start of the ARENA.

§Safety
  • ptr must be allocated by this ARENA.

Trait Implementations§

source§

impl Clone for Arena

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Arena

source§

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

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

impl Drop for Arena

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl Send for Arena

source§

impl Sync for Arena

Auto Trait Implementations§

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

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. 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<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

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

§

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>,

§

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

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more