From 63a4a304c8dd377188fb59e3add017a798cb9982 Mon Sep 17 00:00:00 2001
From: Evan Hemsley <2342303+ehemsley@users.noreply.github.com>
Date: Sat, 28 Dec 2019 20:40:44 -0800
Subject: [PATCH] initial commit
---
.gitignore | 135 +++++++++++++++++++++++++++
MoonTools.FastCollections.sln | 51 ++++++++++
src/BitSet512.cs | 124 ++++++++++++++++++++++++
src/MoonTools.FastCollections.csproj | 17 ++++
test/BitSet512Test.cs | 67 +++++++++++++
test/test.csproj | 20 ++++
6 files changed, 414 insertions(+)
create mode 100644 .gitignore
create mode 100644 MoonTools.FastCollections.sln
create mode 100644 src/BitSet512.cs
create mode 100644 src/MoonTools.FastCollections.csproj
create mode 100644 test/BitSet512Test.cs
create mode 100644 test/test.csproj
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..976300b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,135 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+.vs/
+
+# Build results
+
+[Dd]ebug/
+[Rr]elease/
+x64/
+[Bb]in/
+[Oo]bj/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.log
+*.svclog
+*.scc
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.Publish.xml
+*.pubxml
+*.azurePubxml
+
+# NuGet Packages Directory
+## TODO: If you have NuGet Package Restore enabled, uncomment the next line
+packages/
+## TODO: If the tool you use requires repositories.config, also uncomment the next line
+!packages/repositories.config
+
+# Windows Azure Build Output
+csx/
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+![Ss]tyle[Cc]op.targets
+~$*
+*~
+*.dbmdl
+*.[Pp]ublish.xml
+
+*.publishsettings
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+App_Data/*.mdf
+App_Data/*.ldf
+
+# =========================
+# Windows detritus
+# =========================
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Mac desktop service store files
+.DS_Store
+
+_NCrunch*
+
diff --git a/MoonTools.FastCollections.sln b/MoonTools.FastCollections.sln
new file mode 100644
index 0000000..9de2f73
--- /dev/null
+++ b/MoonTools.FastCollections.sln
@@ -0,0 +1,51 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29613.14
+MinimumVisualStudioVersion = 15.0.26124.0
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MoonTools.FastCollections", "src\MoonTools.FastCollections.csproj", "{A6BAA858-20B5-4274-A216-7E71990DAAFB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "test", "test\test.csproj", "{26DDCFFB-B3AE-4CB4-8671-ABB15862193F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A6BAA858-20B5-4274-A216-7E71990DAAFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A6BAA858-20B5-4274-A216-7E71990DAAFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A6BAA858-20B5-4274-A216-7E71990DAAFB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A6BAA858-20B5-4274-A216-7E71990DAAFB}.Debug|x64.Build.0 = Debug|Any CPU
+ {A6BAA858-20B5-4274-A216-7E71990DAAFB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A6BAA858-20B5-4274-A216-7E71990DAAFB}.Debug|x86.Build.0 = Debug|Any CPU
+ {A6BAA858-20B5-4274-A216-7E71990DAAFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A6BAA858-20B5-4274-A216-7E71990DAAFB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A6BAA858-20B5-4274-A216-7E71990DAAFB}.Release|x64.ActiveCfg = Release|Any CPU
+ {A6BAA858-20B5-4274-A216-7E71990DAAFB}.Release|x64.Build.0 = Release|Any CPU
+ {A6BAA858-20B5-4274-A216-7E71990DAAFB}.Release|x86.ActiveCfg = Release|Any CPU
+ {A6BAA858-20B5-4274-A216-7E71990DAAFB}.Release|x86.Build.0 = Release|Any CPU
+ {26DDCFFB-B3AE-4CB4-8671-ABB15862193F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {26DDCFFB-B3AE-4CB4-8671-ABB15862193F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {26DDCFFB-B3AE-4CB4-8671-ABB15862193F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {26DDCFFB-B3AE-4CB4-8671-ABB15862193F}.Debug|x64.Build.0 = Debug|Any CPU
+ {26DDCFFB-B3AE-4CB4-8671-ABB15862193F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {26DDCFFB-B3AE-4CB4-8671-ABB15862193F}.Debug|x86.Build.0 = Debug|Any CPU
+ {26DDCFFB-B3AE-4CB4-8671-ABB15862193F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {26DDCFFB-B3AE-4CB4-8671-ABB15862193F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {26DDCFFB-B3AE-4CB4-8671-ABB15862193F}.Release|x64.ActiveCfg = Release|Any CPU
+ {26DDCFFB-B3AE-4CB4-8671-ABB15862193F}.Release|x64.Build.0 = Release|Any CPU
+ {26DDCFFB-B3AE-4CB4-8671-ABB15862193F}.Release|x86.ActiveCfg = Release|Any CPU
+ {26DDCFFB-B3AE-4CB4-8671-ABB15862193F}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {085A69AB-C816-491D-B59C-E8533E7F355D}
+ EndGlobalSection
+EndGlobal
diff --git a/src/BitSet512.cs b/src/BitSet512.cs
new file mode 100644
index 0000000..1fc27f4
--- /dev/null
+++ b/src/BitSet512.cs
@@ -0,0 +1,124 @@
+namespace MoonTools.FastCollections
+{
+ public static unsafe class MemoryHelper
+ {
+ public static void Copy(uint* src, uint* dest, int count)
+ {
+ for (; count != 0; count--) *dest++ = *src++;
+ }
+
+ public static void Fill(uint* p, int count, uint value)
+ {
+ for (; count != 0; count--) *p++ = value;
+ }
+
+ public static void And(uint* p, uint* q, uint* result, int count)
+ {
+ for (; count != 0; count--) *result++ = *p++ & *q++;
+ }
+
+ public static void Or(uint* p, uint* q, uint* result, int count)
+ {
+ for (; count != 0; count--) *result++ = *p++ | *q++;
+ }
+
+ public static void Not(uint* p, uint* result, int count)
+ {
+ for (; count != 0; count--) *result++ = ~*p++;
+ }
+
+ public static bool Equal(uint* p, uint* q, int count)
+ {
+ for (; count != 0; count--) if (*p++ != *q++) { return false; }
+ return true;
+ }
+
+ public static bool NotEqual(uint* p, uint* q, int count)
+ {
+ for (; count != 0; count--) if (*p++ == *q++) { return false; }
+ return true;
+ }
+ }
+
+ public unsafe struct BitSet512
+ {
+ public static BitSet512 Zero { get; } = new BitSet512(0);
+ public static BitSet512 Ones { get; } = new BitSet512(uint.MaxValue);
+
+ private const int _uintLength = 16;
+
+ private fixed uint _buffer[_uintLength];
+
+ public BitSet512(uint value)
+ {
+ fixed (uint* p = _buffer) MemoryHelper.Fill(p, _uintLength, value);
+ }
+
+ public BitSet512(uint* src)
+ {
+ fixed (uint* dest = _buffer) MemoryHelper.Copy(src, dest, _uintLength);
+ }
+
+ public static BitSet512 operator &(BitSet512 a, BitSet512 b)
+ {
+ var tmp = stackalloc uint[_uintLength];
+ MemoryHelper.And(a._buffer, b._buffer, tmp, _uintLength);
+ return new BitSet512(tmp);
+ }
+
+ public static BitSet512 operator |(BitSet512 a, BitSet512 b)
+ {
+ var tmp = stackalloc uint[_uintLength];
+ MemoryHelper.Or(a._buffer, b._buffer, tmp, _uintLength);
+ return new BitSet512(tmp);
+ }
+
+ public static BitSet512 operator ~(BitSet512 a)
+ {
+ var tmp = stackalloc uint[_uintLength];
+ MemoryHelper.Not(a._buffer, tmp, _uintLength);
+ return new BitSet512(tmp);
+ }
+
+ public BitSet512 Set(int index)
+ {
+ var tmp = stackalloc uint[_uintLength];
+ fixed (uint* p = _buffer) MemoryHelper.Copy(p, tmp, _uintLength);
+ tmp[index / 32] |= (uint)(1 << index % 32);
+ return new BitSet512(tmp);
+ }
+
+ public BitSet512 UnSet(int index)
+ {
+ var tmp = stackalloc uint[_uintLength];
+ fixed (uint* p = _buffer) MemoryHelper.Copy(p, tmp, _uintLength);
+ tmp[index / 32] &= ~(uint)(1 << index % 32);
+ return new BitSet512(tmp);
+ }
+
+ public bool Get(int bitIndex)
+ {
+ uint thing = _buffer[bitIndex / 32];
+ return (_buffer[bitIndex / 32] & (uint)(1 << bitIndex % 32)) == _buffer[bitIndex / 32];
+ }
+
+ public bool AllTrue()
+ {
+ var tmp = stackalloc uint[_uintLength];
+ MemoryHelper.Fill(tmp, _uintLength, uint.MaxValue);
+ fixed (uint* p = _buffer) return MemoryHelper.Equal(p, tmp, _uintLength);
+ }
+
+ public bool AllFalse()
+ {
+ var tmp = stackalloc uint[_uintLength];
+ MemoryHelper.Fill(tmp, _uintLength, 0);
+ fixed (uint* p = _buffer) return MemoryHelper.Equal(p, tmp, _uintLength);
+ }
+
+ public static BitSet512 BitwiseAnd(BitSet512 left, BitSet512 right)
+ {
+ return left & right;
+ }
+ }
+}
diff --git a/src/MoonTools.FastCollections.csproj b/src/MoonTools.FastCollections.csproj
new file mode 100644
index 0000000..69f61f9
--- /dev/null
+++ b/src/MoonTools.FastCollections.csproj
@@ -0,0 +1,17 @@
+
+
+
+ netstandard2.0
+ true
+ MoonTools.Collections
+ MoonTools.Collections
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
diff --git a/test/BitSet512Test.cs b/test/BitSet512Test.cs
new file mode 100644
index 0000000..b278564
--- /dev/null
+++ b/test/BitSet512Test.cs
@@ -0,0 +1,67 @@
+using NUnit.Framework;
+using FluentAssertions;
+
+namespace MoonTools.FastCollections.Test
+{
+ public class BitSet512Test
+ {
+ [Test]
+ public void Zero()
+ {
+ var bitSet = BitSet512.Zero;
+ bitSet.AllFalse().Should().BeTrue();
+ bitSet.AllTrue().Should().BeFalse();
+ }
+
+ [Test]
+ public void Ones()
+ {
+ var bitSet = BitSet512.Ones;
+ bitSet.AllTrue().Should().BeTrue();
+ bitSet.AllFalse().Should().BeFalse();
+ }
+
+ [Test]
+ public void Set()
+ {
+ var bitSet = BitSet512.Zero.Set(5);
+ bitSet.Get(5).Should().BeTrue();
+ bitSet.AllFalse().Should().BeFalse();
+
+ bitSet = BitSet512.Zero.Set(132);
+ bitSet.Get(132).Should().BeTrue();
+ bitSet.AllFalse().Should().BeFalse();
+
+ bitSet = BitSet512.Zero.Set(268);
+ bitSet.Get(268).Should().BeTrue();
+ bitSet.AllFalse().Should().BeFalse();
+
+ bitSet = BitSet512.Zero.Set(450);
+ bitSet.Get(450).Should().BeTrue();
+ bitSet.AllFalse().Should().BeFalse();
+ }
+
+ [Test]
+ public void UnSet()
+ {
+ var bitSet = BitSet512.Ones.UnSet(285);
+ bitSet.Get(285).Should().BeFalse();
+ bitSet.Set(285).AllTrue().Should().BeTrue();
+ }
+
+ [Test]
+ public void Get()
+ {
+ var bitSet = BitSet512.Zero.Set(359);
+ bitSet.Get(359).Should().BeTrue();
+ bitSet.UnSet(359).AllFalse().Should().BeTrue();
+ }
+
+ [Test]
+ public void Not()
+ {
+ var bitSet = ~BitSet512.Ones;
+ bitSet.AllFalse().Should().BeTrue();
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/test.csproj b/test/test.csproj
new file mode 100644
index 0000000..2a7d93d
--- /dev/null
+++ b/test/test.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+