MCPcopy Create free account
hub / github.com/cosdata/cosdata / get_or_insert

Method get_or_insert

src/models/lru_cache.rs:236–274  ·  view source on GitHub ↗

Gets the value from the cache if it exists, else tries to insert the result of the fn `f` into the cache and returns the same

(
        &self,
        key: K,
        f: impl FnOnce() -> Result<V, E>,
    )

Source from the content-addressed store, hash-verified

234 /// insert the result of the fn `f` into the cache and returns the
235 /// same
236 pub fn get_or_insert<E>(
237 &self,
238 key: K,
239 f: impl FnOnce() -> Result<V, E>,
240 ) -> Result<CachedValue<V>, E> {
241 let mut inserted = false;
242 let k1 = key.clone();
243 let k2 = key.clone();
244 let res = self
245 .map
246 .entry(key)
247 .and_modify(|(_, counter)| {
248 let old_counter = *counter;
249 let new_counter = self.increment_counter();
250 self.index.on_cache_hit(old_counter, new_counter, k1.into());
251 *counter = new_counter;
252 })
253 .or_try_insert_with(|| {
254 inserted = true;
255 let counter = self.increment_counter();
256 self.index.on_cache_miss(counter, k2.into());
257 f().map(|v| (v, counter))
258 })
259 .map(|v| v.0.clone());
260 // @NOTE: We need to clone the value before calling
261 // `self.evict`, that too in a separate block! Otherwise
262 // it causes some deadlock
263 match res {
264 Ok(v) => {
265 if inserted {
266 self.evict();
267 Ok(CachedValue::Miss(v))
268 } else {
269 Ok(CachedValue::Hit(v))
270 }
271 }
272 Err(e) => Err(e),
273 }
274 }
275
276 fn evict(&self) {
277 if self.map.len() > self.capacity {

Callers 4

find_or_create_nodeMethod · 0.45
find_or_create_nodeMethod · 0.45
find_or_create_nodeMethod · 0.45
criterion_benchmarkFunction · 0.45

Calls 5

cloneMethod · 0.80
increment_counterMethod · 0.80
on_cache_hitMethod · 0.80
on_cache_missMethod · 0.80
evictMethod · 0.80

Tested by

no test coverage detected