authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-23 22:30:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-23 22:30:10-07:00
log85747b266aac8a2ff7fea4a4b18f722133544ad7
tree53759fbc1840205ba142d257cc8640a62357750e
parentd9e8671d963dc99ec8b4721f53d77828efa232ed

Revert "Smaller memory footprint for BoundedArray (#16299)"

This reverts commit cb5a6be41ae0efc30d0b59a41b0763db966e5bf4. I deeply apologize for the churn. This change is problematic given that we do not have ranged integers (yet? see #3806). In the meantime, this type needs to be `usize`, matching the length and index types for all std lib data structures. Users who want to save memory should not use heap-allocated BoundedArray values, since it is inherently memory-inefficient. Use a different memory layout instead. If #3806 is accepted and implemented, the length value can become an integer with the appropriate range, without the footgun. If that proposal is not accepted, len type will remain a usize.

1 files changed, 8 insertions(+), 22 deletions(-)

lib/std/bounded_array.zig+8-22
...@@ -39,16 +39,14 @@ pub fn BoundedArrayAligned(...@@ -39,16 +39,14 @@ pub fn BoundedArrayAligned(
39) type {39) type {
40 return struct {40 return struct {
41 const Self = @This();41 const Self = @This();
42 const Len = std.math.IntFittingRange(0, buffer_capacity);
43
44 buffer: [buffer_capacity]T align(alignment) = undefined,42 buffer: [buffer_capacity]T align(alignment) = undefined,
45 len: Len = 0,43 len: usize = 0,
4644
47 /// Set the actual length of the slice.45 /// Set the actual length of the slice.
48 /// Returns error.Overflow if it exceeds the length of the backing array.46 /// Returns error.Overflow if it exceeds the length of the backing array.
49 pub fn init(len: usize) error{Overflow}!Self {47 pub fn init(len: usize) error{Overflow}!Self {
50 if (len > buffer_capacity) return error.Overflow;48 if (len > buffer_capacity) return error.Overflow;
51 return Self{ .len = @intCast(len) };49 return Self{ .len = len };
52 }50 }
5351
54 /// View the internal array as a slice whose size was previously set.52 /// View the internal array as a slice whose size was previously set.
...@@ -69,7 +67,7 @@ pub fn BoundedArrayAligned(...@@ -69,7 +67,7 @@ pub fn BoundedArrayAligned(
69 /// Does not initialize added items if any.67 /// Does not initialize added items if any.
70 pub fn resize(self: *Self, len: usize) error{Overflow}!void {68 pub fn resize(self: *Self, len: usize) error{Overflow}!void {
71 if (len > buffer_capacity) return error.Overflow;69 if (len > buffer_capacity) return error.Overflow;
72 self.len = @intCast(len);70 self.len = len;
73 }71 }
7472
75 /// Remove all elements from the slice.73 /// Remove all elements from the slice.
...@@ -178,7 +176,7 @@ pub fn BoundedArrayAligned(...@@ -178,7 +176,7 @@ pub fn BoundedArrayAligned(
178 /// This operation is O(N).176 /// This operation is O(N).
179 pub fn insertSlice(self: *Self, i: usize, items: []const T) error{Overflow}!void {177 pub fn insertSlice(self: *Self, i: usize, items: []const T) error{Overflow}!void {
180 try self.ensureUnusedCapacity(items.len);178 try self.ensureUnusedCapacity(items.len);
181 self.len = @intCast(self.len + items.len);179 self.len += items.len;
182 mem.copyBackwards(T, self.slice()[i + items.len .. self.len], self.constSlice()[i .. self.len - items.len]);180 mem.copyBackwards(T, self.slice()[i + items.len .. self.len], self.constSlice()[i .. self.len - items.len]);
183 @memcpy(self.slice()[i..][0..items.len], items);181 @memcpy(self.slice()[i..][0..items.len], items);
184 }182 }
...@@ -208,7 +206,7 @@ pub fn BoundedArrayAligned(...@@ -208,7 +206,7 @@ pub fn BoundedArrayAligned(
208 for (self.constSlice()[after_range..], 0..) |item, i| {206 for (self.constSlice()[after_range..], 0..) |item, i| {
209 self.slice()[after_subrange..][i] = item;207 self.slice()[after_subrange..][i] = item;
210 }208 }
211 self.len = @intCast(self.len - len + new_items.len);209 self.len -= len - new_items.len;
212 }210 }
213 }211 }
214212
...@@ -259,7 +257,7 @@ pub fn BoundedArrayAligned(...@@ -259,7 +257,7 @@ pub fn BoundedArrayAligned(
259 /// enough to store the new items.257 /// enough to store the new items.
260 pub fn appendSliceAssumeCapacity(self: *Self, items: []const T) void {258 pub fn appendSliceAssumeCapacity(self: *Self, items: []const T) void {
261 const old_len = self.len;259 const old_len = self.len;
262 self.len = @intCast(self.len + items.len);260 self.len += items.len;
263 @memcpy(self.slice()[old_len..][0..items.len], items);261 @memcpy(self.slice()[old_len..][0..items.len], items);
264 }262 }
265263
...@@ -275,8 +273,8 @@ pub fn BoundedArrayAligned(...@@ -275,8 +273,8 @@ pub fn BoundedArrayAligned(
275 /// Asserts the capacity is enough.273 /// Asserts the capacity is enough.
276 pub fn appendNTimesAssumeCapacity(self: *Self, value: T, n: usize) void {274 pub fn appendNTimesAssumeCapacity(self: *Self, value: T, n: usize) void {
277 const old_len = self.len;275 const old_len = self.len;
278 assert(self.len + n <= buffer_capacity);276 self.len += n;
279 self.len = @intCast(self.len + n);277 assert(self.len <= buffer_capacity);
280 @memset(self.slice()[old_len..self.len], value);278 @memset(self.slice()[old_len..self.len], value);
281 }279 }
282280
...@@ -406,18 +404,6 @@ test BoundedArray {...@@ -406,18 +404,6 @@ test BoundedArray {
406 try testing.expectEqualStrings(s, a.constSlice());404 try testing.expectEqualStrings(s, a.constSlice());
407}405}
408406
409test "BoundedArray sizeOf" {
410 // Just sanity check size on one CPU
411 if (@import("builtin").cpu.arch != .x86_64)
412 return;
413
414 try testing.expectEqual(@sizeOf(BoundedArray(u8, 3)), 4);
415
416 // `len` is the minimum required size to hold the maximum capacity
417 try testing.expectEqual(@TypeOf(@as(BoundedArray(u8, 15), undefined).len), u4);
418 try testing.expectEqual(@TypeOf(@as(BoundedArray(u8, 16), undefined).len), u5);
419}
420
421test "BoundedArrayAligned" {407test "BoundedArrayAligned" {
422 var a = try BoundedArrayAligned(u8, 16, 4).init(0);408 var a = try BoundedArrayAligned(u8, 16, 4).init(0);
423 try a.append(0);409 try a.append(0);