mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-09-14 18:01:58 +00:00
terminal: hash map and ref counted set can initialize from zeroed memory
This commit is contained in:
@@ -152,8 +152,19 @@ pub fn OffsetHashMap(
|
||||
/// memory. The backing memory must be aligned to base_align.
|
||||
pub fn init(buf: OffsetBuf, l: Layout) Self {
|
||||
assert(base_align.check(@intFromPtr(buf.start())));
|
||||
return fromUnmanaged(buf, Unmanaged.init(buf, l));
|
||||
}
|
||||
|
||||
const m = Unmanaged.init(buf, l);
|
||||
/// Like `init`, but for backing memory that the caller guarantees
|
||||
/// is already zero-filled (e.g. fresh OS pages). Only the header
|
||||
/// is written: all-zero slot metadata already means every slot is
|
||||
/// free, so the metadata array is left untouched.
|
||||
pub fn initAssumeZeroed(buf: OffsetBuf, l: Layout) Self {
|
||||
assert(base_align.check(@intFromPtr(buf.start())));
|
||||
return fromUnmanaged(buf, Unmanaged.initAssumeZeroed(buf, l));
|
||||
}
|
||||
|
||||
fn fromUnmanaged(buf: OffsetBuf, m: Unmanaged) Self {
|
||||
return .{ .metadata = getOffset(
|
||||
Unmanaged.Metadata,
|
||||
buf,
|
||||
@@ -344,6 +355,17 @@ fn HashMapUnmanaged(
|
||||
/// Initialize a hash map with a given capacity and a buffer. The
|
||||
/// buffer must fit within the size defined by `layoutForCapacity`.
|
||||
pub fn init(buf: OffsetBuf, layout: Layout) Self {
|
||||
var map = initAssumeZeroed(buf, layout);
|
||||
map.initMetadatas();
|
||||
return map;
|
||||
}
|
||||
|
||||
/// Like `init`, but for a buffer that the caller guarantees is
|
||||
/// already zero-filled. Only the header is written: an all-zero
|
||||
/// metadata byte is a free slot (see `Metadata.isFree`), so the
|
||||
/// slot metadata is left untouched. Behavior is undefined if the
|
||||
/// metadata region is not zero.
|
||||
pub fn initAssumeZeroed(buf: OffsetBuf, layout: Layout) Self {
|
||||
assert(base_align.check(@intFromPtr(buf.start())));
|
||||
|
||||
// Get all our main pointers
|
||||
@@ -351,13 +373,12 @@ fn HashMapUnmanaged(
|
||||
const metadata_ptr: [*]Metadata = @ptrCast(metadata_buf.start());
|
||||
|
||||
// Build our map
|
||||
var map: Self = .{ .metadata = metadata_ptr };
|
||||
const map: Self = .{ .metadata = metadata_ptr };
|
||||
const hdr = map.header();
|
||||
hdr.capacity = layout.capacity;
|
||||
hdr.size = 0;
|
||||
if (@sizeOf([*]K) != 0) hdr.keys = metadata_buf.member(K, layout.keys_start);
|
||||
if (@sizeOf([*]V) != 0) hdr.values = metadata_buf.member(V, layout.vals_start);
|
||||
map.initMetadatas();
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -212,6 +212,30 @@ pub fn RefCountedSet(
|
||||
@memset(table.ptr(base)[0..l.table_cap], 0);
|
||||
@memset(items.ptr(base)[0..l.cap], .{});
|
||||
|
||||
return initFromParts(table, items, l, context);
|
||||
}
|
||||
|
||||
/// Like `init`, but for backing memory that the caller guarantees
|
||||
/// is already zero-filled (e.g. fresh OS pages). This writes
|
||||
/// nothing to the backing buffer, so the OS pages behind the table
|
||||
/// and items stay untouched until the first `add`.
|
||||
///
|
||||
/// Behavior is undefined if the backing memory is not zero.
|
||||
pub fn initAssumeZeroed(base: OffsetBuf, l: Layout, context: Context) Self {
|
||||
return initFromParts(
|
||||
base.member(Id, l.table_start),
|
||||
base.member(Item, l.items_start),
|
||||
l,
|
||||
context,
|
||||
);
|
||||
}
|
||||
|
||||
fn initFromParts(
|
||||
table: Offset(Id),
|
||||
items: Offset(Item),
|
||||
l: Layout,
|
||||
context: Context,
|
||||
) Self {
|
||||
return .{
|
||||
.table = table,
|
||||
.items = items,
|
||||
@@ -726,7 +750,9 @@ pub fn RefCountedSet(
|
||||
|
||||
var psl_stats: [32]Id = @splat(0);
|
||||
|
||||
for (items[0..self.layout.cap], 0..) |item, id| {
|
||||
// Start at item 1 because item 0 is reserved and never
|
||||
// assigned to. Its metadata doesn't matter.
|
||||
for (items[1..self.next_id], 1..) |item, id| {
|
||||
if (item.meta.bucket < std.math.maxInt(Id)) {
|
||||
assert(table[item.meta.bucket] == id);
|
||||
psl_stats[item.meta.psl] += 1;
|
||||
@@ -740,6 +766,7 @@ pub fn RefCountedSet(
|
||||
psl_stats = @splat(0);
|
||||
|
||||
for (table[0..self.layout.table_cap], 0..) |id, bucket| {
|
||||
if (id == 0) continue;
|
||||
const item = items[id];
|
||||
if (item.meta.bucket < std.math.maxInt(Id)) {
|
||||
assert(item.meta.bucket == bucket);
|
||||
|
||||
Reference in New Issue
Block a user