summaryrefslogtreecommitdiffstats
path: root/src/output
diff options
context:
space:
mode:
authorBen S <ogham@bsago.me>2015-06-28 19:57:13 +0100
committerBen S <ogham@bsago.me>2015-06-28 19:57:13 +0100
commit922cd2a1886d7c03d47d77ba87d5bfb0e5cb18fb (patch)
tree3ad921097e4433ab15de9e43ca9cc814d58ed95c /src/output
parent89526964c99446919f3784bd3a74fd03a441a8b1 (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.rs7
-rw-r--r--src/output/grid_details.rs22
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();