33
44//! Concurrent caches for values.
55
6- #[ cfg( test) ]
7- #[ path = "unit_tests/value_cache_tests.rs" ]
8- mod unit_tests;
9-
106#[ cfg( with_metrics) ]
117use std:: any:: type_name;
128use std:: { borrow:: Cow , hash:: Hash , num:: NonZeroUsize , sync:: Mutex } ;
139
14- use linera_base:: { crypto:: CryptoHash , hashed:: Hashed } ;
1510use lru:: LruCache ;
1611use quick_cache:: sync:: Cache ;
1712
13+ use crate :: { crypto:: CryptoHash , hashed:: Hashed } ;
14+
1815/// A counter metric for the number of cache hits in the [`ValueCache`].
1916#[ cfg( with_metrics) ]
2017mod metrics {
2118 use std:: sync:: LazyLock ;
2219
23- use linera_base:: prometheus_util:: register_int_counter_vec;
2420 use prometheus:: IntCounterVec ;
2521
22+ use crate :: prometheus_util:: register_int_counter_vec;
23+
2624 pub static CACHE_HIT_COUNT : LazyLock < IntCounterVec > = LazyLock :: new ( || {
2725 register_int_counter_vec (
2826 "value_cache_hit" ,
@@ -65,11 +63,27 @@ where
6563 }
6664 }
6765
66+ /// Inserts a value into the cache with the given key.
67+ /// Returns `true` if the value was newly inserted, `false` if it already existed.
68+ pub fn insert ( & self , key : K , value : V ) -> bool {
69+ if self . contains_key ( & key) {
70+ false
71+ } else {
72+ self . cache . insert ( key, value) ;
73+ true
74+ }
75+ }
76+
6877 /// Returns a `V` from the cache, if present.
6978 pub fn get ( & self , key : & K ) -> Option < V > {
7079 Self :: track_cache_usage ( self . cache . get ( key) )
7180 }
7281
82+ /// Returns `true` if the cache contains the given key.
83+ pub fn contains_key ( & self , key : & K ) -> bool {
84+ self . cache . get ( key) . is_some ( )
85+ }
86+
7387 fn track_cache_usage ( maybe_value : Option < V > ) -> Option < V > {
7488 #[ cfg( with_metrics) ]
7589 {
@@ -94,7 +108,7 @@ impl<T: Clone> ValueCache<CryptoHash, Hashed<T>> {
94108 /// inserted in the cache.
95109 ///
96110 /// Returns [`true`] if the value was not already present in the cache.
97- pub fn insert ( & self , value : Cow < Hashed < T > > ) -> bool {
111+ pub fn insert_hashed ( & self , value : Cow < Hashed < T > > ) -> bool {
98112 let hash = ( * value) . hash ( ) ;
99113 if self . cache . get ( & hash) . is_some ( ) {
100114 false
@@ -108,7 +122,7 @@ impl<T: Clone> ValueCache<CryptoHash, Hashed<T>> {
108122 ///
109123 /// The `values` are wrapped in [`Cow`]s so that each `value` is only cloned if it
110124 /// needs to be inserted in the cache.
111- #[ cfg( test ) ]
125+ #[ cfg( with_testing ) ]
112126 pub fn insert_all < ' a > ( & self , values : impl IntoIterator < Item = Cow < ' a , Hashed < T > > > )
113127 where
114128 T : ' a ,
@@ -122,7 +136,7 @@ impl<T: Clone> ValueCache<CryptoHash, Hashed<T>> {
122136 }
123137}
124138
125- #[ cfg( test ) ]
139+ #[ cfg( with_testing ) ]
126140impl < K , V > ValueCache < K , V >
127141where
128142 K : Hash + Eq + Clone ,
@@ -137,6 +151,11 @@ where
137151 pub fn len ( & self ) -> usize {
138152 self . cache . len ( )
139153 }
154+
155+ /// Returns [`true`] if the cache is empty.
156+ pub fn is_empty ( & self ) -> bool {
157+ self . cache . len ( ) == 0
158+ }
140159}
141160
142161/// A cache for values that need to be "parked" temporarily and taken out for exclusive use.
0 commit comments