1
0

Add global identifier cache

This commit is contained in:
Jeff 2024-06-24 10:46:37 -04:00
parent 38ffd9b01b
commit fbaf640fce
2 changed files with 24 additions and 19 deletions

View File

@ -1,16 +1,36 @@
use std::{ use std::{
collections::HashMap,
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
sync::Arc, sync::{Arc, OnceLock, RwLock},
}; };
use serde::{de::Visitor, Deserialize, Serialize}; use serde::{de::Visitor, Deserialize, Serialize};
static IDENTIFIER_CACHE: OnceLock<RwLock<HashMap<String, Identifier>>> = OnceLock::new();
fn identifier_cache<'a>() -> &'a RwLock<HashMap<String, Identifier>> {
IDENTIFIER_CACHE.get_or_init(|| RwLock::new(HashMap::new()))
}
#[derive(Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)] #[derive(Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
pub struct Identifier(Arc<String>); pub struct Identifier(Arc<String>);
impl Identifier { impl Identifier {
pub fn new<T: ToString>(string: T) -> Self { pub fn new(string: &str) -> Self {
Identifier(Arc::new(string.to_string())) let cache = identifier_cache();
if let Some(identifier) = cache.read().unwrap().get(string) {
return identifier.clone();
}
let identifier = Identifier(Arc::new(string.to_string()));
cache
.write()
.unwrap()
.insert(string.to_string(), identifier.clone());
identifier
} }
pub fn as_str(&self) -> &str { pub fn as_str(&self) -> &str {

View File

@ -1,8 +1,6 @@
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
use std::{cell::RefCell, collections::HashMap};
use chumsky::{input::SpannedInput, pratt::*, prelude::*}; use chumsky::{input::SpannedInput, pratt::*, prelude::*};
use crate::{ use crate::{
@ -43,21 +41,8 @@ pub fn parser<'src>(
let comment = select_ref! { let comment = select_ref! {
Token::Comment(_) => {} Token::Comment(_) => {}
}; };
let identifiers: RefCell<HashMap<&str, Identifier>> = RefCell::new(HashMap::new());
let identifier = select! { let identifier = select! {
Token::Identifier(text) => { Token::Identifier(text) => Identifier::new(text),
let mut identifiers = identifiers.borrow_mut();
if let Some(identifier) = identifiers.get(&text) {
identifier.clone()
} else {
let new = Identifier::new(text);
identifiers.insert(text, new.clone());
new
}
}
}; };
let positioned_identifier = identifier let positioned_identifier = identifier