Skip to content

Instantly share code, notes, and snippets.

@nilpunch
Created March 14, 2026 11:21
Show Gist options
  • Select an option

  • Save nilpunch/7dc950887c99135bd9e880ee02d6a66c to your computer and use it in GitHub Desktop.

Select an option

Save nilpunch/7dc950887c99135bd9e880ee02d6a66c to your computer and use it in GitHub Desktop.
New iteration algo
public void ForEach<T1, T2, T3, T4, TAction>(ref TAction action)
where TAction : IEntityAction<T1, T2, T3, T4>
{
NoDataException.ThrowIfHasNoData<T1>(World, DataAccessContext.View);
NoDataException.ThrowIfHasNoData<T2>(World, DataAccessContext.View);
NoDataException.ThrowIfHasNoData<T3>(World, DataAccessContext.View);
NoDataException.ThrowIfHasNoData<T4>(World, DataAccessContext.View);
var dataSet1 = World.DataSet<T1>();
var dataSet2 = World.DataSet<T2>();
var dataSet3 = World.DataSet<T3>();
var dataSet4 = World.DataSet<T4>();
FilterException.ThrowIfCantQuery<T1>(Filter, dataSet1);
FilterException.ThrowIfCantQuery<T2>(Filter, dataSet2);
FilterException.ThrowIfCantQuery<T3>(Filter, dataSet3);
FilterException.ThrowIfCantQuery<T4>(Filter, dataSet4);
var cache = QueryCache.Rent()
.AddInclude(dataSet1)
.AddInclude(dataSet2)
.AddInclude(dataSet3)
.AddInclude(dataSet4);
ApplyFilter(Filter, cache);
cache.Update();
var deBruijn = MathUtils.DeBruijn;
var nonEmptyBitsCount = cache.NonEmptyBitsCount;
var nonEmptyBitsIndices = cache.NonEmptyBitsIndices;
var cachedBits = cache.Bits;
for (var i = 0; i < nonEmptyBitsCount; i++)
{
var bitsIndex = nonEmptyBitsIndices[i];
ref var bitsRef = ref cachedBits[bitsIndex];
var bits = bitsRef;
if (bits == 0UL)
{
continue;
}
var bitsOffset = bitsIndex << 6;
var dataOffset = bitsOffset & Constants.PageSizeMinusOne;
var pageIndex = bitsOffset >> Constants.PageSizePower;
var dataPage1 = dataSet1.PagedData[pageIndex];
var dataPage2 = dataSet2.PagedData[pageIndex];
var dataPage3 = dataSet3.PagedData[pageIndex];
var dataPage4 = dataSet4.PagedData[pageIndex];
var isolatedBit = bits & (ulong)-(long)bits;
var bit = deBruijn[(uint)((isolatedBit * 0x37E84A99DAE458FUL) >> 58)];
var dataIndex = dataOffset + bit;
var entityIndex = bitsOffset + bit;
do
{
if ((bits & isolatedBit) == 0)
{
isolatedBit = bits & (ulong)-(long)bits;
bit = deBruijn[(uint)((isolatedBit * 0x37E84A99DAE458FUL) >> 58)];
dataIndex = dataOffset + bit;
entityIndex = bitsOffset + bit;
}
action.Apply(
entityIndex,
ref dataPage1[dataIndex],
ref dataPage2[dataIndex],
ref dataPage3[dataIndex],
ref dataPage4[dataIndex]
);
bits = (bits ^ isolatedBit) & bitsRef;
isolatedBit <<= 1;
dataIndex++;
entityIndex++;
} while (bits != 0);
}
QueryCache.ReturnAndPop(cache);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment