Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: introduce URN to speed up large directory file sorting #1622

Merged
merged 4 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion yazi-adapter/src/ueberzug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ impl Ueberzug {
}

fn create_demon(adapter: Adapter) -> Result<Child> {
// TODO: demon
let result = Command::new("ueberzugpp")
.args(["layer", "-so", &adapter.to_string()])
.env("SPDLOG_LEVEL", if cfg!(debug_assertions) { "debug" } else { "" })
Expand Down
1 change: 1 addition & 0 deletions yazi-core/src/manager/commands/bulk_rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ impl Manager {
}
}

// FIXME: consider old and new in the different directories
if !succeeded.is_empty() {
Pubsub::pub_from_bulk(succeeded.iter().map(|(u, f)| (u, f.url())).collect());
FilesOp::Upserting(cwd, succeeded).emit();
Expand Down
4 changes: 2 additions & 2 deletions yazi-core/src/manager/commands/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ impl Manager {
// Refresh watcher
let mut to_watch = HashSet::with_capacity(3 * self.tabs.len());
for tab in self.tabs.iter() {
to_watch.insert(&tab.current.cwd);
to_watch.insert(tab.cwd());
if let Some(ref p) = tab.parent {
to_watch.insert(&p.cwd);
to_watch.insert(&p.loc);
}
if let Some(h) = tab.current.hovered().filter(|&h| h.is_dir()) {
to_watch.insert(h.url());
Expand Down
2 changes: 1 addition & 1 deletion yazi-core/src/manager/commands/open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ impl Manager {

let find = |folder: Option<&Folder>| {
folder.is_some_and(|folder| {
folder.cwd == p && folder.files.iter().any(|f| f.is_dir() && url == f.url())
p == *folder.loc && folder.files.iter().any(|f| f.is_dir() && url == f.url())
})
};

Expand Down
2 changes: 1 addition & 1 deletion yazi-core/src/manager/commands/tab_create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl Tabs {
} else {
tab.conf = self.active().conf.clone();
tab.apply_files_attrs();
tab.cd(self.active().current.cwd.clone());
tab.cd(self.active().cwd().clone());
}

self.items.insert(self.cursor + 1, tab);
Expand Down
8 changes: 4 additions & 4 deletions yazi-core/src/manager/commands/update_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ impl Manager {
let url = op.url();
tab.selected.apply_op(&op);

if tab.current.cwd == *url {
if url == tab.cwd() {
Self::update_current(tab, op, tasks);
} else if matches!(&tab.parent, Some(p) if p.cwd == *url) {
} else if matches!(&tab.parent, Some(p) if url == &*p.loc) {
Self::update_parent(tab, op);
} else if matches!(tab.current.hovered(), Some(h) if url == h.url()) {
Self::update_hovered(tab, op);
Expand All @@ -59,7 +59,7 @@ impl Manager {
}

fn update_parent(tab: &mut Tab, op: Cow<FilesOp>) {
let cwd = tab.current.cwd.clone();
let cwd = tab.cwd().clone();
let leave = matches!(*op, FilesOp::Deleting(_, ref urls) if urls.contains(&cwd));

if let Some(f) = tab.parent.as_mut() {
Expand Down Expand Up @@ -108,7 +108,7 @@ impl Manager {
}

fn update_history(tab: &mut Tab, op: Cow<FilesOp>) {
let leave = tab.parent.as_ref().and_then(|f| f.cwd.parent_url().map(|p| (&f.cwd, p))).is_some_and(
let leave = tab.parent.as_ref().and_then(|f| f.loc.parent_url().map(|p| (&f.loc, p))).is_some_and(
|(p, pp)| matches!(*op, FilesOp::Deleting(ref parent, ref urls) if *parent == pp && urls.contains(p)),
);

Expand Down
2 changes: 1 addition & 1 deletion yazi-core/src/manager/commands/update_paged.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl Manager {
return;
};

if opt.only_if.is_some_and(|u| u != self.current().cwd) {
if opt.only_if.is_some_and(|u| u != *self.active().cwd()) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion yazi-core/src/manager/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl Manager {

impl Manager {
#[inline]
pub fn cwd(&self) -> &Url { &self.current().cwd }
pub fn cwd(&self) -> &Url { &self.current().loc }

#[inline]
pub fn active(&self) -> &Tab { self.tabs.active() }
Expand Down
7 changes: 5 additions & 2 deletions yazi-core/src/manager/watcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,11 @@ impl Watcher {
}

pub(super) fn trigger_dirs(&self, folders: &[&Folder]) {
let todo: Vec<_> =
folders.iter().filter(|&f| f.cwd.is_regular()).map(|&f| (f.cwd.clone(), f.cha)).collect();
let todo: Vec<_> = folders
.iter()
.filter(|&f| f.loc.is_regular())
.map(|&f| (f.loc.url().clone(), f.cha))
.collect();
if todo.is_empty() {
return;
}
Expand Down
14 changes: 7 additions & 7 deletions yazi-core/src/tab/commands/cd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,33 +39,33 @@ impl Tab {
return self.cd_interactive();
}

if self.current.cwd == opt.target {
if opt.target == *self.cwd() {
return;
}

// Take parent to history
if let Some(rep) = self.parent.take() {
self.history.insert(rep.cwd.clone(), rep);
self.history.insert(rep.loc.url().clone(), rep);
}

// Current
let rep = self.history_new(&opt.target);
let rep = self.history.remove_or(&opt.target);
let rep = mem::replace(&mut self.current, rep);
if rep.cwd.is_regular() {
self.history.insert(rep.cwd.clone(), rep);
if rep.loc.is_regular() {
self.history.insert(rep.loc.url().clone(), rep);
}

// Parent
if let Some(parent) = opt.target.parent_url() {
self.parent = Some(self.history_new(&parent));
self.parent = Some(self.history.remove_or(&parent));
}

// Backstack
if opt.target.is_regular() {
self.backstack.push(opt.target.clone());
}

Pubsub::pub_from_cd(self.idx, &self.current.cwd);
Pubsub::pub_from_cd(self.idx, self.cwd());
ManagerProxy::refresh();
render!();
}
Expand Down
4 changes: 2 additions & 2 deletions yazi-core/src/tab/commands/escape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl Tab {
}

pub fn escape_search(&mut self) -> bool {
let b = self.current.cwd.is_search();
let b = self.cwd().is_search();
self.search_stop();

render_and!(b)
Expand All @@ -108,7 +108,7 @@ impl Tab {
let urls: Vec<_> =
indices.into_iter().filter_map(|i| self.current.files.get(i)).map(|f| f.url()).collect();

let same = !self.current.cwd.is_search();
let same = !self.cwd().is_search();
if !select {
self.selected.remove_many(&urls, same);
} else if self.selected.add_many(&urls, same) != urls.len() {
Expand Down
4 changes: 2 additions & 2 deletions yazi-core/src/tab/commands/leave.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ impl Tab {
.current
.hovered()
.and_then(|h| h.parent())
.filter(|p| *p != self.current.cwd)
.or_else(|| self.current.cwd.parent_url())
.filter(|p| p != self.cwd())
.or_else(|| self.cwd().parent_url())
.map(|u| self.cd(u));
}
}
7 changes: 3 additions & 4 deletions yazi-core/src/tab/commands/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,10 @@ impl Tab {
handle.abort();
}

let mut cwd = self.current.cwd.clone();
let cwd = self.cwd().to_search(&opt.subject);
let hidden = self.conf.show_hidden;

self.search = Some(tokio::spawn(async move {
cwd = cwd.into_search(opt.subject.clone());
let rx = if opt.via == SearchOptVia::Rg {
external::rg(external::RgOpt {
cwd: cwd.clone(),
Expand Down Expand Up @@ -82,8 +81,8 @@ impl Tab {
if let Some(handle) = self.search.take() {
handle.abort();
}
if self.current.cwd.is_search() {
let rep = self.history_new(&self.current.cwd.to_regular());
if self.cwd().is_search() {
let rep = self.history.remove_or(&self.cwd().to_regular());
drop(mem::replace(&mut self.current, rep));
ManagerProxy::refresh();
}
Expand Down
2 changes: 1 addition & 1 deletion yazi-core/src/tab/commands/select_all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl Tab {
None => iter.partition(|&u| self.selected.contains_key(u)),
};

let same = !self.current.cwd.is_search();
let same = !self.cwd().is_search();
render!(self.selected.remove_many(&removal, same) > 0);

let added = self.selected.add_many(&addition, same);
Expand Down
26 changes: 26 additions & 0 deletions yazi-core/src/tab/history.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use std::{collections::HashMap, ops::{Deref, DerefMut}};

use yazi_fs::Folder;
use yazi_shared::fs::Url;

#[derive(Default)]
pub struct History(HashMap<Url, Folder>);

impl Deref for History {
type Target = HashMap<Url, Folder>;

#[inline]
fn deref(&self) -> &Self::Target { &self.0 }
}

impl DerefMut for History {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}

impl History {
#[inline]
pub fn remove_or(&mut self, url: &Url) -> Folder {
self.0.remove(url).unwrap_or_else(|| Folder::from(url))
}
}
2 changes: 2 additions & 0 deletions yazi-core/src/tab/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod backstack;
mod commands;
mod config;
mod finder;
mod history;
mod mode;
mod preview;
mod selected;
Expand All @@ -10,6 +11,7 @@ mod tab;
pub use backstack::*;
pub use config::*;
pub use finder::*;
pub use history::*;
pub use mode::*;
pub use preview::*;
pub use selected::*;
Expand Down
17 changes: 8 additions & 9 deletions yazi-core/src/tab/tab.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap, iter};
use std::iter;

use anyhow::Result;
use ratatui::layout::Rect;
Expand All @@ -8,7 +8,7 @@ use yazi_config::{popup::{Origin, Position}, LAYOUT};
use yazi_fs::{Folder, FolderStage};
use yazi_shared::{fs::Url, render};

use super::{Backstack, Config, Finder, Mode, Preview};
use super::{Backstack, Config, Finder, History, Mode, Preview};
use crate::tab::Selected;

#[derive(Default)]
Expand All @@ -20,7 +20,7 @@ pub struct Tab {
pub parent: Option<Folder>,

pub backstack: Backstack<Url>,
pub history: HashMap<Url, Folder>,
pub history: History,
pub selected: Selected,

pub preview: Preview,
Expand All @@ -38,6 +38,9 @@ impl Tab {

impl Tab {
// --- Current
#[inline]
pub fn cwd(&self) -> &Url { &self.current.loc }

pub fn hovered_rect(&self) -> Option<Rect> {
let y = self.current.files.position(self.current.hovered()?.url())? - self.current.offset;

Expand Down Expand Up @@ -83,10 +86,6 @@ impl Tab {
}

// --- History
#[inline]
pub fn history_new(&mut self, url: &Url) -> Folder {
self.history.remove(url).unwrap_or_else(|| Folder::from(url))
}

#[inline]
pub fn hovered_folder(&self) -> Option<&Folder> {
Expand All @@ -113,8 +112,8 @@ impl Tab {
apply(parent);

// The parent should always track the CWD
parent.hover(&self.current.cwd);
parent.tracing = parent.hovered().map(|h| h.url()) == Some(&self.current.cwd);
parent.hover(&self.current.loc);
parent.tracing = parent.hovered().map(|h| h.url()) == Some(&self.current.loc);
}

self
Expand Down
14 changes: 7 additions & 7 deletions yazi-fm/src/lives/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ impl File {
Ok(cx.manager.mimetype.get(me.url()).cloned())
});
reg.add_method("prefix", |lua, me, ()| {
if !me.folder().cwd.is_search() {
if !me.folder().loc.is_search() {
return Ok(None);
}

let mut p = me.url().strip_prefix(&me.folder().cwd).unwrap_or(me.url()).components();
let mut p = me.url().strip_prefix(&me.folder().loc).unwrap_or(me.url()).components();
p.next_back();
Some(lua.create_string(p.as_path().as_os_str().as_encoded_bytes())).transpose()
});
Expand All @@ -77,7 +77,7 @@ impl File {
});
reg.add_method("is_marked", |_, me, ()| {
use yazi_core::tab::Mode::*;
if !me.tab().mode.is_visual() || me.folder().cwd != me.tab().current.cwd {
if !me.tab().mode.is_visual() || me.folder().loc != me.tab().current.loc {
return Ok(0u8);
}

Expand All @@ -89,11 +89,11 @@ impl File {
});
reg.add_method("is_selected", |_, me, ()| Ok(me.tab().selected.contains_key(me.url())));
reg.add_method("in_parent", |_, me, ()| {
Ok(me.tab().parent.as_ref().is_some_and(|f| me.folder().cwd == f.cwd))
Ok(me.tab().parent.as_ref().is_some_and(|f| me.folder().loc == f.loc))
});
reg.add_method("in_current", |_, me, ()| Ok(me.folder().cwd == me.tab().current.cwd));
reg.add_method("in_current", |_, me, ()| Ok(me.folder().loc == me.tab().current.loc));
reg.add_method("in_preview", |_, me, ()| {
Ok(me.tab().current.hovered().is_some_and(|f| me.folder().cwd == *f.url()))
Ok(me.tab().current.hovered().is_some_and(|f| f.url() == &*me.folder().loc))
});
reg.add_method("found", |lua, me, ()| {
let cx = lua.named_registry_value::<CtxRef>("cx")?;
Expand All @@ -113,7 +113,7 @@ impl File {
let Some(finder) = &cx.manager.active().finder else {
return Ok(None);
};
if me.folder().cwd != me.tab().current.cwd {
if me.folder().loc != me.tab().current.loc {
return Ok(None);
}
let Some(h) = finder.filter.highlighted(me.name()) else {
Expand Down
2 changes: 1 addition & 1 deletion yazi-fm/src/lives/folder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl Folder {

pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
lua.register_userdata_type::<Self>(|reg| {
reg.add_field_method_get("cwd", |lua, me| Url::cast(lua, me.cwd.clone()));
reg.add_field_method_get("cwd", |lua, me| Url::cast(lua, me.loc.url().clone()));
reg.add_field_method_get("files", |_, me| Files::make(0..me.files.len(), me, me.tab()));
reg.add_field_method_get("stage", |lua, me| lua.create_any_userdata(me.stage));
reg.add_field_method_get("window", |_, me| Files::make(me.window.clone(), me, me.tab()));
Expand Down
10 changes: 1 addition & 9 deletions yazi-fm/src/lives/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,7 @@ impl Tab {
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
lua.register_userdata_type::<Self>(|reg| {
reg.add_method("name", |lua, me, ()| {
Some(
lua.create_string(
me.current
.cwd
.file_name()
.map_or(me.current.cwd.as_os_str().as_encoded_bytes(), |n| n.as_encoded_bytes()),
),
)
.transpose()
Some(lua.create_string(me.current.loc.name().as_encoded_bytes())).transpose()
});

reg.add_field_method_get("mode", |_, me| Mode::make(&me.mode));
Expand Down
Loading