obj: Make field tracking use a single bitset
This commit is contained in:
parent
a43ffcacc2
commit
797f8f7a58
1 changed files with 14 additions and 9 deletions
|
|
@ -69,7 +69,7 @@ pub fn Objects(options: ObjectsOptions, comptime T: type) type {
|
||||||
graph: *Graph,
|
graph: *Graph,
|
||||||
|
|
||||||
/// A bitset per-field used to track field changes. Only used if options.track_fields == true.
|
/// A bitset per-field used to track field changes. Only used if options.track_fields == true.
|
||||||
updated: ?std.ArrayListUnmanaged(std.bit_set.DynamicBitSetUnmanaged) = if (options.track_fields) .{} else null,
|
updated: ?std.bit_set.DynamicBitSetUnmanaged = if (options.track_fields) .{} else null,
|
||||||
},
|
},
|
||||||
|
|
||||||
pub const IsMachObjects = void;
|
pub const IsMachObjects = void;
|
||||||
|
|
@ -187,9 +187,9 @@ pub fn Objects(options: ObjectsOptions, comptime T: type) type {
|
||||||
try dead.resize(allocator, data.capacity, true);
|
try dead.resize(allocator, data.capacity, true);
|
||||||
try generation.ensureUnusedCapacity(allocator, 1);
|
try generation.ensureUnusedCapacity(allocator, 1);
|
||||||
|
|
||||||
|
// If we are tracking fields, we need to resize the bitset to hold another object's fields
|
||||||
if (objs.internal.updated) |*updated_fields| {
|
if (objs.internal.updated) |*updated_fields| {
|
||||||
try updated_fields.ensureUnusedCapacity(allocator, 1);
|
try updated_fields.resize(allocator, data.capacity * @typeInfo(T).@"struct".fields.len, false);
|
||||||
updated_fields.appendAssumeCapacity(try std.bit_set.DynamicBitSetUnmanaged.initEmpty(allocator, @typeInfo(T).@"struct".fields.len));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const index = data.len;
|
const index = data.len;
|
||||||
|
|
@ -225,7 +225,11 @@ pub fn Objects(options: ObjectsOptions, comptime T: type) type {
|
||||||
const unpacked = objs.validateAndUnpack(id, "setAll");
|
const unpacked = objs.validateAndUnpack(id, "setAll");
|
||||||
data.set(unpacked.index, value);
|
data.set(unpacked.index, value);
|
||||||
|
|
||||||
if (options.track_fields) objs.internal.updated.items[unpacked.index].setAll();
|
if (objs.internal.updated) |*updated_fields| {
|
||||||
|
const updated_start = unpacked.index * @typeInfo(T).@"struct".fields.len;
|
||||||
|
const updated_end = updated_start + @typeInfo(T).@"struct".fields.len;
|
||||||
|
updated_fields.setRangeValue(.{ .start = @intCast(updated_start), .end = @intCast(updated_end) }, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a single field of the given object to the given value.
|
/// Sets a single field of the given object to the given value.
|
||||||
|
|
@ -257,8 +261,8 @@ pub fn Objects(options: ObjectsOptions, comptime T: type) type {
|
||||||
|
|
||||||
if (options.track_fields)
|
if (options.track_fields)
|
||||||
if (std.meta.fieldIndex(T, @tagName(field_name))) |field_index|
|
if (std.meta.fieldIndex(T, @tagName(field_name))) |field_index|
|
||||||
if (objs.internal.updated) |updated_fields|
|
if (objs.internal.updated) |*updated_fields|
|
||||||
updated_fields.items[unpacked.index].set(field_index);
|
updated_fields.set(unpacked.index * @typeInfo(T).@"struct".fields.len + field_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a single field.
|
/// Get a single field.
|
||||||
|
|
@ -324,9 +328,10 @@ pub fn Objects(options: ObjectsOptions, comptime T: type) type {
|
||||||
const unpacked = objs.validateAndUnpack(id, "updated");
|
const unpacked = objs.validateAndUnpack(id, "updated");
|
||||||
if (std.meta.fieldIndex(T, @tagName(field_name))) |field_index| {
|
if (std.meta.fieldIndex(T, @tagName(field_name))) |field_index| {
|
||||||
if (objs.internal.updated) |*updated_fields| {
|
if (objs.internal.updated) |*updated_fields| {
|
||||||
const value = updated_fields.items[unpacked.index].isSet(field_index);
|
const updated_index = unpacked.index * @typeInfo(T).@"struct".fields.len + field_index;
|
||||||
updated_fields.items[unpacked.index].unset(field_index);
|
const updated_value = updated_fields.isSet(updated_index);
|
||||||
return value;
|
updated_fields.unset(updated_index);
|
||||||
|
return updated_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue