diff --git a/src/containers/table.zig b/src/containers/table.zig index e874f3e..16162a7 100644 --- a/src/containers/table.zig +++ b/src/containers/table.zig @@ -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);