Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
891b22f
import *just* the resp-reader parts from the IO rewrite from side branch
mgravell Feb 13, 2026
a2720ff
WIP; migrate read code - main parse loop untested but complete-ish
mgravell Feb 13, 2026
0bc33eb
nearly compiles
mgravell Feb 15, 2026
757ec4a
getting there
mgravell Feb 15, 2026
7012510
working unit tests and API shim
mgravell Feb 15, 2026
befe691
WIP
mgravell Feb 16, 2026
b9b72fe
deal with LoggingTunnel, untested
mgravell Feb 17, 2026
ab40ca4
core write with basic buffer
mgravell Feb 17, 2026
d09b8f6
fix integer unit tests
mgravell Feb 17, 2026
c64f0d9
start migrating processors
mgravell Feb 17, 2026
a970fce
more processors
mgravell Feb 17, 2026
bdc2ea0
more processors
mgravell Feb 17, 2026
bd0b591
nits
mgravell Feb 17, 2026
5d02603
simplify readers to consider scalar/aggregate as the primary factor, …
mgravell Feb 18, 2026
2dae349
pubsub numsub processor unit test
mgravell Feb 18, 2026
da43320
add missing test cases
mgravell Feb 18, 2026
051f0a6
streaming string tests
mgravell Feb 18, 2026
27985da
streaming aggregate tests
mgravell Feb 18, 2026
35f9259
datetime processor
mgravell Feb 18, 2026
9ab1043
split test files
mgravell Feb 18, 2026
805368d
WIP
mgravell Feb 18, 2026
802cee3
add stateful FillAll and use stateful ReadPastArray
mgravell Feb 18, 2026
22242ca
scan and some stream
mgravell Feb 18, 2026
13d3458
more done
mgravell Feb 18, 2026
54982b3
lease tests/processors
mgravell Feb 18, 2026
3e55330
latency processors
mgravell Feb 18, 2026
9bc1958
vector-set info
mgravell Feb 19, 2026
e482122
role
mgravell Feb 19, 2026
e43e984
allow request/response testing of message and processors together
mgravell Feb 19, 2026
2f0ec27
cleanup
mgravell Feb 19, 2026
a523347
time/timing
mgravell Feb 19, 2026
68a8d18
geo
mgravell Feb 19, 2026
179ae9c
refactor tests; geo
mgravell Feb 19, 2026
7d61495
include all the files
mgravell Feb 19, 2026
f3aab96
WIP
mgravell Feb 20, 2026
ac58b1c
cull
mgravell Feb 20, 2026
d94f177
Test infrastructure for modules developers
mgravell Feb 21, 2026
bc461cf
nits
mgravell Feb 21, 2026
58aa052
fast hash: char support, perf
mgravell Feb 21, 2026
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
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleset>$(MSBuildThisFileDirectory)Shared.ruleset</CodeAnalysisRuleset>
<MSBuildWarningsAsMessages>NETSDK1069</MSBuildWarningsAsMessages>
<NoWarn>$(NoWarn);NU5105;NU1507;SER001;SER002;SER003</NoWarn>
<NoWarn>$(NoWarn);NU5105;NU1507;SER001;SER002;SER003;SER004;SER005</NoWarn>
<PackageReleaseNotes>https://stackexchange.github.io/StackExchange.Redis/ReleaseNotes</PackageReleaseNotes>
<PackageProjectUrl>https://stackexchange.github.io/StackExchange.Redis/</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
3 changes: 3 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
<PackageVersion Include="System.IO.Compression" Version="4.3.0" />
<!-- note that this bumps System.Buffers, so is pinned in down-level in SE csproj -->
<PackageVersion Include="System.IO.Hashing" Version="10.0.2" />
<!-- for RESPite -->
<PackageVersion Include="System.Buffers" Version="4.6.1" />
<PackageVersion Include="System.Memory" Version="4.6.1" />

