summaryrefslogtreecommitdiffstats
path: root/src/options.rs
diff options
context:
space:
mode:
authorBen S <ogham@bsago.me>2015-09-02 23:19:10 +0100
committerBen S <ogham@bsago.me>2015-09-02 23:19:10 +0100
commit4e49b91d2360c23a8ac959222f2d3e87409d8faa (patch)
treeb55fa185bf792ec01383440f08c27015a246eec9 /src/options.rs
parenteee49ece041e96673ce536fc1a4f5afb19d43ead (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.rs67
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,