Expand description
This module contains types for using the arena allocation strategy. See the Arena type
for more information on how to use arena allocation.
§Arena allocation
In many workloads, the lifetime of a heap allocation is scoped to a particular function call. For example:
fn some_function() {
let value = Box::new(SomeType::default());
let value_2 = Box::new(OtherType::default());
// Use `value` and `value_2` in the body of `some_function()`
// ...
use_values(&*value, &*value_2);
// `value` and `value_2` are dropped and deallocated here as the function returns.
}If many values need to be allocated and deallocated for a function body, this can be inefficient as the heap allocator needs to do work to allocate and deallocate each individual value.
To compensate for this, many strategies can be used so that values are allocated from a single block of memory, reducing the work that the memory allocator needs to do. One of these strategies is called arena allocation.
The idea behind arena allocation is to preallocate a large block of memory, and then write values into that block as necessary. Values cannot be freed until the entire block is finished with, when every value is implicitly deallocated at once.
§Examples
To rewrite the above example some_function() using arena allocation provided by this crate,
an Arena would need to be constructed or passed in to the function. Any transient data allocated
by the function would then be allocated from the Arena:
use rotunda::{Arena, handle::Handle};
fn some_function(arena: &Arena) {
// Allocate the values as before:
let value = Handle::new_in(&arena, SomeType::default());
let value_2 = Handle::new_in(&arena, OtherType::default());
// Use the values as before:
use_values(&*value, &*value_2);
// The values are dropped here, but the memory backing them in the arena is
// not deallocated until the `Arena` is dropped, or the `Arena::reset()` method
// is called.
}The Arena can be visualised as an array of memory, with an integer marking the current
end of the Arena. When the Arena is first initialised and has a block allocated, then
the stack is empty:
+-------+-----------------------------------------------------------+
| (H) | |
+-------+-----------------------------------------------------------+
^ ^
Header Arena endThen, when value and value_2 are allocated into the arena, they
are written into the memory, and the end is adjusted to point into the
next available memory space:
+-------+---------------+---------------+--------------------------------------+
| (H) | (data) | (data) | |
+-------+---------------+---------------+--------------------------------------+
^ ^ ^ ^
Header value value_2 Arena endThen, when value and value_2 are dropped, their drop logic will be
called, but the backing storage of the Arena will not shrink to release
the memory; it will remain inaccessible for future allocations:
+-------+-------------------------------+--------------------------------------+
| (H) |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| |
+-------+-------------------------------+--------------------------------------+
^ ^
Header Arena endWhen the Arena::reset() method is called then the memory will be reclaimed,
and will be usable for future allocations. Note that no active references are
allowed into the Arena when Arena::reset() is called, so there is no
danger of referring to dangling memory. When the Arena is dropped, the
backing memory will be deallocated by the system allocator and returned to
the operating system.
If a block of memory in the arena is completely used up, then a new one will be
allocated. Each block stores a pointer to the next block in its header, so blocks
will be accessible. reseting an Arena will cause blocks to be stored in a free
list so that they can be re-used later, reducing pressure on the memory allocator.
§Handle Types
The arena module comes with a few specialised handle types to make working with Arenas
more ergonomic. These provide a few useful conveniences:
- They have a lifetime which ensures that data allocated from the
Arenacannot outlive theArena, preventing use after frees. - They handle
Droplogic when the handle goes out of scope, preventing resource leaks.
§Handle
The basic handle type is handle::Handle, which is analogous to a Box<T> - it provides unique ownership
of an object allocated in an Arena, allows mutation, and drops the object when it goes out of scope.
Read more in the handle module.
§RcHandle and WeakHandle
These are reference counted shared ownership handle types, analogous to Rc<T> and Weak<T>.
Read more in the rc_handle module.
§Buffer
An owned, growable buffer of elements backed by an allocation into an Arena. The Buffer has
a fixed maximum size which cannot be changed in the Arena.
Read more in the buffer module.
§StringBuffer
An owned, growable buffer containing utf8 encoded bytes.
Read more in the string_buffer module.
§LinkedList
A linked list of nodes, backed by an Arena. This allows an ordered collection of elements backed by
an Arena without requiring contiguous space for all elements in the Arena.
Read more in the linked_list module.
§Features
This crate can be customised with a few optional features:
§allocator-api2
This feature uses the allocator-api2 crate for its definitions of the Allocator trait
and other supporting APIs. This allows rotunda to be built on the stable and beta
rust compilers.
It is required that at least one of either this feature or the nightly feature are enabled so that
an allocator API is provided.
§nightly
This feature enables usage of nightly features in rotunda, such as CoercePointee. It also
allows using the Allocator trait and supporting APIs from alloc::alloc. Note that this feature
will supersede allocator-api2 (i.e. alloc::alloc::Allocator will be used over allocator_api2::alloc::Allocator)
if both are enabled.
§std
This feature enables integration with std traits, such as std::io::Read.
§serde
This feature allows the contents of handle types to be serialized transparently using serde.
Modules§
- buffer
- A contiguous, growable array of values allocated in an
Arena. - handle
- A singly-owned mutable pointer backed by an
Arena. - linked_
list - A doubly-linked owned list of nodes, backed by an
Arena. - rc_
handle - Single-threaded reference-counting pointer types backed by an
Arena. - string_
buffer - A UTF8-encoded, growable string. Backed by an
Arena.
Macros§
Structs§
- AllBlocks
Mut - An iterator type over every block of an
Arena. - Arena
- An arena allocator, parameterised by global allocator.
- Free
Blocks Mut - An iterator type over the free blocks of an
Arena.
Enums§
- Error
- Represents error types which may be returned while using an
Arena.