Struct rarena_allocator::Arena
source · pub struct Arena { /* private fields */ }Expand description
Arena should be lock-free
Implementations§
source§impl Arena
impl Arena
sourcepub const fn version(&self) -> u16
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();sourcepub const fn magic_version(&self) -> u16
pub const fn magic_version(&self) -> u16
sourcepub fn allocated(&self) -> usize
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();sourcepub const fn capacity(&self) -> usize
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();sourcepub fn remaining(&self) -> usize
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();sourcepub fn refs(&self) -> usize
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();sourcepub fn discarded(&self) -> u32
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();sourcepub fn increase_discarded(&self, size: u32)
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);sourcepub fn minimum_segment_size(&self) -> u32
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();sourcepub fn set_minimum_segment_size(&self, size: u32)
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);sourcepub const fn data_offset(&self) -> usize
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();sourcepub fn data(&self) -> &[u8] ⓘ
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§impl Arena
impl Arena
sourcepub fn new(opts: ArenaOptions) -> Self
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());sourcepub fn map_mut<P: AsRef<Path>>(
path: P,
opts: ArenaOptions,
open_options: OpenOptions,
mmap_options: MmapOptions,
) -> Result<Self>
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();
sourcepub fn map<P: AsRef<Path>>(
path: P,
open_options: OpenOptions,
mmap_options: MmapOptions,
magic_version: u16,
) -> Result<Self>
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();
sourcepub fn map_anon(opts: ArenaOptions, mmap_options: MmapOptions) -> Result<Self>
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();sourcepub fn flush(&self) -> Result<()>
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();
sourcepub fn flush_async(&self) -> Result<()>
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();
sourcepub fn alloc_bytes_owned(&self, size: u32) -> Result<BytesMut, Error>
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.
sourcepub fn alloc_bytes(&self, size: u32) -> Result<BytesRefMut<'_>, Error>
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.
sourcepub fn alloc_aligned_bytes<T>(
&self,
size: u32,
) -> Result<BytesRefMut<'_>, Error>
pub fn alloc_aligned_bytes<T>( &self, size: u32, ) -> Result<BytesRefMut<'_>, Error>
sourcepub unsafe fn alloc<T>(&self) -> Result<RefMut<'_, T>, Error>
pub unsafe fn alloc<T>(&self) -> Result<RefMut<'_, T>, Error>
Allocates a T in the ARENA.
§Safety
-
If
Tneeds to be dropped and callers invokeRefMut::detach, then the caller must ensure that theTis dropped before the ARENA is dropped. Otherwise, it will lead to memory leaks. -
If this is file backed ARENA, then
Tmust be recoverable from bytes.- Types require allocation are not recoverable.
- Pointers are not recoverable, like
*const T,*mut T,NonNulland 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);sourcepub unsafe fn alloc_owned<T>(&self) -> Result<Owned<T>, Error>
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
- See
allocfor 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);
}sourcepub unsafe fn clear(&self) -> Result<(), Error>
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 behaviorGood 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();
}
sourcepub unsafe fn dealloc(&self, offset: u32, size: u32) -> bool
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 + sizeis not deallocated twice. offsetmust be larger than theArena::data_offset.offset + sizemust be less than theArena::allocated.
sourcepub const unsafe fn get_bytes(&self, offset: usize, size: usize) -> &[u8] ⓘ
pub const unsafe fn get_bytes(&self, offset: usize, size: usize) -> &[u8] ⓘ
Returns a bytes slice from the ARENA.
§Safety
offset..offset + sizemust be allocated memory.offsetmust be less than the capacity of the ARENA.sizemust be less than the capacity of the ARENA.offset + sizemust be less than the capacity of the ARENA.
sourcepub unsafe fn get_bytes_mut(&self, offset: usize, size: usize) -> &mut [u8] ⓘ
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 + sizemust be allocated memory.offsetmust be less than the capacity of the ARENA.sizemust be less than the capacity of the ARENA.offset + sizemust be less than the capacity of the ARENA.
§Panic
- If the ARENA is read-only, then this method will panic.
sourcepub const unsafe fn get_pointer(&self, offset: usize) -> *const u8
pub const unsafe fn get_pointer(&self, offset: usize) -> *const u8
Returns a pointer to the memory at the given offset.
§Safety
offsetmust be less than the capacity of the ARENA.
sourcepub unsafe fn get_pointer_mut(&self, offset: usize) -> *mut u8
pub unsafe fn get_pointer_mut(&self, offset: usize) -> *mut u8
sourcepub unsafe fn get_aligned_pointer<T>(&self, offset: usize) -> *const T
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>() + paddingmust be allocated memory.offsetmust be less than the capacity of the ARENA.
sourcepub unsafe fn get_aligned_pointer_mut<T>(&self, offset: usize) -> NonNull<T>
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>() + paddingmust be allocated memory.offsetmust be less than the capacity of the ARENA.
§Panic
- If the ARENA is read-only, then this method will panic.
Trait Implementations§
impl Send for Arena
impl Sync for Arena
Auto Trait Implementations§
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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