From 19092d4025f8b088275074f0da91dcbe9830ab8e Mon Sep 17 00:00:00 2001 From: Evan Hemsley <2342303+ehemsley@users.noreply.github.com> Date: Sat, 28 Dec 2019 21:16:14 -0800 Subject: [PATCH] add equals to bitset512 --- src/BitSet512.cs | 59 +++++++++++++++++++++++----- src/MoonTools.FastCollections.csproj | 9 ++++- test/BitSet512Test.cs | 52 ++++++++++++++++++++++-- 3 files changed, 104 insertions(+), 16 deletions(-) diff --git a/src/BitSet512.cs b/src/BitSet512.cs index 1fc27f4..8d18741 100644 --- a/src/BitSet512.cs +++ b/src/BitSet512.cs @@ -1,4 +1,7 @@ -namespace MoonTools.FastCollections +using System; +using System.Collections.Generic; + +namespace MoonTools.FastCollections { public static unsafe class MemoryHelper { @@ -40,7 +43,7 @@ } } - public unsafe struct BitSet512 + public unsafe struct BitSet512 : IEquatable { public static BitSet512 Zero { get; } = new BitSet512(0); public static BitSet512 Ones { get; } = new BitSet512(uint.MaxValue); @@ -80,6 +83,16 @@ return new BitSet512(tmp); } + public static bool operator ==(BitSet512 left, BitSet512 right) + { + return left.Equals(right); + } + + public static bool operator !=(BitSet512 left, BitSet512 right) + { + return !(left == right); + } + public BitSet512 Set(int index) { var tmp = stackalloc uint[_uintLength]; @@ -98,27 +111,53 @@ public bool Get(int bitIndex) { - uint thing = _buffer[bitIndex / 32]; - return (_buffer[bitIndex / 32] & (uint)(1 << bitIndex % 32)) == _buffer[bitIndex / 32]; + var bitInt = (uint)(1 << bitIndex % 32); + return (_buffer[bitIndex / 32] & bitInt) == bitInt; } public bool AllTrue() { - var tmp = stackalloc uint[_uintLength]; - MemoryHelper.Fill(tmp, _uintLength, uint.MaxValue); - fixed (uint* p = _buffer) return MemoryHelper.Equal(p, tmp, _uintLength); + return this == Ones; } public bool AllFalse() { - var tmp = stackalloc uint[_uintLength]; - MemoryHelper.Fill(tmp, _uintLength, 0); - fixed (uint* p = _buffer) return MemoryHelper.Equal(p, tmp, _uintLength); + return this == Zero; } public static BitSet512 BitwiseAnd(BitSet512 left, BitSet512 right) { return left & right; } + + public static BitSet512 BitwiseOr(BitSet512 left, BitSet512 right) + { + return left | right; + } + + public static BitSet512 OnesComplement(BitSet512 bitSet) + { + return ~bitSet; + } + + public override bool Equals(object obj) + { + return obj is BitSet512 set && Equals(set); + } + + public bool Equals(BitSet512 other) + { + fixed (uint* p = _buffer) return MemoryHelper.Equal(p, other._buffer, _uintLength); + } + + public override int GetHashCode() + { + var hc = 0; + for (var i = 0; i < _uintLength; i++) + { + hc ^= _buffer[i].GetHashCode(); + } + return hc; + } } } diff --git a/src/MoonTools.FastCollections.csproj b/src/MoonTools.FastCollections.csproj index 69f61f9..cd18c7c 100644 --- a/src/MoonTools.FastCollections.csproj +++ b/src/MoonTools.FastCollections.csproj @@ -3,8 +3,13 @@ netstandard2.0 true - MoonTools.Collections - MoonTools.Collections + MoonTools.FastCollections + MoonTools.FastCollections + true + Evan Hemsley 2019 + Fast collections using unsafe code. + https://github.com/MoonsideGames/MoonTools.FastCollections + https://github.com/MoonsideGames/MoonTools.FastCollections diff --git a/test/BitSet512Test.cs b/test/BitSet512Test.cs index b278564..2f0be43 100644 --- a/test/BitSet512Test.cs +++ b/test/BitSet512Test.cs @@ -44,17 +44,19 @@ namespace MoonTools.FastCollections.Test [Test] public void UnSet() { - var bitSet = BitSet512.Ones.UnSet(285); + var bitSet = BitSet512.Ones.UnSet(285).UnSet(24).UnSet(69); bitSet.Get(285).Should().BeFalse(); - bitSet.Set(285).AllTrue().Should().BeTrue(); + bitSet.Get(24).Should().BeFalse(); + bitSet.Get(69).Should().BeFalse(); } [Test] public void Get() { - var bitSet = BitSet512.Zero.Set(359); + var bitSet = BitSet512.Zero.Set(359).Set(23).Set(63); bitSet.Get(359).Should().BeTrue(); - bitSet.UnSet(359).AllFalse().Should().BeTrue(); + bitSet.Get(23).Should().BeTrue(); + bitSet.Get(63).Should().BeTrue(); } [Test] @@ -63,5 +65,47 @@ namespace MoonTools.FastCollections.Test var bitSet = ~BitSet512.Ones; bitSet.AllFalse().Should().BeTrue(); } + + [Test] + public void Or() + { + var a = BitSet512.Zero.Set(10); + var b = BitSet512.Zero.Set(35); + + var or = a | b; + or.Get(10).Should().BeTrue(); + or.Get(35).Should().BeTrue(); + } + + [Test] + public void And() + { + var a = BitSet512.Zero.Set(10).Set(15).Set(20); + var b = BitSet512.Zero.Set(10).Set(15).Set(18); + + var and = a & b; + and.Get(10).Should().BeTrue(); + and.Get(15).Should().BeTrue(); + and.Get(18).Should().BeFalse(); + } + + [Test] + public void Equal() + { + var zeroes = BitSet512.Zero; + (zeroes == BitSet512.Zero).Should().BeTrue(); + + var ones = BitSet512.Ones; + (ones == BitSet512.Ones).Should().BeTrue(); + + (zeroes != ones).Should().BeTrue(); + + var a = BitSet512.Zero.Set(6); + var b = BitSet512.Zero.Set(6); + var c = BitSet512.Zero.Set(12); + + (a == b).Should().BeTrue(); + (a == c).Should().BeFalse(); + } } } \ No newline at end of file