pub struct Region<T: Flat, B: Buf = AlignedBuf<T>> { /* private fields */ }Expand description
An owning, contiguous byte buffer whose root value T starts at byte 0.
All Near and NearList pointers
inside the region are self-relative offsets, so Clone is a plain memcpy
— no fixup needed.
§Memory layout
┌──────────────────────────────────────────────┐
│ Root T (starts at byte 0) │
│ ├── scalar fields (inline) │
│ ├── Near<U> → i32 offset ───────┐ │
│ └── NearList<V> → i32 + u32 ──┐ │ │
│ │ │ │
│ [padding] │ │ │
│ U value ◄──────────────────────│─┘ │
│ [padding] │ │
│ Segment<V> header ◄────────────┘ │
│ V values... │
└──────────────────────────────────────────────┘§Soundness
Ownership: A Region exclusively owns its buffer. There is no
shared mutable state. Clone performs a byte-for-byte copy of the buffer;
all self-relative offsets remain valid because they are position-independent.
Alignment: The buffer base is aligned to max(align_of::<T>(), 8).
Every sub-allocation is padded to the target type’s alignment. A
compile-time assertion ensures no type exceeds the buffer’s base alignment.
Mutation safety: All mutations go through Session,
which holds &mut Region. The branded 'id lifetime on Ref
prevents refs from escaping or crossing sessions.
Send/Sync: Implemented with T: Send + Sync bounds as
defense-in-depth. All Flat types are Send + Sync by construction
(no heap pointers, no interior mutability), but the bounds let the
compiler verify this.
Implementations§
Source§impl<T: Flat> Region<T>
impl<T: Flat> Region<T>
Sourcepub fn new(builder: impl Emit<T>) -> Self
pub fn new(builder: impl Emit<T>) -> Self
Construct a region from a builder using the default AlignedBuf.
The builder emits the root T (and any nested data) into a fresh
emitter, producing an immutable Region.
§Examples
use nearest::{Flat, NearList, Region, empty};
#[derive(Flat, Debug)]
struct Node {
id: u32,
children: NearList<u32>,
}
// Build with the derive-generated `Node::make(id, children)` builder.
let region = Region::new(Node::make(1, [10u32, 20, 30]));
assert_eq!(region.id, 1);
assert_eq!(region.children.len(), 3);
// Build with an empty list.
let region = Region::new(Node::make(2, empty()));
assert_eq!(region.children.len(), 0);Sourcepub fn with_capacity(capacity: u32, builder: impl Emit<T>) -> Self
pub fn with_capacity(capacity: u32, builder: impl Emit<T>) -> Self
Construct a region with a pre-allocated buffer of at least capacity bytes.
Avoids repeated reallocations when the final size is approximately known.
Source§impl<T: Flat, B: Buf> Region<T, B>
impl<T: Flat, B: Buf> Region<T, B>
Sourcepub fn new_in(builder: impl Emit<T>) -> Self
pub fn new_in(builder: impl Emit<T>) -> Self
Construct a region from a builder using an explicit buffer type B.
For the default heap-backed buffer, use Region::new instead.
Sourcepub fn with_capacity_in(capacity: u32, builder: impl Emit<T>) -> Self
pub fn with_capacity_in(capacity: u32, builder: impl Emit<T>) -> Self
Construct a region with a pre-allocated buffer of at least capacity bytes.
Sourcepub fn session<R>(
&mut self,
f: impl for<'id> FnOnce(&mut Session<'id, '_, T, B>) -> R,
) -> R
pub fn session<R>( &mut self, f: impl for<'id> FnOnce(&mut Session<'id, '_, T, B>) -> R, ) -> R
Open a branded session. Refs created inside the closure
cannot escape or be used with a different session — compile-time safety,
zero runtime cost.
§Examples
use nearest::{Flat, NearList, Region, empty};
#[derive(Flat, Debug)]
struct Node {
id: u32,
children: NearList<u32>,
}
let mut region = Region::new(Node::make(1, [10u32, 20]));
// Read and mutate inside a session.
region.session(|s| {
let root = s.root();
assert_eq!(s.at(root).id, 1);
let children = s.nav(root, |n| &n.children);
s.splice_list(children, [99u32]);
});
assert_eq!(region.children.len(), 1);
assert_eq!(region.children[0], 99);Sourcepub fn byte_len(&self) -> usize
pub fn byte_len(&self) -> usize
Returns the total byte length of the region.
§Examples
use nearest::{Flat, NearList, Region, empty};
#[derive(Flat)]
struct Node { id: u32, items: NearList<u32> }
let region = Region::new(Node::make(1, empty()));
assert!(region.byte_len() >= core::mem::size_of::<Node>());Sourcepub fn trim(&mut self)
pub fn trim(&mut self)
Compact this region by re-emitting only reachable data.
After mutations (e.g. splice_list,
push_front), old targets of redirected
Near/NearList pointers become
dead bytes. trim walks the root T and all transitively reachable
data, emitting a fresh compact buffer via Emit<T> for &T deep-copy.
§Examples
use nearest::{Flat, NearList, Region};
#[derive(Flat, Debug)]
struct Node { items: NearList<u32> }
let mut region = Region::new(Node::make([1u32, 2, 3]));
let before = region.byte_len();
// Mutation leaves dead bytes (old list data).
region.session(|s| {
let items = s.nav(s.root(), |n| &n.items);
s.splice_list(items, [42u32]);
});
assert!(region.byte_len() > before);
// Trim compacts the region.
region.trim();
assert!(region.byte_len() <= before);
assert_eq!(region.items[0], 42);