Skip to main content

yazi_shared/pool/
pool.rs

1use std::marker::PhantomData;
2
3use hashbrown::hash_map::RawEntryMut;
4
5use crate::pool::{SYMBOLS, Symbol, SymbolPtr, compute_hash};
6
7pub struct Pool<T: ?Sized> {
8	_phantom: PhantomData<T>,
9}
10
11impl Pool<[u8]> {
12	pub fn intern(value: &[u8]) -> Symbol<[u8]> {
13		let hash = compute_hash(value);
14
15		match SYMBOLS.lock().raw_entry_mut().from_key_hashed_nocheck(hash, value) {
16			RawEntryMut::Occupied(mut oe) => {
17				let (ptr, count) = oe.get_key_value_mut();
18
19				*count += 1;
20				Symbol::new(ptr.clone())
21			}
22			RawEntryMut::Vacant(ve) => {
23				let boxed = value.to_vec().into_boxed_slice();
24				let ptr = SymbolPtr::leaked(Box::leak(boxed));
25
26				ve.insert_hashed_nocheck(hash, ptr.clone(), 1);
27				Symbol::new(ptr)
28			}
29		}
30	}
31}
32
33impl Pool<str> {
34	pub fn intern(value: impl AsRef<str>) -> Symbol<str> {
35		let symbol = Pool::<[u8]>::intern(value.as_ref().as_bytes());
36		Symbol::new(symbol.into_ptr())
37	}
38}