authorgravatar for lucascarvalhosantos91@gmail.comLucas Santos <lucascarvalhosantos91@gmail.com> 2023-09-30 14:43:08-03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-30 16:17:22-07:00
log303181901b0a5e62ece5d4b786ee537a50d07709
treefc2ce51e937ee3499bb18e64271a3928f3db1655
parent937e8cb7051a3de537e11c2d52946f772f7449c3

Improve (Unmanaged)ArrayList.insert

(Unmanaged)ArrayList.insert has the same inefficiency as the old insertSlice. With the new addManyAt, the solution is trivial. Also improves the test "growing memory preserves contents". In the previous implementation, if any changes were made to the ArrayList memory growth policy (function growMemory), the list could end up with enough capacity to not trigger a memory growth, defeating the purpose of the test. The new implementation more robustly triggers a memory growth.

1 files changed, 10 insertions(+), 10 deletions(-)

lib/std/array_list.zig+10-10
......@@ -146,8 +146,8 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
146146 /// This operation is O(N).
147147 /// Invalidates pointers if additional memory is needed.
148148 pub fn insert(self: *Self, n: usize, item: T) Allocator.Error!void {
149 try self.ensureUnusedCapacity(1);
150 self.insertAssumeCapacity(n, item);
149 const dst = try self.addManyAt(n, 1);
150 dst[0] = item;
151151 }
152152
153153 /// Insert `item` at index `n`. Moves `list[n .. list.len]` to higher indices to make room.
......@@ -702,8 +702,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
702702 /// This operation is O(N).
703703 /// Invalidates pointers if additional memory is needed.
704704 pub fn insert(self: *Self, allocator: Allocator, n: usize, item: T) Allocator.Error!void {
705 try self.ensureUnusedCapacity(allocator, 1);
706 self.insertAssumeCapacity(n, item);
705 const dst = try self.addManyAt(allocator, n, 1);
706 dst[0] = item;
707707 }
708708
709709 /// Insert `item` at index `n`. Moves `list[n .. list.len]` to higher indices to make room.
......@@ -1761,33 +1761,33 @@ test "std.ArrayList/ArrayListUnmanaged.addManyAsArray" {
17611761}
17621762
17631763test "std.ArrayList/ArrayListUnmanaged growing memory preserves contents" {
1764 // Shrink the list after every insertion to ensure that a memory growth
1765 // will be triggered in the next operation.
17641766 const a = std.testing.allocator;
17651767 {
17661768 var list = ArrayList(u8).init(a);
17671769 defer list.deinit();
1768 try list.ensureTotalCapacityPrecise(1);
17691770
17701771 (try list.addManyAsArray(4)).* = "abcd".*;
1771 try list.ensureTotalCapacityPrecise(4);
1772 list.shrinkAndFree(4);
17721773
17731774 try list.appendSlice("efgh");
17741775 try testing.expectEqualSlices(u8, list.items, "abcdefgh");
1775 try list.ensureTotalCapacityPrecise(8);
1776 list.shrinkAndFree(8);
17761777
17771778 try list.insertSlice(4, "ijkl");
17781779 try testing.expectEqualSlices(u8, list.items, "abcdijklefgh");
17791780 }
17801781 {
17811782 var list = ArrayListUnmanaged(u8){};
1782 try list.ensureTotalCapacityPrecise(a, 1);
17831783 defer list.deinit(a);
17841784
17851785 (try list.addManyAsArray(a, 4)).* = "abcd".*;
1786 try list.ensureTotalCapacityPrecise(a, 4);
1786 list.shrinkAndFree(a, 4);
17871787
17881788 try list.appendSlice(a, "efgh");
17891789 try testing.expectEqualSlices(u8, list.items, "abcdefgh");
1790 try list.ensureTotalCapacityPrecise(a, 8);
1790 list.shrinkAndFree(a, 8);
17911791
17921792 try list.insertSlice(a, 4, "ijkl");
17931793 try testing.expectEqualSlices(u8, list.items, "abcdijklefgh");