1+ //! This module helps you efficiently store and retrieve values using interning. 
2+ //! 
3+ //! Interning is a neat trick that keeps only one copy of identical values, saving memory 
4+ //! and making comparisons super fast. Here, we provide the `Interned<T>` struct and the `Internable` trait 
5+ //! to make interning easy for different data types. 
6+ //! 
7+ //! The `Interner` struct handles caching for common types like `String`, `PathBuf`, and `Vec<String>`, 
8+ //! while the `Cache` struct acts as a write-once storage for linking computation steps with their results. 
9+ //! 
10+ //! # Thread Safety 
11+ //! 
12+ //! We use `Mutex` to make sure interning and retrieval are thread-safe. But keep in mind—once a value is 
13+ //! interned, it sticks around for the entire lifetime of the program. 
14+ 
115use  std:: any:: { Any ,  TypeId } ; 
216use  std:: borrow:: Borrow ; 
317use  std:: cell:: RefCell ; 
@@ -12,6 +26,9 @@ use std::{fmt, mem};
1226
1327use  crate :: core:: builder:: Step ; 
1428
29+ /// Represents an interned value of type `T`, allowing for efficient comparisons and retrieval. 
30+ /// 
31+ /// This struct stores a unique index referencing the interned value within an internal cache. 
1532pub  struct  Interned < T > ( usize ,  PhantomData < * const  T > ) ; 
1633
1734impl < T :  Internable  + Default >  Default  for  Interned < T >  { 
@@ -111,6 +128,10 @@ impl<T: Internable + Ord> Ord for Interned<T> {
111128    } 
112129} 
113130
131+ /// A structure for managing the interning of values of type `T`. 
132+ /// 
133+ /// `TyIntern<T>` maintains a mapping between values and their interned representations, 
134+ /// ensuring that duplicate values are not stored multiple times. 
114135struct  TyIntern < T :  Clone  + Eq >  { 
115136    items :  Vec < T > , 
116137    set :  HashMap < T ,  Interned < T > > , 
@@ -123,6 +144,9 @@ impl<T: Hash + Clone + Eq> Default for TyIntern<T> {
123144} 
124145
125146impl < T :  Hash  + Clone  + Eq >  TyIntern < T >  { 
147+     /// Interns a borrowed value, ensuring it is stored uniquely. 
148+ /// 
149+ /// If the value has been previously interned, the same `Interned<T>` instance is returned. 
126150fn  intern_borrow < B > ( & mut  self ,  item :  & B )  -> Interned < T > 
127151    where 
128152        B :  Eq  + Hash  + ToOwned < Owned  = T >  + ?Sized , 
@@ -138,6 +162,9 @@ impl<T: Hash + Clone + Eq> TyIntern<T> {
138162        interned
139163    } 
140164
165+     /// Interns an owned value, storing it uniquely. 
166+ /// 
167+ /// If the value has been previously interned, the existing `Interned<T>` is returned. 
141168fn  intern ( & mut  self ,  item :  T )  -> Interned < T >  { 
142169        if  let  Some ( i)  = self . set . get ( & item)  { 
143170            return  * i; 
@@ -148,18 +175,27 @@ impl<T: Hash + Clone + Eq> TyIntern<T> {
148175        interned
149176    } 
150177
178+     /// Retrieves a reference to the interned value associated with the given `Interned<T>` instance. 
151179fn  get ( & self ,  i :  Interned < T > )  -> & T  { 
152180        & self . items [ i. 0 ] 
153181    } 
154182} 
155183
184+ /// A global interner for managing interned values of common types. 
185+ /// 
186+ /// This structure maintains caches for `String`, `PathBuf`, and `Vec<String>`, ensuring efficient storage 
187+ /// and retrieval of frequently used values. 
156188#[ derive( Default ) ]  
157189pub  struct  Interner  { 
158190    strs :  Mutex < TyIntern < String > > , 
159191    paths :  Mutex < TyIntern < PathBuf > > , 
160192    lists :  Mutex < TyIntern < Vec < String > > > , 
161193} 
162194
195+ /// Defines the behavior required for a type to be internable. 
196+ /// 
197+ /// Types implementing this trait must provide access to a static cache and define an `intern` method 
198+ /// that ensures values are stored uniquely. 
163199trait  Internable :  Clone  + Eq  + Hash  + ' static  { 
164200    fn  intern_cache ( )  -> & ' static  Mutex < TyIntern < Self > > ; 
165201
@@ -187,11 +223,15 @@ impl Internable for Vec<String> {
187223} 
188224
189225impl  Interner  { 
226+     /// Interns a string reference, ensuring it is stored uniquely. 
227+ /// 
228+ /// If the string has been previously interned, the same `Interned<String>` instance is returned. 
190229pub  fn  intern_str ( & self ,  s :  & str )  -> Interned < String >  { 
191230        self . strs . lock ( ) . unwrap ( ) . intern_borrow ( s) 
192231    } 
193232} 
194233
234+ /// A global instance of `Interner` that caches common interned values. 
195235pub  static  INTERNER :  LazyLock < Interner >  = LazyLock :: new ( Interner :: default) ; 
196236
197237/// This is essentially a `HashMap` which allows storing any type in its input and 
@@ -209,10 +249,12 @@ pub struct Cache(
209249) ; 
210250
211251impl  Cache  { 
252+     /// Creates a new empty cache. 
212253pub  fn  new ( )  -> Cache  { 
213254        Cache ( RefCell :: new ( HashMap :: new ( ) ) ) 
214255    } 
215256
257+     /// Stores the result of a computation step in the cache. 
216258pub  fn  put < S :  Step > ( & self ,  step :  S ,  value :  S :: Output )  { 
217259        let  mut  cache = self . 0 . borrow_mut ( ) ; 
218260        let  type_id = TypeId :: of :: < S > ( ) ; 
@@ -225,6 +267,7 @@ impl Cache {
225267        stepcache. insert ( step,  value) ; 
226268    } 
227269
270+     /// Retrieves a cached result for the given step, if available. 
228271pub  fn  get < S :  Step > ( & self ,  step :  & S )  -> Option < S :: Output >  { 
229272        let  mut  cache = self . 0 . borrow_mut ( ) ; 
230273        let  type_id = TypeId :: of :: < S > ( ) ; 
@@ -255,3 +298,6 @@ impl Cache {
255298        self . 0 . borrow ( ) . contains_key ( & TypeId :: of :: < S > ( ) ) 
256299    } 
257300} 
301+ 
302+ #[ cfg( test) ]  
303+ mod  tests; 
0 commit comments