Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements to reflow performance by removing O(n^2) behavior #3045

Merged
merged 3 commits into from
Jan 18, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 17 additions & 29 deletions zellij-server/src/panes/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,37 +166,24 @@ fn transfer_rows_from_viewport_to_lines_above(
count: usize,
max_viewport_width: usize,
) -> isize {
let mut next_lines: Vec<Row> = vec![];
let mut transferred_rows_count: isize = 0;
for _ in 0..count {
if next_lines.is_empty() {
if !viewport.is_empty() {
let next_line = viewport.remove(0);
transferred_rows_count +=
calculate_row_display_height(next_line.width(), max_viewport_width) as isize;
if !next_line.is_canonical {
let mut bottom_canonical_row_and_wraps_in_dst =
get_lines_above_bottom_canonical_row_and_wraps(lines_above);
next_lines.append(&mut bottom_canonical_row_and_wraps_in_dst);
}
next_lines.push(next_line);
next_lines = vec![Row::from_rows(next_lines)];
} else {
break; // no more rows
}
}
let dropped_line_width = bounded_push(lines_above, sixel_grid, next_lines.remove(0));
let drained_lines = std::cmp::min(count, viewport.len());
for next_line in viewport.drain(..drained_lines) {
let mut next_lines: Vec<Row> = vec![];
transferred_rows_count +=
calculate_row_display_height(next_line.width(), max_viewport_width) as isize;
if !next_line.is_canonical {
let mut bottom_canonical_row_and_wraps_in_dst =
get_lines_above_bottom_canonical_row_and_wraps(lines_above);
next_lines.append(&mut bottom_canonical_row_and_wraps_in_dst);
}
next_lines.push(next_line);
let dropped_line_width = bounded_push(lines_above, sixel_grid, Row::from_rows(next_lines));
if let Some(width) = dropped_line_width {
transferred_rows_count -=
calculate_row_display_height(width, max_viewport_width) as isize;
}
}
if !next_lines.is_empty() {
let excess_rows = Row::from_rows(next_lines).split_to_rows_of_length(max_viewport_width);
for row in excess_rows {
viewport.insert(0, row);
}
}
transferred_rows_count
}

Expand Down Expand Up @@ -3379,19 +3366,20 @@ impl Row {
self.width = None;
}
pub fn drain_until(&mut self, x: usize) -> VecDeque<TerminalCharacter> {
let mut drained_part: VecDeque<TerminalCharacter> = VecDeque::new();
let mut drained_part_len = 0;
while let Some(next_character) = self.columns.remove(0) {
let mut split_pos = 0;
for next_character in self.columns.iter() {
// drained_part_len == 0 here is so that if the grid is resized
// to a size of 1, we won't drop wide characters
if drained_part_len + next_character.width <= x || drained_part_len == 0 {
drained_part.push_back(next_character);
drained_part_len += next_character.width;
split_pos += 1
} else {
self.columns.push_front(next_character); // put it back
break;
}
}
// Can't use split_off because it doesn't reduce capacity, causing OOM with long lines
let drained_part = self.columns.drain(..split_pos).collect();
self.width = None;
drained_part
}
Expand Down