feat(render): unify physical residency accounting

This commit is contained in:
Erik 2026-07-24 16:20:48 +02:00
parent 1866ea0c6d
commit 3e18fc2730
25 changed files with 642 additions and 48 deletions

View file

@ -47,6 +47,11 @@ internal sealed class ResidencyManager
private readonly List<ResidencyObservation> _observationScratch = [];
private readonly List<ResidencyDomainSnapshot> _snapshotScratch = [];
public ResidencyManager(ResidencyBudgetOptions? budgets = null) =>
Budgets = budgets ?? ResidencyBudgetOptions.Default;
public ResidencyBudgetOptions Budgets { get; }
public int ActiveAssetCount => _assetByKey.Count;
public int ActiveOwnerCount => _owners.Count(owner => owner is not null);
@ -355,19 +360,46 @@ internal sealed class ResidencyManager
public ResidencySnapshot CaptureSnapshot()
{
_snapshotScratch.Clear();
for (int i = 0; i < _domainSources.Count; i++)
_snapshotScratch.Add(_domainSources[i].CaptureResidency());
Span<bool> sourced = stackalloc bool[
Enum.GetValues<ResidencyDomain>().Length];
ResidencyCharges totals = default;
for (int i = 0; i < _domainSources.Count; i++)
{
ResidencyDomainSnapshot snapshot =
_domainSources[i].CaptureResidency();
_snapshotScratch.Add(snapshot);
sourced[(int)snapshot.Domain] = true;
totals += snapshot.Charges;
}
ResidencyCharges[] logicalCharges =
new ResidencyCharges[sourced.Length];
int[] logicalEntries = new int[sourced.Length];
int[] logicalOwners = new int[sourced.Length];
for (uint index = 1; index < _assets.Count; index++)
{
AssetSlot? slot = _assets[checked((int)index)];
if (slot is not null)
totals += slot.Charges;
if (slot is null || sourced[(int)slot.Key.Domain])
continue;
int domain = (int)slot.Key.Domain;
logicalCharges[domain] += slot.Charges;
logicalEntries[domain]++;
logicalOwners[domain] = checked(
logicalOwners[domain] + slot.Owners.Count);
}
for (int i = 0; i < _snapshotScratch.Count; i++)
totals += _snapshotScratch[i].Charges;
for (int domain = 0; domain < logicalEntries.Length; domain++)
{
if (logicalEntries[domain] == 0)
continue;
ResidencyCharges charges = logicalCharges[domain];
_snapshotScratch.Add(new ResidencyDomainSnapshot(
(ResidencyDomain)domain,
logicalEntries[domain],
logicalOwners[domain],
charges));
totals += charges;
}
return new ResidencySnapshot(_snapshotScratch.ToArray(), totals);
}