Page MenuHomePhorge

No OneTemporary

diff --git a/.gitignore b/.gitignore
index d4be7ab..ce5edeb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,8 @@
build
target
.cache
compile_commands.json
.luacheckcache
benchmarks
flamegraph*
+perf.data*
diff --git a/rust/lib.rs b/rust/lib.rs
index 0189f15..b1e6cf0 100644
--- a/rust/lib.rs
+++ b/rust/lib.rs
@@ -1,86 +1,87 @@
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<HashMap<String, Vec<String>>> = 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<String> {
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 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 {
- // Bail out early if the pattern is empty its never going to find anything
+ 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 String::new();
+ return output;
}
let files = get_files(&base_dir);
- let mut output = String::new();
let sorter_options = sorter::Options::new(pattern);
let files = sorter::sort_strings(sorter_options, files);
- for file in files.lock().unwrap().iter() {
+ for file in files.iter() {
output.push_str(&file.content);
output.push('\n');
}
output
}
diff --git a/rust/sorter.rs b/rust/sorter.rs
index cdb9983..83ba5b9 100644
--- a/rust/sorter.rs
+++ b/rust/sorter.rs
@@ -1,52 +1,59 @@
use super::matcher;
use super::thread_pool;
+use std::sync::mpsc;
use std::sync::Arc;
-use std::sync::Mutex;
pub struct Match {
pub score: i64,
pub content: String,
}
pub struct Options {
pub pattern: String,
pub minimun_score: i64,
}
impl Options {
pub fn new(pattern: String) -> Self {
Self {
pattern,
minimun_score: 20,
}
}
}
-pub fn sort_strings(options: Options, strings: Vec<String>) -> Arc<Mutex<Vec<Match>>> {
- let matches: Arc<Mutex<Vec<Match>>> = Arc::new(Mutex::new(Vec::new()));
- let matcher = Arc::new(Mutex::new(matcher::Matcher::new(options.pattern)));
+pub fn sort_strings(options: Options, strings: Vec<String>) -> Vec<Match> {
+ let mut matches = Vec::new();
+ let matcher = Arc::new(matcher::Matcher::new(options.pattern));
let pool = thread_pool::ThreadPool::new(std::thread::available_parallelism().unwrap().get());
+ let (tx, rx) = mpsc::channel::<Match>();
+
for string in strings {
let thread_matcher = Arc::clone(&matcher);
- let thread_matches = Arc::clone(&matches);
+ let thread_transmitter = tx.clone();
pool.execute(move || {
- let score = thread_matcher.lock().unwrap().score(string.to_string());
+ let score = thread_matcher.score(string.to_string());
if score > 25 {
- let mut tmp = thread_matches.lock().unwrap();
- let content = string.clone();
- tmp.push(Match { score, content });
+ thread_transmitter
+ .send(Match {
+ score,
+ content: string,
+ })
+ .expect("Failed to push data to channel");
}
})
}
drop(pool);
+ drop(tx);
- matches
- .lock()
- .unwrap()
- .sort_by(|a, b| a.score.cmp(&b.score));
+ while let Ok(result) = rx.recv() {
+ matches.push(result)
+ }
+
+ matches.sort_by(|a, b| a.score.cmp(&b.score));
matches
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Sep 12, 9:27 PM (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
7557
Default Alt Text
(4 KB)

Event Timeline