+extern crate futures;
+extern crate futures_cpupool;
+extern crate void;
+
+use std::borrow::Borrow;
use std::collections::HashMap;
-use std::sync::{Arc,RwLock};
-use std::thread;
+use std::sync::{Arc, RwLock};
-fn poll_for(mapping: Arc<RwLock<HashMap<i32, Arc<RwLock<i32>>>>>, key: i32) -> Arc<RwLock<i32>> {
- loop {
- match mapping.read().unwrap().get(&key) {
- Some(i) => return i.clone(),
- None => ()
- }
+use futures::future::{BoxFuture, Future, lazy, ok, Shared, SharedItem, SharedError};
+
+type MyShared = Shared<Future<Item=i32, Error=void::Void>>;
+
+struct CachingMap(Arc<RwLock<HashMap<i32, MyShared>>>);
+
+impl Clone for CachingMap {
+ fn clone(&self) -> CachingMap {
+ CachingMap(self.0.clone())
}
}
-fn q(mapping: Arc<RwLock<HashMap<i32, Arc<RwLock<i32>>>>>, key: i32) -> i32 {
- println!("Running for {:?}", key);
- {
- match mapping.read().unwrap().get(&key) {
- Some(i) => return *i.read().unwrap(),
- None => ()
+impl CachingMap {
+ fn new() -> CachingMap {
+ CachingMap(Arc::new(RwLock::new(HashMap::new())))
+ }
+
+ fn q_basis() -> CachingMap {
+ let caching_map = CachingMap::new();
+ let clone = caching_map.0.clone();
+ let mut mapping = clone.write().unwrap();
+ mapping.insert(1, ok(1).shared());
+ mapping.insert(2, ok(1).shared());
+ caching_map
+ }
+
+ fn q(&self, key: i32) -> MyShared {
+ {
+ match self.0.read().unwrap().get(&key) {
+ Some(value) => return value.clone(),
+ None => (),
+ }
}
- }
- {
- println!("Generating for {:?}", key);
- let lock = Arc::new(RwLock::new(0));
- let mut val = lock.write().unwrap();
+
{
use std::collections::hash_map::Entry::*;
- let mut mutable_mapping = mapping.write().unwrap();
- match mutable_mapping.entry(key) {
- Occupied(entry) => return *entry.get().read().unwrap(),
- Vacant(entry) => {entry.insert(lock.clone());}
+ let mut mapping = self.0.write().unwrap();
+ match mapping.entry(key) {
+ Occupied(entry) => entry.get(),
+ Vacant(entry) => entry.insert(self.calculate_q(key))
}
- println!("Inserted for {:?}", key);
}
- {
- let _mapping = mapping.clone();
- thread::spawn(move || {
- q(_mapping, key - 1);
- });
- }
- {
- let prev = poll_for(mapping.clone(), key - 1);
- let prev_prev = poll_for(mapping.clone(), key - 2);
- let first = poll_for(mapping.clone(), key - *prev.read().unwrap());
- let second = poll_for(mapping.clone(), key - *prev_prev.read().unwrap());
- *val = *first.read().unwrap() + *second.read().unwrap();
- }
- *val
+ }
+
+ fn calculate_q(&self, key: i32) -> MyShared {
+ let prev = lazy(|| self.q(key - 1));
+ let prev_prev = lazy(|| self.q(key - 2));
+ let first = prev.map(|q| self.q(key - q.unwrap()).wait());
+ let second = prev_prev.map(|q| self.q(key - q.unwrap()).wait());
+ first.join(second).map(|(first, second)| first.unwrap() + second.unwrap()).shared()
}
}
fn main() {
- let mut mapping = HashMap::new();
- mapping.insert(1, Arc::new(RwLock::new(1)));
- mapping.insert(2, Arc::new(RwLock::new(1)));
- let mapping = Arc::new(RwLock::new(mapping));
- println!("{:?}", q(mapping.clone(), 10));
- println!("{:?}", q(mapping.clone(), 10));
+ let cache = CachingMap::q_basis();
+ //println!("{:?}", cache.q(10));
+ //println!("{:?}", cache.q(10));
}
Comments