1use std::collections::BTreeMap;
4use std::sync::{Arc, Mutex};
5
6use crate::QueryError;
7use crate::ast::{Query, parse_query};
8use crate::edn::Edn;
9
10#[derive(Clone, Debug, Default)]
12pub struct QueryCache {
13 entries: Arc<Mutex<BTreeMap<Edn, Arc<Query>>>>,
14}
15
16impl QueryCache {
17 #[must_use]
19 pub fn new() -> Self {
20 Self::default()
21 }
22
23 pub fn parse(&self, form: &Edn) -> Result<Arc<Query>, QueryError> {
29 let mut entries = self
30 .entries
31 .lock()
32 .unwrap_or_else(std::sync::PoisonError::into_inner);
33 if let Some(hit) = entries.get(form) {
34 return Ok(Arc::clone(hit));
35 }
36 let parsed = Arc::new(parse_query(form)?);
37 entries.insert(form.clone(), Arc::clone(&parsed));
38 Ok(parsed)
39 }
40
41 #[must_use]
46 pub fn len(&self) -> usize {
47 self.entries
48 .lock()
49 .unwrap_or_else(std::sync::PoisonError::into_inner)
50 .len()
51 }
52
53 #[must_use]
55 pub fn is_empty(&self) -> bool {
56 self.len() == 0
57 }
58}