Add global identifier cache
This commit is contained in:
parent
38ffd9b01b
commit
fbaf640fce
@ -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 {
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user