forked from vv/efemra
1
0
Fork 0

bump gen on remove and add

This commit is contained in:
Vivianne 2022-07-26 22:48:24 -07:00
parent b2a92c5c51
commit 32942c01c8
1 changed files with 8 additions and 6 deletions

View File

@ -94,7 +94,8 @@ pub fn Table(comptime K: type, comptime V: type) type {
}
if (self.free_list.popOrNull()) |index| {
const gen = self.gens.items[index];
// gen is bumped on remove *and* re-add. This way, 'active' slots are even and 'inactive' slots are odd.
self.gens.items[index] = self.gens.items[index] +% 1;
self.keys.items[index] = key;
self.values.items[index] = val;
try self.lookup.putNoClobber(key, index);
@ -102,7 +103,7 @@ pub fn Table(comptime K: type, comptime V: type) type {
return AddResult{
.id = .{
.index = index,
.gen = gen,
.gen = self.gens.items[index],
},
.added = true,
};
@ -226,9 +227,10 @@ test "table across generation" {
// remove first item, then add a new one, then try to access first item!
_ = try table.remove(table.find(48) orelse unreachable);
try std.testing.expectEqual(@as(u8, 1), table.gens.items[0]);
const second_result = try table.add(99, .{ .a = 2, .b = 3 });
try std.testing.expectEqual(@as(u8, 1), second_result.id.gen);
try std.testing.expectEqual(@as(u8, 2), second_result.id.gen);
try std.testing.expect(!table.exists(first_result.id));
try std.testing.expectEqual(@as(?*TestVal, null), table.get(first_result.id));
@ -248,12 +250,12 @@ pub fn RefTable(comptime K: type, comptime V: type) type {
/// Underlying table.
table: InternalTable,
/// Reference counts of the values.
ref_counts: std.ArrayList(usize),
ref_counts: std.ArrayList(u16),
pub fn init(allocator: std.mem.Allocator) Self {
return Self{
.table = Table(K, V).init(allocator),
.ref_counts = std.ArrayList(usize).init(allocator),
.ref_counts = std.ArrayList(u16).init(allocator),
};
}
@ -411,7 +413,7 @@ test "ref counting" {
first_result = try table.add(12, .{ .a = 6, .b = 5 });
try std.testing.expect(first_result.added);
try std.testing.expectEqual(@as(u24, 0), first_result.id.index);
try std.testing.expectEqual(@as(u8, 1), first_result.id.gen);
try std.testing.expectEqual(@as(u8, 2), first_result.id.gen);
const second_result = try table.add(12, .{ .a = 1, .b = 2 });
try std.testing.expect(!second_result.added);