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 alloc_no_case(&mut self, value: &str) -> StrRef {
47 match self.cache.entry(self.hasher.hash_one(Ascii::new(value))) {
48 Entry::Occupied(entry) => *entry.get(),
49 Entry::Vacant(entry) => {
50 let key = StrRef(self.slots.len());
51 entry.insert(key);
52 self.slots.push(value.to_owned());
53
54 key
55 }
56 }
57 }
58
59 pub fn get(&self, key: StrRef) -> &str {
61 &self.slots[key.0]
62 }
63}
64
65#[derive(Debug, Clone, Copy, Serialize)]
69pub struct Expr {
70 pub attrs: Attrs,
72 pub value: Value,
74}
75
76#[derive(Default, Serialize)]
81pub(crate) struct ExprArena {
82 #[serde(skip_serializing)]
83 hasher: FxBuildHasher,
84 exprs: Vec<Expr>,
85 vecs: Vec<Vec<ExprRef>>,
86 recs: Vec<Vec<Field>>,
87}
88
89impl ExprArena {
90 pub fn alloc(&mut self, attrs: Attrs, value: Value) -> ExprRef {
96 let key = ExprKey(self.hasher.hash_one(value));
97
98 let ptr = ExprPtr(self.exprs.len());
99 self.exprs.push(Expr { attrs, value });
100
101 ExprRef { key, ptr }
102 }
103
104 pub fn get(&self, node_ref: ExprRef) -> Expr {
111 self.exprs[node_ref.ptr.0]
112 }
113
114 pub fn alloc_vec(&mut self, values: Vec<ExprRef>) -> VecRef {
116 let key = VecRef(self.vecs.len());
117 self.vecs.push(values);
118
119 key
120 }
121
122 pub fn alloc_rec(&mut self, values: Vec<Field>) -> RecRef {
124 let key = RecRef(self.recs.len());
125 self.recs.push(values);
126
127 key
128 }
129
130 pub fn vec(&self, ptr: VecRef) -> &[ExprRef] {
132 &self.vecs[ptr.0]
133 }
134
135 pub fn vec_get(&self, ptr: VecRef, idx: usize) -> ExprRef {
137 self.vecs[ptr.0][idx]
138 }
139
140 pub fn vec_idxes(&self, ptr: VecRef) -> Range<usize> {
142 0..self.vec(ptr).len()
143 }
144
145 pub fn rec(&self, ptr: RecRef) -> &[Field] {
147 self.recs[ptr.0].as_slice()
148 }
149
150 pub fn rec_get(&self, ptr: RecRef, idx: usize) -> Field {
152 self.recs[ptr.0][idx]
153 }
154
155 pub fn rec_idxes(&self, ptr: RecRef) -> Range<usize> {
157 0..self.rec(ptr).len()
158 }
159}
160
161#[derive(Default, Serialize)]
166pub(crate) struct TypeArena {
167 #[serde(skip_serializing)]
168 args_hasher: FxBuildHasher,
169
170 type_offset: usize,
171 rec_offset: usize,
172
173 dedup_types: FxHashMap<Type, TypeRef>,
174 dedup_args: FxHashMap<u64, ArgsRef>,
175 types: Vec<Type>,
176 pub(crate) records: Vec<FxHashMap<StrRef, Type>>,
177 pub(crate) args: Vec<Vec<Type>>,
178}
179
180impl TypeArena {
181 pub fn freeze(&mut self) {
186 self.rec_offset = self.records.len();
187 self.type_offset = self.types.len();
188 }
189
190 pub fn free_space(&mut self) {
192 for tpe in self.types.drain(self.type_offset..) {
193 self.dedup_types.remove(&tpe);
194 }
195
196 for _ in self.records.drain(self.rec_offset..) {}
197 }
198
199 pub fn register_type(&mut self, tpe: Type) -> TypeRef {
201 match self.dedup_types.entry(tpe) {
202 Entry::Occupied(entry) => *entry.get(),
203 Entry::Vacant(entry) => {
204 let key = TypeRef(self.types.len());
205 self.types.push(tpe);
206 entry.insert(key);
207
208 key
209 }
210 }
211 }
212
213 pub fn alloc_type(&mut self, tpe: Type) -> Type {
215 if let Type::Record(rec) = tpe {
216 let key = Record(self.records.len());
217 self.records.push(self.records[rec.0].clone());
220
221 return Type::Record(key);
222 }
223
224 tpe
225 }
226
227 pub fn alloc_array_of(&mut self, tpe: Type) -> Type {
229 Type::Array(self.register_type(tpe))
230 }
231
232 pub fn alloc_record(&mut self, record: FxHashMap<StrRef, Type>) -> Record {
234 let key = Record(self.records.len());
235 self.records.push(record);
236 key
237 }
238
239 pub fn alloc_args(&mut self, args: &[Type]) -> ArgsRef {
241 let hash = self.args_hasher.hash_one(args);
242
243 match self.dedup_args.entry(hash) {
244 Entry::Occupied(entry) => *entry.get(),
245 Entry::Vacant(entry) => {
246 let key = ArgsRef(self.args.len());
247 entry.insert(key);
248 self.args.push(args.to_vec());
249
250 key
251 }
252 }
253 }
254
255 pub fn get_type(&self, key: TypeRef) -> Type {
257 self.types[key.0]
258 }
259
260 pub fn get_record(&self, key: Record) -> &FxHashMap<StrRef, Type> {
262 &self.records[key.0]
263 }
264
265 pub fn get_args(&self, key: ArgsRef) -> &[Type] {
267 self.args[key.0].as_slice()
268 }
269
270 pub fn args_idxes(&self, key: ArgsRef) -> impl Iterator<Item = usize> + use<> {
272 0..self.get_args(key).len()
273 }
274
275 pub fn args_get(&self, key: ArgsRef, idx: usize) -> Type {
277 self.get_args(key)[idx]
278 }
279
280 pub fn record_get(&self, record: Record, field: StrRef) -> Option<Type> {
282 self.records[record.0].get(&field).copied()
283 }
284
285 pub fn records_have_same_keys(&self, rec_a: Record, rec_b: Record) -> bool {
287 let rec_a = self.get_record(rec_a);
288 let rec_b = self.get_record(rec_b);
289
290 if rec_a.is_empty() && rec_b.is_empty() {
291 return true;
292 }
293
294 if rec_a.len() != rec_b.len() {
295 return false;
296 }
297
298 for bk in rec_b.keys() {
299 if !rec_a.contains_key(bk) {
300 return false;
301 }
302 }
303
304 true
305 }
306
307 pub fn instantiate_record(&mut self) -> Record {
309 self.alloc_record(FxHashMap::default())
310 }
311
312 pub fn record_set(&mut self, record: Record, field: StrRef, value: Type) {
314 self.records[record.0].insert(field, value);
315 }
316
317 pub fn record_len(&self, record: Record) -> usize {
319 self.records[record.0].len()
320 }
321}
322
323#[derive(Default, Serialize)]
325pub struct Arena {
326 pub(crate) exprs: ExprArena,
327 pub(crate) strings: StringArena,
328 pub(crate) types: TypeArena,
329}
330
331impl Arena {
332 pub fn freeze(&mut self) {
334 self.types.freeze();
335 }
336
337 pub fn free_space(&mut self) {
339 self.types.free_space();
340 }
341
342 pub fn get_str(&self, key: StrRef) -> &str {
344 self.strings.get(key)
345 }
346
347 pub fn str_ref(&self, key: &str) -> Option<StrRef> {
349 self.strings.str_ref(key)
350 }
351
352 pub fn get_expr(&self, key: ExprRef) -> Expr {
354 self.exprs.get(key)
355 }
356
357 pub fn get_type(&self, key: TypeRef) -> Type {
359 self.types.get_type(key)
360 }
361
362 pub fn get_vec(&self, key: VecRef) -> &[ExprRef] {
364 self.exprs.vec(key)
365 }
366
367 pub fn get_rec(&self, key: RecRef) -> &[Field] {
369 self.exprs.rec(key)
370 }
371
372 pub fn get_type_rec(&self, key: Record) -> &FxHashMap<StrRef, Type> {
374 self.types.get_record(key)
375 }
376
377 pub fn get_args(&self, key: ArgsRef) -> &[Type] {
379 self.types.get_args(key)
380 }
381}