cs431_homework/hello_server/cache.rs
1//! Thread-safe key/value cache.
2
3use std::collections::hash_map::{Entry, HashMap};
4use std::hash::Hash;
5use std::sync::{Arc, Mutex, RwLock};
6
7/// Cache that remembers the result for each key.
8#[derive(Debug)]
9pub struct Cache<K, V> {
10 // todo! This is an example cache type. Build your own cache type that satisfies the
11 // specification for `get_or_insert_with`.
12 inner: Mutex<HashMap<K, V>>,
13}
14
15impl<K, V> Default for Cache<K, V> {
16 fn default() -> Self {
17 Self {
18 inner: Mutex::new(HashMap::new()),
19 }
20 }
21}
22
23impl<K: Eq + Hash + Clone, V: Clone> Cache<K, V> {
24 /// Retrieve the value or insert a new one created by `f`.
25 ///
26 /// An invocation to this function should not block another invocation with a different key. For
27 /// example, if a thread calls `get_or_insert_with(key1, f1)` and another thread calls
28 /// `get_or_insert_with(key2, f2)` (`key1≠key2`, `key1,key2∉cache`) concurrently, `f1` and `f2`
29 /// should run concurrently.
30 ///
31 /// On the other hand, since `f` may consume a lot of resource (= money), it's undesirable to
32 /// duplicate the work. That is, `f` should be run only once for each key. Specifically, even
33 /// for concurrent invocations of `get_or_insert_with(key, f)`, `f` is called only once per key.
34 ///
35 /// Hint: the [`Entry`] API may be useful in implementing this function.
36 ///
37 /// [`Entry`]: https://doc.rust-lang.org/stable/std/collections/hash_map/struct.HashMap.html#method.entry
38 pub fn get_or_insert_with<F: FnOnce(K) -> V>(&self, key: K, f: F) -> V {
39 todo!()
40 }
41}