+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>>>>, key: i32) -> Arc> { - 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>; + +struct CachingMap(Arc>>); + +impl Clone for CachingMap { + fn clone(&self) -> CachingMap { + CachingMap(self.0.clone()) } } -fn q(mapping: Arc>>>>, 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)); }