<!-- For analyzers, tied to the consumer's build SDK; at the moment, that means "us" -->
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" />
Expand Down
14 changes: 14 additions & 0 deletions StackExchange.Redis.sln
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "eng", "eng", "{5FA0958E-6EB
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StackExchange.Redis.Build", "eng\StackExchange.Redis.Build\StackExchange.Redis.Build.csproj", "{190742E1-FA50-4E36-A8C4-88AE87654340}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RESPite", "src\RESPite\RESPite.csproj", "{AEA77181-DDD2-4E43-828B-908C7460A12D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RESPite.Tests", "tests\RESPite.Tests\RESPite.Tests.csproj", "{1D324077-A15E-4EE2-9AD6-A9045636CEAC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -189,6 +193,14 @@ Global
{190742E1-FA50-4E36-A8C4-88AE87654340}.Debug|Any CPU.Build.0 = Debug|Any CPU
{190742E1-FA50-4E36-A8C4-88AE87654340}.Release|Any CPU.ActiveCfg = Release|Any CPU
{190742E1-FA50-4E36-A8C4-88AE87654340}.Release|Any CPU.Build.0 = Release|Any CPU
{AEA77181-DDD2-4E43-828B-908C7460A12D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AEA77181-DDD2-4E43-828B-908C7460A12D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AEA77181-DDD2-4E43-828B-908C7460A12D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AEA77181-DDD2-4E43-828B-908C7460A12D}.Release|Any CPU.Build.0 = Release|Any CPU
{1D324077-A15E-4EE2-9AD6-A9045636CEAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1D324077-A15E-4EE2-9AD6-A9045636CEAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D324077-A15E-4EE2-9AD6-A9045636CEAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D324077-A15E-4EE2-9AD6-A9045636CEAC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -212,6 +224,8 @@ Global
{69A0ACF2-DF1F-4F49-B554-F732DCA938A3} = {73A5C363-CA1F-44C4-9A9B-EF791A76BA6A}
{59889284-FFEE-82E7-94CB-3B43E87DA6CF} = {73A5C363-CA1F-44C4-9A9B-EF791A76BA6A}
{190742E1-FA50-4E36-A8C4-88AE87654340} = {5FA0958E-6EBD-45F4-808E-3447A293F96F}
{AEA77181-DDD2-4E43-828B-908C7460A12D} = {00CA0876-DA9F-44E8-B0DC-A88716BF347A}
{1D324077-A15E-4EE2-9AD6-A9045636CEAC} = {73A5C363-CA1F-44C4-9A9B-EF791A76BA6A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {193AA352-6748-47C1-A5FC-C9AA6B5F000B}
Expand Down
3 changes: 2 additions & 1 deletion StackExchange.Redis.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=xreadgroup/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=xrevrange/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=zcard/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=zscan/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/UserDictionary/Words/=zscan/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=zset/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
15 changes: 15 additions & 0 deletions docs/exp/SER004.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# RESPite

RESPite is an experimental library that provides high-performance low-level RESP (Redis, etc) parsing and serialization.
It is used as the IO core for StackExchange.Redis v3+. You should not (yet) use it directly unless you have a very
good reason to do so.

```xml
<NoWarn>$(NoWarn);SER004</NoWarn>
```

or more granularly / locally in C#:

``` c#
#pragma warning disable SER004
```
21 changes: 21 additions & 0 deletions docs/exp/SER005.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Unit Testing

Unit testing is great! Yay, do more of that!

This type is provided for external unit testing, in particular by people using modules or server features
not directly implemented by SE.Redis - for example to verify messsage parsing or formatting without
talking to a RESP server.

These types are considered slightly more... *mercurial*. We encourage you to use them, but *occasionally*
(not just for fun) you might need to update your test code if we tweak something. This should not impact
"real" library usage.

```xml
<NoWarn>$(NoWarn);SER005</NoWarn>
```

or more granularly / locally in C#:

``` c#
#pragma warning disable SER005
```
30 changes: 21 additions & 9 deletions eng/StackExchange.Redis.Build/FastHashGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using RESPite;

namespace StackExchange.Redis.Build;

Expand Down Expand Up @@ -78,7 +79,15 @@ private static string GetName(INamedTypeSymbol type)
string name = named.Name, value = "";
foreach (var attrib in named.GetAttributes())
{
if (attrib.AttributeClass?.Name == "FastHashAttribute")
if (attrib.AttributeClass is {
Name: "FastHashAttribute",
ContainingType: null,
ContainingNamespace:
{
Name: "RESPite",
ContainingNamespace.IsGlobalNamespace: true,
}
})
{
if (attrib.ConstructorArguments.Length == 1)
{
Expand Down Expand Up @@ -178,25 +187,28 @@ private void Generate(
// perform string escaping on the generated value (this includes the quotes, note)
var csValue = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(literal.Value)).ToFullString();

var hash = FastHash.Hash64(buffer.AsSpan(0, len));
var hashCS = FastHash.HashCS(buffer.AsSpan(0, len));
var hashCI = FastHash.HashCI(buffer.AsSpan(0, len));
NewLine().Append("static partial class ").Append(literal.Name);
NewLine().Append("{");
indent++;
NewLine().Append("public const int Length = ").Append(len).Append(';');
NewLine().Append("public const long Hash = ").Append(hash).Append(';');
NewLine().Append("public const long HashCS = ").Append(hashCS).Append(';');
NewLine().Append("public const long HashCI = ").Append(hashCI).Append(';');
NewLine().Append("public static ReadOnlySpan<byte> U8 => ").Append(csValue).Append("u8;");
NewLine().Append("public const string Text = ").Append(csValue).Append(';');
if (len <= 8)
if (len <= FastHash.MaxBytesHashIsEqualityCS)
{
// the hash enforces all the values
NewLine().Append("public static bool Is(long hash, in RawResult value) => hash == Hash && value.Payload.Length == Length;");
NewLine().Append("public static bool Is(long hash, ReadOnlySpan<byte> value) => hash == Hash & value.Length == Length;");
// the case-sensitive hash enforces all the values
NewLine().Append("public static bool IsCS(long hash, ReadOnlySpan<byte> value) => hash == HashCS & value.Length == Length;");
NewLine().Append("public static bool IsCI(long hash, ReadOnlySpan<byte> value) => (hash == HashCI & value.Length == Length) && (global::RESPite.FastHash.HashCS(value) == HashCS || global::RESPite.FastHash.EqualsCI(value, U8));");
}
else
{
NewLine().Append("public static bool Is(long hash, in RawResult value) => hash == Hash && value.IsEqual(U8);");
NewLine().Append("public static bool Is(long hash, ReadOnlySpan<byte> value) => hash == Hash && value.SequenceEqual(U8);");
NewLine().Append("public static bool IsCS(long hash, ReadOnlySpan<byte> value) => hash == HashCS && value.SequenceEqual(U8);");
NewLine().Append("public static bool IsCI(long hash, ReadOnlySpan<byte> value) => (hash == HashCI & value.Length == Length) && global::RESPite.FastHash.EqualsCI(value, U8);");
}

indent--;
NewLine().Append("}");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
</ItemGroup>

<ItemGroup>
<Compile Include="..\..\src\StackExchange.Redis\FastHash.cs">
<Link>FastHash.cs</Link>
<Compile Include="..\..\src\RESPite\Shared\FastHash.cs">
<Link>Shared/FastHash.cs</Link>
</Compile>
<Compile Include="..\..\src\RESPite\Shared\Experiments.cs">
<Link>Shared/Experiments.cs</Link>
</Compile>
</ItemGroup>

Expand Down
Loading