Skip to content

Commit

Permalink
partial hash map impl
Browse files Browse the repository at this point in the history
  • Loading branch information
2A5F committed Dec 5, 2023
1 parent d70fda2 commit 9a01202
Show file tree
Hide file tree
Showing 9 changed files with 852 additions and 290 deletions.
507 changes: 405 additions & 102 deletions BetterCollections/Misc/ASwissTable.cs

Large diffs are not rendered by default.

127 changes: 0 additions & 127 deletions BetterCollections/Misc/ASwissTable.net_7_or_8.cs

This file was deleted.

57 changes: 0 additions & 57 deletions BetterCollections/Misc/ASwissTable.net_stand_or_6.cs

This file was deleted.

94 changes: 94 additions & 0 deletions BetterCollections/Misc/ASwissTable.simd.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#if NET7_0_OR_GREATER
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;

namespace BetterCollections.Misc;

public abstract partial class ASwissTable
{
#region MatchH2

#if NET8_0_OR_GREATER

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchH2(Vector512<byte> group, Vector512<byte> h2) =>
MatchEmptyOrDelete(Vector512.Equals(group, h2));

#endif

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchH2(Vector256<byte> group, Vector256<byte> h2) =>
MatchEmptyOrDelete(Vector256.Equals(group, h2));

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchH2(Vector128<byte> group, Vector128<byte> h2) =>
MatchEmptyOrDelete(Vector128.Equals(group, h2));

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchH2(Vector64<byte> group, Vector64<byte> h2) =>
MatchEmptyOrDelete(Vector64.Equals(group, h2));

#endregion

#region MatchEmpty

#if NET8_0_OR_GREATER

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchEmpty(Vector512<byte> group) => MatchH2(group, Vector512<byte>.AllBitsSet);

#endif

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchEmpty(Vector256<byte> group) => MatchH2(group, Vector256<byte>.AllBitsSet);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchEmpty(Vector128<byte> group) => MatchH2(group, Vector128<byte>.AllBitsSet);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchEmpty(Vector64<byte> group) => MatchH2(group, Vector64<byte>.AllBitsSet);

#endregion

#region MatchEmptyOrDelete

#if NET8_0_OR_GREATER

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchEmptyOrDelete(Vector512<byte> group) => new(group.ExtractMostSignificantBits());

#endif

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchEmptyOrDelete(Vector256<byte> group) => new(group.ExtractMostSignificantBits());

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchEmptyOrDelete(Vector128<byte> group) => new(group.ExtractMostSignificantBits());

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchEmptyOrDelete(Vector64<byte> group) => new(group.ExtractMostSignificantBits());

#endregion

#region MatchValue

#if NET8_0_OR_GREATER

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchValue(Vector512<byte> group) => MatchEmptyOrDelete(~group);

#endif

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchValue(Vector256<byte> group) => MatchEmptyOrDelete(~group);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchValue(Vector128<byte> group) => MatchEmptyOrDelete(~group);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchValue(Vector64<byte> group) => MatchEmptyOrDelete(~group);

#endregion
}

#endif
64 changes: 64 additions & 0 deletions BetterCollections/Misc/ASwissTable.soft.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Buffers.Binary;
using System.Numerics;
using System.Runtime.CompilerServices;

namespace BetterCollections.Misc;

public abstract partial class ASwissTable
{
// reference https://github.com/rust-lang/hashbrown/blob/9f20bd03377ed725ff125db1bcbabf8c11cd81c7/src/raw/generic.rs

#region Consts

private const ulong ul_x80 = 0x8080808080808080;
private const ulong ul_x01 = 0x0101010101010101;

#endregion

#region MatchH2

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchH2(ulong group, ulong h2)
{
// https://github.com/rust-lang/hashbrown/blob/9f20bd03377ed725ff125db1bcbabf8c11cd81c7/src/raw/generic.rs#L110
// https://graphics.stanford.edu/~seander/bithacks.html##ValueInWord
var cmp = group ^ h2;
var bits = unchecked(cmp - ul_x01) & ~cmp & ul_x80;
if (!BitConverter.IsLittleEndian) bits = BinaryPrimitives.ReverseEndianness(bits);
return new MatchBits(bits, true);
}

#endregion

#region MatchEmpty

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchEmpty(ulong group)
{
var bits = group & (group << 1) & ul_x80;
if (!BitConverter.IsLittleEndian) bits = BinaryPrimitives.ReverseEndianness(bits);
return new MatchBits(bits, true);
}

#endregion

#region MatchEmptyOrDelete

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchEmptyOrDelete(ulong group)
{
var bits = group & ul_x80;
if (!BitConverter.IsLittleEndian) bits = BinaryPrimitives.ReverseEndianness(bits);
return new MatchBits(bits, true);
}

#endregion

#region MatchValue

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static MatchBits MatchValue(ulong group) => MatchEmptyOrDelete(~group);

#endregion
}
Loading

0 comments on commit 9a01202

Please sign in to comment.