mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
std.hash_map: fetchRemove increment available
To avoid leaking slots, `fetchRemove` must increment `available` (when the "fetch" succeeds).
Without the `available += 1`, the added test `"std.hash_map repeat fetchRemove"` fails with
run test std-x86-linux-none-Debug: error: thread 432734 panic: integer overflow
.../zig/lib/std/hash_map.zig:1365:28: 0x6471d5 in getOrPutAssumeCapacityAdapted__anon_47495 (test)
self.available -= 1;
^
.../zig/lib/std/hash_map.zig:1308:62: 0x616950 in getOrPutAssumeCapacityContext (test)
const result = self.getOrPutAssumeCapacityAdapted(key, ctx);
^
Alternatively, `fetchRemove` could call `removeByIndex`, though that would entail calling `header()` twice instead of once.
This commit is contained in:
parent
99fe2a23c0
commit
f04e65bc09
@ -1113,6 +1113,7 @@ pub fn HashMapUnmanaged(
|
||||
old_key.* = undefined;
|
||||
old_val.* = undefined;
|
||||
self.size -= 1;
|
||||
self.available += 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2193,3 +2194,27 @@ test "std.hash_map removeByPtr 0 sized key" {
|
||||
|
||||
try testing.expect(map.count() == 0);
|
||||
}
|
||||
|
||||
test "std.hash_map repeat fetchRemove" {
|
||||
var map = AutoHashMapUnmanaged(u64, void){};
|
||||
defer map.deinit(testing.allocator);
|
||||
|
||||
try map.ensureTotalCapacity(testing.allocator, 4);
|
||||
|
||||
map.putAssumeCapacity(0, {});
|
||||
map.putAssumeCapacity(1, {});
|
||||
map.putAssumeCapacity(2, {});
|
||||
map.putAssumeCapacity(3, {});
|
||||
|
||||
// fetchRemove() should make slots available.
|
||||
var i: usize = 0;
|
||||
while (i < 10) : (i += 1) {
|
||||
try testing.expect(map.fetchRemove(3) != null);
|
||||
map.putAssumeCapacity(3, {});
|
||||
}
|
||||
|
||||
try testing.expect(map.get(0) != null);
|
||||
try testing.expect(map.get(1) != null);
|
||||
try testing.expect(map.get(2) != null);
|
||||
try testing.expect(map.get(3) != null);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user