terminal: ScreenSearch prunes by min serial

pull/9711/head
Mitchell Hashimoto 2025-11-26 08:45:38 -08:00
parent 30f189d774
commit 9b7753a36f
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
1 changed files with 11 additions and 41 deletions

View File

@ -313,49 +313,19 @@ pub const ScreenSearch = struct {
}
fn pruneHistory(self: *ScreenSearch) void {
const history: *PageListSearch = if (self.history) |*h| &h.searcher else return;
// Keep track of the last checked node to avoid redundant work.
var last_checked: ?*PageList.List.Node = null;
// Go through our history results in reverse order to find
// the oldest matches first (since oldest nodes are pruned first).
for (0..self.history_results.items.len) |rev_i| {
const i = self.history_results.items.len - 1 - rev_i;
const node = node: {
const hl = &self.history_results.items[i];
break :node hl.chunks.items(.node)[0];
};
// If this is the same node as what we last checked and
// found to prune, then continue until we find the first
// non-matching, non-pruned node so we can prune the older
// ones.
if (last_checked == node) continue;
last_checked = node;
// Try to find this node in the PageList using a standard
// O(N) traversal. This isn't as bad as it seems because our
// oldest matches are likely to be near the start of the
// list and as soon as we find one we're done.
var it = history.list.pages.first;
while (it) |valid_node| : (it = valid_node.next) {
if (valid_node != node) continue;
// This is a valid node. If we're not at rev_i 0 then
// it means we have some data to prune! If we are
// at rev_i 0 then we can break out because there
// is nothing to prune.
if (rev_i == 0) return;
// Prune the last rev_i items.
// Go through our history results in order (newest to oldest) to find
// any result that contains an invalid serial. Prune up to that
// point.
for (0..self.history_results.items.len) |i| {
const hl = &self.history_results.items[i];
const serials = hl.chunks.items(.serial);
const lowest = serials[0];
if (lowest < self.screen.pages.page_serial_min) {
// Everything from here forward we assume is invalid because
// our history results only get older.
const alloc = self.allocator();
for (self.history_results.items[i + 1 ..]) |*prune_hl| {
prune_hl.deinit(alloc);
}
for (self.history_results.items[i..]) |*prune_hl| prune_hl.deinit(alloc);
self.history_results.shrinkAndFree(alloc, i);
// Once we've pruned, future results can't be invalid.
return;
}
}