diff --git a/rust/q_sequence/src/main.rs b/rust/q_sequence/src/main.rs new file mode 100644 --- /dev/null +++ b/rust/q_sequence/src/main.rs @@ -0,0 +1,59 @@ +use std::collections::HashMap; +use std::sync::{Arc,RwLock}; +use std::thread; + +fn poll_for(mapping: Arc>>>>, key: i32) -> Arc> { + loop { + match mapping.read().unwrap().get(&key) { + Some(i) => return i.clone(), + None => () + } + } +} + +fn q(mapping: &mut Arc>>>>, key: i32) -> i32 { + println!("Running for {:?}", key); + { + match mapping.read().unwrap().get(&key) { + Some(i) => return *i.read().unwrap(), + 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());} + } + println!("Inserted for {:?}", key); + } + { + let mut _mapping = mapping.clone(); + thread::spawn(move || { + q(&mut _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 main() { + let mut mapping = HashMap::new(); + mapping.insert(1, Arc::new(RwLock::new(1))); + mapping.insert(2, Arc::new(RwLock::new(1))); + let mut mapping = Arc::new(RwLock::new(mapping)); + println!("{:?}", q(&mut mapping, 10)); + println!("{:?}", q(&mut mapping, 10)); +}