Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions eng/StackExchange.Redis.Build/AsciiHashGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -484,13 +484,30 @@ private void BuildEnumParsers(
alwaysCaseSensitive = true;
}

bool twoPart = method.Members.Max(x => x.ParseText.Length) > AsciiHash.MaxBytesHashed;
if (alwaysCaseSensitive)
{
NewLine().Append("var hashCS = global::RESPite.AsciiHash.HashCS(").Append(method.From.Name).Append(");");
if (twoPart)
{
NewLine().Append("global::RESPite.AsciiHash.HashCS(").Append(method.From.Name).Append(", out var cs0, out var cs1);");
}
else
{
NewLine().Append("var cs0 = global::RESPite.AsciiHash.HashCS(").Append(method.From.Name).Append(");");
}
}
else
{
NewLine().Append("global::RESPite.AsciiHash.Hash(").Append(method.From.Name).Append(", out var hashCS, out var hashUC);");
if (twoPart)
{
NewLine().Append("global::RESPite.AsciiHash.Hash(").Append(method.From.Name)
.Append(", out var cs0, out var uc0, out var cs1, out var uc1);");
}
else
{
NewLine().Append("global::RESPite.AsciiHash.Hash(").Append(method.From.Name)
.Append(", out var cs0, out var uc0);");
}
}

if (string.IsNullOrEmpty(method.CaseSensitive.Name))
Expand Down Expand Up @@ -544,31 +561,45 @@ void Write(bool caseSensitive)
.ThenBy(x => x.ParseText))
{
var len = member.ParseText.Length;
AsciiHash.Hash(member.ParseText, out var hashCS, out var hashUC);
AsciiHash.Hash(member.ParseText, out var cs0, out var uc0, out var cs1, out var uc1);

bool valueCaseSensitive = caseSensitive || !HasCaseSensitiveCharacters(member.ParseText);

line = NewLine().Append(len);
line = NewLine().Append(len).Append(" when ");
if (twoPart) line.Append("(");
if (valueCaseSensitive)
{
line.Append(" when hashCS is ").Append(hashCS);
line.Append("cs0 is ").Append(cs0);
}
else
{
line.Append(" when hashUC is ").Append(hashUC);
line.Append("uc0 is ").Append(uc0);
}

if (len > AsciiHash.MaxBytesHashed)
{
if (valueCaseSensitive)
{
line.Append(" & cs1 is ").Append(cs1);
}
else
{
line.Append(" & uc1 is ").Append(uc1);
}
}
if (twoPart) line.Append(")");
if (len > 2 * AsciiHash.MaxBytesHashed)
{
line.Append(" && ");
var csValue = SyntaxFactory
.LiteralExpression(
SyntaxKind.StringLiteralExpression,
SyntaxFactory.Literal(member.ParseText))
SyntaxFactory.Literal(member.ParseText.Substring(2 * AsciiHash.MaxBytesHashed)))
.ToFullString();

line.Append("global::RESPite.AsciiHash.")
.Append(valueCaseSensitive ? nameof(AsciiHash.SequenceEqualsCS) : nameof(AsciiHash.SequenceEqualsCI))
.Append("(").Append(method.From.Name).Append(", ").Append(csValue);
.Append("(").Append(method.From.Name).Append(".Slice(").Append(2 * AsciiHash.MaxBytesHashed).Append("), ").Append(csValue);
if (method.From.IsBytes) line.Append("u8");
line.Append(")");
}
Expand Down
9 changes: 8 additions & 1 deletion src/RESPite/PublicAPI/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
[SER004]RESPite.AsciiHash.AsciiHash() -> void
[SER004]RESPite.AsciiHash.AsciiHash(byte[]! arr) -> void
[SER004]RESPite.AsciiHash.AsciiHash(byte[]! arr, int index, int length) -> void
[SER004]RESPite.AsciiHash.AsciiHash(string! value) -> void
[SER004]RESPite.AsciiHash.AsciiHash(System.ReadOnlySpan<byte> value) -> void
[SER004]RESPite.AsciiHash.BufferLength.get -> int
[SER004]RESPite.AsciiHash.Equals(in RESPite.AsciiHash other) -> bool
Expand All @@ -21,6 +20,8 @@
[SER004]RESPite.AsciiHashAttribute.CaseSensitive.get -> bool
[SER004]RESPite.AsciiHashAttribute.CaseSensitive.set -> void
[SER004]RESPite.AsciiHashAttribute.Token.get -> string!
[SER004]RESPite.AsciiHash.AsciiHash(string? value) -> void
[SER004]RESPite.AsciiHash.IsEmpty.get -> bool
[SER004]RESPite.Buffers.CycleBuffer
[SER004]RESPite.Buffers.CycleBuffer.Commit(int count) -> void
[SER004]RESPite.Buffers.CycleBuffer.CommittedIsEmpty.get -> bool
Expand Down Expand Up @@ -58,11 +59,17 @@
[SER004]static RESPite.AsciiHash.EqualsCS(System.ReadOnlySpan<byte> first, System.ReadOnlySpan<byte> second) -> bool
[SER004]static RESPite.AsciiHash.EqualsCS(System.ReadOnlySpan<char> first, System.ReadOnlySpan<char> second) -> bool
[SER004]static RESPite.AsciiHash.Hash(scoped System.ReadOnlySpan<byte> value, out long cs, out long uc) -> void
[SER004]static RESPite.AsciiHash.Hash(scoped System.ReadOnlySpan<byte> value, out long cs0, out long uc0, out long cs1, out long uc1) -> void
[SER004]static RESPite.AsciiHash.Hash(scoped System.ReadOnlySpan<char> value, out long cs, out long uc) -> void
[SER004]static RESPite.AsciiHash.Hash(scoped System.ReadOnlySpan<char> value, out long cs0, out long uc0, out long cs1, out long uc1) -> void
[SER004]static RESPite.AsciiHash.HashCS(scoped System.ReadOnlySpan<byte> value) -> long
[SER004]static RESPite.AsciiHash.HashCS(scoped System.ReadOnlySpan<byte> value, out long cs0, out long cs1) -> void
[SER004]static RESPite.AsciiHash.HashCS(scoped System.ReadOnlySpan<char> value) -> long
[SER004]static RESPite.AsciiHash.HashCS(scoped System.ReadOnlySpan<char> value, out long cs0, out long cs1) -> void
[SER004]static RESPite.AsciiHash.HashUC(scoped System.ReadOnlySpan<byte> value) -> long
[SER004]static RESPite.AsciiHash.HashUC(scoped System.ReadOnlySpan<byte> value, out long cs0, out long cs1) -> void
[SER004]static RESPite.AsciiHash.HashUC(scoped System.ReadOnlySpan<char> value) -> long
[SER004]static RESPite.AsciiHash.HashUC(scoped System.ReadOnlySpan<char> value, out long cs0, out long cs1) -> void
[SER004]static RESPite.AsciiHash.SequenceEqualsCI(System.ReadOnlySpan<byte> first, System.ReadOnlySpan<byte> second) -> bool
[SER004]static RESPite.AsciiHash.SequenceEqualsCI(System.ReadOnlySpan<char> first, System.ReadOnlySpan<char> second) -> bool
[SER004]static RESPite.AsciiHash.SequenceEqualsCS(System.ReadOnlySpan<byte> first, System.ReadOnlySpan<byte> second) -> bool
Expand Down
3 changes: 2 additions & 1 deletion src/RESPite/Shared/AsciiHash.Instance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ namespace RESPite;
public int BufferLength => (Length + 1 + 7) & ~7; // an extra byte, then round up to word-size

