Simplify and fix narrow map

Filling the narrow map in parallel caused invalid indices.

Also narrow map can be simplified to a Vec since it anyways only maps continous
selection indices starting at 0 to entry indices.
This commit is contained in:
Armin Friedl 2021-10-26 20:16:45 +02:00
parent c382a121a5
commit 7a45982064
2 changed files with 20 additions and 35 deletions

View file

@ -35,7 +35,7 @@ pub struct Roftl {
sources: Vec<SourceRef>, sources: Vec<SourceRef>,
matcher: MatcherRef, matcher: MatcherRef,
entries: Vec<Entry>, entries: Vec<Entry>,
narrow_map: Mutex<HashMap<usize, usize>> narrow_map: Vec<usize>
} }
impl Roftl { impl Roftl {
@ -44,7 +44,7 @@ impl Roftl {
sources: vec![], sources: vec![],
matcher: PrefixMatcher::new(), matcher: PrefixMatcher::new(),
entries: vec![], entries: vec![],
narrow_map: Mutex::default() narrow_map: vec![]
} }
} }
@ -72,14 +72,13 @@ impl Roftl {
debug!("Entries {:?}", self.entries); debug!("Entries {:?}", self.entries);
} }
pub fn narrow(&self, input: &str) -> Vec<(&Entry, Vec<usize>)> { pub fn narrow(&mut self, input: &str) -> Vec<(&Entry, Vec<usize>)> {
let count = Arc::new(AtomicUsize::new(0));
self.narrow_map.lock().unwrap().clear();
let mut scored_entries: Vec<(f64, usize, &Entry, Vec<usize>)> = self.entries let mut scored_entries: Vec<(f64, usize, &Entry, Vec<usize>)> = self.entries
.par_iter() .par_iter()
.enumerate() .enumerate()
.filter_map(|(idx, entry)| { .filter_map(|(idx, entry)| {
if input.is_empty() { return Some((0.0, idx, entry, vec![])) }
let match_result = self.matcher.try_match(&entry.name, input); let match_result = self.matcher.try_match(&entry.name, input);
return match_result.map(|(score, indices)| (score, idx, entry, indices) ) return match_result.map(|(score, indices)| (score, idx, entry, indices) )
}) })
@ -88,11 +87,10 @@ impl Roftl {
scored_entries scored_entries
.par_sort_by(|e1, e2| e1.0.partial_cmp(&e2.0).unwrap()); .par_sort_by(|e1, e2| e1.0.partial_cmp(&e2.0).unwrap());
scored_entries self.narrow_map.clear();
.par_iter() for se in &scored_entries {
.for_each(|se| { self.narrow_map.push(se.1)
self.narrow_map.lock().unwrap().insert(count.fetch_add(1, Ordering::Relaxed), se.1); }
});
scored_entries scored_entries
.par_iter() .par_iter()
@ -100,11 +98,10 @@ impl Roftl {
.collect() .collect()
} }
pub fn action(&self, entry_id: usize, action: Action) { pub fn action(&self, selection_id: usize, action: Action) {
debug!{"NarrowMap {:?}", self.narrow_map.lock().unwrap()}; let entry_id = self.narrow_map[selection_id];
let entry = &self.entries[entry_id];
let real_id = *self.narrow_map.lock().unwrap().get(&entry_id).unwrap(); debug!{"Got entry {:?} for id {} ", entry, entry_id};
let entry = self.entries.get(real_id).unwrap();
let source = self let source = self
.sources .sources
@ -112,6 +109,6 @@ impl Roftl {
.find(|&s| s.name().eq(entry.source)) .find(|&s| s.name().eq(entry.source))
.unwrap(); .unwrap();
source.action(entry, action); source.action(&entry, action);
} }
} }

View file

@ -1,7 +1,7 @@
use std::{os::unix::prelude::CommandExt, process::{Command, Stdio}}; use std::{os::unix::prelude::CommandExt, process::{Command, Stdio}};
use freedesktop_entry_parser as parser; use freedesktop_entry_parser as parser;
use log::{debug, error}; use log::{debug, error, trace};
use walkdir::WalkDir; use walkdir::WalkDir;
use nix::unistd::{getpid, setpgid}; use nix::unistd::{getpid, setpgid};
@ -14,18 +14,6 @@ struct App {
terminal: bool terminal: bool
} }
fn with_term<'a>(term_cmd: &'a Option<String>, exec: &'a str,) {
if let Some(term) = term_cmd {
let mut args: Vec<&str> =
term.split(' ').chain(exec.split(' ')).collect();
let term = args.remove(0).to_owned();
} else {
let term = std::env::var("TERM").unwrap();
let mut args: Vec<&str> = exec.split(' ').collect();
args.insert(0, "-e");
}
}
pub fn parse_command_string<'a>(exec: &'a str) -> (String, Vec<String>) { pub fn parse_command_string<'a>(exec: &'a str) -> (String, Vec<String>) {
let mut iter = exec.split(' '); let mut iter = exec.split(' ');
let cmd = iter.next().expect("Empty Exec").to_owned(); let cmd = iter.next().expect("Empty Exec").to_owned();
@ -38,7 +26,7 @@ pub fn run_bg(mut command: Command) {
unsafe { unsafe {
command.pre_exec(|| { command.pre_exec(|| {
let pid = getpid(); let pid = getpid();
if let Err(e) = setpgid(pid, pid) { if let Err(_) = setpgid(pid, pid) {
error!{"Failed to set pgid of child process with pid {}", pid}; error!{"Failed to set pgid of child process with pid {}", pid};
} }
Ok(()) Ok(())
@ -122,13 +110,13 @@ impl Apps {
} }
fn strip_entry_args(exec: &str) -> String { fn strip_entry_args(exec: &str) -> String {
debug!{"Stripping {}", exec} trace!{"Stripping {}", exec}
let iter = exec.split(' '); let iter = exec.split(' ');
let result = iter.filter(|item| !item.starts_with('%')) let result = iter.filter(|item| !item.starts_with('%'))
.collect::<Vec<&str>>() .collect::<Vec<&str>>()
.join(" "); .join(" ");
debug!{"Stripped into {}", result} trace!{"Stripped into {}", result}
result result
} }
@ -183,7 +171,7 @@ impl Source for Apps {
} }
debug!{"Got desktop entries: {:?}", entries} trace!{"Got desktop entries: {:?}", entries}
entries entries
} }
@ -191,7 +179,7 @@ impl Source for Apps {
fn action(&self, entry: &Entry, action: Action) { fn action(&self, entry: &Entry, action: Action) {
debug!{"Got desktop entry {:?} for action", entry} debug!{"Got desktop entry {:?} for action", entry}
debug!{"Desktop entry has id {}", entry.identifier} debug!{"Desktop entry has id {}", entry.identifier}
debug!{"Apps has entries {:?}", self.entries} trace!{"Apps has entries {:?}", self.entries}
let app = self.entries.get(entry.identifier as usize).unwrap(); let app = self.entries.get(entry.identifier as usize).unwrap();
debug!{"Doing primary action {} for {}", app.name, app.command} debug!{"Doing primary action {} for {}", app.name, app.command}
app.run(); app.run();