commit 485231deaef9b12e013d423facdef1624f16014b (tree)
parent abcd4ea5d88541a21062e63fe427b2d2ea16a041
Author: Vexu <git@vexu.eu>
Date: Mon, 6 Jul 2020 16:51:53 +0300
fix HashMap.clone()
Diffstat:
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/lib/std/hash_map.zig b/lib/std/hash_map.zig
@@ -529,12 +529,13 @@ pub fn HashMapUnmanaged(
}
pub fn clone(self: Self, allocator: *Allocator) !Self {
- // TODO this can be made more efficient by directly allocating
- // the memory slices and memcpying the elements.
- var other = Self.init();
- try other.initCapacity(allocator, self.entries.len);
- for (self.entries.items) |entry| {
- other.putAssumeCapacityNoClobber(entry.key, entry.value);
+ var other: Self = .{};
+ try other.entries.appendSlice(allocator, self.entries.items);
+
+ if (self.index_header) |header| {
+ const new_header = try IndexHeader.alloc(allocator, header.indexes_len);
+ other.insertAllEntriesIntoNewHeader(new_header);
+ other.index_header = new_header;
}
return other;
}
@@ -976,6 +977,25 @@ test "ensure capacity" {
testing.expect(initial_capacity == map.capacity());
}
+test "clone" {
+ var original = AutoHashMap(i32, i32).init(std.testing.allocator);
+ defer original.deinit();
+
+ // put more than `linear_scan_max` so we can test that the index header is properly cloned
+ var i: u8 = 0;
+ while (i < 10) : (i += 1) {
+ try original.putNoClobber(i, i * 10);
+ }
+
+ var copy = try original.clone();
+ defer copy.deinit();
+
+ i = 0;
+ while (i < 10) : (i += 1) {
+ testing.expect(copy.get(i).? == i * 10);
+ }
+}
+
pub fn getHashPtrAddrFn(comptime K: type) (fn (K) u32) {
return struct {
fn hash(key: K) u32 {