summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2020-01-27 17:39:42 +0100
committerrabite <rabite@posteo.de>2020-01-27 17:39:42 +0100
commitc8e6ea51bba91e861898bc8c3ebf7b62868bdaad (patch)
tree076f19c2ef681e2e1da87b0df7a58a7c04c7490e
parent5899ee9b65485b91c44641101d0c4c727c6690a9 (diff)
further speed up creation of Files
-rw-r--r--src/file_browser.rs67
-rw-r--r--src/files.rs215
-rw-r--r--src/listview.rs4
3 files changed, 65 insertions, 221 deletions
diff --git a/src/file_browser.rs b/src/file_browser.rs
index 1ed031e..9361dce 100644
--- a/src/file_browser.rs
+++ b/src/file_browser.rs
@@ -476,22 +476,20 @@ impl FileBrowser {
self.prev_cwd = Some(self.cwd.clone());
self.cwd = dir.clone();
+ let file_source = FileSource::Path(self.cwd.clone());
- let main_async_widget = self.main_async_widget_mut()?;
- main_async_widget.change_to(move |stale: &Stale, core| {
- let (selected_file, files) = cache.get_files(&dir, stale.clone())?;
- let files = files.run_sync()?;
+ let main_async_widget = self.main_async_widget_mut()?;
+ main_async_widget.change_to(move |stale: &Stale, core| {
+ let view = ListView::builder(core, file_source)
+ .meta_all()
+ .prerender()
+ .with_cache(cache)
+ .with_stale(stale.clone())
+ .build()?;
- let mut list = ListView::new(&core, files);
+ Ok(view)
+ }).log();
- list.content.meta_set_fresh().log();
- list.content.meta_all();
-
- if let Some(file) = selected_file {
- list.select_file(&file);
- }
- Ok(list)
- }).log();
if let Ok(grand_parent) = self.cwd()?.parent_as_file() {
self.left_widget_goto(&grand_parent).log();
@@ -505,27 +503,28 @@ impl FileBrowser {
}
pub fn left_widget_goto(&mut self, dir: &File) -> HResult<()> {
- // Check if we're in the correct directory already and return
- // if we are
- let left_dir = &self.left_widget()?.content.directory;
- if self.left_widget().is_ok() && left_dir == dir {
- return Ok(());
- }
-
- let cache = self.fs_cache.clone();
- let dir = dir.clone();
-
- let left_async_widget = self.left_async_widget_mut()?;
- left_async_widget.change_to(move |stale, core| {
- let cached_files = cache.get_files(&dir, stale.clone())?;
- let (_, files) = cached_files;
-
- let files = files.run_sync()?;
-
- let list = ListView::new(&core, files);
- Ok(list)
- })?;
- Ok(())
+ // Check if we're in the correct directory already and return
+ // if we are
+ let left_dir = &self.left_widget()?.content.directory;
+ if self.left_widget().is_ok() && left_dir == dir {
+ return Ok(());
+ }
+
+ let cache = self.fs_cache.clone();
+ let file_source = FileSource::Path(dir.clone());
+ let left_async_widget = self.left_async_widget_mut()?;
+ left_async_widget.change_to(move |stale, core| {
+ let view = ListView::builder(core, file_source)
+ .meta_all()
+ .prerender()
+ .with_cache(cache)
+ .with_stale(stale.clone())
+ .build()?;
+
+ Ok(view)
+ }).log();
+
+ Ok(())
}
pub fn go_back(&mut self) -> HResult<()> {
diff --git a/src/files.rs b/src/files.rs
index 90e2bb5..25592de 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -344,8 +344,7 @@ impl Files {
None
} else {
let file = File::new_from_direntry(file,
- Some(dirty_meta.clone()),
- stale.clone());
+ Some(dirty_meta.clone()));
Some(file)
}
})
@@ -470,7 +469,7 @@ impl Files {
}
match (a.meta(), b.meta()) {
- (Ok(a_meta), Ok(b_meta)) => {
+ (Some(a_meta), Some(b_meta)) => {
match a_meta.size() == b_meta.size() {
true => compare_str(&b.name, &a.name),
false => b_meta.size()
@@ -496,7 +495,7 @@ impl Files {
}
match (a.meta(), b.meta()) {
- (Ok(a_meta), Ok(b_meta)) => {
+ (Some(a_meta), Some(b_meta)) => {
match a_meta.mtime() == b_meta.mtime() {
true => compare_str(&b.name, &a.name),
false => b_meta.mtime()
@@ -621,59 +620,22 @@ impl Files {
}
pub fn meta_all_sync(&mut self) -> HResult<()> {
+ let mut same = true;
+
for file in self.iter_files_mut() {
if !file.meta_processed {
file.meta_sync().log();
+ same = false;
}
}
- self.set_dirty();
- Ok(())
- }
-
- pub fn meta_all(&mut self) {
- let len = self.len();
- self.meta_upto(len, None);
- self.dirty_meta.set_dirty();
- self.meta_set_fresh().log();
- }
-
- pub fn meta_upto(&mut self, to: usize, sender: Option<Sender<Events>>) {
- let meta_files = if self.meta_upto > Some(to) {
- self.meta_upto.unwrap()
- } else {
- if to > self.len() {
- self.len()
- } else {
- to
- }
- };
-
- if self.meta_upto >= Some(meta_files) && !self.dirty_meta.is_dirty() { return }
-
- self.set_dirty();
- self.dirty_meta.set_clean();
- let meta_pool = make_pool(sender.clone());
-
- for file in self.iter_files_mut()
- .take(meta_files) {
- if !file.meta_processed {
- file.take_meta(&meta_pool).ok();
- }
- if file.is_dir() {
- file.take_dirsize(&meta_pool).ok();
- }
+ if !same {
+ self.set_dirty();
}
- self.meta_upto = Some(meta_files);
- }
-
- pub fn meta_set_fresh(&self) -> HResult<()> {
- self.iter_files().nth(0)?.meta.set_fresh()?;
Ok(())
}
-
pub fn set_filter(&mut self, filter: Option<String>) {
self.filter = filter;
@@ -771,10 +733,10 @@ pub struct File {
pub path: PathBuf,
pub hidden: bool,
pub kind: Kind,
- pub dirsize: Option<Async<usize>>,
+ pub dirsize: Option<usize>,
pub target: Option<PathBuf>,
pub color: Option<lscolors::Color>,
- pub meta: Async<Metadata>,
+ pub meta: Option<Metadata>,
pub dirty_meta: Option<AsyncDirtyBit>,
pub meta_processed: bool,
pub selected: bool,
@@ -787,19 +749,15 @@ impl File {
path: PathBuf,
dirty_meta: Option<AsyncDirtyBit>) -> File {
let hidden = name.starts_with(".");
- let meta = File::make_async_meta(&path, dirty_meta.clone(), None);
- let dirsize = if path.is_dir() {
- Some(File::make_async_dirsize(&path, dirty_meta.clone(), None))
- } else { None };
File {
name: name.to_string(),
hidden: hidden,
kind: if path.is_dir() { Kind::Directory } else { Kind::File },
path: path,
- dirsize: dirsize,
+ dirsize: None,
target: None,
- meta: meta,
+ meta: None,
meta_processed: false,
dirty_meta: dirty_meta,
color: None,
@@ -810,26 +768,17 @@ impl File {
pub fn new_with_stale(name: &str,
path: PathBuf,
- dirty_meta: Option<AsyncDirtyBit>,
- stale: Stale) -> File {
+ dirty_meta: Option<AsyncDirtyBit>) -> File {
let hidden = name.starts_with(".");
- let meta = File::make_async_meta(&path,
- dirty_meta.clone(),
- Some(stale.clone()));
- let dirsize = if path.is_dir() {
- Some(File::make_async_dirsize(&path,
- dirty_meta.clone(),
- Some(stale)))
- } else { None };
File {
name: name.to_string(),
hidden: hidden,
kind: if path.is_dir() { Kind::Directory } else { Kind::File },
path: path,
- dirsize: dirsize,
+ dirsize: None,
target: None,
- meta: meta,
+ meta: None,
meta_processed: false,
dirty_meta: dirty_meta,
color: None,
@@ -839,8 +788,7 @@ impl File {
}
pub fn new_from_direntry(direntry: std::fs::DirEntry,
- dirty_meta: Option<AsyncDirtyBit>,
- stale: Stale) -> File {
+ dirty_meta: Option<AsyncDirtyBit>) -> File {
let path = direntry.path();
let name = direntry.file_name()
.to_string_lossy()
@@ -855,25 +803,14 @@ impl File {
_ => Kind::Placeholder
};
- let meta = File::make_async_meta(&path,
- dirty_meta.clone(),
- Some(stale.clone()));
-
- let dirsize = match kind {
- Kind::Directory => Some(File::make_async_dirsize(&path,
- dirty_meta.clone(),
- Some(stale.clone()))),
- _ => None
- };
-
File {
name: name,
hidden: hidden,
kind: kind,
path: path,
- dirsize: dirsize,
+ dirsize: None,
target: None,
- meta: meta,
+ meta: None,
meta_processed: false,
dirty_meta: dirty_meta,
color: None,
@@ -907,104 +844,24 @@ impl File {
}
pub fn meta_sync(&mut self) -> HResult<()> {
- let stale = self.meta.get_stale();
- let meta = std::fs::metadata(&self.path)?;
- self.meta = Async::new_with_value(meta);
- self.meta.put_stale(stale);
+ let meta = std::fs::symlink_metadata(&self.path)?;
+ self.meta = Some(meta);
self.process_meta().log();
if self.is_dir() {
- let dirsize = self.dirsize
- .take()
- .map(|s| s.run_sync())??;
- self.dirsize = Some(Async::new_with_value(dirsize));
- }
-
- Ok(())
- }
-
- pub fn make_async_meta(path: &PathBuf,
- dirty_meta: Option<AsyncDirtyBit>,
- stale_preview: Option<Stale>) -> Async<Metadata> {
- let path = path.clone();
-
- let mut meta = Async::new(move |stale: &Stale| {
- if stale.is_stale()? { HError::stale()? }
- Ok(std::fs::symlink_metadata(&path)?)
- });
-
- stale_preview.map(|s| meta.put_stale(s));
-
- dirty_meta.map(|mut d|
- meta.on_ready(move |_,_| {
- d.set_dirty();
-
- Ok(())
- }).log()
- );
- meta
- }
-
- pub fn make_async_dirsize(path: &PathBuf,
- dirty_meta: Option<AsyncDirtyBit>,
- stale_preview: Option<Stale>) -> Async<usize> {
- let path = path.clone();
-
- let mut dirsize = Async::new(move |stale: &Stale| {
- if stale.is_stale()? { HError::stale()? }
- Ok(std::fs::read_dir(&path)?.count())
- });
-
- stale_preview.map(|s| dirsize.put_stale(s));
-
- dirty_meta.map(|mut d|
- dirsize.on_ready(move |_,_| {
- d.set_dirty();
-
- Ok(())
- }).log()
- );
- dirsize
- }
-
- pub fn meta(&self) -> HResult<&Metadata> {
- Ok(self.meta.get()?)
- }
-
- fn take_dirsize(&mut self,
- pool: &ThreadPool) -> HResult<()> {
- let dirsize = self.dirsize.as_mut()?;
- if let Ok(_) = dirsize.value { return Ok(()) }
-
- if !dirsize.is_running() && !dirsize.is_ready() {
- dirsize.run_pooled(Some(&*pool))?;
- }
-
- if dirsize.is_ready() {
- dirsize.pull_async()?;
+ let dirsize = std::fs::read_dir(&self.path)?.count();
+ self.dirsize = Some(dirsize);
}
Ok(())
}
- pub fn take_meta(&mut self,
- pool: &ThreadPool) -> HResult<()> {
- if self.meta_processed { return Ok(()) }
-
- if !self.meta.is_running() && !self.meta.is_ready() {
- self.meta.run_pooled(Some(&*pool))?;
- }
-
- if self.meta.is_ready() {
- self.meta.pull_async()?;
- self.process_meta()?;
- }
-
- Ok(())
+ pub fn meta(&self) -> Option<&Metadata> {
+ self.meta.as_ref()
}
pub fn process_meta(&mut self) -> HResult<()> {
- if let Ok(meta) = self.meta.get() {
+ if let Some(ref meta) = self.meta {
let color = self.get_color(&meta);
let target = if meta.file_type().is_symlink() {
self.path.read_link().ok()
@@ -1019,18 +876,7 @@ impl File {
pub fn reload_meta(&mut self) -> HResult<()> {
self.meta_processed = false;
- self.meta = File::make_async_meta(&self.path,
- self.dirty_meta.clone(),
- None);
- self.meta.run()?;
-
- if self.dirsize.is_some() {
- self.dirsize = Some(File::make_async_dirsize(&self.path,
- self.dirty_meta.clone(),
- None));
- self.dirsize.as_mut()?.run()?;
- }
- Ok(())
+ self.meta_sync()
}
fn get_color(&self, meta: &std::fs::Metadata) -> Option<lscolors::Color> {
@@ -1042,7 +888,7 @@ impl File {
pub fn calculate_size(&self) -> HResult<(u32, &str)> {
if let Some(ref dirsize) = self.dirsize {
- return Ok((*dirsize.value.as_ref().unwrap_or(&0) as u32, ""))
+ return Ok((*dirsize as u32, ""))
}
@@ -1073,7 +919,6 @@ impl File {
// Fix crash in tree_magic when called on non-regular file
// Also fix crash when a file doesn't exist any more
self.meta()
- .ok()
.and_then(|meta| {
if meta.is_file() && self.path.exists() {
let mime = tree_magic::from_filepath(&self.path);
@@ -1239,7 +1084,7 @@ impl File {
}
pub fn pretty_user(&self) -> Option<String> {
- if self.meta().is_err() { return None }
+ if self.meta().is_none() { return None }
let uid = self.meta().unwrap().uid();
let file_user = users::get_user_by_uid(uid)?;
let cur_user = users::get_current_username()?;
@@ -1252,7 +1097,7 @@ impl File {
}
pub fn pretty_group(&self) -> Option<String> {
- if self.meta().is_err() { return None }
+ if self.meta().is_none() { return None }
let gid = self.meta().unwrap().gid();
let file_group = users::get_group_by_gid(gid)?;
let cur_group = users::get_current_groupname()?;
@@ -1265,7 +1110,7 @@ impl File {
}
pub fn pretty_mtime(&self) -> Option<String> {
- if self.meta().is_err() { return None }
+ if self.meta().is_none() { return None }
let time: chrono::DateTime<chrono::Local>
= chrono::Local.timestamp(self.meta().unwrap().mtime(), 0);
Some(time.format("%F %R").to_string())
diff --git a/src/listview.rs b/src/listview.rs
index 3a70820..4222787 100644
--- a/src/listview.rs
+++ b/src/listview.rs
@@ -108,7 +108,7 @@ impl Listable for ListView<Files> {
.cloned()
.unwrap_or_default();
- if !file.meta.value.is_ok() {
+ if file.meta.is_none() {
file.meta_sync().log();
}
@@ -311,7 +311,7 @@ impl FileListBuilder {
pub fn build(self) -> HResult<ListView<Files>> {
let c = &self.cache;
let s = self.stale.clone();
- let mut files = match self.source {
+ let files = match self.source {
FileSource::Files(f) => Ok(f),
FileSource::Path(f) => {
c.as_ref()