Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- +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));
- }
Advertisement
Add Comment
Please, Sign In to add comment