pub struct QueryArena { /* private fields */ }Expand description
Arena allocator for query-scoped allocations
Uses a bump-pointer strategy to allocate from a pre-allocated buffer. All allocations are freed when the arena is reset or dropped.
§Example
use vibesql_executor::memory::QueryArena;
use std::mem::MaybeUninit;
let arena = QueryArena::with_capacity(1024);
// Allocate a value
let x = arena.alloc(42i64);
assert_eq!(*x, 42);
// Allocate a slice (returns uninitialized memory)
let slice = arena.alloc_slice::<i32>(10);
for i in 0..10 {
slice[i] = MaybeUninit::new(i as i32);
}Implementations§
Source§impl QueryArena
impl QueryArena
Sourcepub const DEFAULT_CAPACITY: usize = 10_485_760usize
pub const DEFAULT_CAPACITY: usize = 10_485_760usize
Default arena size: 10MB
Based on TPC-H Q6 analysis:
- 60K rows × 16 columns = 960K SqlValues
- Intermediate results: ~2MB
- Expression temporaries: ~1MB
- Safety margin: 7MB
Sourcepub fn with_capacity(bytes: usize) -> Self
pub fn with_capacity(bytes: usize) -> Self
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new arena with the default capacity (10MB)
§Example
use vibesql_executor::memory::QueryArena;
let arena = QueryArena::new();Sourcepub fn alloc<T>(&self, value: T) -> &T
pub fn alloc<T>(&self, value: T) -> &T
Allocate a value in the arena
Returns a reference to the allocated value with lifetime tied to the arena.
§Performance
Allocation overhead: ~1ns (vs ~100ns for heap allocation)
§Panics
Panics if the arena is out of space. Use try_alloc for fallible allocation.
§Example
use vibesql_executor::memory::QueryArena;
let arena = QueryArena::new();
let x = arena.alloc(42i64);
let y = arena.alloc(3.5f64);
assert_eq!(*x, 42);
assert_eq!(*y, 3.5);Sourcepub fn alloc_slice<T>(&self, len: usize) -> &mut [MaybeUninit<T>]
pub fn alloc_slice<T>(&self, len: usize) -> &mut [MaybeUninit<T>]
Allocate a slice in the arena
Returns a mutable slice of MaybeUninit<T> with the specified length.
Caller must initialize elements before assuming them to be initialized.
Using MaybeUninit ensures memory safety - uninitialized memory cannot
be accidentally read or dropped, preventing undefined behavior.
§Performance
Allocation overhead: ~1ns + negligible bounds check
§Panics
Panics if the arena is out of space.
§Example
use vibesql_executor::memory::QueryArena;
use std::mem::MaybeUninit;
let arena = QueryArena::new();
let slice = arena.alloc_slice::<i32>(100);
// Initialize the slice
for i in 0..100 {
slice[i] = MaybeUninit::new(i as i32);
}
// SAFETY: All elements have been initialized above
let initialized_slice = unsafe {
std::slice::from_raw_parts(
slice.as_ptr() as *const i32,
slice.len()
)
};
assert_eq!(initialized_slice[50], 50);Sourcepub fn try_alloc<T>(&self, value: T) -> Option<&T>
pub fn try_alloc<T>(&self, value: T) -> Option<&T>
Try to allocate a value in the arena
Returns None if the arena is out of space.
§Example
use vibesql_executor::memory::QueryArena;
let arena = QueryArena::with_capacity(64);
// This succeeds
assert!(arena.try_alloc(42i64).is_some());
// Eventually this fails (arena full)
let mut count = 0;
while arena.try_alloc(count).is_some() {
count += 1;
}Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Reset the arena, allowing it to be reused
This doesn’t deallocate the buffer, just resets the bump pointer. All previously allocated values are invalidated.
§Example
use vibesql_executor::memory::QueryArena;
let mut arena = QueryArena::new();
// Allocate some values (i64 = 8 bytes)
let x = arena.alloc(42i64);
assert_eq!(arena.used_bytes(), 8);
// Reset and reuse
arena.reset();
assert_eq!(arena.used_bytes(), 0);
// Can allocate again
let y = arena.alloc(100i64);Sourcepub fn used_bytes(&self) -> usize
pub fn used_bytes(&self) -> usize
Get the number of bytes used in this arena
§Example
use vibesql_executor::memory::QueryArena;
let arena = QueryArena::new();
arena.alloc(42i64); // 8 bytes
arena.alloc(3.5f64); // 8 bytes
assert_eq!(arena.used_bytes(), 16);Sourcepub fn capacity_bytes(&self) -> usize
pub fn capacity_bytes(&self) -> usize
Get the total capacity of this arena in bytes
§Example
use vibesql_executor::memory::QueryArena;
let arena = QueryArena::with_capacity(1024);
assert_eq!(arena.capacity_bytes(), 1024);Sourcepub fn remaining_bytes(&self) -> usize
pub fn remaining_bytes(&self) -> usize
Get the number of bytes remaining in this arena
§Example
use vibesql_executor::memory::QueryArena;
let arena = QueryArena::with_capacity(1024);
arena.alloc(42i64); // 8 bytes
assert_eq!(arena.remaining_bytes(), 1024 - 8);Trait Implementations§
Auto Trait Implementations§
impl !Freeze for QueryArena
impl !RefUnwindSafe for QueryArena
impl Send for QueryArena
impl !Sync for QueryArena
impl Unpin for QueryArena
impl UnwindSafe for QueryArena
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> 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