1use crate::typing::{ArgsRef, Record, Type, TypeRef};
2use crate::{Attrs, ExprKey, ExprPtr, ExprRef, Field, RecRef, StrRef, Value, VecRef};
3use rustc_hash::{FxBuildHasher, FxHashMap};
4use serde::Serialize;
5use std::collections::hash_map::Entry;
6use std::hash::BuildHasher;
7use std::ops::Range;
8use unicase::Ascii;
9
10#[derive(Default, Serialize)]
14pub(crate) struct StringArena {
15 #[serde(skip_serializing)]
16 hasher: FxBuildHasher,
17
18 cache: FxHashMap<u64, StrRef>,
19 slots: Vec<String>,
20}
21
22impl StringArena {
23 pub fn alloc(&mut self, value: &str) -> StrRef {
25 match self.cache.entry(self.hasher.hash_one(value)) {
26 Entry::Occupied(entry) => *entry.get(),
27 Entry::Vacant(entry) => {
28 let key = StrRef(self.slots.len());
29 entry.insert(key);
30 self.slots.push(value.to_owned());
31
32 key
33 }
34 }
35 }
36
37 pub fn str_ref(&self, value: &str) -> Option<StrRef> {
39 self.cache.get(&self.hasher.hash_one(value)).copied()
40 }
41
42 pub fn str_ref_no_case(&self, value: &str) -> Option<StrRef> {
44 self.cache
45 .get(&self.hasher.hash_one(Ascii::new(value)))
46 .copied()
47 }
48
49 pub fn alloc_no_case(&mut self, value: &str) -> StrRef {
54 match self.cache.entry(self.hasher.hash_one(Ascii::new(value))) {
55 Entry::Occupied(entry) => *entry.get(),
56 Entry::Vacant(entry) => {
57 let key = StrRef(self.slots.len());
58 entry.insert(key);
59 self.slots.push(value.to_owned());
60
61 key
62 }
63 }
64 }
65
66 pub fn get(&self, key: StrRef) -> &str {
68 &self.slots[key.0]
69 }
70
71 pub fn eq_ignore_ascii_case(&self, ka: StrRef, kb: StrRef) -> bool {
73 self.get(ka).eq_ignore_ascii_case(self.get(kb))
74 }
75}
76
77#[derive(Debug, Clone, Copy, Serialize)]
81pub struct Expr {
82 pub attrs: Attrs,
84 pub value: Value,
86}
87
88#[derive(Default, Serialize)]
93pub(crate) struct ExprArena {
94 #[serde(skip_serializing)]
95 hasher: FxBuildHasher,
96 exprs: Vec<Expr>,
97 vecs: Vec<Vec<ExprRef>>,
98 recs: Vec<Vec<Field>>,
99}
100
101impl ExprArena {
102 pub fn alloc(&mut self, attrs: Attrs, value: Value) -> ExprRef {
108 let key = ExprKey(self.hasher.hash_one(value));
109
110 let ptr = ExprPtr(self.exprs.len());
111 self.exprs.push(Expr { attrs, value });
112
113 ExprRef { key, ptr }
114 }
115
116 pub fn get(&self, node_ref: ExprRef) -> Expr {
123 self.exprs[node_ref.ptr.0]
124 }
125
126 pub fn alloc_vec(&mut self, values: Vec<ExprRef>) -> VecRef {
128 let key = VecRef(self.vecs.len());
129 self.vecs.push(values);
130
131 key
132 }
133
134 pub fn alloc_rec(&mut self, values: Vec<Field>) -> RecRef {
136 let key = RecRef(self.recs.len());
137 self.recs.push(values);
138
139 key
140 }
141
142 pub fn vec(&self, ptr: VecRef) -> &[ExprRef] {
144 &self.vecs[ptr.0]
145 }
146
147 pub fn vec_get(&self, ptr: VecRef, idx: usize) -> ExprRef {
149 self.vecs[ptr.0][idx]
150 }
151
152 pub fn vec_idxes(&self, ptr: VecRef) -> Range<usize> {
154 0..self.vec(ptr).len()
155 }
156
157 pub fn rec(&self, ptr: RecRef) -> &[Field] {
159 self.recs[ptr.0].as_slice()
160 }
161
162 pub fn rec_get(&self, ptr: RecRef, idx: usize) -> Field {
164 self.recs[ptr.0][idx]
165 }
166
167 pub fn rec_idxes(&self, ptr: RecRef) -> Range<usize> {
169 0..self.rec(ptr).len()
170 }
171}
172
173#[derive(Default, Serialize)]
178pub(crate) struct TypeArena {
179 #[serde(skip_serializing)]
180 args_hasher: FxBuildHasher,
181
182 type_offset: usize,
183 rec_offset: usize,
184
185 dedup_types: FxHashMap<Type, TypeRef>,
186 dedup_args: FxHashMap<u64, ArgsRef>,
187 types: Vec<Type>,
188 pub(crate) records: Vec<FxHashMap<StrRef, Type>>,
189 pub(crate) args: Vec<Vec<Type>>,
190}
191
192impl TypeArena {
193 pub fn freeze(&mut self) {
198 self.rec_offset = self.records.len();
199 self.type_offset = self.types.len();
200 }
201
202 pub fn free_space(&mut self) {
204 for tpe in self.types.drain(self.type_offset..) {
205 self.dedup_types.remove(&tpe);
206 }
207
208 for _ in self.records.drain(self.rec_offset..) {}
209 }
210
211 pub fn register_type(&mut self, tpe: Type) -> TypeRef {
213 match self.dedup_types.entry(tpe) {
214 Entry::Occupied(entry) => *entry.get(),
215 Entry::Vacant(entry) => {
216 let key = TypeRef(self.types.len());
217 self.types.push(tpe);
218 entry.insert(key);
219
220 key
221 }
222 }
223 }
224
225 pub fn alloc_type(&mut self, tpe: Type) -> Type {
227 if let Type::Record(rec) = tpe {
228 let key = Record(self.records.len());
229 self.records.push(self.records[rec.0].clone());
232
233 return Type::Record(key);
234 }
235
236 tpe
237 }
238
239 pub fn alloc_array_of(&mut self, tpe: Type) -> Type {
241 Type::Array(self.register_type(tpe))
242 }
243
244 pub fn alloc_record(&mut self, record: FxHashMap<StrRef, Type>) -> Record {
246 let key = Record(self.records.len());
247 self.records.push(record);
248 key
249 }
250
251 pub fn alloc_args(&mut self, args: &[Type]) -> ArgsRef {
253 let hash = self.args_hasher.hash_one(args);
254
255 match self.dedup_args.entry(hash) {
256 Entry::Occupied(entry) => *entry.get(),
257 Entry::Vacant(entry) => {
258 let key = ArgsRef(self.args.len());
259 entry.insert(key);
260 self.args.push(args.to_vec());
261
262 key
263 }
264 }
265 }
266
267 pub fn get_type(&self, key: TypeRef) -> Type {
269 self.types[key.0]
270 }
271
272 pub fn get_record(&self, key: Record) -> &FxHashMap<StrRef, Type> {
274 &self.records[key.0]
275 }
276
277 pub fn get_args(&self, key: ArgsRef) -> &[Type] {
279 self.args[key.0].as_slice()
280 }
281
282 pub fn args_idxes(&self, key: ArgsRef) -> impl Iterator<Item = usize> + use<> {
284 0..self.get_args(key).len()
285 }
286
287 pub fn args_get(&self, key: ArgsRef, idx: usize) -> Type {
289 self.get_args(key)[idx]
290 }
291
292 pub fn record_get(&self, record: Record, field: StrRef) -> Option<Type> {
294 self.records[record.0].get(&field).copied()
295 }
296
297 pub fn records_have_same_keys(&self, rec_a: Record, rec_b: Record) -> bool {
299 let rec_a = self.get_record(rec_a);
300 let rec_b = self.get_record(rec_b);
301
302 if rec_a.is_empty() && rec_b.is_empty() {
303 return true;
304 }
305
306 if rec_a.len() != rec_b.len() {
307 return false;
308 }
309
310 for bk in rec_b.keys() {
311 if !rec_a.contains_key(bk) {
312 return false;
313 }
314 }
315
316 true
317 }
318
319 pub fn instantiate_record(&mut self) -> Record {
321 self.alloc_record(FxHashMap::default())
322 }
323
324 pub fn record_set(&mut self, record: Record, field: StrRef, value: Type) {
326 self.records[record.0].insert(field, value);
327 }
328
329 pub fn record_len(&self, record: Record) -> usize {
331 self.records[record.0].len()
332 }
333}
334
335#[derive(Default, Serialize)]
337pub struct Arena {
338 pub(crate) exprs: ExprArena,
339 pub(crate) strings: StringArena,
340 pub(crate) types: TypeArena,
341}
342
343impl Arena {
344 pub fn freeze(&mut self) {
346 self.types.freeze();
347 }
348
349 pub fn free_space(&mut self) {
351 self.types.free_space();
352 }
353
354 pub fn get_str(&self, key: StrRef) -> &str {
356 self.strings.get(key)
357 }
358
359 pub fn str_ref(&self, key: &str) -> Option<StrRef> {
361 self.strings.str_ref(key)
362 }
363
364 pub fn get_expr(&self, key: ExprRef) -> Expr {
366 self.exprs.get(key)
367 }
368
369 pub fn get_type(&self, key: TypeRef) -> Type {
371 self.types.get_type(key)
372 }
373
374 pub fn get_vec(&self, key: VecRef) -> &[ExprRef] {
376 self.exprs.vec(key)
377 }
378
379 pub fn get_rec(&self, key: RecRef) -> &[Field] {
381 self.exprs.rec(key)
382 }
383
384 pub fn get_type_rec(&self, key: Record) -> &FxHashMap<StrRef, Type> {
386 self.types.get_record(key)
387 }
388
389 pub fn get_args(&self, key: ArgsRef) -> &[Type] {
391 self.types.get_args(key)
392 }
393}