mirror of
https://github.com/JockeTF/fimfareader.git
synced 2024-11-27 07:28:00 +01:00
Add interner for static reference sharing
This commit is contained in:
parent
3b1d99e14c
commit
5f52b590cc
2 changed files with 36 additions and 0 deletions
35
src/archive/interner.rs
Normal file
35
src/archive/interner.rs
Normal 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))
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
//! Archive module.
|
//! Archive module.
|
||||||
|
|
||||||
mod fetcher;
|
mod fetcher;
|
||||||
|
mod interner;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod story;
|
mod story;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue