Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@awsaba
Created December 13, 2016 21:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awsaba/96ec9f4d7004c111cb82eb67327f4bdc to your computer and use it in GitHub Desktop.
Save awsaba/96ec9f4d7004c111cb82eb67327f4bdc to your computer and use it in GitHub Desktop.
trait Resource: Read {}
trait Factory {
type R: Resource;
fn get(&self, index: u8) -> Result<Self::R, ()>;
}
#[derive(Clone)]
struct CacheEntry<R: Resource> {
value: Arc<Mutex<R>>,
}
struct Cache<F: Factory> {
factory: F,
map: RefCell<BTreeMap<u8, CacheEntry<F::R>>>,
}
impl<R: Resource> Resource for CacheEntry<R> {}
impl<R: Resource> Read for CacheEntry<R> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self.value.lock().unwrap().read(buf)
}
}
impl<F: Factory> Factory for Cache<F> {
type R = CacheEntry<F::R>;
fn get(&self, index: u8) -> Result<Self::R, ()> {
let mut map = self.map.borrow_mut();
match map.entry(index) {
Entry::Occupied(e) => Ok(CacheEntry { value: e.get().value.clone() }),
Entry::Vacant(v) => {
let resource = self.factory.get(index)?;
let entry = CacheEntry { value: Arc::new(Mutex::new(resource)) };
Ok(CacheEntry { value: v.insert(entry).value.clone() })
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment