Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F31219
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Sep 12, 9:27 PM (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
7557
Default Alt Text
(4 KB)
Attached To
Mode
R1 ivy.nvim
Attached
Detach File
Event Timeline
Log In to Comment