pub struct ArcInterner<T: ?Sized>(/* private fields */);
Expand description
An interner returning atomically reference-counted pointers to the interned data
Interned objects will be deallocated when there are no references to them
any more and shrink_to_fit()
is called on the interner
§Example
use refcount_interner::ArcInterner;
let mut interner = ArcInterner::new();
let x = interner.intern(42);
let y = interner.intern(1337);
assert_eq!(*x, 42);
assert_ne!(x, y);
assert!(Arc::ptr_eq(&x, &interner.intern(42)));
Implementations§
Source§impl<T: ?Sized + Hash + Eq> ArcInterner<T>
impl<T: ?Sized + Hash + Eq> ArcInterner<T>
Sourcepub fn new() -> ArcInterner<T>
pub fn new() -> ArcInterner<T>
Sourcepub fn try_intern(&self, t: &T) -> Option<Arc<T>>
pub fn try_intern(&self, t: &T) -> Option<Arc<T>>
Attempt to get a reference to an already interned object.
If the object has already been interned, an option containing a reference to the already interned object will be returned.
If the object has not yet been interned, None
will be returned.
§Example
let mut interner = ArcInterner::new();
let x = interner.intern(42);
assert_eq!(interner.try_intern(&42), Some(Arc::new(42)));
assert_eq!(interner.try_intern(&1337), None);
Sourcepub fn intern_boxed(&mut self, t: Box<T>) -> Arc<T>
pub fn intern_boxed(&mut self, t: Box<T>) -> Arc<T>
Intern a boxed object
This method must be used to intern unsized types, since unsized types
cannot be passed to intern()
. The two most common unsized types,
&[T]
and &str
can be interned with intern_slice()
and
intern_str()
as well.
If the object has already been interned, the passed object will be dropped and deallocated, and a reference to the already interned object will be returned.
If the object has not yet been interned, the passed object will be moved
into an Arc<T>
, remembered for future calls to intern()
, and
returned.
§Example
let mut interner = ArcInterner::new();
let x = Box::new(42);
let y = interner.intern_boxed(x);
assert_eq!(*y, 42);
Sourcepub fn shrink_to_fit(&mut self)
pub fn shrink_to_fit(&mut self)
Deallocate all interned objects that are no longer referenced and shrink the internal storage to fit.
§Example
let mut interner = ArcInterner::new();
let x = interner.intern(42);
let y = interner.intern(1337);
let z = y.clone();
drop(x);
drop(y);
interner.shrink_to_fit();
assert_eq!(interner.try_intern(&42), None);
assert_eq!(interner.try_intern(&1337), Some(Arc::new(1337)));
Source§impl<T: Sized + Hash + Eq> ArcInterner<T>
impl<T: Sized + Hash + Eq> ArcInterner<T>
Sourcepub fn intern(&mut self, t: T) -> Arc<T>
pub fn intern(&mut self, t: T) -> Arc<T>
Intern an owned object
If the object has already been interned, the passed object will be dropped, and a reference to the already interned object will be returned.
If the object has not yet been interned, the passed object will be moved
into an Arc<T>
, remembered for future calls to intern()
, and
returned.
§Example
let mut interner = ArcInterner::new();
let x = interner.intern(42);
let y = interner.intern(1337);
assert_eq!(*x, 42);
assert_ne!(x, y);
assert!(Arc::ptr_eq(&x, &interner.intern(42)));
Source§impl<T: Sized + Hash + Eq + Clone> ArcInterner<T>
impl<T: Sized + Hash + Eq + Clone> ArcInterner<T>
Sourcepub fn intern_cloned(&mut self, t: &T) -> Arc<T>
pub fn intern_cloned(&mut self, t: &T) -> Arc<T>
Intern a borrowed object, cloning if it has not yet been interned
If the object has already been interned, a reference to the already interned object will be returned.
If the object has not yet been interned, the passed object will be moved
into an Arc<T>
, remembered for future calls to intern()
, and
returned.
§Example
let mut interner = ArcInterner::new();
let x = 42;
let y = interner.intern_cloned(&x);
assert_eq!(x, *y);
Source§impl<T: Sized + Hash + Eq + Clone> ArcInterner<[T]>
impl<T: Sized + Hash + Eq + Clone> ArcInterner<[T]>
Sourcepub fn intern_slice(&mut self, t: &[T]) -> Arc<[T]>
pub fn intern_slice(&mut self, t: &[T]) -> Arc<[T]>
Intern a slice object
This method can be used to intern slices without boxing them.
If the slice has already been interned, a reference to the already interned slice will be returned.
If the slice has not yet been interned, the passed object will be
cloned into an Arc<[T]>
, remembered for future calls to intern()
,
and returned.
§Example
let mut interner = ArcInterner::new();
let x = interner.intern_slice(&[1, 2, 3]);
assert_eq!(x.as_ref(), &[1, 2, 3]);
Sourcepub fn intern_vec(&mut self, t: Vec<T>) -> Arc<[T]>
pub fn intern_vec(&mut self, t: Vec<T>) -> Arc<[T]>
Intern an owned vector
If the slice behind the vector has already been interned, a reference to the already / interned slice will be returned.
If the slice has not yet been interned, the passed vector will be moved
into an Arc<[T]>
, remembered for future calls to intern()
, and
returned.
§Example
let mut interner = ArcInterner::new();
let v = vec![1, 2, 3];
let x = interner.intern_vec(v);
assert_eq!(x.as_ref(), &[1, 2, 3]);
Source§impl ArcInterner<str>
impl ArcInterner<str>
Sourcepub fn intern_str(&mut self, t: &str) -> Arc<str>
pub fn intern_str(&mut self, t: &str) -> Arc<str>
Intern a string slice
This method can be used to intern string slices without boxing them.
If the string slice has already been interned, a reference to the already interned string slice will be returned.
If the string slice has not yet been interned, the passed object will be
cloned into an Arc<str>
, remembered for future calls to intern()
,
and returned.
§Example
let mut interner = ArcInterner::new();
let x = interner.intern_str("hello");
assert_eq!(x.as_ref(), "hello");
Sourcepub fn intern_string(&mut self, t: String) -> Arc<str>
pub fn intern_string(&mut self, t: String) -> Arc<str>
Intern an owned string
If the string has already been interned, a reference to the already interned string slice will be returned.
If the string has not yet been interned, the passed string will be moved
into an Arc<str>
, remembered for future calls to intern()
, and
returned.
§Example
let mut interner = ArcInterner::new();
let s = String::from("hello");
let x = interner.intern_string(s);
assert_eq!(x.as_ref(), "hello");