Skip to content

Commit

Permalink
Fixes a bug with the bitset hash (#171)
Browse files Browse the repository at this point in the history
* Test verifing bitset bug

* Fixing bitset

---------

Co-authored-by: ConroyG <conroygriffiths@windowslive.com>
  • Loading branch information
RoyconSkylands and ConroyG authored Nov 7, 2023
1 parent 776664d commit f4da5f0
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 21 deletions.
53 changes: 33 additions & 20 deletions src/Arch.Tests/BitSetTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Arch.Tests;


/// <summary>
/// Checks <see cref="BitSet"/> and HashCode related methods.
/// </summary>
Expand All @@ -17,7 +16,6 @@ public class BitSetTest
[Test]
public void ComponentHashOrder()
{

ComponentType[] array1 = { typeof(int), typeof(byte) };
ComponentType[] array2 = { typeof(int), typeof(byte) };
ComponentType[] array3 = { typeof(byte), typeof(int) };
Expand All @@ -32,13 +30,7 @@ public void ComponentHashOrder()
[Test]
public void HashSimilarity()
{
var array = new ComponentType[]
{
new (1, 0),
new (36, 0),
new (65, 0),
new (5, 0),
};
var array = new ComponentType[] { new(1, 0), new(36, 0), new(65, 0), new(5, 0), };

var bitSet = new BitSet();
bitSet.SetBit(1);
Expand Down Expand Up @@ -66,7 +58,8 @@ public void BitsetSetAll()
{
count += 32; // 32 Bits in each uint
}
count--; // Minus one because we start at 0

count--; // Minus one because we start at 0

// ALl fit
That(bitSet.HighestBit, Is.EqualTo(count));
Expand All @@ -78,8 +71,8 @@ public void BitsetSetAll()
/// <param name="multiplier">The multiplier for the passed values. Mainly for vectorization-testing to increase the set bits.</param>
/// </summary>
[Test]
[TestCase(new []{5,6,7}, 1)] // Sets bit 5,6,7
[TestCase(new []{5,6,7}, 100)] // Sets bit 500,600,700
[TestCase(new[] { 5, 6, 7 }, 1)] // Sets bit 5,6,7
[TestCase(new[] { 5, 6, 7 }, 100)] // Sets bit 500,600,700
public void BitsetAll(int[] values, int multiplier)
{
var bitSet1 = new BitSet();
Expand All @@ -105,8 +98,8 @@ public void BitsetAll(int[] values, int multiplier)
/// <param name="multiplier">The multiplier for the passed values. Mainly for vectorization-testing to increase the set bits.</param>
/// </summary>
[Test]
[TestCase(new []{5,6,35,36,37}, 1)]
[TestCase(new []{5,6,35,36,37}, 100)]
[TestCase(new[] { 5, 6, 35, 36, 37 }, 1)]
[TestCase(new[] { 5, 6, 35, 36, 37 }, 100)]
public void BitsetAny(int[] values, int multiplier)
{
var bitSet1 = new BitSet();
Expand Down Expand Up @@ -139,8 +132,8 @@ public void BitsetAny(int[] values, int multiplier)
/// <param name="multiplier">The multiplier for the passed values. Mainly for vectorization-testing to increase the set bits.</param>
/// </summary>
[Test]
[TestCase(new []{5,6,25,38,4}, 1)]
[TestCase(new []{5,6,25,38,4}, 100)]
[TestCase(new[] { 5, 6, 25, 38, 4 }, 1)]
[TestCase(new[] { 5, 6, 25, 38, 4 }, 100)]
public void BitsetNone(int[] values, int multiplier)
{
var bitSet1 = new BitSet();
Expand Down Expand Up @@ -178,8 +171,8 @@ public void BitsetNone(int[] values, int multiplier)
/// <param name="multiplier">The multiplier for the passed values. Mainly for vectorization-testing to increase the set bits.</param>
/// </summary>
[Test]
[TestCase(new []{5,6,25}, 1)]
[TestCase(new []{5,6,25}, 100)]
[TestCase(new[] { 5, 6, 25 }, 1)]
[TestCase(new[] { 5, 6, 25 }, 100)]
public void BitsetExclusive(int[] values, int multiplier)
{
var bitSet1 = new BitSet();
Expand Down Expand Up @@ -216,8 +209,8 @@ public void BitsetExclusive(int[] values, int multiplier)
/// <param name="multiplier">The multiplier for the passed values. Mainly for vectorization-testing to increase the set bits.</param>
/// </summary>
[Test]
[TestCase(new []{5,33}, 1)]
[TestCase(new []{5,33}, 100)]
[TestCase(new[] { 5, 33 }, 1)]
[TestCase(new[] { 5, 33 }, 100)]
public void AllWithDifferentLengthBitSet(int[] values, int multiplier)
{
var bitSet1 = new BitSet();
Expand All @@ -235,4 +228,24 @@ public void AllWithDifferentLengthBitSet(int[] values, int multiplier)
That(noneResult, Is.EqualTo(true));
That(exclusive, Is.EqualTo(false));
}

/// <summary>
/// Checks if <see cref="ComponentType"/> Id borders a bitset size correctly.
/// <param name="borderComponentId">The component Id bordering a bitset size</param>
/// </summary>
[Theory]
[TestCase(32)]
[TestCase(64)]
[TestCase(96)]
[TestCase(128)]
public void Component32Hash(int borderComponentId)
{
var componentTypeNotOnBorder = new ComponentType(borderComponentId - 10, 0);
var componentTypeOnBorder = new ComponentType(borderComponentId, 0);

ComponentType[] array1 = { componentTypeNotOnBorder, componentTypeOnBorder };
ComponentType[] array2 = { componentTypeNotOnBorder };

That(Component.GetHashCode(array1), Is.Not.EqualTo(Component.GetHashCode(array2)));
}
}
2 changes: 1 addition & 1 deletion src/Arch/Core/Utils/CompileTimeStatics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ public static int GetHashCode(Span<ComponentType> obj)
}

// Allocate the stack and set bits to replicate a bitset
var length = BitSet.RequiredLength(highestId);
var length = BitSet.RequiredLength(highestId + 1);
Span<uint> stack = stackalloc uint[length];
var spanBitSet = new SpanBitSet(stack);

Expand Down

0 comments on commit f4da5f0

Please sign in to comment.