1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
//! # stack-arena
//!
//! A fast, stack-like arena allocator for efficient memory management, implemented in Rust.
//!
//! ## Overview
//!
//! This library provides a set of memory allocation tools that follow a stack-like
//! (Last-In-First-Out) allocation pattern. It's designed for scenarios where performance
//! is critical and memory usage needs to be minimized with low per-allocation overhead.
//!
//! ## When to Use
//!
//! Stack-arena is ideal for scenarios where:
//!
//! - You need to allocate many small objects in sequence
//! - Objects follow a stack-like (LIFO) allocation/deallocation pattern
//! - Memory usage needs to be minimized with low per-allocation overhead
//! - Performance is critical, especially for parsers, interpreters, or compilers
//! - You want to avoid the overhead of the system allocator for short-lived objects
//!
//! ## Architecture
//!
//! The library is organized in layers:
//!
//! 1. [`Chunk`] - The lowest level, representing a contiguous region of memory
//! 2. [`BufferArena`] - Manages a single memory chunk with bump allocation
//! 3. [`StackArena`] - Manages multiple chunks with LIFO allocation/deallocation
//! 4. [`ObjectStack`] - High-level interface for building objects incrementally
//!
//! ## Features
//!
//! - Efficient allocation of variable-sized objects with minimal overhead
//! - Stack-like (LIFO) allocation and deallocation pattern
//! - Memory is managed in chunks, automatically growing when needed, with old chunks preserved to maintain pointer validity
//! - Objects can be built incrementally using `extend` and `finish` methods
//! - Implements `std::fmt::Write` for string formatting directly into objects
//! - Implements the [`Allocator`] trait for compatibility with allocation APIs
//! - Automatic chunk reuse for improved performance
//!
//! ## Usage Examples
//!
//! ### Using ObjectStack (high-level API)
//!
//! The [`ObjectStack`] provides a user-friendly interface for building and managing objects:
//!
//! ```rust
//! use stack_arena::ObjectStack;
//! use std::fmt::Write;
//!
//! let mut stack = ObjectStack::new();
//!
//! // Push a complete object
//! stack.push(b"greetings!");
//!
//! // Build an object incrementally
//! stack.extend("hello");
//! stack.extend(" ");
//! stack.extend("world");
//! write!(&mut stack, "!").unwrap();
//! let ptr = stack.finish();
//!
//! // Access the object
//! let hello_world = unsafe { std::str::from_utf8_unchecked(ptr.as_ref()) };
//! assert_eq!(hello_world, "hello world!");
//!
//! // Pop the object when done
//! stack.pop();
//! ```
//!
//! ### Using StackArena (low-level API)
//!
//! The [`StackArena`] provides more control over memory allocation:
//!
//! ```rust
//! use stack_arena::{StackArena, Allocator};
//! use std::alloc::Layout;
//!
//! // Create with default chunk size (4096 bytes)
//! let mut arena = StackArena::new();
//!
//! // Or create with a custom chunk size
//! let mut custom_arena = StackArena::with_chunk_size(8192);
//!
//! // Allocate memory
//! let layout = Layout::from_size_align(10, 1).unwrap();
//! let ptr = unsafe { arena.allocate(layout).unwrap() };
//!
//! // Use the memory...
//! unsafe { std::ptr::write_bytes(ptr.as_ptr() as *mut u8, 0xAA, 10) };
//!
//! // Deallocate when done
//! unsafe { arena.deallocate(ptr.cast(), layout) };
//! ```
//!
//! ## Performance
//!
//! The library is optimized for scenarios with many small allocations that follow
//! a stack-like pattern. Benchmarks show it significantly outperforms the system
//! allocator in these cases:
//!
//! - Up to 10x faster for consecutive small allocations
//! - Minimal overhead for allocation and deallocation
//! - Efficient memory reuse with the LIFO pattern
//! - Reduced memory fragmentation
//!
//! ## Safety
//!
//! - All returned pointers are valid until the corresponding object is deallocated
//! - Objects are stored in contiguous memory chunks
//! - Unsafe operations are used internally for performance
//! - The library follows LIFO (Last-In-First-Out) allocation pattern for efficiency
//! - Users must ensure proper memory safety when working with raw pointers
pub use BufferArena;
pub use AllocError;
pub use ObjectStack;
pub use StackArena;
pub use Allocator;