This is an automated email from the ASF dual-hosted git repository.
blankensteiner pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar-dotpulsar.git
The following commit(s) were added to refs/heads/master by this push:
new c6c4891 Implementing MurmurHash to remove dependency
c6c4891 is described below
commit c6c4891b92b8cacd3bf3525728bb5c2cddb329ba
Author: Daniel Blankensteiner <[email protected]>
AuthorDate: Mon Sep 29 14:55:08 2025 +0200
Implementing MurmurHash to remove dependency
---
CHANGELOG.md | 6 ++
src/DotPulsar/DotPulsar.csproj | 15 +---
src/DotPulsar/Internal/MurmurHash3.cs | 82 ++++++++++++++++++++++
src/DotPulsar/RoundRobinPartitionRouter.cs | 2 +-
src/DotPulsar/SinglePartitionRouter.cs | 2 +-
tests/DotPulsar.Tests/Internal/MurmurHash3Tests.cs | 45 ++++++++++++
6 files changed, 138 insertions(+), 14 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b7278ca..f9db8cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,12 @@ The format is based on [Keep a
Changelog](https://keepachangelog.com/en/1.1.0/)
- Replaced the protobuf-net (version 3.2.56) dependency with Google.Protobuf
(version 3.32.1)
- System.Collections.Immutable (version 9.0.9) is now a dependency for .NET
Standard 2.0 and 2.1
+- Updated the System.IO.Pipelines dependency from version 8.0.0 to 9.0.9 for
.NET Standard 2.0 and 2.1
+
+### Removed
+
+- The HashDepot dependency has been removed
+- .NET 6 and 7 removed as a target frameworks
## [4.3.2] - 2025-09-17
diff --git a/src/DotPulsar/DotPulsar.csproj b/src/DotPulsar/DotPulsar.csproj
index 94110e7..c778576 100644
--- a/src/DotPulsar/DotPulsar.csproj
+++ b/src/DotPulsar/DotPulsar.csproj
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
-
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
+
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
@@ -29,7 +29,6 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers;
buildtransitive</IncludeAssets>
</PackageReference>
- <PackageReference Include="HashDepot" Version="2.0.3" />
<PackageReference Include="Microsoft.Extensions.ObjectPool"
Version="9.0.9" />
</ItemGroup>
@@ -38,21 +37,13 @@
<PackageReference Include="Microsoft.Bcl.HashCode" Version="6.0.0" />
<PackageReference Include="System.Collections.Immutable" Version="9.0.9" />
<PackageReference Include="System.Diagnostics.DiagnosticSource"
Version="9.0.9" />
- <PackageReference Include="System.IO.Pipelines" Version="8.0.0" />
+ <PackageReference Include="System.IO.Pipelines" Version="9.0.9" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
<PackageReference Include="System.Collections.Immutable" Version="9.0.9" />
<PackageReference Include="System.Diagnostics.DiagnosticSource"
Version="9.0.9" />
- <PackageReference Include="System.IO.Pipelines" Version="8.0.0" />
- </ItemGroup>
-
- <ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
- <PackageReference Include="System.IO.Pipelines" Version="8.0.0" />
- </ItemGroup>
-
- <ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
- <PackageReference Include="System.IO.Pipelines" Version="8.0.0" />
+ <PackageReference Include="System.IO.Pipelines" Version="9.0.9" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
diff --git a/src/DotPulsar/Internal/MurmurHash3.cs
b/src/DotPulsar/Internal/MurmurHash3.cs
new file mode 100644
index 0000000..018b4ca
--- /dev/null
+++ b/src/DotPulsar/Internal/MurmurHash3.cs
@@ -0,0 +1,82 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace DotPulsar.Internal;
+
+public static class MurmurHash3
+{
+ private const int UintSize = sizeof(uint);
+
+ public static uint Hash32(ReadOnlySpan<byte> buffer, uint seed)
+ {
+ var length = buffer.Length;
+ var hash = seed;
+ var quotient = Math.DivRem(length, UintSize, out int remainder);
+ var i = 0;
+ var blocks = quotient * UintSize;
+ while (i < blocks)
+ {
+#if NETSTANDARD2_0
+ var value = BitConverter.ToUInt32(buffer.Slice(i,
UintSize).ToArray(), 0);
+#else
+ var value = BitConverter.ToUInt32(buffer.Slice(i, UintSize));
+#endif
+ Round32(ref value, ref hash);
+ hash = RotateLeft(hash, 13);
+ hash *= 5;
+ hash += 0xe6546b64;
+ i += UintSize;
+ }
+
+ if (remainder > 0)
+ {
+ var remaining = PartialBytesToUInt32(buffer.Slice(i, remainder));
+ Round32(ref remaining, ref hash);
+ }
+
+ hash ^= (uint) length;
+ hash ^= hash >> 16;
+ hash *= 0x85ebca6b;
+ hash ^= hash >> 13;
+ hash *= 0xc2b2ae35;
+ hash ^= hash >> 16;
+ return hash;
+ }
+
+ private static uint RotateLeft(uint value, int offset) => (value <<
offset) | (value >> (32 - offset));
+
+ private static void Round32(ref uint value, ref uint hash)
+ {
+ value *= 0xcc9e2d51;
+ value = RotateLeft(value, 15);
+ value *= 0x1b873593;
+ hash ^= value;
+ }
+
+#if NETSTANDARD2_0
+ private static uint PartialBytesToUInt32(ReadOnlySpan<byte> remainingBytes)
+ {
+ var buffer = new byte[UintSize];
+ remainingBytes.CopyTo(buffer);
+ return BitConverter.ToUInt32(buffer, 0);
+ }
+#else
+ private static uint PartialBytesToUInt32(ReadOnlySpan<byte> remainingBytes)
+ {
+ Span<byte> buffer = stackalloc byte[UintSize];
+ remainingBytes.CopyTo(buffer);
+ return BitConverter.ToUInt32(buffer);
+ }
+#endif
+}
diff --git a/src/DotPulsar/RoundRobinPartitionRouter.cs
b/src/DotPulsar/RoundRobinPartitionRouter.cs
index bf692e1..bf72951 100644
--- a/src/DotPulsar/RoundRobinPartitionRouter.cs
+++ b/src/DotPulsar/RoundRobinPartitionRouter.cs
@@ -15,7 +15,7 @@
namespace DotPulsar;
using DotPulsar.Abstractions;
-using HashDepot;
+using DotPulsar.Internal;
/// <summary>
/// The round-robin partition messages router, which is the default router.
diff --git a/src/DotPulsar/SinglePartitionRouter.cs
b/src/DotPulsar/SinglePartitionRouter.cs
index c4284c6..6c909a5 100644
--- a/src/DotPulsar/SinglePartitionRouter.cs
+++ b/src/DotPulsar/SinglePartitionRouter.cs
@@ -15,7 +15,7 @@
namespace DotPulsar;
using DotPulsar.Abstractions;
-using HashDepot;
+using DotPulsar.Internal;
/// <summary>
/// The single partition messages router.
diff --git a/tests/DotPulsar.Tests/Internal/MurmurHash3Tests.cs
b/tests/DotPulsar.Tests/Internal/MurmurHash3Tests.cs
new file mode 100644
index 0000000..401610a
--- /dev/null
+++ b/tests/DotPulsar.Tests/Internal/MurmurHash3Tests.cs
@@ -0,0 +1,45 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace DotPulsar.Tests.Internal;
+
+using DotPulsar.Internal;
+
+[Trait("Category", "Unit")]
+public sealed class MurmurHash3Tests
+{
+ [Theory]
+ [InlineAutoData("", 0U, 0U)]
+ [InlineAutoData("", 1U, 0x514E28B7U)]
+ [InlineAutoData("", 0xffffffffU, 0x81F16F39U)]
+ [InlineAutoData("\0\0\0\0", 0U, 0x2362F9DEU)]
+ [InlineAutoData("aaaa", 0x9747b28cU, 0x5A97808AU)]
+ [InlineAutoData("aaa", 0x9747b28cU, 0x283E0130U)]
+ [InlineAutoData("aa", 0x9747b28cU, 0x5D211726U)]
+ [InlineAutoData("a", 0x9747b28cU, 0x7FA09EA6U)]
+ [InlineAutoData("abcd", 0x9747b28cU, 0xF0478627U)]
+ [InlineAutoData("abc", 0x9747b28cU, 0xC84A62DDU)]
+ [InlineAutoData("ab", 0x9747b28cU, 0x74875592U)]
+ public void Hash32_GivenInput_ShouldCalculateHash(string text, uint seed,
uint expected)
+ {
+ // Arrange
+ var data = System.Text.Encoding.UTF8.GetBytes(text);
+
+ // Act
+ var actual = MurmurHash3.Hash32(data, seed);
+
+ // Assert
+ actual.ShouldBe(expected);
+ }
+}