110110use std:: hash:: Hash ;
111111
112112use crate :: ds:: ClockRing ;
113+ use crate :: ds:: clock_ring:: { IntoIter , Iter , IterMut } ;
113114use crate :: traits:: { CoreCache , MutableCache , ReadOnlyCache } ;
114115
115116#[ cfg( feature = "metrics" ) ]
@@ -143,10 +144,7 @@ use crate::metrics::traits::MetricsSnapshotProvider;
143144/// assert_eq!(cache.get(&"key1"), Some(&"value1"));
144145/// assert_eq!(cache.len(), 2);
145146/// ```
146- pub struct ClockCache < K , V >
147- where
148- K : Clone + Eq + Hash ,
149- {
147+ pub struct ClockCache < K , V > {
150148 ring : ClockRing < K , V > ,
151149 #[ cfg( feature = "metrics" ) ]
152150 metrics : ClockMetrics ,
@@ -158,6 +156,10 @@ where
158156{
159157 /// Creates a new Clock cache with the specified capacity.
160158 ///
159+ /// A capacity of `0` is valid and produces a cache that accepts no entries;
160+ /// all [`insert`](CoreCache::insert) calls will return `None` and the
161+ /// value is silently dropped.
162+ ///
161163 /// # Example
162164 ///
163165 /// ```
@@ -178,21 +180,106 @@ where
178180 }
179181
180182 /// Returns `true` if the cache is empty.
183+ ///
184+ /// # Example
185+ ///
186+ /// ```
187+ /// use cachekit::policy::clock::ClockCache;
188+ /// use cachekit::traits::{CoreCache, ReadOnlyCache};
189+ ///
190+ /// let mut cache = ClockCache::new(10);
191+ /// assert!(cache.is_empty());
192+ ///
193+ /// cache.insert("a", 1);
194+ /// assert!(!cache.is_empty());
195+ /// ```
181196 #[ inline]
182197 pub fn is_empty ( & self ) -> bool {
183198 self . ring . is_empty ( )
184199 }
185200
201+ /// Returns an iterator over `(&K, &V)` pairs in slot order.
202+ ///
203+ /// Does **not** set reference bits.
204+ ///
205+ /// # Example
206+ ///
207+ /// ```
208+ /// use cachekit::policy::clock::ClockCache;
209+ /// use cachekit::traits::CoreCache;
210+ ///
211+ /// let mut cache = ClockCache::new(10);
212+ /// cache.insert("a", 1);
213+ /// cache.insert("b", 2);
214+ ///
215+ /// let pairs: Vec<_> = cache.iter().collect();
216+ /// assert_eq!(pairs.len(), 2);
217+ /// ```
218+ #[ inline]
219+ pub fn iter ( & self ) -> Iter < ' _ , K , V > {
220+ self . ring . iter ( )
221+ }
222+
223+ /// Returns an iterator over `(&K, &mut V)` pairs in slot order.
224+ ///
225+ /// Does **not** set reference bits.
226+ ///
227+ /// # Example
228+ ///
229+ /// ```
230+ /// use cachekit::policy::clock::ClockCache;
231+ /// use cachekit::traits::CoreCache;
232+ ///
233+ /// let mut cache = ClockCache::new(10);
234+ /// cache.insert("a", 1);
235+ /// cache.insert("b", 2);
236+ ///
237+ /// for (_key, value) in cache.iter_mut() {
238+ /// *value += 10;
239+ /// }
240+ /// ```
241+ #[ inline]
242+ pub fn iter_mut ( & mut self ) -> IterMut < ' _ , K , V > {
243+ self . ring . iter_mut ( )
244+ }
245+
186246 /// Returns the underlying [`ClockRing`] for advanced operations.
187247 ///
188- /// This provides access to additional methods like `peek()`, `touch()`,
189- /// `peek_victim()`, and `pop_victim()`.
248+ /// Provides access to additional methods like [`ClockRing::peek`],
249+ /// [`ClockRing::touch`], [`ClockRing::peek_victim`], and
250+ /// [`ClockRing::pop_victim`].
251+ ///
252+ /// # Example
253+ ///
254+ /// ```
255+ /// use cachekit::policy::clock::ClockCache;
256+ /// use cachekit::traits::CoreCache;
257+ ///
258+ /// let mut cache = ClockCache::new(10);
259+ /// cache.insert("a", 1);
260+ ///
261+ /// // peek reads without setting the reference bit
262+ /// assert_eq!(cache.as_ring().peek(&"a"), Some(&1));
263+ /// ```
190264 #[ inline]
191265 pub fn as_ring ( & self ) -> & ClockRing < K , V > {
192266 & self . ring
193267 }
194268
195269 /// Returns a mutable reference to the underlying [`ClockRing`].
270+ ///
271+ /// # Example
272+ ///
273+ /// ```
274+ /// use cachekit::policy::clock::ClockCache;
275+ /// use cachekit::traits::CoreCache;
276+ ///
277+ /// let mut cache = ClockCache::new(10);
278+ /// cache.insert("a", 1);
279+ ///
280+ /// // touch sets the reference bit without returning the value
281+ /// assert!(cache.as_ring_mut().touch(&"a"));
282+ /// ```
196283 #[ inline]
197284 pub fn as_ring_mut ( & mut self ) -> & mut ClockRing < K , V > {
198285 & mut self . ring
@@ -317,6 +404,20 @@ where
317404 }
318405
319406 /// Clears all entries from the cache.
407+ ///
408+ /// # Example
409+ ///
410+ /// ```
411+ /// use cachekit::policy::clock::ClockCache;
412+ /// use cachekit::traits::{CoreCache, ReadOnlyCache};
413+ ///
414+ /// let mut cache = ClockCache::new(10);
415+ /// cache.insert("a", 1);
416+ /// cache.insert("b", 2);
417+ ///
418+ /// cache.clear();
419+ /// assert!(cache.is_empty());
420+ /// ```
320421 fn clear ( & mut self ) {
321422 self . ring . clear ( ) ;
322423 #[ cfg( feature = "metrics" ) ]
@@ -358,6 +459,20 @@ where
358459 K : Clone + Eq + Hash ,
359460{
360461 /// Returns a snapshot of cache metrics.
462+ ///
463+ /// # Example
464+ ///
465+ /// ```
466+ /// use cachekit::policy::clock::ClockCache;
467+ /// use cachekit::traits::CoreCache;
468+ ///
469+ /// let mut cache = ClockCache::new(10);
470+ /// cache.insert("a", 1);
471+ /// cache.get(&"a");
472+ ///
473+ /// let snap = cache.metrics_snapshot();
474+ /// assert_eq!(snap.get_hits, 1);
475+ /// ```
361476 pub fn metrics_snapshot ( & self ) -> ClockMetricsSnapshot {
362477 ClockMetricsSnapshot {
363478 get_calls : self . metrics . get_calls ,
@@ -388,7 +503,7 @@ where
388503
389504impl < K , V > std:: fmt:: Debug for ClockCache < K , V >
390505where
391- K : Clone + Eq + Hash + std :: fmt :: Debug ,
506+ K : Clone + Eq + Hash ,
392507{
393508 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
394509 f. debug_struct ( "ClockCache" )
@@ -398,6 +513,71 @@ where
398513 }
399514}
400515
516+ impl < K , V > Clone for ClockCache < K , V >
517+ where
518+ K : Clone + Eq + Hash ,
519+ V : Clone ,
520+ {
521+ fn clone ( & self ) -> Self {
522+ Self {
523+ ring : self . ring . clone ( ) ,
524+ #[ cfg( feature = "metrics" ) ]
525+ metrics : self . metrics ,
526+ }
527+ }
528+ }
529+
530+ impl < K , V > AsRef < ClockRing < K , V > > for ClockCache < K , V > {
531+ fn as_ref ( & self ) -> & ClockRing < K , V > {
532+ & self . ring
533+ }
534+ }
535+
536+ impl < K , V > AsMut < ClockRing < K , V > > for ClockCache < K , V > {
537+ fn as_mut ( & mut self ) -> & mut ClockRing < K , V > {
538+ & mut self . ring
539+ }
540+ }
541+
542+ impl < K , V > IntoIterator for ClockCache < K , V >
543+ where
544+ K : Clone + Eq + Hash ,
545+ {
546+ type Item = ( K , V ) ;
547+ type IntoIter = IntoIter < K , V > ;
548+
549+ fn into_iter ( self ) -> Self :: IntoIter {
550+ self . ring . into_iter ( )
551+ }
552+ }
553+
554+ impl < ' a , K , V > IntoIterator for & ' a ClockCache < K , V > {
555+ type Item = ( & ' a K , & ' a V ) ;
556+ type IntoIter = Iter < ' a , K , V > ;
557+
558+ fn into_iter ( self ) -> Self :: IntoIter {
559+ self . ring . iter ( )
560+ }
561+ }
562+
563+ impl < ' a , K , V > IntoIterator for & ' a mut ClockCache < K , V > {
564+ type Item = ( & ' a K , & ' a mut V ) ;
565+ type IntoIter = IterMut < ' a , K , V > ;
566+
567+ fn into_iter ( self ) -> Self :: IntoIter {
568+ self . ring . iter_mut ( )
569+ }
570+ }
571+
572+ impl < K , V > Extend < ( K , V ) > for ClockCache < K , V >
573+ where
574+ K : Clone + Eq + Hash ,
575+ {
576+ fn extend < I : IntoIterator < Item = ( K , V ) > > ( & mut self , iter : I ) {
577+ self . ring . extend ( iter) ;
578+ }
579+ }
580+
401581#[ cfg( test) ]
402582mod tests {
403583 use super :: * ;
0 commit comments