authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-01 14:28:27-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-11-01 14:28:27-04:00
log77eefebe65fc2baed08755bceb8e4df77fe8103c
tree7c6d967f3f9973c3a40c1cceab5ec1d54b238c93
parent002fbb0af043d90b0ab7d2f2804effc6fa2d690c
parenta34375814106dbc0e0181bca7cc4ffb1821cb51e
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #10077 from squeek502/arraylist-capacity

std.ArrayList: add ensureTotalCapacityPrecise and update doc comments

5 files changed, 35 insertions(+), 22 deletions(-)

lib/std/array_list.zig+30-17
...@@ -56,19 +56,11 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {...@@ -56,19 +56,11 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
56 }56 }
5757
58 /// Initialize with capacity to hold at least `num` elements.58 /// Initialize with capacity to hold at least `num` elements.
59 /// The resulting capacity is likely to be equal to `num`.
59 /// Deinitialize with `deinit` or use `toOwnedSlice`.60 /// Deinitialize with `deinit` or use `toOwnedSlice`.
60 pub fn initCapacity(allocator: *Allocator, num: usize) !Self {61 pub fn initCapacity(allocator: *Allocator, num: usize) !Self {
61 var self = Self.init(allocator);62 var self = Self.init(allocator);
6263 try self.ensureTotalCapacityPrecise(num);
63 if (@sizeOf(T) > 0) {
64 const new_memory = try self.allocator.allocAdvanced(T, alignment, num, .at_least);
65 self.items.ptr = new_memory.ptr;
66 self.capacity = new_memory.len;
67 } else {
68 // If `T` is a zero-sized type, then we do not need to allocate memory.
69 self.capacity = std.math.maxInt(usize);
70 }
71
72 return self;64 return self;
73 }65 }
7466
...@@ -330,8 +322,22 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {...@@ -330,8 +322,22 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
330 if (better_capacity >= new_capacity) break;322 if (better_capacity >= new_capacity) break;
331 }323 }
332324
325 return self.ensureTotalCapacityPrecise(better_capacity);
326 } else {
327 self.capacity = std.math.maxInt(usize);
328 }
329 }
330
331 /// Modify the array so that it can hold at least `new_capacity` items.
332 /// Like `ensureTotalCapacity`, but the resulting capacity is much more likely
333 /// (but not guaranteed) to be equal to `new_capacity`.
334 /// Invalidates pointers if additional memory is needed.
335 pub fn ensureTotalCapacityPrecise(self: *Self, new_capacity: usize) !void {
336 if (@sizeOf(T) > 0) {
337 if (self.capacity >= new_capacity) return;
338
333 // TODO This can be optimized to avoid needlessly copying undefined memory.339 // TODO This can be optimized to avoid needlessly copying undefined memory.
334 const new_memory = try self.allocator.reallocAtLeast(self.allocatedSlice(), better_capacity);340 const new_memory = try self.allocator.reallocAtLeast(self.allocatedSlice(), new_capacity);
335 self.items.ptr = new_memory.ptr;341 self.items.ptr = new_memory.ptr;
336 self.capacity = new_memory.len;342 self.capacity = new_memory.len;
337 } else {343 } else {
...@@ -464,14 +470,11 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -464,14 +470,11 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
464 pub const Slice = if (alignment) |a| ([]align(a) T) else []T;470 pub const Slice = if (alignment) |a| ([]align(a) T) else []T;
465471
466 /// Initialize with capacity to hold at least num elements.472 /// Initialize with capacity to hold at least num elements.
473 /// The resulting capacity is likely to be equal to `num`.
467 /// Deinitialize with `deinit` or use `toOwnedSlice`.474 /// Deinitialize with `deinit` or use `toOwnedSlice`.
468 pub fn initCapacity(allocator: *Allocator, num: usize) !Self {475 pub fn initCapacity(allocator: *Allocator, num: usize) !Self {
469 var self = Self{};476 var self = Self{};
470477 try self.ensureTotalCapacityPrecise(allocator, num);
471 const new_memory = try allocator.allocAdvanced(T, alignment, num, .at_least);
472 self.items.ptr = new_memory.ptr;
473 self.capacity = new_memory.len;
474
475 return self;478 return self;
476 }479 }
477480
...@@ -685,7 +688,17 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -685,7 +688,17 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
685 if (better_capacity >= new_capacity) break;688 if (better_capacity >= new_capacity) break;
686 }689 }
687690
688 const new_memory = try allocator.reallocAtLeast(self.allocatedSlice(), better_capacity);691 return self.ensureTotalCapacityPrecise(allocator, better_capacity);
692 }
693
694 /// Modify the array so that it can hold at least `new_capacity` items.
695 /// Like `ensureTotalCapacity`, but the resulting capacity is much more likely
696 /// (but not guaranteed) to be equal to `new_capacity`.
697 /// Invalidates pointers if additional memory is needed.
698 pub fn ensureTotalCapacityPrecise(self: *Self, allocator: *Allocator, new_capacity: usize) !void {
699 if (self.capacity >= new_capacity) return;
700
701 const new_memory = try allocator.reallocAtLeast(self.allocatedSlice(), new_capacity);
689 self.items.ptr = new_memory.ptr;702 self.items.ptr = new_memory.ptr;
690 self.capacity = new_memory.len;703 self.capacity = new_memory.len;
691 }704 }
lib/std/coff.zig+2-2
...@@ -276,7 +276,7 @@ pub const Coff = struct {...@@ -276,7 +276,7 @@ pub const Coff = struct {
276 if (self.sections.items.len == self.coff_header.number_of_sections)276 if (self.sections.items.len == self.coff_header.number_of_sections)
277 return;277 return;
278278
279 try self.sections.ensureTotalCapacity(self.coff_header.number_of_sections);279 try self.sections.ensureTotalCapacityPrecise(self.coff_header.number_of_sections);
280280
281 const in = self.in_file.reader();281 const in = self.in_file.reader();
282282
...@@ -297,7 +297,7 @@ pub const Coff = struct {...@@ -297,7 +297,7 @@ pub const Coff = struct {
297 std.mem.set(u8, name[8..], 0);297 std.mem.set(u8, name[8..], 0);
298 }298 }
299299
300 try self.sections.append(Section{300 self.sections.appendAssumeCapacity(Section{
301 .header = SectionHeader{301 .header = SectionHeader{
302 .name = name,302 .name = name,
303 .misc = SectionHeader.Misc{ .virtual_size = try in.readIntLittle(u32) },303 .misc = SectionHeader.Misc{ .virtual_size = try in.readIntLittle(u32) },
src/Module.zig+1-1
...@@ -4146,7 +4146,7 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: *Allocator) Se...@@ -4146,7 +4146,7 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: *Allocator) Se
4146 // for the runtime ones.4146 // for the runtime ones.
4147 const fn_ty = decl.ty;4147 const fn_ty = decl.ty;
4148 const runtime_params_len = @intCast(u32, fn_ty.fnParamLen());4148 const runtime_params_len = @intCast(u32, fn_ty.fnParamLen());
4149 try inner_block.instructions.ensureTotalCapacity(gpa, runtime_params_len);4149 try inner_block.instructions.ensureTotalCapacityPrecise(gpa, runtime_params_len);
4150 try sema.air_instructions.ensureUnusedCapacity(gpa, fn_info.total_params_len * 2); // * 2 for the `addType`4150 try sema.air_instructions.ensureUnusedCapacity(gpa, fn_info.total_params_len * 2); // * 2 for the `addType`
4151 try sema.inst_map.ensureUnusedCapacity(gpa, fn_info.total_params_len);4151 try sema.inst_map.ensureUnusedCapacity(gpa, fn_info.total_params_len);
41524152
src/link/MachO/CodeSignature.zig+1-1
...@@ -102,7 +102,7 @@ pub fn calcAdhocSignature(...@@ -102,7 +102,7 @@ pub fn calcAdhocSignature(
102 var buffer = try allocator.alloc(u8, page_size);102 var buffer = try allocator.alloc(u8, page_size);
103 defer allocator.free(buffer);103 defer allocator.free(buffer);
104104
105 try cdir.data.ensureTotalCapacity(allocator, total_pages * hash_size + id.len + 1);105 try cdir.data.ensureTotalCapacityPrecise(allocator, total_pages * hash_size + id.len + 1);
106106
107 // 1. Save the identifier and update offsets107 // 1. Save the identifier and update offsets
108 cdir.inner.identOffset = cdir.inner.length;108 cdir.inner.identOffset = cdir.inner.length;
src/link/MachO/commands.zig+1-1
...@@ -223,7 +223,7 @@ pub const SegmentCommand = struct {...@@ -223,7 +223,7 @@ pub const SegmentCommand = struct {
223 var segment = SegmentCommand{223 var segment = SegmentCommand{
224 .inner = inner,224 .inner = inner,
225 };225 };
226 try segment.sections.ensureTotalCapacity(alloc, inner.nsects);226 try segment.sections.ensureTotalCapacityPrecise(alloc, inner.nsects);
227227
228 var i: usize = 0;228 var i: usize = 0;
229 while (i < inner.nsects) : (i += 1) {229 while (i < inner.nsects) : (i += 1) {