();
+ for (var i = 0; i < 10; i++)
+ {
+ messages.Add(BackplaneMessage.ForChanged(_ownderBytes, "somerandomkey" + i, CacheItemChangedEventAction.Update));
+ messages.Add(BackplaneMessage.ForChanged(_ownderBytes, "somerandomkey" + i, "withregion", CacheItemChangedEventAction.Add));
+ }
+ for (var i = 0; i < 10; i++)
+ {
+ messages.Add(BackplaneMessage.ForClear(_ownderBytes));
+ }
+ for (var i = 0; i < 10; i++)
+ {
+ messages.Add(BackplaneMessage.ForClearRegion(_ownderBytes, "somerandomregion" + i));
+ }
+ for (var i = 0; i < 10; i++)
+ {
+ messages.Add(BackplaneMessage.ForRemoved(_ownderBytes, "somerandomkey" + i, "withregion"));
+ }
+ _multiple = messages.ToArray();
+ }
+
+ [Benchmark]
+ public void SerializeMany()
+ {
+ var bytes = BackplaneMessage.Serialize(_multiple);
+ }
+
+ [Benchmark()]
+ public void DeserializeMany()
+ {
+ var messages = BackplaneMessage.Deserialize(_multipleSerialized).ToArray();
+ }
+ }
+
+ public class BackplaneMessageBenchmark
+ {
+ private static byte[] _ownderBytes = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString());
+
+ private static BackplaneMessage _dataSingleChange = BackplaneMessage.ForChanged(_ownderBytes, "somerandomkey", CacheItemChangedEventAction.Update);
+ private byte[] _rawSingleChange = BackplaneMessage.Serialize(_dataSingleChange);
+
+ private static BackplaneMessage _dataSingleChangeRegion = BackplaneMessage.ForChanged(_ownderBytes, "somerandomkey", "withregion", CacheItemChangedEventAction.Add);
+ private byte[] _rawSingleChangeRegion = BackplaneMessage.Serialize(_dataSingleChangeRegion);
+
+ private static BackplaneMessage _dataSingleClear = BackplaneMessage.ForClear(_ownderBytes);
+ private byte[] _rawSingleClear = BackplaneMessage.Serialize(_dataSingleClear);
+
+ private static BackplaneMessage _dataSingleClearRegion = BackplaneMessage.ForClearRegion(_ownderBytes, "somerandomregion");
+ private byte[] _rawSingleClearRegion = BackplaneMessage.Serialize(_dataSingleClearRegion);
+
+ private static BackplaneMessage _dataSingleRemove = BackplaneMessage.ForRemoved(_ownderBytes, "somerandomkey", "withregion");
+ private byte[] _rawSingleRemove = BackplaneMessage.Serialize(_dataSingleRemove);
+
+ [Benchmark(Baseline = true)]
+ public void SerializeChange()
+ {
+ var fullMessage = BackplaneMessage.Serialize(_dataSingleChange);
+ }
+
+ [Benchmark()]
+ public void DeserializeChange()
+ {
+ var msg = BackplaneMessage.Deserialize(_rawSingleChange).ToArray();
+ }
+
+ [Benchmark]
+ public void SerializeChangeRegion()
+ {
+ var fullMessage = BackplaneMessage.Serialize(_dataSingleChangeRegion);
+ }
+
+ [Benchmark()]
+ public void DeserializeChangeRegion()
+ {
+ var msg = BackplaneMessage.Deserialize(_rawSingleChangeRegion).ToArray();
+ }
+
+ [Benchmark]
+ public void SerializeClear()
+ {
+ var fullMessage = BackplaneMessage.Serialize(_dataSingleClear);
+ }
+
+ [Benchmark()]
+ public void DeserializeClear()
+ {
+ var msg = BackplaneMessage.Deserialize(_rawSingleClear).ToArray();
+ }
+
+ [Benchmark]
+ public void SerializeClearRegion()
+ {
+ var fullMessage = BackplaneMessage.Serialize(_dataSingleClearRegion);
+ }
+
+ [Benchmark()]
+ public void DeserializeClearRegion()
+ {
+ var msg = BackplaneMessage.Deserialize(_rawSingleClearRegion).ToArray();
+ }
+
+ [Benchmark]
+ public void SerializeRemove()
+ {
+ var fullMessage = BackplaneMessage.Serialize(_dataSingleRemove);
+ }
+
+ [Benchmark()]
+ public void DeserializeRemove()
+ {
+ var msg = BackplaneMessage.Deserialize(_rawSingleRemove).ToArray();
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/CacheManager.Benchmarks/BaseCacheManagerBenchmark.cs b/test/CacheManager.Benchmarks/BaseCacheManagerBenchmark.cs
index 70dc472c..b165682c 100644
--- a/test/CacheManager.Benchmarks/BaseCacheManagerBenchmark.cs
+++ b/test/CacheManager.Benchmarks/BaseCacheManagerBenchmark.cs
@@ -7,7 +7,6 @@
namespace CacheManager.Benchmarks
{
- [Config(typeof(CacheManagerBenchConfig))]
public abstract class BaseCacheBenchmark
{
private static ICacheManagerConfiguration BaseConfig
diff --git a/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmark-report-github.md b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmark-report-github.md
new file mode 100644
index 00000000..d7468b8d
--- /dev/null
+++ b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmark-report-github.md
@@ -0,0 +1,24 @@
+``` ini
+
+BenchmarkDotNet=v0.10.8, OS=Windows 10 Redstone 2 (10.0.15063)
+Processor=Intel Core i7-6700 CPU 3.40GHz (Skylake), ProcessorCount=8
+Frequency=3328125 Hz, Resolution=300.4695 ns, Timer=TSC
+ [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2098.0
+ Job-VUBPRE : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2098.0
+
+Runtime=Clr LaunchCount=1 TargetCount=10
+WarmupCount=4
+
+```
+ | Method | Mean | Error | StdDev | Median | Op/s | Scaled | ScaledSD | Rank | Gen 0 | Allocated |
+ |------------------------ |----------:|----------:|---------:|----------:|-------------:|-------:|---------:|-----:|-------:|----------:|
+ | SerializeChange | 194.57 ns | 11.309 ns | 7.480 ns | 192.86 ns | 5,139,629.5 | 1.00 | 0.00 | 4 | 0.1523 | 640 B |
+ | DeserializeChange | 241.69 ns | 10.354 ns | 6.848 ns | 238.51 ns | 4,137,485.5 | 1.24 | 0.06 | 5 | 0.0875 | 368 B |
+ | SerializeChangeRegion | 249.23 ns | 7.700 ns | 4.582 ns | 249.67 ns | 4,012,334.1 | 1.28 | 0.05 | 6 | 0.1826 | 768 B |
+ | DeserializeChangeRegion | 305.05 ns | 8.953 ns | 5.922 ns | 306.25 ns | 3,278,156.0 | 1.57 | 0.06 | 7 | 0.0987 | 416 B |
+ | SerializeClear | 96.21 ns | 4.459 ns | 2.949 ns | 95.74 ns | 10,393,877.9 | 0.50 | 0.02 | 1 | 0.1162 | 488 B |
+ | DeserializeClear | 158.92 ns | 7.949 ns | 5.258 ns | 159.25 ns | 6,292,374.9 | 0.82 | 0.04 | 2 | 0.0741 | 312 B |
+ | SerializeClearRegion | 169.66 ns | 7.262 ns | 3.798 ns | 169.60 ns | 5,894,312.1 | 0.87 | 0.04 | 3 | 0.1581 | 664 B |
+ | DeserializeClearRegion | 240.22 ns | 8.661 ns | 5.154 ns | 240.20 ns | 4,162,849.7 | 1.24 | 0.05 | 5 | 0.0892 | 376 B |
+ | SerializeRemove | 255.63 ns | 15.071 ns | 9.968 ns | 258.50 ns | 3,911,924.7 | 1.32 | 0.07 | 6 | 0.1826 | 768 B |
+ | DeserializeRemove | 300.98 ns | 9.420 ns | 5.606 ns | 299.66 ns | 3,322,483.1 | 1.55 | 0.06 | 7 | 0.0987 | 416 B |
diff --git a/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmark-report.csv b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmark-report.csv
new file mode 100644
index 00000000..67ac40c6
--- /dev/null
+++ b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmark-report.csv
@@ -0,0 +1,11 @@
+Method;Job;AnalyzeLaunchVariance;EvaluateOverhead;MaxAbsoluteError;MaxRelativeError;MinInvokeCount;MinIterationTime;RemoveOutliers;Affinity;Jit;Platform;Runtime;AllowVeryLargeObjects;Concurrent;CpuGroups;Force;RetainVm;Server;Clock;EngineFactory;Toolchain;InvocationCount;IterationTime;LaunchCount;RunStrategy;TargetCount;UnrollFactor;WarmupCount;Mean;Error;StdDev;Median;Op/s;Scaled;ScaledSD;Rank;Gen 0;Allocated
+SerializeChange;Default;False;Default;Default;Default;Default;Default;Default;255;RyuJit;X64;Clr;False;True;False;True;False;False;Default;Default;Default;1;Default;1;Default;10;16;4;194.57 ns;11.309 ns;7.480 ns;192.86 ns;"5,139,629.5";1.00;0.00;4;0.1523;640 B
+DeserializeChange;Default;False;Default;Default;Default;Default;Default;Default;255;RyuJit;X64;Clr;False;True;False;True;False;False;Default;Default;Default;1;Default;1;Default;10;16;4;241.69 ns;10.354 ns;6.848 ns;238.51 ns;"4,137,485.5";1.24;0.06;5;0.0875;368 B
+SerializeChangeRegion;Default;False;Default;Default;Default;Default;Default;Default;255;RyuJit;X64;Clr;False;True;False;True;False;False;Default;Default;Default;1;Default;1;Default;10;16;4;249.23 ns;7.700 ns;4.582 ns;249.67 ns;"4,012,334.1";1.28;0.05;6;0.1826;768 B
+DeserializeChangeRegion;Default;False;Default;Default;Default;Default;Default;Default;255;RyuJit;X64;Clr;False;True;False;True;False;False;Default;Default;Default;1;Default;1;Default;10;16;4;305.05 ns;8.953 ns;5.922 ns;306.25 ns;"3,278,156.0";1.57;0.06;7;0.0987;416 B
+SerializeClear;Default;False;Default;Default;Default;Default;Default;Default;255;RyuJit;X64;Clr;False;True;False;True;False;False;Default;Default;Default;1;Default;1;Default;10;16;4;96.21 ns;4.459 ns;2.949 ns;95.74 ns;"10,393,877.9";0.50;0.02;1;0.1162;488 B
+DeserializeClear;Default;False;Default;Default;Default;Default;Default;Default;255;RyuJit;X64;Clr;False;True;False;True;False;False;Default;Default;Default;1;Default;1;Default;10;16;4;158.92 ns;7.949 ns;5.258 ns;159.25 ns;"6,292,374.9";0.82;0.04;2;0.0741;312 B
+SerializeClearRegion;Default;False;Default;Default;Default;Default;Default;Default;255;RyuJit;X64;Clr;False;True;False;True;False;False;Default;Default;Default;1;Default;1;Default;10;16;4;169.66 ns;7.262 ns;3.798 ns;169.60 ns;"5,894,312.1";0.87;0.04;3;0.1581;664 B
+DeserializeClearRegion;Default;False;Default;Default;Default;Default;Default;Default;255;RyuJit;X64;Clr;False;True;False;True;False;False;Default;Default;Default;1;Default;1;Default;10;16;4;240.22 ns;8.661 ns;5.154 ns;240.20 ns;"4,162,849.7";1.24;0.05;5;0.0892;376 B
+SerializeRemove;Default;False;Default;Default;Default;Default;Default;Default;255;RyuJit;X64;Clr;False;True;False;True;False;False;Default;Default;Default;1;Default;1;Default;10;16;4;255.63 ns;15.071 ns;9.968 ns;258.50 ns;"3,911,924.7";1.32;0.07;6;0.1826;768 B
+DeserializeRemove;Default;False;Default;Default;Default;Default;Default;Default;255;RyuJit;X64;Clr;False;True;False;True;False;False;Default;Default;Default;1;Default;1;Default;10;16;4;300.98 ns;9.420 ns;5.606 ns;299.66 ns;"3,322,483.1";1.55;0.06;7;0.0987;416 B
diff --git a/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmark-report.html b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmark-report.html
new file mode 100644
index 00000000..b39c51c1
--- /dev/null
+++ b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmark-report.html
@@ -0,0 +1,41 @@
+
+
+
+
+BackplaneMessageBenchmark
+
+
+
+
+
+BenchmarkDotNet=v0.10.8, OS=Windows 10 Redstone 2 (10.0.15063)
+Processor=Intel Core i7-6700 CPU 3.40GHz (Skylake), ProcessorCount=8
+Frequency=3328125 Hz, Resolution=300.4695 ns, Timer=TSC
+ [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2098.0
+ Job-VUBPRE : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2098.0
+
+Runtime=Clr LaunchCount=1 TargetCount=10
+WarmupCount=4
+
+
+
+ Method | Mean | Error | StdDev | Median | Op/s | Scaled | ScaledSD | Rank | Gen 0 | Allocated |
+
+ SerializeChange | 194.57 ns | 11.309 ns | 7.480 ns | 192.86 ns | 5,139,629.5 | 1.00 | 0.00 | 4 | 0.1523 | 640 B |
+
DeserializeChange | 241.69 ns | 10.354 ns | 6.848 ns | 238.51 ns | 4,137,485.5 | 1.24 | 0.06 | 5 | 0.0875 | 368 B |
+
SerializeChangeRegion | 249.23 ns | 7.700 ns | 4.582 ns | 249.67 ns | 4,012,334.1 | 1.28 | 0.05 | 6 | 0.1826 | 768 B |
+
DeserializeChangeRegion | 305.05 ns | 8.953 ns | 5.922 ns | 306.25 ns | 3,278,156.0 | 1.57 | 0.06 | 7 | 0.0987 | 416 B |
+
SerializeClear | 96.21 ns | 4.459 ns | 2.949 ns | 95.74 ns | 10,393,877.9 | 0.50 | 0.02 | 1 | 0.1162 | 488 B |
+
DeserializeClear | 158.92 ns | 7.949 ns | 5.258 ns | 159.25 ns | 6,292,374.9 | 0.82 | 0.04 | 2 | 0.0741 | 312 B |
+
SerializeClearRegion | 169.66 ns | 7.262 ns | 3.798 ns | 169.60 ns | 5,894,312.1 | 0.87 | 0.04 | 3 | 0.1581 | 664 B |
+
DeserializeClearRegion | 240.22 ns | 8.661 ns | 5.154 ns | 240.20 ns | 4,162,849.7 | 1.24 | 0.05 | 5 | 0.0892 | 376 B |
+
SerializeRemove | 255.63 ns | 15.071 ns | 9.968 ns | 258.50 ns | 3,911,924.7 | 1.32 | 0.07 | 6 | 0.1826 | 768 B |
+
DeserializeRemove | 300.98 ns | 9.420 ns | 5.606 ns | 299.66 ns | 3,322,483.1 | 1.55 | 0.06 | 7 | 0.0987 | 416 B |
+
+
+
diff --git a/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmarkMultiple-report-github.md b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmarkMultiple-report-github.md
new file mode 100644
index 00000000..74c67239
--- /dev/null
+++ b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmarkMultiple-report-github.md
@@ -0,0 +1,16 @@
+``` ini
+
+BenchmarkDotNet=v0.10.8, OS=Windows 10 Redstone 2 (10.0.15063)
+Processor=Intel Core i7-6700 CPU 3.40GHz (Skylake), ProcessorCount=8
+Frequency=3328125 Hz, Resolution=300.4695 ns, Timer=TSC
+ [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2098.0
+ Job-VUBPRE : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2098.0
+
+Runtime=Clr LaunchCount=1 TargetCount=10
+WarmupCount=4
+
+```
+ | Method | Mean | Error | StdDev | Median | Op/s | Rank | Gen 0 | Allocated |
+ |---------------- |---------:|----------:|----------:|---------:|----------:|-----:|-------:|----------:|
+ | SerializeMany | 5.650 us | 0.1873 us | 0.1239 us | 5.626 us | 177,004.2 | 1 | 2.3804 | 9.78 KB |
+ | DeserializeMany | 7.132 us | 0.3477 us | 0.2300 us | 7.115 us | 140,203.9 | 2 | 1.7548 | 7.22 KB |
diff --git a/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmarkMultiple-report.csv b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmarkMultiple-report.csv
new file mode 100644
index 00000000..4c935232
--- /dev/null
+++ b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmarkMultiple-report.csv
@@ -0,0 +1,3 @@
+Method;Job;AnalyzeLaunchVariance;EvaluateOverhead;MaxAbsoluteError;MaxRelativeError;MinInvokeCount;MinIterationTime;RemoveOutliers;Affinity;Jit;Platform;Runtime;AllowVeryLargeObjects;Concurrent;CpuGroups;Force;RetainVm;Server;Clock;EngineFactory;Toolchain;InvocationCount;IterationTime;LaunchCount;RunStrategy;TargetCount;UnrollFactor;WarmupCount;Mean;Error;StdDev;Median;Op/s;Rank;Gen 0;Allocated
+SerializeMany;Default;False;Default;Default;Default;Default;Default;Default;255;RyuJit;X64;Clr;False;True;False;True;False;False;Default;Default;Default;1;Default;1;Default;10;16;4;5.650 us;0.1873 us;0.1239 us;5.626 us;"177,004.2";1;2.3804;9.78 KB
+DeserializeMany;Default;False;Default;Default;Default;Default;Default;Default;255;RyuJit;X64;Clr;False;True;False;True;False;False;Default;Default;Default;1;Default;1;Default;10;16;4;7.132 us;0.3477 us;0.2300 us;7.115 us;"140,203.9";2;1.7548;7.22 KB
diff --git a/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmarkMultiple-report.html b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmarkMultiple-report.html
new file mode 100644
index 00000000..566df967
--- /dev/null
+++ b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/BackplaneMessageBenchmarkMultiple-report.html
@@ -0,0 +1,33 @@
+
+
+
+
+BackplaneMessageBenchmarkMultiple
+
+
+
+
+
+BenchmarkDotNet=v0.10.8, OS=Windows 10 Redstone 2 (10.0.15063)
+Processor=Intel Core i7-6700 CPU 3.40GHz (Skylake), ProcessorCount=8
+Frequency=3328125 Hz, Resolution=300.4695 ns, Timer=TSC
+ [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2098.0
+ Job-VUBPRE : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2098.0
+
+Runtime=Clr LaunchCount=1 TargetCount=10
+WarmupCount=4
+
+
+
+ Method | Mean | Error | StdDev | Median | Op/s | Rank | Gen 0 | Allocated |
+
+SerializeMany | 5.650 us | 0.1873 us | 0.1239 us | 5.626 us | 177,004.2 | 1 | 2.3804 | 9.78 KB |
+
DeserializeMany | 7.132 us | 0.3477 us | 0.2300 us | 7.115 us | 140,203.9 | 2 | 1.7548 | 7.22 KB |
+
+
+
diff --git a/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/GzBenchmark-report-github.md b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/GzBenchmark-report-github.md
index 996b0a08..b6efab5b 100644
--- a/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/GzBenchmark-report-github.md
+++ b/test/CacheManager.Benchmarks/BenchmarkDotNet.Artifacts/results/GzBenchmark-report-github.md
@@ -10,7 +10,8 @@ Platform=X64 LaunchCount=2 TargetCount=15
WarmupCount=10
```
- Method | Mean | StdDev | Scaled | Scaled-StdDev | Gen 0 | Allocated |
+
+Method | Mean | StdDev | Scaled | Scaled-StdDev | Gen 0 | Allocated |
------------- |---------- |---------- |------- |-------------- |-------- |---------- |
Naive | 1.3792 ms | 0.0211 ms | 1.00 | 0.00 | 29.6875 | 301.06 kB |
Manuel | 1.3892 ms | 0.0465 ms | 1.01 | 0.04 | 5.4688 | 191.09 kB |
diff --git a/test/CacheManager.Benchmarks/CacheManager.Benchmarks.csproj b/test/CacheManager.Benchmarks/CacheManager.Benchmarks.csproj
index 2d90d266..f34ceb8f 100644
--- a/test/CacheManager.Benchmarks/CacheManager.Benchmarks.csproj
+++ b/test/CacheManager.Benchmarks/CacheManager.Benchmarks.csproj
@@ -18,7 +18,7 @@
-
+
@@ -27,4 +27,4 @@
-
+
\ No newline at end of file
diff --git a/test/CacheManager.Benchmarks/GzBenchmark.cs b/test/CacheManager.Benchmarks/GzBenchmark.cs
index cc96929a..ad50d49a 100644
--- a/test/CacheManager.Benchmarks/GzBenchmark.cs
+++ b/test/CacheManager.Benchmarks/GzBenchmark.cs
@@ -9,7 +9,6 @@
namespace CacheManager.Benchmarks
{
- [Config(typeof(CacheManagerBenchConfig))]
public class GzBenchmark
{
private static ArrayPool _pool = ArrayPool.Create();
diff --git a/test/CacheManager.Benchmarks/PlainDictionaryUpdateBenchmark.cs b/test/CacheManager.Benchmarks/PlainDictionaryUpdateBenchmark.cs
index fb314a61..8b7fd44f 100644
--- a/test/CacheManager.Benchmarks/PlainDictionaryUpdateBenchmark.cs
+++ b/test/CacheManager.Benchmarks/PlainDictionaryUpdateBenchmark.cs
@@ -6,7 +6,6 @@
namespace CacheManager.Benchmarks
{
- [Config(typeof(CacheManagerBenchConfig))]
public class PlainDictionaryUpdateBenchmark
{
private const int Threads = 6;
@@ -59,7 +58,7 @@ public int UpdateImpl(Func updateFactory)
success = _dictionary.TryUpdate("key", updateFactory(value), value);
} while (!success);
-
+
return value;
}
diff --git a/test/CacheManager.Benchmarks/Program.cs b/test/CacheManager.Benchmarks/Program.cs
index 97114a88..06074b7f 100644
--- a/test/CacheManager.Benchmarks/Program.cs
+++ b/test/CacheManager.Benchmarks/Program.cs
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Reflection;
+using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
@@ -21,11 +22,40 @@ public class Program
{
public static void Main(string[] args)
{
+ //new BackplaneMessageBenchmark().DeserializeChange();
+ new BackplaneMessageBenchmarkMultiple().SerializeMany();
+ new BackplaneMessageBenchmarkMultiple().DeserializeMany();
+
do
{
+ var config = ManualConfig.Create(DefaultConfig.Instance)
+ //.With(exporters: BenchmarkDotNet.Exporters.DefaultExporters.)
+ .With(BenchmarkDotNet.Analysers.EnvironmentAnalyser.Default)
+ .With(BenchmarkDotNet.Exporters.MarkdownExporter.GitHub)
+ .With(BenchmarkDotNet.Diagnosers.MemoryDiagnoser.Default)
+ .With(StatisticColumn.Mean)
+ .With(StatisticColumn.Median)
+ //.With(StatisticColumn.Min)
+ //.With(StatisticColumn.Max)
+ .With(StatisticColumn.StdDev)
+ .With(StatisticColumn.OperationsPerSecond)
+ .With(BaselineScaledColumn.Scaled)
+ //.With(BaselineScaledColumn.ScaledStdDev)
+ .With(RankColumn.Arabic)
+
+ .With(Job.Clr
+ .WithTargetCount(10)
+ .WithWarmupCount(4)
+ .WithLaunchCount(1));
+
+ //.With(Job.Clr
+ // .WithTargetCount(10)
+ // .WithWarmupCount(5)
+ // .WithLaunchCount(1));
+
BenchmarkSwitcher
.FromAssembly(typeof(Program).GetTypeInfo().Assembly)
- .Run(args);
+ .Run(args, config);
Console.WriteLine("done!");
Console.WriteLine("Press escape to exit or any key to continue...");
diff --git a/test/CacheManager.Benchmarks/SerializationBenchmark.cs b/test/CacheManager.Benchmarks/SerializationBenchmark.cs
index 727aa514..34ffe55a 100644
--- a/test/CacheManager.Benchmarks/SerializationBenchmark.cs
+++ b/test/CacheManager.Benchmarks/SerializationBenchmark.cs
@@ -18,7 +18,6 @@
namespace CacheManager.Benchmarks
{
- [Config(typeof(CacheManagerBenchConfig))]
public class SerializationBenchmark
{
private int _iterations = 1000;
@@ -66,14 +65,14 @@ public void Setup()
_payload = new Queue>(items);
}
-
+
private void ExecRun(Action> action)
{
var item = _payload.Dequeue();
action(item);
_payload.Enqueue(item);
}
-
+
[Benchmark()]
public void BinarySerializer()
{
diff --git a/test/CacheManager.Benchmarks/UnixTimestampBenchmark.cs b/test/CacheManager.Benchmarks/UnixTimestampBenchmark.cs
index c3f55e45..7c52f650 100644
--- a/test/CacheManager.Benchmarks/UnixTimestampBenchmark.cs
+++ b/test/CacheManager.Benchmarks/UnixTimestampBenchmark.cs
@@ -5,7 +5,6 @@
namespace CacheManager.Benchmarks
{
- [Config(typeof(CacheManagerBenchConfig))]
public class UnixTimestampBenchmark
{
[Benchmark(Baseline = true)]
@@ -21,7 +20,7 @@ public long ManualCalcNaive()
{
return (long)(DateTime.UtcNow - _date1970).TotalMilliseconds;
}
-
+
[Benchmark()]
public long ManualCalcOptimized()
{
diff --git a/test/CacheManager.Events.Tests/EventCommand.cs b/test/CacheManager.Events.Tests/EventCommand.cs
index f3b6e4ab..c6f35a9c 100644
--- a/test/CacheManager.Events.Tests/EventCommand.cs
+++ b/test/CacheManager.Events.Tests/EventCommand.cs
@@ -86,6 +86,7 @@ protected async Task Runner(Func task, params EventCounter p.Cache.Name))}; showing [local][remote] events.");
try
{
var reportTask = Task.Run(async () =>
@@ -94,7 +95,12 @@ protected async Task Runner(Func task, params EventCounter(Func task, params EventCounter GetStatus(EventCounter[] handlings)
+ private static IEnumerable GetStatus(EventCounter[] handlings, bool printEmpty = false)
{
foreach (var handling in handlings)
{
@@ -146,7 +152,10 @@ private static IEnumerable GetStatus(EventCounter p > 0))
+ {
+ report.Append($"{kv.Key}:[{string.Join("][", kv.Value)}] ");
+ }
}
//Console.WriteLine("Expected: " + report.ToString());
diff --git a/test/CacheManager.Events.Tests/EventHandling.cs b/test/CacheManager.Events.Tests/EventHandling.cs
index 9d75a0a1..5d61bd8a 100644
--- a/test/CacheManager.Events.Tests/EventHandling.cs
+++ b/test/CacheManager.Events.Tests/EventHandling.cs
@@ -23,14 +23,13 @@ public EventCounter(ICacheManager cache)
Cache.OnPut += OnPut;
Cache.OnUpdate += OnUpdate;
- _updates.Add(CacheEvent.Add, new int[1]);
- _updates.Add(CacheEvent.Put, new int[1]);
- _updates.Add(CacheEvent.Rem, new int[1]);
- _updates.Add(CacheEvent.Get, new int[1]);
- _updates.Add(CacheEvent.ReH, new int[1]);
- _updates.Add(CacheEvent.Upd, new int[1]);
+ _updates.Add(CacheEvent.Add, new int[2]);
+ _updates.Add(CacheEvent.Put, new int[2]);
+ _updates.Add(CacheEvent.Rem, new int[2]);
+ _updates.Add(CacheEvent.Get, new int[2]);
+ _updates.Add(CacheEvent.ReH, new int[2]);
+ _updates.Add(CacheEvent.Upd, new int[2]);
}
-
public Dictionary GetExpectedState()
{
@@ -38,47 +37,54 @@ public Dictionary GetExpectedState()
foreach (var kv in _updates.ToArray())
{
- result.Add(kv.Key, new[] { kv.Value[0] });
+ result.Add(kv.Key, new[] { kv.Value[0], kv.Value[1] });
}
return result;
}
- private void Update(CacheEvent ev, string key)
+ private void Update(CacheEvent ev, string key, CacheActionEventArgOrigin origin)
{
- Interlocked.Increment(ref _updates[ev][0]);
+ if (origin == CacheActionEventArgOrigin.Local)
+ {
+ Interlocked.Increment(ref _updates[ev][0]);
+ }
+ else
+ {
+ Interlocked.Increment(ref _updates[ev][1]);
+ }
}
public ICacheManager Cache { get; }
private void OnUpdate(object sender, CacheActionEventArgs e)
{
- Update(CacheEvent.Upd, e.Key);
+ Update(CacheEvent.Upd, e.Key, e.Origin);
}
private void OnPut(object sender, CacheActionEventArgs e)
{
- Update(CacheEvent.Put, e.Key);
+ Update(CacheEvent.Put, e.Key, e.Origin);
}
private void OnGet(object sender, CacheActionEventArgs e)
{
- Update(CacheEvent.Get, e.Key);
+ Update(CacheEvent.Get, e.Key, e.Origin);
}
private void OnAdd(object sender, CacheActionEventArgs e)
{
- Update(CacheEvent.Add, e.Key);
+ Update(CacheEvent.Add, e.Key, e.Origin);
}
private void OnRemove(object sender, CacheActionEventArgs e)
{
- Update(CacheEvent.Rem, e.Key);
+ Update(CacheEvent.Rem, e.Key, e.Origin);
}
private void OnRemoveByHandle(object sender, CacheItemRemovedEventArgs e)
{
- Update(CacheEvent.ReH, e.Key);
+ Update(CacheEvent.ReH, e.Key, CacheActionEventArgOrigin.Local);
}
}
}
\ No newline at end of file
diff --git a/test/CacheManager.Events.Tests/Program.cs b/test/CacheManager.Events.Tests/Program.cs
index a6bbf823..fea3c31a 100644
--- a/test/CacheManager.Events.Tests/Program.cs
+++ b/test/CacheManager.Events.Tests/Program.cs
@@ -14,7 +14,9 @@ private static void Main(string[] args)
.AddConsole(LogLevel.Warning);
var app = new CommandLineApplication(false);
+ app.Command("redis", (cmdApp) => new RedisCommand(cmdApp, loggerFactory), throwOnUnexpectedArg: true);
app.Command("redisAndMemory", (cmdApp) => new RedisAndMemoryCommand(cmdApp, loggerFactory), throwOnUnexpectedArg: true);
+ app.Command("redisAndMemoryNoMessages", (cmdApp) => new RedisAndMemoryNoMessagingCommand(cmdApp, loggerFactory), throwOnUnexpectedArg: true);
app.Command("memoryOnly", (cmdApp) => new MemoryOnlyCommand(cmdApp, loggerFactory), throwOnUnexpectedArg: true);
app.HelpOption("-h|--help");
if (args.Length == 0)
diff --git a/test/CacheManager.Events.Tests/Properties/launchSettings.json b/test/CacheManager.Events.Tests/Properties/launchSettings.json
index 335c2a11..a8986eb0 100644
--- a/test/CacheManager.Events.Tests/Properties/launchSettings.json
+++ b/test/CacheManager.Events.Tests/Properties/launchSettings.json
@@ -2,7 +2,7 @@
"profiles": {
"CacheManager.Events.Tests": {
"commandName": "Project",
- "commandLineArgs": "redisAndMemory -r 50 -j 1"
+ "commandLineArgs": "redis -r 20 -j 10"
}
}
}
\ No newline at end of file
diff --git a/test/CacheManager.Events.Tests/RedisAndMemoryCommand.cs b/test/CacheManager.Events.Tests/RedisAndMemoryCommand.cs
index 5d084df3..5a550c18 100644
--- a/test/CacheManager.Events.Tests/RedisAndMemoryCommand.cs
+++ b/test/CacheManager.Events.Tests/RedisAndMemoryCommand.cs
@@ -8,10 +8,53 @@
namespace CacheManager.Events.Tests
{
+ public class RedisAndMemoryNoMessagingCommand : RedisAndMemoryCommand
+ {
+ public RedisAndMemoryNoMessagingCommand(CommandLineApplication app, ILoggerFactory loggerFactory) : base(app, loggerFactory)
+ {
+ }
+
+ protected override void Configure()
+ {
+ base.Configure();
+
+ _multiplexer = ConnectionMultiplexer.Connect("127.0.0.1,allowAdmin=true");
+ _configuration = new ConfigurationBuilder()
+ .WithMicrosoftLogging(LoggerFactory)
+ .WithMicrosoftMemoryCacheHandle("in-memory")
+ .And
+ .WithJsonSerializer()
+ .WithRedisConfiguration("redisConfig", _multiplexer, enableKeyspaceNotifications: false)
+ .WithRedisCacheHandle("redisConfig")
+ .Build();
+ }
+ }
+
+ public class RedisCommand : RedisAndMemoryCommand
+ {
+ public RedisCommand(CommandLineApplication app, ILoggerFactory loggerFactory) : base(app, loggerFactory)
+ {
+ }
+
+ protected override void Configure()
+ {
+ base.Configure();
+
+ _multiplexer = ConnectionMultiplexer.Connect("127.0.0.1,allowAdmin=true");
+ _configuration = new ConfigurationBuilder()
+ .WithMicrosoftLogging(LoggerFactory)
+ .WithRedisBackplane("redisConfig")
+ .WithJsonSerializer()
+ .WithRedisConfiguration("redisConfig", _multiplexer, enableKeyspaceNotifications: true)
+ .WithRedisCacheHandle("redisConfig")
+ .Build();
+ }
+ }
+
public class RedisAndMemoryCommand : EventCommand
{
- private ICacheManagerConfiguration _configuration;
- private ConnectionMultiplexer _multiplexer;
+ protected ICacheManagerConfiguration _configuration;
+ protected ConnectionMultiplexer _multiplexer;
public RedisAndMemoryCommand(CommandLineApplication app, ILoggerFactory loggerFactory) : base(app, loggerFactory)
{
@@ -21,7 +64,7 @@ protected override void Configure()
{
base.Configure();
- _multiplexer = ConnectionMultiplexer.Connect("localhost,allowAdmin=true");
+ _multiplexer = ConnectionMultiplexer.Connect("127.0.0.1,allowAdmin=true");
_configuration = new ConfigurationBuilder()
.WithMicrosoftLogging(LoggerFactory)
.WithMicrosoftMemoryCacheHandle("in-memory")
@@ -46,86 +89,13 @@ public override async Task Execute()
var rndNumber = rnd.Next(42, 420);
var key = Guid.NewGuid().ToString();
- bool didRemove = false;
- bool didUpdate = false;
- bool removeTriggeredA = false;
- bool updateTriggeredA = false;
- bool removeTriggeredB = false;
- bool updateTriggeredB = false;
-
- void OnUpdate(object sender, CacheActionEventArgs args)
- {
- if (args.Key.Equals(key))
- {
- if (!didUpdate)
- {
- Console.WriteLine("Key has been updated without me calling it");
- }
- else if (sender.Equals(cacheA))
- {
- updateTriggeredA = true;
- }
- else if (sender.Equals(cacheB))
- {
- updateTriggeredB = true;
- }
- }
- }
-
- void OnRemove(object sender, CacheActionEventArgs args)
- {
- if (args.Key.Equals(key))
- {
- if (!didRemove)
- {
- Console.WriteLine("Key has been removed without me removing it");
- }
- else if (sender.Equals(cacheA))
- {
- removeTriggeredA = true;
- }
- else if (sender.Equals(cacheB))
- {
- removeTriggeredB = true;
- }
- }
- }
-
- cacheA.OnUpdate += OnUpdate;
- cacheA.OnRemove += OnRemove;
- cacheB.OnUpdate += OnUpdate;
- cacheB.OnRemove += OnRemove;
-
- while (!cacheA.Add(key, rndNumber))
- {
- key = Guid.NewGuid().ToString();
- }
-
- didUpdate = true;
- cacheA.TryUpdate(key, (oldVal) => oldVal + 1, out int? newValue);
- //while (!updateTriggeredA || !updateTriggeredB)
- //{
- // await Task.Delay(1);
- //}
+ cacheA.Add(key, rndNumber);
- if (cacheA[key] != cacheB[key] && cacheA[key] != null)
- {
- // log warn?
- }
+ cacheA.TryUpdate(key, (oldVal) => oldVal + 1, out int? newValue);
- await Task.Delay(0);
- didRemove = true;
_multiplexer.GetDatabase(0).KeyDelete(key, CommandFlags.HighPriority);
- //while (!removeTriggeredA || !removeTriggeredB)
- //{
- // await Task.Delay(1);
- //}
-
- cacheA.OnUpdate -= OnUpdate;
- cacheA.OnRemove -= OnRemove;
- cacheB.OnUpdate -= OnUpdate;
- cacheB.OnRemove -= OnRemove;
+ await Task.Delay(0);
});
}
catch (Exception ex)
diff --git a/test/CacheManager.Tests/BackplaneMessageTest.cs b/test/CacheManager.Tests/BackplaneMessageTest.cs
new file mode 100644
index 00000000..753ffe14
--- /dev/null
+++ b/test/CacheManager.Tests/BackplaneMessageTest.cs
@@ -0,0 +1,647 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using CacheManager.Core.Internal;
+using FluentAssertions;
+using Xunit;
+
+namespace CacheManager.Tests
+{
+ [ExcludeFromCodeCoverage]
+ public class BackplaneMessageTest
+ {
+ [Fact]
+ public void BackplaneMessage_ChangeAddKey()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+ var key = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, CacheItemChangedEventAction.Add);
+
+ // act
+ var serialized = BackplaneMessage.Serialize(msg);
+ var deserialized = BackplaneMessage.Deserialize(serialized).First();
+
+ // assert
+ deserialized.Key.Should().Be(key);
+ deserialized.Region.Should().Be(null);
+ deserialized.ChangeAction.Should().Be(CacheItemChangedEventAction.Add);
+ deserialized.Action.Should().Be(BackplaneAction.Changed);
+ deserialized.OwnerIdentity.ShouldBeEquivalentTo(owner);
+ deserialized.ShouldBeEquivalentTo(msg);
+ }
+
+ [Fact]
+ public void BackplaneMessage_ChangeAddKeyRegion()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Add);
+
+ // act
+ var serialized = BackplaneMessage.Serialize(msg);
+ var deserialized = BackplaneMessage.Deserialize(serialized).First();
+
+ // assert
+ deserialized.Key.Should().Be(key);
+ deserialized.Region.Should().Be(region);
+ deserialized.ChangeAction.Should().Be(CacheItemChangedEventAction.Add);
+ deserialized.Action.Should().Be(BackplaneAction.Changed);
+ deserialized.OwnerIdentity.ShouldBeEquivalentTo(owner);
+ deserialized.ShouldBeEquivalentTo(msg);
+ }
+
+ [Fact]
+ public void BackplaneMessage_ChangePutKey()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+ var key = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, CacheItemChangedEventAction.Put);
+
+ // act
+ var serialized = BackplaneMessage.Serialize(msg);
+ var deserialized = BackplaneMessage.Deserialize(serialized).First();
+
+ // assert
+ deserialized.Key.Should().Be(key);
+ deserialized.Region.Should().Be(null);
+ deserialized.ChangeAction.Should().Be(CacheItemChangedEventAction.Put);
+ deserialized.Action.Should().Be(BackplaneAction.Changed);
+ deserialized.OwnerIdentity.ShouldBeEquivalentTo(owner);
+ deserialized.ShouldBeEquivalentTo(msg);
+ }
+
+ [Fact]
+ public void BackplaneMessage_ChangePutKeyRegion()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Put);
+
+ // act
+ var serialized = BackplaneMessage.Serialize(msg);
+ var deserialized = BackplaneMessage.Deserialize(serialized).First();
+
+ // assert
+ deserialized.Key.Should().Be(key);
+ deserialized.Region.Should().Be(region);
+ deserialized.ChangeAction.Should().Be(CacheItemChangedEventAction.Put);
+ deserialized.Action.Should().Be(BackplaneAction.Changed);
+ deserialized.OwnerIdentity.ShouldBeEquivalentTo(owner);
+ deserialized.ShouldBeEquivalentTo(msg);
+ }
+
+ [Fact]
+ public void BackplaneMessage_ChangeUpdateKey()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+ var key = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, CacheItemChangedEventAction.Update);
+
+ // act
+ var serialized = BackplaneMessage.Serialize(msg);
+ var deserialized = BackplaneMessage.Deserialize(serialized).First();
+
+ // assert
+ deserialized.Key.Should().Be(key);
+ deserialized.Region.Should().Be(null);
+ deserialized.ChangeAction.Should().Be(CacheItemChangedEventAction.Update);
+ deserialized.Action.Should().Be(BackplaneAction.Changed);
+ deserialized.OwnerIdentity.ShouldBeEquivalentTo(owner);
+ deserialized.ShouldBeEquivalentTo(msg);
+ }
+
+ [Fact]
+ public void BackplaneMessage_ChangePutUpdateRegion()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Update);
+
+ // act
+ var serialized = BackplaneMessage.Serialize(msg);
+ var deserialized = BackplaneMessage.Deserialize(serialized).First();
+
+ // assert
+ deserialized.Key.Should().Be(key);
+ deserialized.Region.Should().Be(region);
+ deserialized.ChangeAction.Should().Be(CacheItemChangedEventAction.Update);
+ deserialized.Action.Should().Be(BackplaneAction.Changed);
+ deserialized.OwnerIdentity.ShouldBeEquivalentTo(owner);
+ deserialized.ShouldBeEquivalentTo(msg);
+ }
+
+ [Fact]
+ public void BackplaneMessage_RemovedKey()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+ var key = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForRemoved(owner, key);
+
+ // act
+ var serialized = BackplaneMessage.Serialize(msg);
+ var deserialized = BackplaneMessage.Deserialize(serialized).First();
+
+ // assert
+ deserialized.Key.Should().Be(key);
+ deserialized.Region.Should().Be(null);
+ deserialized.ChangeAction.Should().Be(CacheItemChangedEventAction.Invalid);
+ deserialized.Action.Should().Be(BackplaneAction.Removed);
+ deserialized.OwnerIdentity.ShouldBeEquivalentTo(owner);
+ deserialized.ShouldBeEquivalentTo(msg);
+ }
+
+ [Fact]
+ public void BackplaneMessage_RemovedKeyRegion()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForRemoved(owner, key, region);
+
+ // act
+ var serialized = BackplaneMessage.Serialize(msg);
+ var deserialized = BackplaneMessage.Deserialize(serialized).First();
+
+ // assert
+ deserialized.Key.Should().Be(key);
+ deserialized.Region.Should().Be(region);
+ deserialized.ChangeAction.Should().Be(CacheItemChangedEventAction.Invalid);
+ deserialized.Action.Should().Be(BackplaneAction.Removed);
+ deserialized.OwnerIdentity.ShouldBeEquivalentTo(owner);
+ deserialized.ShouldBeEquivalentTo(msg);
+ }
+
+ [Fact]
+ public void BackplaneMessage_Clear()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+ var msg = BackplaneMessage.ForClear(owner);
+
+ // act
+ var serialized = BackplaneMessage.Serialize(msg);
+ var deserialized = BackplaneMessage.Deserialize(serialized).First();
+
+ // assert
+ deserialized.Key.Should().Be(null);
+ deserialized.Region.Should().Be(null);
+ deserialized.ChangeAction.Should().Be(CacheItemChangedEventAction.Invalid);
+ deserialized.Action.Should().Be(BackplaneAction.Clear);
+ deserialized.OwnerIdentity.ShouldBeEquivalentTo(owner);
+ deserialized.ShouldBeEquivalentTo(msg);
+ }
+
+ [Fact]
+ public void BackplaneMessage_ClearRegion()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForClearRegion(owner, region);
+
+ // act
+ var serialized = BackplaneMessage.Serialize(msg);
+ var deserialized = BackplaneMessage.Deserialize(serialized).First();
+
+ // assert
+ deserialized.Key.Should().Be(null);
+ deserialized.Region.Should().Be(region);
+ deserialized.ChangeAction.Should().Be(CacheItemChangedEventAction.Invalid);
+ deserialized.Action.Should().Be(BackplaneAction.ClearRegion);
+ deserialized.OwnerIdentity.ShouldBeEquivalentTo(owner);
+ deserialized.ShouldBeEquivalentTo(msg);
+ }
+
+ [Fact]
+ public void BackplaneMessage_RefEquals()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForClearRegion(owner, region);
+
+ // act
+ msg.Equals(msg).Should().BeTrue();
+ }
+
+ [Fact]
+ public void BackplaneMessage_EqualsOtherChangedKey()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, CacheItemChangedEventAction.Update);
+ var msg2 = BackplaneMessage.ForChanged(owner, key, CacheItemChangedEventAction.Update);
+
+ // act
+ msg.Equals(msg2).Should().BeTrue();
+ }
+
+ [Fact]
+ public void BackplaneMessage_EqualsOtherChangedKeyRegion()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Update);
+ var msg2 = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Update);
+
+ // act
+ msg.Equals(msg2).Should().BeTrue();
+ }
+
+ [Fact]
+ public void BackplaneMessage_EqualsOtherRemovedKey()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForRemoved(owner, key);
+ var msg2 = BackplaneMessage.ForRemoved(owner, key);
+
+ // act
+ msg.Equals(msg2).Should().BeTrue();
+ }
+
+ [Fact]
+ public void BackplaneMessage_EqualsOtherRemovedKeyRegion()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForRemoved(owner, key, region);
+ var msg2 = BackplaneMessage.ForRemoved(owner, key, region);
+
+ // act
+ msg.Equals(msg2).Should().BeTrue();
+ }
+
+ [Fact]
+ public void BackplaneMessage_EqualsOtherClearRegion()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForClearRegion(owner, region);
+ var msg2 = BackplaneMessage.ForClearRegion(owner, region);
+
+ // act
+ msg.Equals(msg2).Should().BeTrue();
+ }
+
+ [Fact]
+ public void BackplaneMessage_EqualsOtherClear()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+ var msg = BackplaneMessage.ForClear(owner);
+ var msg2 = BackplaneMessage.ForClear(owner);
+
+ // act
+ msg.Equals(msg2).Should().BeTrue();
+ }
+
+ [Fact]
+ public void BackplaneMessage_NotEqualNull()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForClearRegion(owner, region);
+
+ // act
+ msg.Equals(null).Should().BeFalse();
+ }
+
+ [Fact]
+ public void BackplaneMessage_NotEqualOther()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForClearRegion(owner, region);
+
+ // act
+ msg.Equals("hello").Should().BeFalse();
+ }
+
+ [Fact]
+ public void BackplaneMessage_HashChangedKey()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, CacheItemChangedEventAction.Update);
+ var msg2 = BackplaneMessage.ForChanged(owner, key, CacheItemChangedEventAction.Update);
+
+ // act
+ msg.GetHashCode().Should().Be(msg2.GetHashCode());
+ }
+
+ [Fact]
+ public void BackplaneMessage_HashChangedKeyRegion()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Update);
+ var msg2 = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Update);
+
+ // act
+ msg.GetHashCode().Should().Be(msg2.GetHashCode());
+ }
+
+ [Fact]
+ public void BackplaneMessage_HashRemovedKey()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForRemoved(owner, key);
+ var msg2 = BackplaneMessage.ForRemoved(owner, key);
+
+ // act
+ msg.GetHashCode().Should().Be(msg2.GetHashCode());
+ }
+
+ [Fact]
+ public void BackplaneMessage_HashRemovedKeyRegion()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForRemoved(owner, key, region);
+ var msg2 = BackplaneMessage.ForRemoved(owner, key, region);
+
+ // act
+ msg.GetHashCode().Should().Be(msg2.GetHashCode());
+ }
+
+ [Fact]
+ public void BackplaneMessage_HashClearRegion()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForClearRegion(owner, region);
+ var msg2 = BackplaneMessage.ForClearRegion(owner, region);
+
+ // act
+ msg.GetHashCode().Should().Be(msg2.GetHashCode());
+ }
+
+ [Fact]
+ public void BackplaneMessage_HashClear()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+ var msg = BackplaneMessage.ForClear(owner);
+ var msg2 = BackplaneMessage.ForClear(owner);
+
+ // act
+ msg.GetHashCode().Should().Be(msg2.GetHashCode());
+ }
+
+ [Fact]
+ public void BackplaneMessage_Hashset_AllEqual()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Update);
+ var msg2 = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Update);
+
+ var hashset = new HashSet();
+
+ // act
+ hashset.Add(msg);
+ hashset.Add(msg);
+ hashset.Count.Should().Be(1);
+ hashset.Add(msg2);
+ hashset.Add(msg2);
+ hashset.Count.Should().Be(1);
+ }
+
+ [Fact]
+ public void BackplaneMessage_Hashset_DifferentChangeAction()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Update);
+ var msg2 = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Add);
+
+ var hashset = new HashSet();
+
+ // act
+ hashset.Add(msg);
+ hashset.Add(msg);
+ hashset.Count.Should().Be(1);
+ hashset.Add(msg2);
+ hashset.Add(msg2);
+ hashset.Count.Should().Be(2);
+ }
+
+ [Fact]
+ public void BackplaneMessage_Hashset_DifferentKey()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var key2 = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Update);
+ var msg2 = BackplaneMessage.ForChanged(owner, key2, region, CacheItemChangedEventAction.Update);
+
+ var hashset = new HashSet();
+
+ // act
+ hashset.Add(msg);
+ hashset.Add(msg);
+ hashset.Count.Should().Be(1);
+ hashset.Add(msg2);
+ hashset.Add(msg2);
+ hashset.Count.Should().Be(2);
+ }
+
+ [Fact]
+ public void BackplaneMessage_Hashset_DifferentRegion()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var region2 = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Update);
+ var msg2 = BackplaneMessage.ForChanged(owner, key, region2, CacheItemChangedEventAction.Update);
+
+ var hashset = new HashSet();
+
+ // act
+ hashset.Add(msg);
+ hashset.Add(msg);
+ hashset.Count.Should().Be(1);
+ hashset.Add(msg2);
+ hashset.Add(msg2);
+ hashset.Count.Should().Be(2);
+ }
+
+ [Fact]
+ public void BackplaneMessage_Hashset_DifferentMessage()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+ var msg = BackplaneMessage.ForChanged(owner, key, region, CacheItemChangedEventAction.Update);
+ var msg2 = BackplaneMessage.ForRemoved(owner, key, region);
+
+ var hashset = new HashSet();
+
+ // act
+ hashset.Add(msg);
+ hashset.Add(msg);
+ hashset.Count.Should().Be(1);
+ hashset.Add(msg2);
+ hashset.Add(msg2);
+ hashset.Count.Should().Be(2);
+ }
+
+ [Fact]
+ public void BackplaneMessage_Mulitple()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var messages = CreateMany(owner);
+
+ var serialized = BackplaneMessage.Serialize(messages.ToArray());
+ var deserialized = BackplaneMessage.Deserialize(serialized).ToArray();
+
+ messages.Count.Should().Be(41);
+ deserialized.ShouldAllBeEquivalentTo(messages);
+ }
+
+ [Fact]
+ public void BackplaneMessage_Mulitple_IgnoreOwner()
+ {
+ // arrange
+ var owner = new byte[] { 1, 2, 3, 4 };
+
+ var messages = CreateMany(owner);
+
+ var serialized = BackplaneMessage.Serialize(messages.ToArray());
+ var deserialized = BackplaneMessage.Deserialize(serialized, skipOwner: owner).ToArray();
+
+ messages.Count.Should().Be(41);
+ deserialized.Length.Should().Be(0);
+ }
+
+ private static ISet CreateMany(byte[] owner)
+ {
+ var messages = new HashSet();
+ var key = Guid.NewGuid().ToString();
+ var region = Guid.NewGuid().ToString();
+
+ // test hash compare works too, result hashset should still have 41 messages only!
+ for (var m = 0; m < 10000; m++)
+ {
+ for (var i = 0; i < 10; i++)
+ {
+ messages.Add(BackplaneMessage.ForChanged(owner, key + i, CacheItemChangedEventAction.Update));
+ messages.Add(BackplaneMessage.ForChanged(owner, key + i, region, CacheItemChangedEventAction.Add));
+ }
+
+ messages.Add(BackplaneMessage.ForClear(owner));
+
+ for (var i = 0; i < 10; i++)
+ {
+ messages.Add(BackplaneMessage.ForClearRegion(owner, region + i));
+ }
+ for (var i = 0; i < 10; i++)
+ {
+ messages.Add(BackplaneMessage.ForRemoved(owner, key + i, region));
+ }
+ }
+
+ return messages;
+ }
+
+ [Fact]
+ public void BackplaneMessage_DeserializeInvalidBytes_WrongOwnerLen()
+ {
+ // arrange
+ var data = new byte[] { 4, 0, 1, 2, 3, 4 };
+
+ Action act = () => BackplaneMessage.Deserialize(data).First();
+ act.ShouldThrow().WithMessage("*Cannot read bytes,*");
+ }
+
+ [Fact]
+ public void BackplaneMessage_DeserializeInvalidBytes_NoAction()
+ {
+ // arrange
+ var data = new byte[] { 4, 0, 0, 0, 1, 2, 3, 4 };
+
+ Action act = () => BackplaneMessage.Deserialize(data).First();
+ act.ShouldThrow().WithMessage("*Cannot read byte,*");
+ }
+
+ [Fact]
+ public void BackplaneMessage_DeserializeInvalidBytes_WrongAction()
+ {
+ // arrange
+ var data = new byte[] { 4, 0, 0, 0, 1, 2, 3, 4, 255 };
+
+ Action act = () => BackplaneMessage.Deserialize(data).First();
+ act.ShouldThrow().WithMessage("*invalid message type*");
+ }
+
+ [Fact]
+ public void BackplaneMessage_DeserializeInvalidBytes_InvalidString()
+ {
+ // arrange clear region with wrong region string
+ var data = new byte[] { 4, 0, 0, 0, 1, 2, 3, 4, 3, 10, 0, 0, 0, 42 };
+
+ Action act = () => BackplaneMessage.Deserialize(data).First();
+ act.ShouldThrow().WithMessage("*Cannot read string,*");
+ }
+ }
+}
\ No newline at end of file