diff options
author | Ben S <ogham@bsago.me> | 2015-06-28 19:57:13 +0100 |
---|---|---|
committer | Ben S <ogham@bsago.me> | 2015-06-28 19:57:13 +0100 |
commit | 922cd2a1886d7c03d47d77ba87d5bfb0e5cb18fb (patch) | |
tree | 3ad921097e4433ab15de9e43ca9cc814d58ed95c /src/output | |
parent | 89526964c99446919f3784bd3a74fd03a441a8b1 (diff) |
Cache the rendered cells
Previously, each time it tried to render a table (to check its width), it both re-queried the filesystem and re-formatted the values into coloured strings.
These values are now calculated only once before the table is drawn, and are used repeatedly throughout.
Although it looks as though there's more `clone()`ing going on than before, it used to be recalculating things and storing them as vectors anyway, so the memory would still be used in any case.
Diffstat (limited to 'src/output')
-rw-r--r-- | src/output/details.rs | 7 | ||||
-rw-r--r-- | src/output/grid_details.rs | 22 |
2 files changed, 19 insertions, 10 deletions
diff --git a/src/output/details.rs b/src/output/details.rs index e67490d..9988b69 100644 --- a/src/output/details.rs +++ b/src/output/details.rs @@ -197,9 +197,14 @@ impl<U> Table<U> where U: Users { /// Get the cells for the given file, and add the result to the table. pub fn add_file(&mut self, file: &File, depth: usize, last: bool, links: bool) { + let cells = self.cells_for_file(file); + self.add_file_with_cells(cells, file, depth, last, links) + } + + pub fn add_file_with_cells(&mut self, cells: Vec<Cell>, file: &File, depth: usize, last: bool, links: bool) { let row = Row { depth: depth, - cells: self.cells_for_file(file), + cells: cells, name: Cell { text: filename(file, &self.colours, links), length: file.file_name_width() }, last: last, attrs: file.xattrs.clone(), diff --git a/src/output/grid_details.rs b/src/output/grid_details.rs index a95e852..192cb1f 100644 --- a/src/output/grid_details.rs +++ b/src/output/grid_details.rs @@ -2,7 +2,7 @@ use std::iter::repeat; use term_grid as grid; -use column::Cell; +use column::{Column, Cell}; use dir::Dir; use file::File; use output::details::{Details, Table}; @@ -16,10 +16,14 @@ pub struct GridDetails { impl GridDetails { pub fn view(&self, dir: Option<&Dir>, files: &[File]) { - let mut last_working_table = self.make_grid(1, dir, files); + let columns_for_dir = self.details.columns.for_dir(dir); + let mut first_table = Table::with_options(self.details.colours, columns_for_dir.clone()); + let cells: Vec<_> = files.iter().map(|file| first_table.cells_for_file(file)).collect(); + + let mut last_working_table = self.make_grid(1, &*columns_for_dir, files, cells.clone()); for column_count in 2.. { - let grid = self.make_grid(column_count, dir, files); + let grid = self.make_grid(column_count, &*columns_for_dir, files, cells.clone()); if grid.fit_into_columns(column_count).width() <= self.grid.console_width { last_working_table = grid; @@ -31,22 +35,22 @@ impl GridDetails { } } - pub fn make_grid(&self, column_count: usize, dir: Option<&Dir>, files: &[File]) -> grid::Grid { + pub fn make_grid(&self, column_count: usize, columns_for_dir: &[Column], files: &[File], cells: Vec<Vec<Cell>>) -> grid::Grid { let make_table = || { - let mut table = Table::with_options(self.details.colours, self.details.columns.for_dir(dir)); + let mut table = Table::with_options(self.details.colours, columns_for_dir.into()); if self.details.header { table.add_header() } table }; let mut tables: Vec<_> = repeat(()).map(|_| make_table()).take(column_count).collect(); - let mut height = files.len() / column_count; - if files.len() % column_count != 0 { + let mut height = cells.len() / column_count; + if cells.len() % column_count != 0 { height += 1; } - for (i, file) in files.iter().enumerate() { - tables[i / height].add_file(file, 0, false, false); + for (i, (file, row)) in files.iter().zip(cells.into_iter()).enumerate() { + tables[i / height].add_file_with_cells(row, file, 0, false, false); } let columns: Vec<_> = tables.iter().map(|t| t.print_table(false, false)).collect(); |