Skip to content

Commit 3031819

Browse files
LucasSantos91andrewrk
authored andcommitted
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 parent 937e8cb commit 3031819

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

lib/std/array_list.zig

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

17631763
test "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");

0 commit comments

Comments
 (0)