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;
};
render!(finder.catchup(&self.current.files));
render!(finder.catchup(&self.current));
if opt.prev {
finder.prev(&self.current.files, self.current.cursor, false).map(|s| self.arrow(s));
} else {

View file

@ -2,17 +2,29 @@ use std::collections::HashMap;
use anyhow::Result;
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 filter: Filter,
matched: HashMap<Url, u8>,
revision: u64,
pub filter: Filter,
pub matched: HashMap<UrnBuf, u8>,
lock: FinderLock,
}
#[derive(Default)]
struct FinderLock {
cwd: Url,
revision: u64,
}
impl Finder {
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> {
@ -35,19 +47,19 @@ impl Finder {
None
}
pub(super) fn catchup(&mut self, files: &Files) -> bool {
if self.revision == files.revision {
pub(super) fn catchup(&mut self, folder: &Folder) -> bool {
if self.lock == *folder {
return false;
}
self.matched.clear();
let mut i = 0u8;
for file in files.iter() {
for file in folder.files.iter() {
if !self.filter.matches(file.name()) {
continue;
}
self.matched.insert(file.url_owned(), i);
self.matched.insert(file.urn_owned(), i);
if self.matched.len() > 99 {
break;
}
@ -55,15 +67,27 @@ impl Finder {
i += 1;
}
self.revision = files.revision;
self.lock = folder.into();
true
}
}
impl Finder {
#[inline]
pub fn matched(&self) -> &HashMap<Url, u8> { &self.matched }
#[inline]
pub fn matched_idx(&self, url: &Url) -> Option<u8> { self.matched.get(url).copied() }
pub fn matched_idx(&self, folder: &Folder, urn: &Urn) -> Option<u8> {
if self.lock == *folder { self.matched.get(urn).copied() } else { None }
}
}
// --- 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);
};
let Some(idx) = finder.matched_idx(&me.url) else {
let Some(idx) = finder.matched_idx(&me.folder, me.urn()) else {
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()
})
});

View file

@ -23,11 +23,13 @@ impl Filter {
}
#[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]
pub fn highlighted(&self, name: &OsStr) -> Option<Vec<Range<usize>>> {
self.regex.find(name.as_encoded_bytes()).map(|m| vec![m.range()])
pub fn highlighted(&self, name: impl AsRef<OsStr>) -> Option<Vec<Range<usize>>> {
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) {
return;
}
Self::update(me.clone(), move || _ = cb());
Self::update(me.clone(), cb);
});
Box::into_raw(Box::new(boxed)) as *mut c_void
};