public ReadOnlySpan<byte> Span => new(_arr ?? [], _index, _length);
public bool IsEmpty => Length != 0;

public AsciiHash(ReadOnlySpan<byte> value) : this(value.ToArray(), 0, value.Length) { }
public AsciiHash(string value) : this(Encoding.ASCII.GetBytes(value)) { }
public AsciiHash(string? value) : this(value is null ? [] : Encoding.ASCII.GetBytes(value)) { }

/// <inheritdoc/>
public override int GetHashCode() => _hashCS.GetHashCode();
Expand Down
53 changes: 51 additions & 2 deletions src/RESPite/Shared/AsciiHash.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Buffers;
using System.Buffers.Binary;
using System.Buffers.Binary;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -241,4 +240,54 @@ public static long HashCS(scoped ReadOnlySpan<char> value)
}
return (long)tally;
}

public static void HashCS(scoped ReadOnlySpan<byte> value, out long cs0, out long cs1)
{
cs0 = HashCS(value);
cs1 = value.Length > MaxBytesHashed ? HashCS(value.Slice(start: MaxBytesHashed)) : 0;
}

public static void HashCS(scoped ReadOnlySpan<char> value, out long cs0, out long cs1)
{
cs0 = HashCS(value);
cs1 = value.Length > MaxBytesHashed ? HashCS(value.Slice(start: MaxBytesHashed)) : 0;
}

public static void HashUC(scoped ReadOnlySpan<byte> value, out long cs0, out long cs1)
{
cs0 = HashUC(value);
cs1 = value.Length > MaxBytesHashed ? HashUC(value.Slice(start: MaxBytesHashed)) : 0;
}

public static void HashUC(scoped ReadOnlySpan<char> value, out long cs0, out long cs1)
{
cs0 = HashUC(value);
cs1 = value.Length > MaxBytesHashed ? HashUC(value.Slice(start: MaxBytesHashed)) : 0;
}

public static void Hash(scoped ReadOnlySpan<byte> value, out long cs0, out long uc0, out long cs1, out long uc1)
{
Hash(value, out cs0, out uc0);
if (value.Length > MaxBytesHashed)
{
Hash(value.Slice(start: MaxBytesHashed), out cs1, out uc1);
}
else
{
cs1 = uc1 = 0;
}
}

public static void Hash(scoped ReadOnlySpan<char> value, out long cs0, out long uc0, out long cs1, out long uc1)
{
Hash(value, out cs0, out uc0);
if (value.Length > MaxBytesHashed)
{
Hash(value.Slice(start: MaxBytesHashed), out cs1, out uc1);
}
else
{
cs1 = uc1 = 0;
}
}
}
Loading
Loading