1use std::sync::Mutex;
2
3static MATCHERS: Mutex<Vec<nucleo::Matcher>> = Mutex::new(Vec::new());
4
5pub const LENGTH_PENALTY: f64 = 0.01;
6
7fn pool_cap() -> usize {
8 std::thread::available_parallelism()
9 .map(|n| n.get())
10 .unwrap_or(8)
11 .max(1)
12}
13
14pub fn get_matcher(config: nucleo::Config) -> nucleo::Matcher {
15 let mut matchers = MATCHERS.lock().unwrap_or_else(|e| e.into_inner());
16 match matchers.pop() {
17 Some(mut matcher) => {
18 matcher.config = config;
19 matcher
20 }
21 None => nucleo::Matcher::new(config),
22 }
23}
24
25pub fn return_matcher(matcher: nucleo::Matcher) {
26 let mut pool = MATCHERS.lock().unwrap_or_else(|e| e.into_inner());
27 if pool.len() < pool_cap() {
28 pool.push(matcher);
29 }
30}
31
32pub fn get_matchers(n: usize, config: nucleo::Config) -> Vec<nucleo::Matcher> {
33 let mut matchers: Vec<_> = {
34 let mut pool = MATCHERS.lock().unwrap_or_else(|e| e.into_inner());
35 let available = pool.len().min(n);
36 pool.drain(..available)
37 .map(|mut matcher| {
38 matcher.config = config.clone();
39 matcher
40 })
41 .collect()
42 };
43 matchers.resize_with(n, || nucleo::Matcher::new(config.clone()));
44 matchers
45}
46
47pub fn return_matchers(matchers: Vec<nucleo::Matcher>) {
48 let cap = pool_cap();
49 let mut pool = MATCHERS.lock().unwrap_or_else(|e| e.into_inner());
50 let space = cap.saturating_sub(pool.len());
51 pool.extend(matchers.into_iter().take(space));
52}