Created
July 19, 2020 19:24
-
-
Save alexgmcm/5d8c4e7b024ef255cf282daad3efdeb5 to your computer and use it in GitHub Desktop.
Why does input need a static lifetime even though I'm passing an Arc to the thread?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::HashMap; | |
//use std::sync::Mutex; | |
use std::sync::Arc; | |
use std::thread; | |
pub fn frequency(input: &[&str], worker_count: usize) -> HashMap<char, usize> { | |
let input_len = input.len(); | |
let lines_per_thread = ((input_len as f64) / (worker_count as f64)).ceil() as usize; | |
let mut thread_handles = vec![]; | |
/* | |
OLD - now we'll fold across thread results | |
// Create hashmap for letters counts, held by mutex | |
let m: Mutex<HashMap<char, usize>> = Mutex::new(HashMap::new()); | |
*/ | |
for i in 0..worker_count { | |
//Create worker_count threads and divide input between them. | |
let nlines; | |
if (i * lines_per_thread) + lines_per_thread > input_len { | |
nlines = lines_per_thread - 1; | |
} else { | |
nlines = lines_per_thread; | |
} | |
let input_arc = Arc::new(input); | |
let start_index = Arc::new(i * lines_per_thread); | |
let end_index = Arc::new((i * lines_per_thread) + nlines); | |
let handle = thread::spawn(move || { | |
let mut dict: HashMap<char, usize> = HashMap::new(); | |
let thread_input = &(*input_arc.clone())[*(start_index.clone())..*(end_index.clone())]; | |
// loop through input counting chars | |
for line in thread_input.iter() { | |
for c in line.chars() { | |
if dict.contains_key(&c) { | |
let old_val = dict.get(&c).unwrap().to_owned(); | |
dict.insert(c, old_val + 1); | |
} else { | |
let val: usize = 1; | |
dict.insert(c, val); | |
} | |
} | |
} | |
dict | |
}); | |
thread_handles.push(handle); | |
} | |
let result: Result<Vec<_>, _> = thread_handles.into_iter().map(|t| t.join()).collect(); | |
let result = result.unwrap(); | |
let ret_val: HashMap<char, usize> = result.into_iter().fold(HashMap::new(), |mut acc, x| { | |
for (k, v) in x.iter() { | |
if acc.contains_key(k) { | |
let old_val = acc.get(k).unwrap().to_owned(); | |
acc.insert(*k, old_val + v); | |
} else { | |
acc.insert(*k, *v); | |
} | |
} | |
acc | |
}); | |
/* unimplemented!( | |
"Count the frequency of letters in the given input '{:?}'. Ensure that you are using {} to process the input.", | |
input, | |
match worker_count { | |
1 => format!("1 worker"), | |
_ => format!("{} workers", worker_count), | |
} | |
); */ | |
return ret_val; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment