fix(terminal): properly lookup hyperlinks when cloning rows across pages

Before this we were doing bad things with the memory, looking at
`PageEntry`s for links not actually in the page we were reading the
strings from.
This commit is contained in:
Qwerasd
2025-02-10 15:45:53 -05:00
parent e540a79032
commit a1b682d0da
3 changed files with 19 additions and 7 deletions

View File

@ -194,14 +194,24 @@ pub const Set = RefCountedSet(
Id,
size.CellCountInt,
struct {
/// The page which holds the strings for items in this set.
page: ?*Page = null,
/// The page which holds the strings for items
/// looked up with, e.g., `add` or `lookup`,
/// if different from the destination page.
src_page: ?*const Page = null,
pub fn hash(self: *const @This(), link: PageEntry) u64 {
return link.hash(self.page.?.memory);
return link.hash((self.src_page orelse self.page.?).memory);
}
pub fn eql(self: *const @This(), a: PageEntry, b: PageEntry) bool {
return a.eql(self.page.?.memory, &b, self.page.?.memory);
return a.eql(
(self.src_page orelse self.page.?).memory,
&b,
self.page.?.memory,
);
}
pub fn deleted(self: *const @This(), link: PageEntry) void {

View File

@ -821,11 +821,7 @@ pub const Page = struct {
if (self.hyperlink_set.lookupContext(
self.memory,
other_link.*,
// `lookupContext` uses the context for hashing, and
// that doesn't write to the page, so this constCast
// is completely safe.
.{ .page = @constCast(other) },
.{ .page = self, .src_page = @constCast(other) },
)) |i| {
self.hyperlink_set.use(self.memory, i);
break :dst_id i;

View File

@ -38,8 +38,14 @@ const fastmem = @import("../fastmem.zig");
///
/// `Context`
/// A type containing methods to define behaviors.
///
/// - `fn hash(*Context, T) u64` - Return a hash for an item.
///
/// - `fn eql(*Context, T, T) bool` - Check two items for equality.
/// The first of the two items passed in is guaranteed to be from
/// a value passed in to an `add` or `lookup` function, the second
/// is guaranteed to be a value already resident in the set.
///
/// - `fn deleted(*Context, T) void` - [OPTIONAL] Deletion callback.
/// If present, called whenever an item is finally deleted.
/// Useful if the item has memory that needs to be freed.