perf: store only Urn instead of full Url in find results (#2914)

This commit is contained in:
三咲雅 misaki masa 2025-06-24 13:13:51 +08:00 committed by GitHub
parent ab0fe93150
commit 1ed244a0a5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 47 additions and 21 deletions

View file

@ -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 {

View file

@ -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
}
} }

View file

@ -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()
}) })
}); });

View file

@ -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()])
} }
} }

View file

@ -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
}; };