mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Smaller memory footprint for BoundedArray (#16299)
Store BoundedArray's length using the smallest possible integer Co-authored-by: zooster <r00ster91@proton.me>
This commit is contained in:
parent
28ad74e8a6
commit
cb5a6be41a
@ -39,14 +39,16 @@ pub fn BoundedArrayAligned(
|
|||||||
) type {
|
) type {
|
||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
const Len = std.math.IntFittingRange(0, buffer_capacity);
|
||||||
|
|
||||||
buffer: [buffer_capacity]T align(alignment) = undefined,
|
buffer: [buffer_capacity]T align(alignment) = undefined,
|
||||||
len: usize = 0,
|
len: Len = 0,
|
||||||
|
|
||||||
/// Set the actual length of the slice.
|
/// Set the actual length of the slice.
|
||||||
/// Returns error.Overflow if it exceeds the length of the backing array.
|
/// Returns error.Overflow if it exceeds the length of the backing array.
|
||||||
pub fn init(len: usize) error{Overflow}!Self {
|
pub fn init(len: usize) error{Overflow}!Self {
|
||||||
if (len > buffer_capacity) return error.Overflow;
|
if (len > buffer_capacity) return error.Overflow;
|
||||||
return Self{ .len = len };
|
return Self{ .len = @intCast(len) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// View the internal array as a slice whose size was previously set.
|
/// View the internal array as a slice whose size was previously set.
|
||||||
@ -67,7 +69,7 @@ pub fn BoundedArrayAligned(
|
|||||||
/// Does not initialize added items if any.
|
/// Does not initialize added items if any.
|
||||||
pub fn resize(self: *Self, len: usize) error{Overflow}!void {
|
pub fn resize(self: *Self, len: usize) error{Overflow}!void {
|
||||||
if (len > buffer_capacity) return error.Overflow;
|
if (len > buffer_capacity) return error.Overflow;
|
||||||
self.len = len;
|
self.len = @intCast(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copy the content of an existing slice.
|
/// Copy the content of an existing slice.
|
||||||
@ -163,7 +165,7 @@ pub fn BoundedArrayAligned(
|
|||||||
/// This operation is O(N).
|
/// This operation is O(N).
|
||||||
pub fn insertSlice(self: *Self, i: usize, items: []const T) error{Overflow}!void {
|
pub fn insertSlice(self: *Self, i: usize, items: []const T) error{Overflow}!void {
|
||||||
try self.ensureUnusedCapacity(items.len);
|
try self.ensureUnusedCapacity(items.len);
|
||||||
self.len += items.len;
|
self.len = @intCast(self.len + items.len);
|
||||||
mem.copyBackwards(T, self.slice()[i + items.len .. self.len], self.constSlice()[i .. self.len - items.len]);
|
mem.copyBackwards(T, self.slice()[i + items.len .. self.len], self.constSlice()[i .. self.len - items.len]);
|
||||||
@memcpy(self.slice()[i..][0..items.len], items);
|
@memcpy(self.slice()[i..][0..items.len], items);
|
||||||
}
|
}
|
||||||
@ -193,7 +195,7 @@ pub fn BoundedArrayAligned(
|
|||||||
for (self.constSlice()[after_range..], 0..) |item, i| {
|
for (self.constSlice()[after_range..], 0..) |item, i| {
|
||||||
self.slice()[after_subrange..][i] = item;
|
self.slice()[after_subrange..][i] = item;
|
||||||
}
|
}
|
||||||
self.len -= len - new_items.len;
|
self.len = @intCast(self.len - len + new_items.len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +246,7 @@ pub fn BoundedArrayAligned(
|
|||||||
/// enough to store the new items.
|
/// enough to store the new items.
|
||||||
pub fn appendSliceAssumeCapacity(self: *Self, items: []const T) void {
|
pub fn appendSliceAssumeCapacity(self: *Self, items: []const T) void {
|
||||||
const old_len = self.len;
|
const old_len = self.len;
|
||||||
self.len += items.len;
|
self.len = @intCast(self.len + items.len);
|
||||||
@memcpy(self.slice()[old_len..][0..items.len], items);
|
@memcpy(self.slice()[old_len..][0..items.len], items);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,8 +262,8 @@ pub fn BoundedArrayAligned(
|
|||||||
/// Asserts the capacity is enough.
|
/// Asserts the capacity is enough.
|
||||||
pub fn appendNTimesAssumeCapacity(self: *Self, value: T, n: usize) void {
|
pub fn appendNTimesAssumeCapacity(self: *Self, value: T, n: usize) void {
|
||||||
const old_len = self.len;
|
const old_len = self.len;
|
||||||
self.len += n;
|
assert(self.len + n <= buffer_capacity);
|
||||||
assert(self.len <= buffer_capacity);
|
self.len = @intCast(self.len + n);
|
||||||
@memset(self.slice()[old_len..self.len], value);
|
@memset(self.slice()[old_len..self.len], value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,6 +389,18 @@ test "BoundedArray" {
|
|||||||
try testing.expectEqualStrings(s, a.constSlice());
|
try testing.expectEqualStrings(s, a.constSlice());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "BoundedArray sizeOf" {
|
||||||
|
// Just sanity check size on one CPU
|
||||||
|
if (@import("builtin").cpu.arch != .x86_64)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try testing.expectEqual(@sizeOf(BoundedArray(u8, 3)), 4);
|
||||||
|
|
||||||
|
// `len` is the minimum required size to hold the maximum capacity
|
||||||
|
try testing.expectEqual(@TypeOf(@as(BoundedArray(u8, 15), undefined).len), u4);
|
||||||
|
try testing.expectEqual(@TypeOf(@as(BoundedArray(u8, 16), undefined).len), u5);
|
||||||
|
}
|
||||||
|
|
||||||
test "BoundedArrayAligned" {
|
test "BoundedArrayAligned" {
|
||||||
var a = try BoundedArrayAligned(u8, 16, 4).init(0);
|
var a = try BoundedArrayAligned(u8, 16, 4).init(0);
|
||||||
try a.append(0);
|
try a.append(0);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user