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 alloc_no_case(&mut self, value: &str) -> StrRef {
42 let hash = Ascii::new(value);
43 match self.cache.entry(self.hasher.hash_one(hash)) {
44 Entry::Occupied(entry) => *entry.get(),
45 Entry::Vacant(entry) => {
46 let key = StrRef(self.slots.len());
47 entry.insert(key);
48 self.slots.push(value.to_owned());
49
50 key
51 }
52 }
53 }
54
55 pub fn get(&self, key: StrRef) -> &str {
57 &self.slots[key.0]
58 }
59
60 pub fn eq_ignore_ascii_case(&self, ka: StrRef, kb: StrRef) -> bool {
62 self.get(ka).eq_ignore_ascii_case(self.get(kb))
63 }
64}
65
66#[derive(Debug, Clone, Copy, Serialize)]
70pub struct Expr {
71 pub attrs: Attrs,
73 pub value: Value,
75}
76
77#[derive(Default, Serialize)]
82pub(crate) struct ExprArena {
83 #[serde(skip_serializing)]
84 hasher: FxBuildHasher,
85 exprs: Vec<Expr>,
86 vecs: Vec<Vec<ExprRef>>,
87 recs: Vec<Vec<Field>>,
88}
89
90impl ExprArena {
91 pub fn alloc(&mut self, attrs: Attrs, value: Value) -> ExprRef {
97 let key = ExprKey(self.hasher.hash_one(value));
98
99 let ptr = ExprPtr(self.exprs.len());
100 self.exprs.push(Expr { attrs, value });
101
102 ExprRef { key, ptr }
103 }
104
105 pub fn get(&self, node_ref: ExprRef) -> Expr {
112 self.exprs[node_ref.ptr.0]
113 }
114
115 pub fn alloc_vec(&mut self, values: Vec<ExprRef>) -> VecRef {
117 let key = VecRef(self.vecs.len());
118 self.vecs.push(values);
119
120 key
121 }
122
123 pub fn alloc_rec(&mut self, values: Vec<Field>) -> RecRef {
125 let key = RecRef(self.recs.len());
126 self.recs.push(values);
127
128 key
129 }
130
131 pub fn vec(&self, ptr: VecRef) -> &[ExprRef] {
133 &self.vecs[ptr.0]
134 }
135
136 pub fn vec_get(&self, ptr: VecRef, idx: usize) -> ExprRef {
138 self.vecs[ptr.0][idx]
139 }
140
141 pub fn vec_idxes(&self, ptr: VecRef) -> Range<usize> {
143 0..self.vec(ptr).len()
144 }
145
146 pub fn rec(&self, ptr: RecRef) -> &[Field] {
148 self.recs[ptr.0].as_slice()
149 }
150
151 pub fn rec_get(&self, ptr: RecRef, idx: usize) -> Field {
153 self.recs[ptr.0][idx]
154 }
155
156 pub fn rec_idxes(&self, ptr: RecRef) -> Range<usize> {
158 0..self.rec(ptr).len()
159 }
160}
161
162#[derive(Default, Serialize)]
167pub(crate) struct TypeArena {
168 #[serde(skip_serializing)]
169 args_hasher: FxBuildHasher,
170
171 type_offset: usize,
172 rec_offset: usize,
173
174 dedup_types: FxHashMap<Type, TypeRef>,
175 dedup_args: FxHashMap<u64, ArgsRef>,
176 types: Vec<Type>,
177 pub(crate) records: Vec<FxHashMap<StrRef, Type>>,
178 pub(crate) args: Vec<Vec<Type>>,
179}
180
181impl TypeArena {
182 pub fn freeze(&mut self) {
187 self.rec_offset = self.records.len();
188 self.type_offset = self.types.len();
189 }
190
191 pub fn free_space(&mut self) {
193 for tpe in self.types.drain(self.type_offset..) {
194 self.dedup_types.remove(&tpe);
195 }
196
197 for _ in self.records.drain(self.rec_offset..) {}
198 }
199
200 pub fn register_type(&mut self, tpe: Type) -> TypeRef {
202 match self.dedup_types.entry(tpe) {
203 Entry::Occupied(entry) => *entry.get(),
204 Entry::Vacant(entry) => {
205 let key = TypeRef(self.types.len());
206 self.types.push(tpe);
207 entry.insert(key);
208
209 key
210 }
211 }
212 }
213
214 pub fn alloc_type(&mut self, tpe: Type) -> Type {
216 if let Type::Record(rec) = tpe {
217 let key = Record(self.records.len());
218 self.records.push(self.records[rec.0].clone());
221
222 return Type::Record(key);
223 }
224
225 tpe
226 }
227
228 pub fn alloc_array_of(&mut self, tpe: Type) -> Type {
230 Type::Array(self.register_type(tpe))
231 }
232
233 pub fn alloc_record(&mut self, record: FxHashMap<StrRef, Type>) -> Record {
235 let key = Record(self.records.len());
236 self.records.push(record);
237 key
238 }
239
240 pub fn alloc_args(&mut self, args: &[Type]) -> ArgsRef {
242 let hash = self.args_hasher.hash_one(args);
243
244 match self.dedup_args.entry(hash) {
245 Entry::Occupied(entry) => *entry.get(),
246 Entry::Vacant(entry) => {
247 let key = ArgsRef(self.args.len());
248 entry.insert(key);
249 self.args.push(args.to_vec());
250
251 key
252 }
253 }
254 }
255
256 pub fn get_type(&self, key: TypeRef) -> Type {
258 self.types[key.0]
259 }
260
261 pub fn get_record(&self, key: Record) -> &FxHashMap<StrRef, Type> {
263 &self.records[key.0]
264 }
265
266 pub fn get_args(&self, key: ArgsRef) -> &[Type] {
268 self.args[key.0].as_slice()
269 }
270
271 pub fn args_idxes(&self, key: ArgsRef) -> impl Iterator<Item = usize> + use<> {
273 0..self.get_args(key).len()
274 }
275
276 pub fn args_get(&self, key: ArgsRef, idx: usize) -> Type {
278 self.get_args(key)[idx]
279 }
280
281 pub fn record_get(&self, record: Record, field: StrRef) -> Option<Type> {
283 self.records[record.0].get(&field).copied()
284 }
285
286 pub fn records_have_same_keys(&self, rec_a: Record, rec_b: Record) -> bool {
288 let rec_a = self.get_record(rec_a);
289 let rec_b = self.get_record(rec_b);
290
291 if rec_a.is_empty() && rec_b.is_empty() {
292 return true;
293 }
294
295 if rec_a.len() != rec_b.len() {
296 return false;
297 }
298
299 for bk in rec_b.keys() {
300 if !rec_a.contains_key(bk) {
301 return false;
302 }
303 }
304
305 true
306 }
307
308 pub fn instantiate_record(&mut self) -> Record {
310 self.alloc_record(FxHashMap::default())
311 }
312
313 pub fn record_set(&mut self, record: Record, field: StrRef, value: Type) {
315 self.records[record.0].insert(field, value);
316 }
317
318 pub fn record_len(&self, record: Record) -> usize {
320 self.records[record.0].len()
321 }
322}
323
324#[derive(Default, Serialize)]
326pub struct Arena {
327 pub(crate) exprs: ExprArena,
328 pub(crate) strings: StringArena,
329 pub(crate) types: TypeArena,
330}
331
332impl Arena {
333 pub fn freeze(&mut self) {
335 self.types.freeze();
336 }
337
338 pub fn free_space(&mut self) {
340 self.types.free_space();
341 }
342
343 pub fn get_str(&self, key: StrRef) -> &str {
345 self.strings.get(key)
346 }
347
348 pub fn get_expr(&self, key: ExprRef) -> Expr {
350 self.exprs.get(key)
351 }
352
353 pub fn get_type(&self, key: TypeRef) -> Type {
355 self.types.get_type(key)
356 }
357
358 pub fn get_vec(&self, key: VecRef) -> &[ExprRef] {
360 self.exprs.vec(key)
361 }
362
363 pub fn get_rec(&self, key: RecRef) -> &[Field] {
365 self.exprs.rec(key)
366 }
367
368 pub fn get_args(&self, key: ArgsRef) -> &[Type] {
370 self.types.get_args(key)
371 }
372}