From f4da5f08a243d8de717f78853afee63f06f0ab4b Mon Sep 17 00:00:00 2001 From: Roycon <4994730+RoyconSkylands@users.noreply.github.com> Date: Tue, 7 Nov 2023 14:39:15 +0000 Subject: [PATCH] Fixes a bug with the bitset hash (#171) * Test verifing bitset bug * Fixing bitset --------- Co-authored-by: ConroyG --- src/Arch.Tests/BitSetTest.cs | 53 ++++++++++++++--------- src/Arch/Core/Utils/CompileTimeStatics.cs | 2 +- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/Arch.Tests/BitSetTest.cs b/src/Arch.Tests/BitSetTest.cs index baa80e26..6d4b99d5 100644 --- a/src/Arch.Tests/BitSetTest.cs +++ b/src/Arch.Tests/BitSetTest.cs @@ -4,7 +4,6 @@ namespace Arch.Tests; - /// /// Checks and HashCode related methods. /// @@ -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) }; @@ -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); @@ -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)); @@ -78,8 +71,8 @@ public void BitsetSetAll() /// The multiplier for the passed values. Mainly for vectorization-testing to increase the set bits. /// [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(); @@ -105,8 +98,8 @@ public void BitsetAll(int[] values, int multiplier) /// The multiplier for the passed values. Mainly for vectorization-testing to increase the set bits. /// [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(); @@ -139,8 +132,8 @@ public void BitsetAny(int[] values, int multiplier) /// The multiplier for the passed values. Mainly for vectorization-testing to increase the set bits. /// [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(); @@ -178,8 +171,8 @@ public void BitsetNone(int[] values, int multiplier) /// The multiplier for the passed values. Mainly for vectorization-testing to increase the set bits. /// [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(); @@ -216,8 +209,8 @@ public void BitsetExclusive(int[] values, int multiplier) /// The multiplier for the passed values. Mainly for vectorization-testing to increase the set bits. /// [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(); @@ -235,4 +228,24 @@ public void AllWithDifferentLengthBitSet(int[] values, int multiplier) That(noneResult, Is.EqualTo(true)); That(exclusive, Is.EqualTo(false)); } + + /// + /// Checks if Id borders a bitset size correctly. + /// The component Id bordering a bitset size + /// + [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))); + } } diff --git a/src/Arch/Core/Utils/CompileTimeStatics.cs b/src/Arch/Core/Utils/CompileTimeStatics.cs index dfc1abad..29b12b08 100644 --- a/src/Arch/Core/Utils/CompileTimeStatics.cs +++ b/src/Arch/Core/Utils/CompileTimeStatics.cs @@ -442,7 +442,7 @@ public static int GetHashCode(Span obj) } // Allocate the stack and set bits to replicate a bitset - var length = BitSet.RequiredLength(highestId); + var length = BitSet.RequiredLength(highestId + 1); Span stack = stackalloc uint[length]; var spanBitSet = new SpanBitSet(stack);