mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
perf: store only Urn instead of full Url in find results (#2914)
This commit is contained in:
parent
ab0fe93150
commit
1ed244a0a5
5 changed files with 47 additions and 21 deletions
|
|
@ -18,7 +18,7 @@ impl Tab {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
render!(finder.catchup(&self.current.files));
|
render!(finder.catchup(&self.current));
|
||||||
if opt.prev {
|
if opt.prev {
|
||||||
finder.prev(&self.current.files, self.current.cursor, false).map(|s| self.arrow(s));
|
finder.prev(&self.current.files, self.current.cursor, false).map(|s| self.arrow(s));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,29 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use yazi_fs::{Files, Filter, FilterCase};
|
use yazi_fs::{Files, Filter, FilterCase};
|
||||||
use yazi_shared::url::Url;
|
use yazi_shared::url::{Url, Urn, UrnBuf};
|
||||||
|
|
||||||
|
use crate::tab::Folder;
|
||||||
|
|
||||||
pub struct Finder {
|
pub struct Finder {
|
||||||
pub filter: Filter,
|
pub filter: Filter,
|
||||||
matched: HashMap<Url, u8>,
|
pub matched: HashMap<UrnBuf, u8>,
|
||||||
revision: u64,
|
lock: FinderLock,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct FinderLock {
|
||||||
|
cwd: Url,
|
||||||
|
revision: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Finder {
|
impl Finder {
|
||||||
pub(super) fn new(s: &str, case: FilterCase) -> Result<Self> {
|
pub(super) fn new(s: &str, case: FilterCase) -> Result<Self> {
|
||||||
Ok(Self { filter: Filter::new(s, case)?, matched: Default::default(), revision: 0 })
|
Ok(Self {
|
||||||
|
filter: Filter::new(s, case)?,
|
||||||
|
matched: Default::default(),
|
||||||
|
lock: Default::default(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn prev(&self, files: &Files, cursor: usize, include: bool) -> Option<isize> {
|
pub(super) fn prev(&self, files: &Files, cursor: usize, include: bool) -> Option<isize> {
|
||||||
|
|
@ -35,19 +47,19 @@ impl Finder {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn catchup(&mut self, files: &Files) -> bool {
|
pub(super) fn catchup(&mut self, folder: &Folder) -> bool {
|
||||||
if self.revision == files.revision {
|
if self.lock == *folder {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
self.matched.clear();
|
self.matched.clear();
|
||||||
|
|
||||||
let mut i = 0u8;
|
let mut i = 0u8;
|
||||||
for file in files.iter() {
|
for file in folder.files.iter() {
|
||||||
if !self.filter.matches(file.name()) {
|
if !self.filter.matches(file.name()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.matched.insert(file.url_owned(), i);
|
self.matched.insert(file.urn_owned(), i);
|
||||||
if self.matched.len() > 99 {
|
if self.matched.len() > 99 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -55,15 +67,27 @@ impl Finder {
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.revision = files.revision;
|
self.lock = folder.into();
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Finder {
|
impl Finder {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn matched(&self) -> &HashMap<Url, u8> { &self.matched }
|
pub fn matched_idx(&self, folder: &Folder, urn: &Urn) -> Option<u8> {
|
||||||
|
if self.lock == *folder { self.matched.get(urn).copied() } else { None }
|
||||||
#[inline]
|
}
|
||||||
pub fn matched_idx(&self, url: &Url) -> Option<u8> { self.matched.get(url).copied() }
|
}
|
||||||
|
|
||||||
|
// --- Lock
|
||||||
|
impl From<&Folder> for FinderLock {
|
||||||
|
fn from(value: &Folder) -> Self {
|
||||||
|
Self { cwd: value.url.clone(), revision: value.files.revision }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq<Folder> for FinderLock {
|
||||||
|
fn eq(&self, other: &Folder) -> bool {
|
||||||
|
self.revision == other.files.revision && self.cwd == other.url
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,11 +125,11 @@ impl UserData for File {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(idx) = finder.matched_idx(&me.url) else {
|
let Some(idx) = finder.matched_idx(&me.folder, me.urn()) else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(lua.create_sequence_from([idx.into_lua(lua)?, finder.matched().len().into_lua(lua)?]))
|
Some(lua.create_sequence_from([idx.into_lua(lua)?, finder.matched.len().into_lua(lua)?]))
|
||||||
.transpose()
|
.transpose()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,13 @@ impl Filter {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn matches(&self, name: &OsStr) -> bool { self.regex.is_match(name.as_encoded_bytes()) }
|
pub fn matches(&self, name: impl AsRef<OsStr>) -> bool {
|
||||||
|
self.regex.is_match(name.as_ref().as_encoded_bytes())
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn highlighted(&self, name: &OsStr) -> Option<Vec<Range<usize>>> {
|
pub fn highlighted(&self, name: impl AsRef<OsStr>) -> Option<Vec<Range<usize>>> {
|
||||||
self.regex.find(name.as_encoded_bytes()).map(|m| vec![m.range()])
|
self.regex.find(name.as_ref().as_encoded_bytes()).map(|m| vec![m.range()])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ impl Partitions {
|
||||||
if mem::replace(&mut me.write().need_update, true) {
|
if mem::replace(&mut me.write().need_update, true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Self::update(me.clone(), move || _ = cb());
|
Self::update(me.clone(), cb);
|
||||||
});
|
});
|
||||||
Box::into_raw(Box::new(boxed)) as *mut c_void
|
Box::into_raw(Box::new(boxed)) as *mut c_void
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue