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}