diff options
author | Ben S <ogham@bsago.me> | 2015-09-02 23:19:10 +0100 |
---|---|---|
committer | Ben S <ogham@bsago.me> | 2015-09-02 23:19:10 +0100 |
commit | 4e49b91d2360c23a8ac959222f2d3e87409d8faa (patch) | |
tree | b55fa185bf792ec01383440f08c27015a246eec9 /src/options.rs | |
parent | eee49ece041e96673ce536fc1a4f5afb19d43ead (diff) |
Parallelise the details view!
This commit removes the threadpool in `main.rs` that stats each command-line argument separately, and replaces it with a *scoped* threadpool in `options/details.rs` that builds the table in parallel! Running this on my machine halves the execution time when tree-ing my entire home directory (which isn't exactly a common occurrence, but it's the only way to give exa a large running time)
The statting will be added back in parallel at a later stage. This was facilitated by the previous changes to recursion that made it easier to deal with.
There's a lot of large sweeping architectural changes. Here's a smattering of them:
- In `main.rs`, the files are now passed around as vectors of files rather than array slices of files. This is because `File`s aren't `Clone`, and the `Vec` is necessary to give away ownership of the files at the appropriate point.
- In the details view, files are now sorted *all* the time, rather than obeying the command-line order. As they're run in parallel, they have no guaranteed order anyway, so we *have* to sort them again. (I'm not sure if this should be the intended behaviour or not!) This means that the `Details` struct has to have the filter *all* the time, not only while recursing, so it's been moved out of the `recurse` field.
- We use `scoped_threadpool` over `threadpool`, a recent addition. It's only safely used on Nightly, which we're using anyway, so that's OK!
- Removed a bunch of out-of-date comments.
This also fixes #77, mainly by accident :)
Diffstat (limited to 'src/options.rs')
-rw-r--r-- | src/options.rs | 67 |
1 files changed, 38 insertions, 29 deletions
diff --git a/src/options.rs b/src/options.rs index d88eee5..dd76218 100644 --- a/src/options.rs +++ b/src/options.rs @@ -107,8 +107,12 @@ impl Options { }, path_strs)) } - pub fn transform_files(&self, files: &mut Vec<File>) { - self.filter.transform_files(files) + pub fn sort_files(&self, files: &mut Vec<File>) { + self.filter.sort_files(files) + } + + pub fn filter_files(&self, files: &mut Vec<File>) { + self.filter.filter_files(files) } /// Whether the View specified in this set of options includes a Git @@ -124,7 +128,7 @@ impl Options { } -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(Default, PartialEq, Debug, Copy, Clone)] pub struct FileFilter { list_dirs_first: bool, reverse: bool, @@ -133,26 +137,14 @@ pub struct FileFilter { } impl FileFilter { - /// Transform the files (sorting, reversing, filtering) before listing them. - pub fn transform_files(&self, files: &mut Vec<File>) { - + pub fn filter_files(&self, files: &mut Vec<File>) { if !self.show_invisibles { files.retain(|f| !f.is_dotfile()); } + } - match self.sort_field { - SortField::Unsorted => {}, - SortField::Name => files.sort_by(|a, b| natord::compare(&*a.name, &*b.name)), - SortField::Size => files.sort_by(|a, b| a.metadata.len().cmp(&b.metadata.len())), - SortField::FileInode => files.sort_by(|a, b| a.metadata.ino().cmp(&b.metadata.ino())), - SortField::ModifiedDate => files.sort_by(|a, b| a.metadata.mtime().cmp(&b.metadata.mtime())), - SortField::AccessedDate => files.sort_by(|a, b| a.metadata.atime().cmp(&b.metadata.atime())), - SortField::CreatedDate => files.sort_by(|a, b| a.metadata.ctime().cmp(&b.metadata.ctime())), - SortField::Extension => files.sort_by(|a, b| match a.ext.cmp(&b.ext) { - cmp::Ordering::Equal => natord::compare(&*a.name, &*b.name), - order => order, - }), - } + pub fn sort_files(&self, files: &mut Vec<File>) { + files.sort_by(|a, b| self.compare_files(a, b)); if self.reverse { files.reverse(); @@ -163,6 +155,22 @@ impl FileFilter { files.sort_by(|a, b| b.is_directory().cmp(&a.is_directory())); } } + + pub fn compare_files(&self, a: &File, b: &File) -> cmp::Ordering { + match self.sort_field { + SortField::Unsorted => cmp::Ordering::Equal, + SortField::Name => natord::compare(&*a.name, &*b.name), + SortField::Size => a.metadata.len().cmp(&b.metadata.len()), + SortField::FileInode => a.metadata.ino().cmp(&b.metadata.ino()), + SortField::ModifiedDate => a.metadata.mtime().cmp(&b.metadata.mtime()), + SortField::AccessedDate => a.metadata.atime().cmp(&b.metadata.atime()), + SortField::CreatedDate => a.metadata.ctime().cmp(&b.metadata.ctime()), + SortField::Extension => match a.ext.cmp(&b.ext) { + cmp::Ordering::Equal => natord::compare(&*a.name, &*b.name), + order => order, + }, + } + } } /// User-supplied field to sort by. @@ -280,7 +288,8 @@ impl View { let details = Details { columns: Some(try!(Columns::deduce(matches))), header: matches.opt_present("header"), - recurse: dir_action.recurse_options().map(|o| (o, filter)), + recurse: dir_action.recurse_options(), + filter: filter, xattr: xattr::ENABLED && matches.opt_present("extended"), colours: if dimensions().is_some() { Colours::colourful() } else { Colours::plain() }, }; @@ -328,7 +337,8 @@ impl View { let details = Details { columns: None, header: false, - recurse: dir_action.recurse_options().map(|o| (o, filter)), + recurse: dir_action.recurse_options(), + filter: filter, xattr: false, colours: if dimensions().is_some() { Colours::colourful() } else { Colours::plain() }, }; @@ -406,6 +416,7 @@ impl SizeFormat { } } + #[derive(PartialEq, Debug, Copy, Clone)] pub enum TimeType { FileAccessed, @@ -423,6 +434,7 @@ impl TimeType { } } + #[derive(PartialEq, Debug, Copy, Clone)] pub struct TimeTypes { accessed: bool, @@ -479,6 +491,7 @@ impl TimeTypes { } } + /// What to do when encountering a directory? #[derive(PartialEq, Debug, Copy, Clone)] pub enum DirAction { @@ -510,21 +523,16 @@ impl DirAction { } } - pub fn is_as_file(&self) -> bool { + pub fn treat_dirs_as_files(&self) -> bool { match *self { DirAction::AsFile => true, - _ => false, - } - } - - pub fn is_tree(&self) -> bool { - match *self { DirAction::Recurse(RecurseOptions { tree, .. }) => tree, _ => false, - } + } } } + #[derive(PartialEq, Debug, Copy, Clone)] pub struct RecurseOptions { pub tree: bool, @@ -559,6 +567,7 @@ impl RecurseOptions { } } + #[derive(PartialEq, Copy, Clone, Debug, Default)] pub struct Columns { size_format: SizeFormat, |