1use std::{cell::RefCell, collections::HashMap};
7use typed_arena::Arena;
8
9pub struct StringArena {
11 arena: Arena<String>,
12 interned: RefCell<HashMap<&'static str, &'static str>>,
13}
14
15impl StringArena {
16 pub fn new() -> Self {
18 Self {
19 arena: Arena::new(),
20 interned: RefCell::new(HashMap::new()),
21 }
22 }
23
24 pub fn alloc_str(&self, s: String) -> &str {
26 self.arena.alloc(s).as_str()
27 }
28
29 pub fn intern(&self, s: &str) -> &str {
31 if let Some(&interned) = self.interned.borrow().get(s) {
33 return interned;
34 }
35
36 let allocated = self.alloc_str(s.to_string());
37 let static_ref: &'static str = unsafe { std::mem::transmute(allocated) };
39 self.interned.borrow_mut().insert(static_ref, static_ref);
40 static_ref
41 }
42
43 pub fn memory_usage(&self) -> ArenaStats {
45 ArenaStats {
47 chunks_allocated: 1, total_bytes: 0, strings_allocated: 0, }
51 }
52}
53
54impl Default for StringArena {
55 fn default() -> Self {
56 Self::new()
57 }
58}
59
60pub struct ValueArena<T> {
62 arena: Arena<T>,
63 allocated_count: RefCell<usize>,
64}
65
66impl<T> ValueArena<T> {
67 pub fn new() -> Self {
69 Self {
70 arena: Arena::new(),
71 allocated_count: RefCell::new(0),
72 }
73 }
74
75 pub fn alloc(&self, value: T) -> &mut T {
77 *self.allocated_count.borrow_mut() += 1;
78 self.arena.alloc(value)
79 }
80
81 pub fn alloc_extend<I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] {
83 let values: Vec<T> = iter.into_iter().collect();
84 *self.allocated_count.borrow_mut() += values.len();
85 self.arena.alloc_extend(values)
86 }
87
88 pub fn allocated_count(&self) -> usize {
90 *self.allocated_count.borrow()
91 }
92}
93
94impl<T> Default for ValueArena<T> {
95 fn default() -> Self {
96 Self::new()
97 }
98}
99
100#[derive(Debug, Clone)]
102pub struct ArenaStats {
103 pub chunks_allocated: usize,
104 pub total_bytes: usize,
105 pub strings_allocated: usize,
106}
107
108pub struct JsonArena {
110 pub strings: StringArena,
112 pub objects: ValueArena<serde_json::Map<String, serde_json::Value>>,
114 pub arrays: ValueArena<Vec<serde_json::Value>>,
116 pub values: ValueArena<serde_json::Value>,
118}
119
120impl JsonArena {
121 pub fn new() -> Self {
123 Self {
124 strings: StringArena::new(),
125 objects: ValueArena::new(),
126 arrays: ValueArena::new(),
127 values: ValueArena::new(),
128 }
129 }
130
131 pub fn stats(&self) -> CombinedArenaStats {
133 CombinedArenaStats {
134 string_stats: self.strings.memory_usage(),
135 objects_allocated: self.objects.allocated_count(),
136 arrays_allocated: self.arrays.allocated_count(),
137 values_allocated: self.values.allocated_count(),
138 }
139 }
140
141 pub fn reset(&mut self) {
143 *self = Self::new();
145 }
146}
147
148impl Default for JsonArena {
149 fn default() -> Self {
150 Self::new()
151 }
152}
153
154#[derive(Debug, Clone)]
156pub struct CombinedArenaStats {
157 pub string_stats: ArenaStats,
158 pub objects_allocated: usize,
159 pub arrays_allocated: usize,
160 pub values_allocated: usize,
161}
162
163pub struct ArenaJsonParser {
165 arena: JsonArena,
166 reuse_threshold: usize,
167}
168
169impl ArenaJsonParser {
170 pub fn new() -> Self {
172 Self {
173 arena: JsonArena::new(),
174 reuse_threshold: 1000, }
176 }
177
178 pub fn parse(&mut self, json: &str) -> Result<serde_json::Value, serde_json::Error> {
180 let stats = self.arena.stats();
182 if stats.values_allocated > self.reuse_threshold {
183 self.arena.reset();
184 }
185
186 serde_json::from_str(json)
189 }
190
191 pub fn arena_stats(&self) -> CombinedArenaStats {
193 self.arena.stats()
194 }
195}
196
197impl Default for ArenaJsonParser {
198 fn default() -> Self {
199 Self::new()
200 }
201}
202
203#[cfg(test)]
204mod tests {
205 use super::*;
206
207 #[test]
208 fn test_string_arena_basic() {
209 let arena = StringArena::new();
210 let s1 = arena.alloc_str("hello".to_string());
211 let s2 = arena.alloc_str("world".to_string());
212
213 assert_eq!(s1, "hello");
214 assert_eq!(s2, "world");
215 }
216
217 #[test]
218 fn test_value_arena_counting() {
219 let arena = ValueArena::new();
220 assert_eq!(arena.allocated_count(), 0);
221
222 arena.alloc(42);
223 assert_eq!(arena.allocated_count(), 1);
224
225 arena.alloc_extend([1, 2, 3]);
226 assert_eq!(arena.allocated_count(), 4);
227 }
228
229 #[test]
230 fn test_json_arena_stats() {
231 let arena = JsonArena::new();
232 let stats = arena.stats();
233
234 assert_eq!(stats.objects_allocated, 0);
236 assert_eq!(stats.arrays_allocated, 0);
237 assert_eq!(stats.values_allocated, 0);
238 }
239
240 #[test]
241 fn test_arena_parser() {
242 let mut parser = ArenaJsonParser::new();
243 let result = parser.parse(r#"{"key": "value"}"#);
244
245 assert!(result.is_ok());
246 let value = result.unwrap();
247 assert!(value.is_object());
248 }
249
250 #[test]
251 fn test_arena_reset() {
252 let mut arena = JsonArena::new();
253
254 arena.values.alloc(serde_json::Value::Null);
256 arena.objects.alloc(serde_json::Map::new());
257
258 let initial_stats = arena.stats();
259 assert!(initial_stats.values_allocated > 0);
260
261 arena.reset();
263 let reset_stats = arena.stats();
264 assert_eq!(reset_stats.values_allocated, 0);
265 assert_eq!(reset_stats.objects_allocated, 0);
266 }
267}