bump gen on remove and add
This commit is contained in:
parent
b2a92c5c51
commit
32942c01c8
|
@ -94,7 +94,8 @@ pub fn Table(comptime K: type, comptime V: type) type {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.free_list.popOrNull()) |index| {
|
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.keys.items[index] = key;
|
||||||
self.values.items[index] = val;
|
self.values.items[index] = val;
|
||||||
try self.lookup.putNoClobber(key, index);
|
try self.lookup.putNoClobber(key, index);
|
||||||
|
@ -102,7 +103,7 @@ pub fn Table(comptime K: type, comptime V: type) type {
|
||||||
return AddResult{
|
return AddResult{
|
||||||
.id = .{
|
.id = .{
|
||||||
.index = index,
|
.index = index,
|
||||||
.gen = gen,
|
.gen = self.gens.items[index],
|
||||||
},
|
},
|
||||||
.added = true,
|
.added = true,
|
||||||
};
|
};
|
||||||
|
@ -226,9 +227,10 @@ test "table across generation" {
|
||||||
|
|
||||||
// remove first item, then add a new one, then try to access first item!
|
// remove first item, then add a new one, then try to access first item!
|
||||||
_ = try table.remove(table.find(48) orelse unreachable);
|
_ = 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 });
|
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.expect(!table.exists(first_result.id));
|
||||||
try std.testing.expectEqual(@as(?*TestVal, null), table.get(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.
|
/// Underlying table.
|
||||||
table: InternalTable,
|
table: InternalTable,
|
||||||
/// Reference counts of the values.
|
/// Reference counts of the values.
|
||||||
ref_counts: std.ArrayList(usize),
|
ref_counts: std.ArrayList(u16),
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator) Self {
|
pub fn init(allocator: std.mem.Allocator) Self {
|
||||||
return Self{
|
return Self{
|
||||||
.table = Table(K, V).init(allocator),
|
.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 });
|
first_result = try table.add(12, .{ .a = 6, .b = 5 });
|
||||||
try std.testing.expect(first_result.added);
|
try std.testing.expect(first_result.added);
|
||||||
try std.testing.expectEqual(@as(u24, 0), first_result.id.index);
|
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 });
|
const second_result = try table.add(12, .{ .a = 1, .b = 2 });
|
||||||
try std.testing.expect(!second_result.added);
|
try std.testing.expect(!second_result.added);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue