elements_frequency/
interface.rs1use num_cpus;
2use rayon_core::scope;
3use std::collections::HashMap;
4use std::fmt::Debug;
5use std::hash::{BuildHasherDefault, Hash};
6use std::sync::Mutex;
7use twox_hash::XxHash64;
8
9#[allow(clippy::drop_copy)]
10pub fn frequency_finder<T>(list: &[T]) -> HashMap<T, u64, BuildHasherDefault<XxHash64>>
19where
20 T: Copy + Hash + Eq + Sync + Send + Debug,
21{
22 let logical_cores = num_cpus::get();
24 let range: usize = list.len() / logical_cores;
26 let split_index: usize = logical_cores * range;
29 let remainder: usize = list.len() % logical_cores;
31
32 let map_mtx: Mutex<HashMap<T, u64, BuildHasherDefault<XxHash64>>> =
34 Mutex::new(Default::default());
35 let map_ref = &map_mtx;
37
38 scope(|s| {
39 for idx in 1..=logical_cores {
40 s.spawn(move |_| {
41 let mut map_guard = map_ref.lock().unwrap();
42
43 for item in list.iter().take(idx * range).skip((idx - 1) * range) {
44 match map_guard.get_mut(item) {
45 Some(val) => *val += 1,
47 None => drop(map_guard.insert(*item, 1)),
49 }
50 }
51 });
52 }
53
54 s.spawn(move |_| {
56 let mut map_guard = map_ref.lock().unwrap();
57
58 for item in list.iter().skip(split_index).take(remainder) {
59 match map_guard.get_mut(item) {
60 Some(val) => *val += 1,
61
62 None => drop(map_guard.insert(*item, 1)),
63 }
64 }
65 })
66 });
67
68 Mutex::into_inner(map_mtx).unwrap()
69}