| author | |
| committer | |
| log | d12123a88cf56428874b359cb63acb8618dfbcfd |
| tree | cb4798e72f47d303d5ac527467b021f467c86818 |
| parent | 5b9b5e45cb710ddaad1a97813d1619755eb35a98 |
also std.MultiArrayList5 files changed, 47 insertions(+), 32 deletions(-)
lib/std/array_list.zig+19-19| ... | ... | @@ -181,7 +181,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 181 | 181 | // a new buffer and doing our own copy. With a realloc() call, |
| 182 | 182 | // the allocator implementation would pointlessly copy our |
| 183 | 183 | // extra capacity. |
| 184 | const new_capacity = growCapacity(self.capacity, new_len); | |
| 184 | const new_capacity = ArrayListAlignedUnmanaged(T, alignment).growCapacity(self.capacity, new_len); | |
| 185 | 185 | const old_memory = self.allocatedSlice(); |
| 186 | 186 | if (self.allocator.remap(old_memory, new_capacity)) |new_memory| { |
| 187 | 187 | self.items.ptr = new_memory.ptr; |
| ... | ... | @@ -446,7 +446,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 446 | 446 | |
| 447 | 447 | if (self.capacity >= new_capacity) return; |
| 448 | 448 | |
| 449 | const better_capacity = growCapacity(self.capacity, new_capacity); | |
| 449 | const better_capacity = ArrayListAlignedUnmanaged(T, alignment).growCapacity(self.capacity, new_capacity); | |
| 450 | 450 | return self.ensureTotalCapacityPrecise(better_capacity); |
| 451 | 451 | } |
| 452 | 452 | |
| ... | ... | @@ -1062,14 +1062,12 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 1062 | 1062 | self.capacity = 0; |
| 1063 | 1063 | } |
| 1064 | 1064 | |
| 1065 | /// If the current capacity is less than `new_capacity`, this function will | |
| 1066 | /// modify the array so that it can hold at least `new_capacity` items. | |
| 1065 | /// Modify the array so that it can hold at least `new_capacity` items. | |
| 1066 | /// Implements super-linear growth to achieve amortized O(1) append operations. | |
| 1067 | 1067 | /// Invalidates element pointers if additional memory is needed. |
| 1068 | pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_capacity: usize) Allocator.Error!void { | |
| 1068 | pub fn ensureTotalCapacity(self: *Self, gpa: Allocator, new_capacity: usize) Allocator.Error!void { | |
| 1069 | 1069 | if (self.capacity >= new_capacity) return; |
| 1070 | ||
| 1071 | const better_capacity = growCapacity(self.capacity, new_capacity); | |
| 1072 | return self.ensureTotalCapacityPrecise(allocator, better_capacity); | |
| 1070 | return self.ensureTotalCapacityPrecise(gpa, growCapacity(self.capacity, new_capacity)); | |
| 1073 | 1071 | } |
| 1074 | 1072 | |
| 1075 | 1073 | /// If the current capacity is less than `new_capacity`, this function will |
| ... | ... | @@ -1218,18 +1216,20 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 1218 | 1216 | if (self.items.len == 0) return null; |
| 1219 | 1217 | return self.getLast(); |
| 1220 | 1218 | } |
| 1221 | }; | |
| 1222 | } | |
| 1223 | 1219 | |
| 1224 | /// Called when memory growth is necessary. Returns a capacity larger than | |
| 1225 | /// minimum that grows super-linearly. | |
| 1226 | fn growCapacity(current: usize, minimum: usize) usize { | |
| 1227 | var new = current; | |
| 1228 | while (true) { | |
| 1229 | new +|= new / 2 + 8; | |
| 1230 | if (new >= minimum) | |
| 1231 | return new; | |
| 1232 | } | |
| 1220 | const init_capacity = @as(comptime_int, @max(1, std.atomic.cache_line / @sizeOf(T))); | |
| 1221 | ||
| 1222 | /// Called when memory growth is necessary. Returns a capacity larger than | |
| 1223 | /// minimum that grows super-linearly. | |
| 1224 | fn growCapacity(current: usize, minimum: usize) usize { | |
| 1225 | var new = current; | |
| 1226 | while (true) { | |
| 1227 | new +|= new / 2 + init_capacity; | |
| 1228 | if (new >= minimum) | |
| 1229 | return new; | |
| 1230 | } | |
| 1231 | } | |
| 1232 | }; | |
| 1233 | 1233 | } |
| 1234 | 1234 | |
| 1235 | 1235 | /// Integer addition returning `error.OutOfMemory` on overflow. |
lib/std/json/scanner_test.zig+7-2| ... | ... | @@ -435,8 +435,13 @@ fn testEnsureStackCapacity(do_ensure: bool) !void { |
| 435 | 435 | var fail_alloc = std.testing.FailingAllocator.init(std.testing.allocator, .{ .fail_index = 1 }); |
| 436 | 436 | const failing_allocator = fail_alloc.allocator(); |
| 437 | 437 | |
| 438 | const nestings = 999; // intentionally not a power of 2. | |
| 439 | var scanner = JsonScanner.initCompleteInput(failing_allocator, "[" ** nestings ++ "]" ** nestings); | |
| 438 | const nestings = 2049; // intentionally not a power of 2. | |
| 439 | var input_string: std.ArrayListUnmanaged(u8) = .empty; | |
| 440 | try input_string.appendNTimes(std.testing.allocator, '[', nestings); | |
| 441 | try input_string.appendNTimes(std.testing.allocator, ']', nestings); | |
| 442 | defer input_string.deinit(std.testing.allocator); | |
| 443 | ||
| 444 | var scanner = JsonScanner.initCompleteInput(failing_allocator, input_string.items); | |
| 440 | 445 | defer scanner.deinit(); |
| 441 | 446 | |
| 442 | 447 | if (do_ensure) { |
lib/std/json/static_test.zig+1-1| ... | ... | @@ -916,7 +916,7 @@ test "parse at comptime" { |
| 916 | 916 | uptime: u64, |
| 917 | 917 | }; |
| 918 | 918 | const config = comptime x: { |
| 919 | var buf: [32]u8 = undefined; | |
| 919 | var buf: [256]u8 = undefined; | |
| 920 | 920 | var fba = std.heap.FixedBufferAllocator.init(&buf); |
| 921 | 921 | const res = parseFromSliceLeaky(Config, fba.allocator(), doc, .{}); |
| 922 | 922 | // Assert no error can occur since we are |
lib/std/multi_array_list.zig+19-9| ... | ... | @@ -405,17 +405,27 @@ pub fn MultiArrayList(comptime T: type) type { |
| 405 | 405 | |
| 406 | 406 | /// Modify the array so that it can hold at least `new_capacity` items. |
| 407 | 407 | /// Implements super-linear growth to achieve amortized O(1) append operations. |
| 408 | /// Invalidates pointers if additional memory is needed. | |
| 409 | pub fn ensureTotalCapacity(self: *Self, gpa: Allocator, new_capacity: usize) !void { | |
| 410 | var better_capacity = self.capacity; | |
| 411 | if (better_capacity >= new_capacity) return; | |
| 408 | /// Invalidates element pointers if additional memory is needed. | |
| 409 | pub fn ensureTotalCapacity(self: *Self, gpa: Allocator, new_capacity: usize) Allocator.Error!void { | |
| 410 | if (self.capacity >= new_capacity) return; | |
| 411 | return self.setCapacity(gpa, growCapacity(self.capacity, new_capacity)); | |
| 412 | } | |
| 413 | ||
| 414 | const init_capacity = init: { | |
| 415 | var max = 1; | |
| 416 | for (fields) |field| max = @as(comptime_int, @max(max, @sizeOf(field.type))); | |
| 417 | break :init @as(comptime_int, @max(1, std.atomic.cache_line / max)); | |
| 418 | }; | |
| 412 | 419 | |
| 420 | /// Called when memory growth is necessary. Returns a capacity larger than | |
| 421 | /// minimum that grows super-linearly. | |
| 422 | fn growCapacity(current: usize, minimum: usize) usize { | |
| 423 | var new = current; | |
| 413 | 424 | while (true) { |
| 414 | better_capacity += better_capacity / 2 + 8; | |
| 415 | if (better_capacity >= new_capacity) break; | |
| 425 | new +|= new / 2 + init_capacity; | |
| 426 | if (new >= minimum) | |
| 427 | return new; | |
| 416 | 428 | } |
| 417 | ||
| 418 | return self.setCapacity(gpa, better_capacity); | |
| 419 | 429 | } |
| 420 | 430 | |
| 421 | 431 | /// Modify the array so that it can hold at least `additional_count` **more** items. |
| ... | ... | @@ -838,7 +848,7 @@ test "union" { |
| 838 | 848 | |
| 839 | 849 | try testing.expectEqual(@as(usize, 0), list.items(.tags).len); |
| 840 | 850 | |
| 841 | try list.ensureTotalCapacity(ally, 2); | |
| 851 | try list.ensureTotalCapacity(ally, 3); | |
| 842 | 852 | |
| 843 | 853 | list.appendAssumeCapacity(.{ .a = 1 }); |
| 844 | 854 | list.appendAssumeCapacity(.{ .b = "zigzag" }); |
lib/std/zig/string_literal.zig+1-1| ... | ... | @@ -377,7 +377,7 @@ test parseAlloc { |
| 377 | 377 | const expectError = std.testing.expectError; |
| 378 | 378 | const eql = std.mem.eql; |
| 379 | 379 | |
| 380 | var fixed_buf_mem: [64]u8 = undefined; | |
| 380 | var fixed_buf_mem: [512]u8 = undefined; | |
| 381 | 381 | var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(&fixed_buf_mem); |
| 382 | 382 | const alloc = fixed_buf_alloc.allocator(); |
| 383 | 383 |