Add interner for static reference sharing

This commit is contained in:
Joakim Soderlund 2020-05-22 23:52:09 +02:00
parent 3b1d99e14c
commit 5f52b590cc
2 changed files with 36 additions and 0 deletions

35
src/archive/interner.rs Normal file
View file

@ -0,0 +1,35 @@
//! Interner module.
use std::collections::HashSet;
use std::sync::RwLock;
pub struct Interner<T: 'static>(RwLock<HashSet<&'static T>>);
impl<T> Interner<T>
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<T> = 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))
}
}

View file

@ -1,6 +1,7 @@
//! Archive module.
mod fetcher;
mod interner;
mod parser;
mod story;