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.
This commit is contained in:
Ben S 2015-06-28 19:57:13 +01:00
parent 89526964c9
commit 922cd2a188
3 changed files with 20 additions and 11 deletions

View File

@ -57,7 +57,7 @@ impl Column {
}
#[derive(PartialEq, Debug)]
#[derive(PartialEq, Debug, Clone)]
pub struct Cell {
pub length: usize,
pub text: String,

View File

@ -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(),

View File

@ -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();