#![forbid(unsafe_code)]
#![deny(clippy::all)]
use std::cell::RefCell;
const INITIAL_CHUNK_SIZE: usize = 8 * 1024;
const MAX_CHUNK_SIZE: usize = 1024 * 1024;
const MAX_POOL_SIZE: usize = 4;
const SHRINK_THRESHOLD: usize = 64 * 1024;
pub struct Arena {
chunks: Vec<Vec<u8>>,
prefix_sums: Vec<usize>,
current: usize,
offset: usize,
}
impl Arena {
pub fn new() -> Self {
let chunk = Vec::with_capacity(INITIAL_CHUNK_SIZE);
Self {
chunks: vec![chunk],
prefix_sums: vec![0],
current: 0,
offset: 0,
}
}
pub fn empty() -> Self {
Self {
chunks: Vec::new(),
prefix_sums: Vec::new(),
current: 0,
offset: 0,
}
}
pub fn alloc(&mut self, len: usize) -> &mut [u8] {
if len == 0 {
return &mut [];
}
self.ensure_capacity(len);
let chunk = &mut self.chunks[self.current];
let start = self.offset;
let new_len = start + len;
if new_len > chunk.len() {
chunk.resize(new_len, 0);
}
self.offset = new_len;
&mut chunk[start..new_len]
}
#[inline(always)]
pub fn alloc_copy(&mut self, data: &[u8]) -> usize {
let len = data.len();
if len == 0 {
return self.global_offset();
}
let chunk = &mut self.chunks[self.current];
let remaining = chunk.capacity() - self.offset;
if remaining >= len {
let start = self.offset;
if start == chunk.len() {
chunk.extend_from_slice(data);
} else {
let new_len = start + len;
if new_len > chunk.len() {
chunk.resize(new_len, 0);
}
chunk[start..start + len].copy_from_slice(data);
}
let global = self.prefix_sums[self.current] + start;
self.offset = start + len;
return global;
}
self.alloc_copy_slow(data)
}
#[cold]
#[inline(never)]
fn alloc_copy_slow(&mut self, data: &[u8]) -> usize {
self.ensure_capacity(data.len());
let chunk = &mut self.chunks[self.current];
let start = self.offset;
chunk.extend_from_slice(data);
let global = self.prefix_sums[self.current] + start;
self.offset = start + data.len();
global
}
pub fn get(&self, global_offset: usize, len: usize) -> &[u8] {
if len == 0 {
return &[];
}
let (chunk_idx, local_offset) = self.resolve_offset(global_offset);
&self.chunks[chunk_idx][local_offset..local_offset + len]
}
pub fn get_str(&self, global_offset: usize, len: usize) -> Option<&str> {
if len == 0 {
return Some("");
}
simdutf8::basic::from_utf8(self.get(global_offset, len)).ok()
}
pub fn reset(&mut self) {
self.chunks.retain(|c| c.capacity() <= SHRINK_THRESHOLD);
if self.chunks.is_empty() {
self.chunks.push(Vec::with_capacity(INITIAL_CHUNK_SIZE));
}
for chunk in &mut self.chunks {
chunk.clear();
}
self.rebuild_prefix_sums();
self.current = 0;
self.offset = 0;
}
pub fn allocated(&self) -> usize {
if self.chunks.is_empty() {
return 0;
}
if self.current == 0 {
return self.offset;
}
let mut total = self.offset;
for chunk in &self.chunks[..self.current] {
total += chunk.len();
}
total
}
pub fn capacity(&self) -> usize {
self.chunks.iter().map(|c| c.capacity()).sum()
}
fn ensure_capacity(&mut self, len: usize) {
let chunk = &self.chunks[self.current];
let remaining = chunk.capacity().saturating_sub(self.offset);
if remaining >= len {
return;
}
let prev_cap = chunk.capacity();
let new_cap = prev_cap
.saturating_mul(2)
.max(len)
.max(INITIAL_CHUNK_SIZE)
.min(MAX_CHUNK_SIZE.max(len));
let next_idx = self.current + 1;
if next_idx < self.chunks.len() && self.chunks[next_idx].capacity() >= len {
self.current = next_idx;
self.offset = 0;
return;
}
let new_chunk = Vec::with_capacity(new_cap);
let prefix = self.prefix_sums[self.chunks.len() - 1]
+ self.chunks.last().map_or(0, |c| c.capacity());
if next_idx < self.chunks.len() {
self.chunks[next_idx] = new_chunk;
self.rebuild_prefix_sums();
} else {
self.chunks.push(new_chunk);
self.prefix_sums.push(prefix);
}
self.current = next_idx;
self.offset = 0;
}
fn rebuild_prefix_sums(&mut self) {
self.prefix_sums.clear();
let mut sum = 0;
for chunk in &self.chunks {
self.prefix_sums.push(sum);
sum += chunk.capacity();
}
}
pub fn global_offset(&self) -> usize {
self.global_offset_at(self.current, self.offset)
}
fn global_offset_at(&self, chunk_idx: usize, local_offset: usize) -> usize {
self.prefix_sums[chunk_idx] + local_offset
}
fn resolve_offset(&self, global_offset: usize) -> (usize, usize) {
if self.chunks.len() == 1 {
debug_assert!(
global_offset < self.chunks[0].capacity(),
"arena offset {global_offset} out of bounds in single chunk (cap={})",
self.chunks[0].capacity()
);
return (0, global_offset);
}
let idx = match self.prefix_sums.binary_search(&global_offset) {
Ok(i) => i,
Err(0) => 0, Err(i) => i - 1,
};
let local = global_offset - self.prefix_sums[idx];
debug_assert!(
local < self.chunks[idx].capacity(),
"arena offset {global_offset} out of bounds in chunk {idx} (cap={})",
self.chunks[idx].capacity()
);
(idx, local)
}
}
impl Default for Arena {
fn default() -> Self {
Self::new()
}
}
thread_local! {
static ARENA_POOL: RefCell<Vec<Arena>> = const { RefCell::new(Vec::new()) };
}
pub fn acquire_arena() -> Arena {
ARENA_POOL
.with(|pool| pool.borrow_mut().pop())
.unwrap_or_default()
}
pub fn release_arena(mut arena: Arena) {
arena.reset();
ARENA_POOL.with(|pool| {
let mut pool = pool.borrow_mut();
if pool.len() < MAX_POOL_SIZE {
pool.push(arena);
}
});
}
pub struct ArenaRows<T> {
rows: Vec<T>,
arena: Arena,
}
impl<T> ArenaRows<T> {
pub fn new(rows: Vec<T>, arena: Arena) -> Self {
Self { rows, arena }
}
#[inline]
pub fn len(&self) -> usize {
self.rows.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.rows.is_empty()
}
#[inline]
pub fn get(&self, idx: usize) -> Option<&T> {
self.rows.get(idx)
}
#[inline]
pub fn iter(&self) -> std::slice::Iter<'_, T> {
self.rows.iter()
}
pub fn into_parts(self) -> (Vec<T>, Arena) {
(self.rows, self.arena)
}
#[inline]
pub fn arena_allocated(&self) -> usize {
self.arena.allocated()
}
}
impl<T> std::ops::Deref for ArenaRows<T> {
type Target = [T];
#[inline]
fn deref(&self) -> &[T] {
&self.rows
}
}
impl<'a, T> IntoIterator for &'a ArenaRows<T> {
type Item = &'a T;
type IntoIter = std::slice::Iter<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.rows.iter()
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for ArenaRows<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ArenaRows")
.field("len", &self.rows.len())
.field("arena_allocated", &self.arena.allocated())
.field("rows", &self.rows)
.finish()
}
}
pub struct ValidatedRows<T> {
rows: Vec<T>,
text_buf: String,
blob_arena: Arena,
}
impl<T> ValidatedRows<T> {
pub fn new(rows: Vec<T>, text_buf: String, blob_arena: Arena) -> Self {
Self {
rows,
text_buf,
blob_arena,
}
}
#[inline]
pub fn text(&self) -> &str {
&self.text_buf
}
#[inline]
pub fn text_slice(&self, start: u32, end: u32) -> &str {
&self.text_buf[start as usize..end as usize]
}
#[inline]
pub fn blob_slice(&self, offset: u32, len: u32) -> &[u8] {
self.blob_arena.get(offset as usize, len as usize)
}
#[inline]
pub fn len(&self) -> usize {
self.rows.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.rows.is_empty()
}
#[inline]
pub fn get_inner(&self, idx: usize) -> Option<&T> {
self.rows.get(idx)
}
#[inline]
pub fn iter_inner(&self) -> std::slice::Iter<'_, T> {
self.rows.iter()
}
#[inline]
pub fn text_len(&self) -> usize {
self.text_buf.len()
}
#[inline]
pub fn blob_allocated(&self) -> usize {
self.blob_arena.allocated()
}
#[inline]
pub fn arena_allocated(&self) -> usize {
self.text_buf.len() + self.blob_arena.allocated()
}
}
impl<T> std::ops::Deref for ValidatedRows<T> {
type Target = [T];
#[inline]
fn deref(&self) -> &[T] {
&self.rows
}
}
impl<'a, T> IntoIterator for &'a ValidatedRows<T> {
type Item = &'a T;
type IntoIter = std::slice::Iter<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.rows.iter()
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for ValidatedRows<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ValidatedRows")
.field("len", &self.rows.len())
.field("text_len", &self.text_buf.len())
.field("blob_allocated", &self.blob_arena.allocated())
.field("rows", &self.rows)
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn basic_alloc_and_get() {
let mut arena = Arena::new();
let offset = arena.alloc_copy(b"hello");
assert_eq!(arena.get(offset, 5), b"hello");
}
#[test]
fn multiple_allocs() {
let mut arena = Arena::new();
let o1 = arena.alloc_copy(b"foo");
let o2 = arena.alloc_copy(b"bar");
let o3 = arena.alloc_copy(b"baz");
assert_eq!(arena.get(o1, 3), b"foo");
assert_eq!(arena.get(o2, 3), b"bar");
assert_eq!(arena.get(o3, 3), b"baz");
}
#[test]
fn alloc_str_retrieval() {
let mut arena = Arena::new();
let offset = arena.alloc_copy(b"hello world");
assert_eq!(arena.get_str(offset, 11), Some("hello world"));
}
#[test]
fn zero_length_alloc() {
let mut arena = Arena::new();
let offset = arena.alloc_copy(b"");
let data = arena.get(offset, 0);
assert!(data.is_empty());
}
#[test]
fn alloc_returns_zeroed_slice() {
let mut arena = Arena::new();
let slice = arena.alloc(16);
assert!(slice.iter().all(|&b| b == 0));
}
#[test]
fn reset_allows_reuse() {
let mut arena = Arena::new();
let _o1 = arena.alloc_copy(b"before reset");
assert_eq!(arena.allocated(), 12);
arena.reset();
assert_eq!(arena.allocated(), 0);
let o2 = arena.alloc_copy(b"after reset");
assert_eq!(arena.get(o2, 11), b"after reset");
}
#[test]
fn chunk_growth() {
let mut arena = Arena::new();
let big = vec![0xAA; INITIAL_CHUNK_SIZE + 1];
let offset = arena.alloc_copy(&big);
assert_eq!(arena.get(offset, big.len())[0], 0xAA);
assert!(
arena.chunks.len() >= 2,
"should have grown to a second chunk"
);
}
#[test]
fn large_single_alloc() {
let mut arena = Arena::new();
let data = vec![0x42; 2 * MAX_CHUNK_SIZE];
let offset = arena.alloc_copy(&data);
let result = arena.get(offset, data.len());
assert!(result.iter().all(|&b| b == 0x42));
}
#[test]
fn one_hundred_rows_in_one_chunk() {
let mut arena = Arena::new();
let row_data = b"typical row data, about 50 bytes of text content.";
let mut offsets = Vec::new();
for _ in 0..100 {
offsets.push(arena.alloc_copy(row_data));
}
assert_eq!(arena.chunks.len(), 1);
for &offset in &offsets {
assert_eq!(arena.get(offset, row_data.len()), row_data);
}
}
#[test]
fn reset_discards_oversized_chunks() {
let mut arena = Arena::new();
let big = vec![0xFF; SHRINK_THRESHOLD + 1];
arena.alloc_copy(&big);
let _chunks_before = arena.chunks.len();
arena.reset();
for chunk in &arena.chunks {
assert!(
chunk.capacity() <= SHRINK_THRESHOLD,
"oversized chunk not discarded: capacity={}",
chunk.capacity()
);
}
}
#[test]
fn thread_local_pool_acquire_release() {
let mut arena = acquire_arena();
arena.alloc_copy(b"test data");
release_arena(arena);
let arena2 = acquire_arena();
assert_eq!(arena2.allocated(), 0); release_arena(arena2);
}
#[test]
fn thread_local_pool_max_size() {
for _ in 0..MAX_POOL_SIZE + 2 {
let arena = Arena::new();
release_arena(arena);
}
ARENA_POOL.with(|pool| {
assert!(pool.borrow().len() <= MAX_POOL_SIZE);
});
}
#[test]
fn capacity_reports_total() {
let arena = Arena::new();
assert!(arena.capacity() >= INITIAL_CHUNK_SIZE);
}
#[test]
fn allocated_tracks_usage() {
let mut arena = Arena::new();
assert_eq!(arena.allocated(), 0);
arena.alloc_copy(b"12345");
assert_eq!(arena.allocated(), 5);
arena.alloc_copy(b"67890");
assert_eq!(arena.allocated(), 10);
}
#[test]
fn alloc_at_exact_8kb_boundary() {
let mut arena = Arena::new();
let filler = vec![0xAA; INITIAL_CHUNK_SIZE];
let o1 = arena.alloc_copy(&filler);
assert_eq!(arena.get(o1, INITIAL_CHUNK_SIZE)[0], 0xAA);
assert_eq!(arena.chunks.len(), 1);
let o2 = arena.alloc_copy(b"x");
assert_eq!(arena.get(o2, 1), b"x");
assert!(arena.chunks.len() >= 2, "should have grown past 8KB chunk");
assert_eq!(arena.get(o1, INITIAL_CHUNK_SIZE)[0], 0xAA);
assert_eq!(
arena.get(o1, INITIAL_CHUNK_SIZE)[INITIAL_CHUNK_SIZE - 1],
0xAA
);
}
#[test]
fn prefix_sums_correct_after_multi_chunk() {
let mut arena = Arena::new();
let mut offsets = Vec::new();
for i in 0..4 {
let data = vec![i as u8; INITIAL_CHUNK_SIZE + 1];
offsets.push((arena.alloc_copy(&data), data.len()));
}
for (idx, &(offset, len)) in offsets.iter().enumerate() {
let data = arena.get(offset, len);
assert!(data.iter().all(|&b| b == idx as u8));
}
}
#[test]
fn prefix_sums_correct_after_reset() {
let mut arena = Arena::new();
let big = vec![0xBB; INITIAL_CHUNK_SIZE + 1];
arena.alloc_copy(&big);
assert!(arena.chunks.len() >= 2);
arena.reset();
let o = arena.alloc_copy(b"after reset");
assert_eq!(arena.get(o, 11), b"after reset");
}
#[test]
fn resolve_offset_zero() {
let arena = Arena::new();
let (chunk_idx, local) = arena.resolve_offset(0);
assert_eq!(chunk_idx, 0);
assert_eq!(local, 0);
}
#[test]
fn resolve_offset_single_chunk_fast_path() {
let mut arena = Arena::new();
let o1 = arena.alloc_copy(b"hello");
let o2 = arena.alloc_copy(b"world");
assert_eq!(arena.chunks.len(), 1, "should be single chunk");
assert_eq!(arena.get(o1, 5), b"hello");
assert_eq!(arena.get(o2, 5), b"world");
}
#[test]
fn get_str_invalid_utf8_returns_none() {
let mut arena = Arena::new();
let offset = arena.alloc_copy(&[0xFF, 0xFE, 0xFD]);
assert_eq!(arena.get_str(offset, 3), None);
}
#[test]
fn get_str_valid_utf8() {
let mut arena = Arena::new();
let offset = arena.alloc_copy("hello".as_bytes());
assert_eq!(arena.get_str(offset, 5), Some("hello"));
}
#[test]
fn get_str_empty_returns_some_empty() {
let arena = Arena::new();
assert_eq!(arena.get_str(0, 0), Some(""));
}
#[test]
#[should_panic]
fn get_out_of_bounds_panics() {
let arena = Arena::new();
arena.get(INITIAL_CHUNK_SIZE + 100, 1);
}
#[test]
fn ensure_capacity_reuses_next_chunk() {
let mut arena = Arena::new();
let big = vec![0xAA; INITIAL_CHUNK_SIZE + 1];
arena.alloc_copy(&big);
assert!(arena.chunks.len() >= 2);
arena.reset();
assert_eq!(arena.current, 0);
assert_eq!(arena.offset, 0);
let filler = vec![0xBB; INITIAL_CHUNK_SIZE];
arena.alloc_copy(&filler);
let o = arena.alloc_copy(b"reuse check");
assert_eq!(arena.get(o, 11), b"reuse check");
}
#[test]
fn arena_cross_thread_no_crash() {
let mut arena = Arena::new();
arena.alloc_copy(b"test data");
let handle = std::thread::spawn(move || {
assert_eq!(arena.get(0, 9), b"test data");
arena.reset();
arena
});
let arena = handle.join().unwrap();
release_arena(arena);
}
#[test]
fn arena_rows_basic() {
let arena = Arena::new();
let ar: ArenaRows<i64> = ArenaRows::new(vec![42], arena);
assert_eq!(ar.len(), 1);
assert!(!ar.is_empty());
assert_eq!(ar[0], 42);
assert_eq!(ar.get(0), Some(&42));
}
#[test]
fn arena_rows_empty() {
let arena = Arena::new();
let ar: ArenaRows<i64> = ArenaRows::new(vec![], arena);
assert!(ar.is_empty());
assert_eq!(ar.len(), 0);
assert!(ar.get(0).is_none());
}
#[test]
fn arena_rows_iter() {
let arena = Arena::new();
let ar: ArenaRows<i64> = ArenaRows::new(vec![10, 20, 30], arena);
let vals: Vec<&i64> = ar.iter().collect();
assert_eq!(vals, vec![&10, &20, &30]);
}
#[test]
fn arena_rows_deref() {
let arena = Arena::new();
let ar: ArenaRows<i64> = ArenaRows::new(vec![1, 2, 3], arena);
let slice: &[i64] = &ar;
assert_eq!(slice, &[1, 2, 3]);
}
#[test]
fn arena_rows_for_loop() {
let arena = Arena::new();
let ar: ArenaRows<i64> = ArenaRows::new(vec![10, 20], arena);
let mut sum = 0;
for &val in &ar {
sum += val;
}
assert_eq!(sum, 30);
}
#[test]
fn arena_rows_debug() {
let arena = Arena::new();
let ar: ArenaRows<i64> = ArenaRows::new(vec![42], arena);
let dbg = format!("{ar:?}");
assert!(dbg.contains("ArenaRows"));
assert!(dbg.contains("42"));
}
#[test]
fn arena_rows_arena_allocated() {
let mut arena = Arena::new();
arena.alloc_copy(b"some data");
let allocated = arena.allocated();
let ar: ArenaRows<i64> = ArenaRows::new(vec![], arena);
assert_eq!(ar.arena_allocated(), allocated);
}
#[test]
fn arena_rows_into_parts() {
let arena = Arena::new();
let ar: ArenaRows<i64> = ArenaRows::new(vec![1, 2, 3], arena);
let (v, _arena) = ar.into_parts();
assert_eq!(v, vec![1, 2, 3]);
}
#[test]
fn arena_rows_into_parts_empty() {
let arena = Arena::new();
let ar: ArenaRows<i64> = ArenaRows::new(vec![], arena);
let (v, _arena) = ar.into_parts();
assert!(v.is_empty());
}
#[test]
fn arena_rows_get_out_of_bounds() {
let arena = Arena::new();
let ar: ArenaRows<i64> = ArenaRows::new(vec![42], arena);
assert_eq!(ar.get(0), Some(&42));
assert_eq!(ar.get(1), None);
assert_eq!(ar.get(999), None);
}
#[test]
fn validated_rows_basic() {
let text_buf = String::from("alicebob");
let blob_arena = Arena::new();
#[derive(Debug)]
#[allow(dead_code)]
struct Inner {
id: i64,
name_start: u32,
name_end: u32,
}
let rows = vec![
Inner {
id: 1,
name_start: 0,
name_end: 5,
},
Inner {
id: 2,
name_start: 5,
name_end: 8,
},
];
let vr = ValidatedRows::new(rows, text_buf, blob_arena);
assert_eq!(vr.len(), 2);
assert!(!vr.is_empty());
assert_eq!(vr.text_slice(vr[0].name_start, vr[0].name_end), "alice");
assert_eq!(vr.text_slice(vr[1].name_start, vr[1].name_end), "bob");
}
#[test]
fn validated_rows_empty() {
let vr: ValidatedRows<i64> = ValidatedRows::new(vec![], String::new(), Arena::new());
assert!(vr.is_empty());
assert_eq!(vr.len(), 0);
assert_eq!(vr.text_len(), 0);
}
#[test]
fn validated_rows_blob() {
let mut blob_arena = Arena::new();
let off = blob_arena.alloc_copy(&[0xDE, 0xAD]);
#[derive(Debug)]
struct Inner {
blob_off: u32,
blob_len: u32,
}
let rows = vec![Inner {
blob_off: off as u32,
blob_len: 2,
}];
let vr = ValidatedRows::new(rows, String::new(), blob_arena);
assert_eq!(vr.blob_slice(vr[0].blob_off, vr[0].blob_len), &[0xDE, 0xAD]);
}
#[test]
fn validated_rows_arena_allocated() {
let mut blob_arena = Arena::new();
blob_arena.alloc_copy(&[1, 2, 3]);
let text_buf = String::from("hello");
let vr: ValidatedRows<i64> = ValidatedRows::new(vec![], text_buf, blob_arena);
assert_eq!(vr.arena_allocated(), 5 + 3); }
#[test]
fn validated_rows_debug() {
let vr: ValidatedRows<i64> = ValidatedRows::new(vec![42], String::new(), Arena::new());
let dbg = format!("{vr:?}");
assert!(dbg.contains("ValidatedRows"));
assert!(dbg.contains("42"));
}
#[test]
fn validated_rows_deref() {
let vr: ValidatedRows<i64> = ValidatedRows::new(vec![1, 2, 3], String::new(), Arena::new());
let slice: &[i64] = &vr;
assert_eq!(slice, &[1, 2, 3]);
}
#[test]
fn validated_rows_iter() {
let vr: ValidatedRows<i64> = ValidatedRows::new(vec![10, 20], String::new(), Arena::new());
let mut sum = 0;
for &val in &vr {
sum += val;
}
assert_eq!(sum, 30);
}
#[test]
fn alloc_zero_returns_empty_slice() {
let mut arena = Arena::new();
let slice = arena.alloc(0);
assert!(slice.is_empty());
}
#[test]
fn get_str_zero_len_returns_empty() {
let arena = Arena::new();
assert_eq!(arena.get_str(0, 0), Some(""));
}
#[test]
fn validated_rows_empty_text_buf() {
let vr: ValidatedRows<i64> = ValidatedRows::new(vec![1, 2, 3], String::new(), Arena::new());
assert_eq!(vr.text(), "");
assert_eq!(vr.text_len(), 0);
assert_eq!(vr.len(), 3);
}
#[test]
fn validated_rows_blob_only_no_text() {
let mut blob_arena = Arena::new();
let o1 = blob_arena.alloc_copy(&[0x01, 0x02, 0x03]);
let o2 = blob_arena.alloc_copy(&[0xAA, 0xBB]);
#[derive(Debug)]
struct Inner {
off: u32,
len: u32,
}
let rows = vec![
Inner {
off: o1 as u32,
len: 3,
},
Inner {
off: o2 as u32,
len: 2,
},
];
let vr = ValidatedRows::new(rows, String::new(), blob_arena);
assert_eq!(vr.text_len(), 0);
assert_eq!(vr.blob_slice(vr[0].off, vr[0].len), &[0x01, 0x02, 0x03]);
assert_eq!(vr.blob_slice(vr[1].off, vr[1].len), &[0xAA, 0xBB]);
}
#[test]
#[should_panic]
fn validated_rows_text_slice_out_of_bounds() {
let vr: ValidatedRows<i64> = ValidatedRows::new(vec![], String::from("hi"), Arena::new());
vr.text_slice(0, 100);
}
#[test]
#[should_panic]
fn validated_rows_blob_slice_out_of_bounds() {
let blob_arena = Arena::new();
let vr: ValidatedRows<i64> = ValidatedRows::new(vec![], String::new(), blob_arena);
vr.blob_slice(0, 100);
}
#[test]
fn validated_rows_large_10k_rows() {
let mut text_buf = String::new();
let blob_arena = Arena::new();
#[derive(Debug)]
struct Inner {
start: u32,
end: u32,
}
let mut rows = Vec::with_capacity(10_000);
for i in 0..10_000u32 {
let start = text_buf.len() as u32;
text_buf.push_str(&format!("row_{i}"));
let end = text_buf.len() as u32;
rows.push(Inner { start, end });
}
let vr = ValidatedRows::new(rows, text_buf, blob_arena);
assert_eq!(vr.len(), 10_000);
assert_eq!(vr.text_slice(vr[0].start, vr[0].end), "row_0");
assert_eq!(vr.text_slice(vr[9999].start, vr[9999].end), "row_9999");
}
#[test]
fn validated_rows_text_slice_empty_range() {
let vr: ValidatedRows<i64> =
ValidatedRows::new(vec![], String::from("hello"), Arena::new());
assert_eq!(vr.text_slice(0, 0), "");
assert_eq!(vr.text_slice(3, 3), "");
}
#[test]
fn validated_rows_get_inner() {
let vr: ValidatedRows<i64> =
ValidatedRows::new(vec![10, 20, 30], String::new(), Arena::new());
assert_eq!(vr.get_inner(0), Some(&10));
assert_eq!(vr.get_inner(1), Some(&20));
assert_eq!(vr.get_inner(2), Some(&30));
assert_eq!(vr.get_inner(3), None);
}
#[test]
fn validated_rows_iter_inner() {
let vr: ValidatedRows<i64> = ValidatedRows::new(vec![5, 10], String::new(), Arena::new());
let vals: Vec<&i64> = vr.iter_inner().collect();
assert_eq!(vals, vec![&5, &10]);
}
#[test]
fn validated_rows_blob_allocated_zero() {
let vr: ValidatedRows<i64> = ValidatedRows::new(vec![], String::new(), Arena::new());
assert_eq!(vr.blob_allocated(), 0);
}
#[test]
fn arena_get_zero_len() {
let arena = Arena::new();
let data = arena.get(0, 0);
assert!(data.is_empty());
}
#[test]
fn arena_alloc_copy_zero_len() {
let mut arena = Arena::new();
let offset = arena.alloc_copy(b"");
assert_eq!(arena.get(offset, 0), &[]);
}
#[test]
fn arena_global_offset_initial() {
let arena = Arena::new();
assert_eq!(arena.global_offset(), 0);
}
#[test]
fn arena_global_offset_advances() {
let mut arena = Arena::new();
arena.alloc_copy(b"12345");
assert_eq!(arena.global_offset(), 5);
arena.alloc_copy(b"67890");
assert_eq!(arena.global_offset(), 10);
}
#[test]
fn arena_multiple_resets() {
let mut arena = Arena::new();
for _ in 0..10 {
arena.alloc_copy(b"data");
assert_eq!(arena.allocated(), 4);
arena.reset();
assert_eq!(arena.allocated(), 0);
}
}
#[test]
fn arena_get_str_unicode() {
let texts = [
"\u{1F600}\u{1F4A9}", "\u{4e16}\u{754c}", "caf\u{00e9}", "\u{1F468}\u{200D}\u{1F469}", ];
for text in &texts {
let mut arena = Arena::new();
let offset = arena.alloc_copy(text.as_bytes());
assert_eq!(
arena.get_str(offset, text.len()),
Some(*text),
"failed for text: {text}"
);
}
}
#[test]
fn arena_get_str_partial_utf8_returns_none() {
let mut arena = Arena::new();
let offset = arena.alloc_copy(&[0xC3]);
assert_eq!(arena.get_str(offset, 1), None);
}
#[test]
fn arena_default_is_new() {
let a1 = Arena::new();
let a2 = Arena::default();
assert_eq!(a1.allocated(), a2.allocated());
assert_eq!(a1.capacity(), a2.capacity());
}
#[test]
fn arena_rows_large() {
let arena = Arena::new();
let rows: Vec<i64> = (0..1000).collect();
let ar = ArenaRows::new(rows, arena);
assert_eq!(ar.len(), 1000);
assert_eq!(ar[0], 0);
assert_eq!(ar[999], 999);
}
#[test]
fn arena_rows_with_arena_data() {
let mut arena = Arena::new();
let offset = arena.alloc_copy(b"stored data");
#[derive(Debug)]
#[allow(dead_code)]
struct Inner {
off: usize,
len: usize,
}
let ar = ArenaRows::new(
vec![Inner {
off: offset,
len: 11,
}],
arena,
);
assert_eq!(ar.len(), 1);
}
#[test]
fn thread_local_pool_acquire_fresh() {
ARENA_POOL.with(|pool| pool.borrow_mut().clear());
let arena = acquire_arena();
assert_eq!(arena.allocated(), 0);
release_arena(arena);
}
#[test]
fn thread_local_pool_recycle_resets() {
let mut arena = Arena::new();
arena.alloc_copy(b"something");
assert!(arena.allocated() > 0);
release_arena(arena);
let arena2 = acquire_arena();
assert_eq!(arena2.allocated(), 0, "recycled arena should be reset");
release_arena(arena2);
}
#[test]
fn arena_reset_clears_data_positions() {
let mut arena = Arena::new();
let o1 = arena.alloc_copy(b"first query data");
assert_eq!(arena.get(o1, 16), b"first query data");
arena.reset();
assert_eq!(arena.allocated(), 0);
assert_eq!(arena.current, 0);
assert_eq!(arena.offset, 0);
let o2 = arena.alloc_copy(b"second query dat");
assert_eq!(o2, 0, "first alloc after reset should be at offset 0");
assert_eq!(arena.get(o2, 16), b"second query dat");
}
#[test]
fn arena_reset_discards_oversized_chunks() {
let mut arena = Arena::new();
let big = vec![0xAA; 128 * 1024];
arena.alloc_copy(&big);
let cap_before = arena.capacity();
assert!(cap_before >= 128 * 1024);
arena.reset();
let cap_after = arena.capacity();
assert!(
cap_after < cap_before,
"oversized chunks should be discarded on reset: before={cap_before}, after={cap_after}"
);
}
#[test]
fn alloc_copy_zero_length_returns_valid_offset() {
let mut arena = Arena::new();
let o1 = arena.alloc_copy(b"");
let o2 = arena.alloc_copy(b"hello");
assert_eq!(o1, o2, "zero-length alloc should not advance offset");
assert_eq!(arena.get(o2, 5), b"hello");
}
#[test]
fn get_zero_length_returns_empty() {
let arena = Arena::new();
assert_eq!(arena.get(0, 0), &[]);
assert_eq!(arena.get(9999, 0), &[]);
}
#[test]
#[should_panic]
fn arena_empty_alloc_copy_panics_without_reset() {
let mut arena = Arena::empty();
assert_eq!(arena.chunks.len(), 0);
let _ = arena.alloc_copy(b"boom");
}
#[test]
#[should_panic]
fn arena_empty_alloc_panics_without_reset() {
let mut arena = Arena::empty();
let _ = arena.alloc(8);
}
#[test]
fn arena_empty_reset_does_not_panic() {
let mut arena = Arena::empty();
arena.reset();
assert!(
!arena.chunks.is_empty(),
"reset should create initial chunk if empty"
);
assert_eq!(arena.allocated(), 0);
assert_eq!(arena.current, 0);
assert_eq!(arena.offset, 0);
}
#[test]
fn arena_empty_reset_then_alloc() {
let mut arena = Arena::empty();
arena.reset();
let offset = arena.alloc_copy(b"after reset on empty");
assert_eq!(arena.get(offset, 20), b"after reset on empty");
}
#[test]
fn arena_empty_capacity_is_zero() {
let arena = Arena::empty();
assert_eq!(arena.capacity(), 0);
assert_eq!(arena.allocated(), 0);
}
#[test]
fn arena_empty_reset_then_multiple_allocs() {
let mut arena = Arena::empty();
arena.reset(); let o1 = arena.alloc_copy(b"first");
let o2 = arena.alloc_copy(b"second");
assert_eq!(arena.get(o1, 5), b"first");
assert_eq!(arena.get(o2, 6), b"second");
}
#[test]
fn alloc_copy_exactly_fills_chunk() {
let mut arena = Arena::new();
let data = vec![0xCC; INITIAL_CHUNK_SIZE];
let offset = arena.alloc_copy(&data);
assert_eq!(arena.chunks.len(), 1, "should still be one chunk");
assert_eq!(arena.get(offset, INITIAL_CHUNK_SIZE)[0], 0xCC);
assert_eq!(arena.allocated(), INITIAL_CHUNK_SIZE);
let o2 = arena.alloc_copy(b"");
assert_eq!(arena.get(o2, 0), &[]);
}
#[test]
fn arena_empty_get_zero_len() {
let arena = Arena::empty();
assert_eq!(arena.get(0, 0), &[]);
}
#[test]
fn get_str_unicode_multibyte() {
let mut arena = Arena::new();
let text = "\u{1F600}\u{00E9}";
let offset = arena.alloc_copy(text.as_bytes());
assert_eq!(arena.get_str(offset, text.len()), Some(text));
}
#[test]
fn release_arena_empty_does_not_panic() {
let arena = Arena::empty();
release_arena(arena); }
#[test]
fn validated_rows_blob_slice_roundtrip() {
let mut arena = Arena::new();
let offset = arena.alloc_copy(&[0xDE, 0xAD]);
let rows: ValidatedRows<u32> =
ValidatedRows::new(vec![offset as u32], String::new(), arena);
let blob = rows.blob_slice(offset as u32, 2);
assert_eq!(blob, &[0xDE, 0xAD]);
}
#[test]
fn validated_rows_deref_and_for_loop() {
let arena = Arena::new();
let rows: ValidatedRows<i32> = ValidatedRows::new(vec![1, 2, 3], String::new(), arena);
let slice: &[i32] = &rows;
assert_eq!(slice, &[1, 2, 3]);
let mut sum = 0;
for &v in &rows {
sum += v;
}
assert_eq!(sum, 6);
}
}