diff --git a/src/archive/interner.rs b/src/archive/interner.rs new file mode 100644 index 0000000..42020bc --- /dev/null +++ b/src/archive/interner.rs @@ -0,0 +1,35 @@ +//! Interner module. + +use std::collections::HashSet; +use std::sync::RwLock; + +pub struct Interner(RwLock>); + +impl Interner +where + T: Eq + std::hash::Hash, +{ + pub fn new() -> Self { + Self(RwLock::new(HashSet::new())) + } + + fn get(&self, value: &T) -> Option<&'static T> { + let store = self.0.read().unwrap(); + + store.get(value).map(|value| *value) + } + + fn set(&self, value: T) -> &'static T { + let boxed: Box = Box::new(value); + let leaked: &'static T = Box::leak(boxed); + let mut store = self.0.write().unwrap(); + + store.insert(leaked); + + leaked + } + + pub fn intern(&self, value: T) -> &'static T { + self.get(&value).unwrap_or_else(|| self.set(value)) + } +} diff --git a/src/archive/mod.rs b/src/archive/mod.rs index 1216681..0882039 100644 --- a/src/archive/mod.rs +++ b/src/archive/mod.rs @@ -1,6 +1,7 @@ //! Archive module. mod fetcher; +mod interner; mod parser; mod story;