diff --git a/rust/lib.rs b/rust/lib.rs index 74bda52..e2aca28 100644 --- a/rust/lib.rs +++ b/rust/lib.rs @@ -1,87 +1,86 @@ mod finder; mod matcher; mod sorter; -mod thread_pool; use std::collections::HashMap; use std::ffi::CStr; use std::ffi::CString; use std::os::raw::{c_char, c_int}; use std::sync::Mutex; #[macro_use] extern crate lazy_static; lazy_static! { static ref GLOBAL_FILE_CACHE: Mutex>> = Mutex::new(HashMap::new()); } fn to_string(input: *const c_char) -> String { unsafe { CStr::from_ptr(input) } .to_str() .unwrap() .to_string() } fn get_files(directory: &String) -> Vec { let mut cache = GLOBAL_FILE_CACHE.lock().unwrap(); if !cache.contains_key(directory) { let finder_options = finder::Options { directory: directory.clone(), }; cache.insert(directory.clone(), finder::find_files(finder_options)); } return cache.get(directory).unwrap().to_vec(); } #[no_mangle] pub extern "C" fn ivy_init(c_base_dir: *const c_char) { let directory = to_string(c_base_dir); get_files(&directory); } #[no_mangle] pub extern "C" fn ivy_match(c_pattern: *const c_char, c_text: *const c_char) -> c_int { let pattern = to_string(c_pattern); let text = to_string(c_text); inner_match(pattern, text) } pub fn inner_match(pattern: String, text: String) -> i32 { let m = matcher::Matcher::new(pattern); m.score(text.as_str()) as i32 } #[no_mangle] pub extern "C" fn ivy_files(c_pattern: *const c_char, c_base_dir: *const c_char) -> *const c_char { let pattern = to_string(c_pattern); let directory = to_string(c_base_dir); let output = inner_files(pattern, directory); CString::new(output).unwrap().into_raw() } pub fn inner_files(pattern: String, base_dir: String) -> String { let mut output = String::new(); // Bail out early if the pattern is empty; it's never going to find anything if pattern.is_empty() { return output; } let files = get_files(&base_dir); let sorter_options = sorter::Options::new(pattern); let files = sorter::sort_strings(sorter_options, files); for file in files.iter() { output.push_str(&file.content); output.push('\n'); } output } diff --git a/rust/thread_pool.rs b/rust/thread_pool.rs deleted file mode 100644 index d2d287e..0000000 --- a/rust/thread_pool.rs +++ /dev/null @@ -1,87 +0,0 @@ -use std::sync::mpsc; -use std::sync::Arc; -use std::sync::Mutex; -use std::thread; - -enum Message { - NewJob(Job), - Terminate, -} - -pub struct ThreadPool { - jobs: mpsc::Sender, - threads: Vec, -} - -trait FnBox { - fn call_box(self: Box); -} - -impl FnBox for F { - fn call_box(self: Box) { - (*self)() - } -} - -type Job = Box; - -impl ThreadPool { - pub fn new(thread_count: usize) -> Self { - let (jobs, receiver) = mpsc::channel(); - let receiver = Arc::new(Mutex::new(receiver)); - - let mut threads: Vec = Vec::new(); - for id in 1..thread_count { - threads.push(Worker::new(id, Arc::clone(&receiver))); - } - - ThreadPool { jobs, threads } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - self.jobs.send(Message::NewJob(job)).unwrap(); - } -} - -impl Drop for ThreadPool { - fn drop(&mut self) { - for _ in &mut self.threads { - self.jobs.send(Message::Terminate).unwrap(); - } - - for worker in &mut self.threads { - if let Some(thread) = worker.thread.take() { - thread.join().unwrap(); - } - } - } -} - -struct Worker { - _id: usize, - thread: Option>, -} - -impl Worker { - fn new(id: usize, receiver: Arc>>) -> Worker { - let thread = thread::spawn(move || loop { - let message = receiver.lock().unwrap().recv().unwrap(); - - match message { - Message::NewJob(job) => job.call_box(), - Message::Terminate => { - break; - } - } - }); - - Worker { - _id: id, - thread: Some(thread), - } - } -}