Last active
March 17, 2023 20:57
-
-
Save ltbringer/0ebd783e38049f13f0bb27d8e3a47d9f to your computer and use it in GitHub Desktop.
Search numbers in a really long list.
This file contains hidden or 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::thread; | |
use std::sync::atomic::{Ordering, AtomicIsize}; | |
use std::sync::Arc; | |
use std::time::{Instant}; | |
fn parallel_search(sstables: &Vec<u8>, k: u8, n_threads: usize) -> isize { | |
let n_sstables = sstables.len(); | |
let mut handles = vec![]; | |
let early_exit = Arc::new(AtomicIsize::new(-1)); | |
let chunk_size = (n_sstables + n_threads - 1) / n_threads; | |
for i in 0..n_threads { | |
let mut sstables = sstables.clone(); | |
let early_exit = early_exit.clone(); | |
let handle = thread::spawn(move || { | |
let start = i * chunk_size; | |
let end = std::cmp::min(n_sstables, start + chunk_size); | |
for (j, sstable) in sstables.drain(start..end).enumerate() { | |
let x = early_exit.load(Ordering::Relaxed); | |
if x > (start + j) as isize && x != 0 { | |
println!("{} had an early exit because {} > {}!", i, x, j + start); | |
return; | |
} | |
if sstable == k && (start+j) as isize > x { | |
early_exit.store((start+j) as isize, Ordering::Relaxed); | |
} | |
} | |
}); | |
handles.push(handle); | |
} | |
for handle in handles { | |
handle.join().unwrap(); | |
} | |
early_exit.load(Ordering::Relaxed) | |
} | |
fn main() { | |
let start = Instant::now(); | |
let list = vec![26; 125_000_000]; | |
let result = parallel_search(&list, 26, 8); | |
let duration = start.elapsed(); | |
println!("{:?} produced in {:?}", result, duration); | |
assert_eq!(result, (list.len() - 1) as isize); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment