From b24616ab7d919bc09b11ff562c7216300903b7b8 Mon Sep 17 00:00:00 2001 From: shack2 <1341413415@qq.com> Date: Thu, 21 Mar 2019 19:57:03 +0800 Subject: [PATCH] update20190321 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 调整界面,变更ssh库。 优化RDP检查,免注册dll,如果远程桌面配置为“只允许运行带网络级身份验证的远程桌面的计算机连接”,程序暂时无法检查。 --- SNETCracker/Main.Designer.cs | 236 +- SNETCracker/Main.cs | 11 +- SNETCracker/Model/CrackSSH.cs | 7 +- SNETCracker/SNETCracker.csproj | 61 +- SNETCracker/libs/rdp/AxInterop.MSTSCLib.dll | Bin 339968 -> 0 bytes SNETCracker/libs/rdp/AxMSTSCLib.dll | Bin 0 -> 61440 bytes SNETCracker/libs/rdp/Interop.MSTSCLib.dll | Bin 600064 -> 0 bytes SNETCracker/libs/rdp/MSTSCLib.dll | Bin 0 -> 122880 bytes SNETCracker/libs/rebex/Rebex.Common.dll | Bin 1010840 -> 1066136 bytes SNETCracker/libs/rebex/Rebex.FileServer.dll | Bin 263320 -> 266392 bytes SNETCracker/libs/rebex/Rebex.FileSystem.dll | Bin 521880 -> 521368 bytes SNETCracker/libs/rebex/Rebex.Networking.dll | Bin 397976 -> 423576 bytes SNETCracker/libs/rebex/Rebex.Sftp.dll | Bin 247960 -> 250520 bytes SNETCracker/libs/rebex/Rebex.SshShell.dll | Bin 80024 -> 79512 bytes SNETCracker/libs/rebex/Rebex.Telnet.dll | Bin 59544 -> 59544 bytes SNETCracker/libs/rebex/Rebex.Terminal.dll | Bin 308376 -> 310416 bytes .../StackExchange.Redis-1.2.6/.gitignore | 23 - .../redis/StackExchange.Redis-1.2.6/.hgignore | 20 - .../.nuget/packages.config | 5 - .../.vscode/launch.json | 23 - .../.vscode/tasks.json | 16 - .../BasicTest/BasicTest.csproj | 26 - .../BasicTest/Program.cs | 38 - .../ConnectionWatcher/App.config | 6 - .../ConnectionWatcher.csproj | 129 - .../ConnectionWatcher/Form1.Designer.cs | 579 ---- .../ConnectionWatcher/Form1.cs | 621 ---- .../ConnectionWatcher/Form1.resx | 138 - .../ConnectionWatcher/Program.cs | 19 - .../Properties/AssemblyInfo.cs | 35 - .../Properties/Resources.Designer.cs | 71 - .../Properties/Resources.resx | 117 - .../Properties/Settings.Designer.cs | 30 - .../Properties/Settings.settings | 7 - .../Directory.build.props | 44 - .../redis/StackExchange.Redis-1.2.6/LICENSE | 47 - ...oft.Threading.Tasks.Extensions.Desktop.dll | Bin 0 -> 47424 bytes .../Microsoft.Threading.Tasks.Extensions.dll | Bin 0 -> 31520 bytes .../Microsoft.Threading.Tasks.dll | Bin 0 -> 37104 bytes .../MigratedBookSleeveTestSuite/App.config | 6 - .../MigratedBookSleeveTestSuite/Batches.cs | 60 - .../MigratedBookSleeveTestSuite/Config.cs | 289 -- .../MigratedBookSleeveTestSuite/Connection.cs | 312 -- .../Constraints.cs | 52 - .../MigratedBookSleeveTestSuite/Hashes.cs | 507 ---- .../Issues/Issue10.cs | 30 - .../Issues/Massive Delete.cs | 78 - .../Issues/SO10504853.cs | 87 - .../Issues/SO10825542.cs | 33 - .../Issues/SO11766033.cs | 41 - .../MigratedBookSleeveTestSuite/Keys.cs | 511 ---- .../MigratedBookSleeveTestSuite/Lists.cs | 713 ----- .../MigratedBookSleeveTestSuite/Locking.cs | 241 -- .../MigratedBookSleeveTestSuite.csproj | 56 - .../Performance.cs | 96 - .../MigratedBookSleeveTestSuite/Program.cs | 178 -- .../Properties/AssemblyInfo.cs | 35 - .../MigratedBookSleeveTestSuite/PubSub.cs | 269 -- .../MigratedBookSleeveTestSuite/Scripting.cs | 369 --- .../MigratedBookSleeveTestSuite/Server.cs | 446 --- .../MigratedBookSleeveTestSuite/Sets.cs | 513 ---- .../MigratedBookSleeveTestSuite/SortedSets.cs | 376 --- .../MigratedBookSleeveTestSuite/Strings.cs | 253 -- .../Transactions.cs | 296 -- .../redis-sharp.cs | 877 ------ .../NRediSearch.Test/ExampleUsage.cs | 76 - .../NRediSearch.Test/NRediSearch.Test.csproj | 20 - .../NRediSearch/Client.cs | 420 --- .../NRediSearch/Document.cs | 51 - .../NRediSearch/Literals.cs | 36 - .../NRediSearch/NRediSearch.csproj | 12 - .../NRediSearch/Query.cs | 294 -- .../NRediSearch/Schema.cs | 133 - .../NRediSearch/SearchResult.cs | 75 - .../StackExchange.Redis-1.2.6/NuGet.Config | 7 - .../redis/StackExchange.Redis-1.2.6/README.md | 4 - .../Redis Configs/Cluster/7000/nodes.conf | 7 - .../Redis Configs/Cluster/7000/redis.conf | 4 - .../Redis Configs/Cluster/7001/nodes.conf | 7 - .../Redis Configs/Cluster/7001/redis.conf | 4 - .../Redis Configs/Cluster/7002/nodes.conf | 7 - .../Redis Configs/Cluster/7002/redis.conf | 4 - .../Redis Configs/Cluster/7003/nodes.conf | 7 - .../Redis Configs/Cluster/7003/redis.conf | 4 - .../Redis Configs/Cluster/7004/nodes.conf | 7 - .../Redis Configs/Cluster/7004/redis.conf | 4 - .../Redis Configs/Cluster/7005/nodes.conf | 7 - .../Redis Configs/Cluster/7005/redis.conf | 4 - .../Redis Configs/master.conf | 5 - .../Redis Configs/redis-cli 7000.cmd | 1 - .../Redis Configs/redis-cli 7001.cmd | 1 - .../Redis Configs/redis-cli 7002.cmd | 1 - .../Redis Configs/redis-cli 7003.cmd | 1 - .../Redis Configs/redis-cli 7004.cmd | 1 - .../Redis Configs/redis-cli 7005.cmd | 1 - .../Redis Configs/redis-cli master.cmd | 1 - .../Redis Configs/redis-cli secure.cmd | 1 - .../Redis Configs/redis-cli slave.cmd | 1 - .../Redis Configs/redis-server all local.cmd | 3 - .../Redis Configs/redis-server cluster.cmd | 19 - .../Redis Configs/redis-server master.cmd | 1 - .../Redis Configs/redis-server secure.cmd | 1 - .../Redis Configs/redis-server slave.cmd | 1 - .../Redis Configs/redis-trib.rb | 1699 ----------- .../Redis Configs/secure.conf | 6 - .../Redis Configs/slave.conf | 6 - .../RediSearch/Client.cs | 420 --- .../RediSearch/Document.cs | 51 - .../RediSearch/Literals.cs | 36 - .../RediSearch/Query.cs | 264 -- .../RediSearch/Schema.cs | 103 - .../RediSearch/SearchResult.cs | 75 - .../StackExchange.Redis.Modules.csproj | 12 - .../StackExchange.Redis.Modules/Throttling.cs | 52 - .../StackExchange.Redis.StrongName.csproj | 72 - .../StackExchange.Redis.StrongName/build.cmd | 1 - .../StackExchange.Redis.Tests/AdhocTests.cs | 35 - .../StackExchange.Redis.Tests/AsyncTests.cs | 45 - .../StackExchange.Redis.Tests/BasicOps.cs | 709 ----- .../BatchWrapperTests.cs | 31 - .../StackExchange.Redis.Tests/Bits.cs | 23 - .../StackExchange.Redis.Tests/Cluster.cs | 673 ---- .../StackExchange.Redis.Tests/Commands.cs | 21 - .../StackExchange.Redis.Tests/Config.cs | 338 --- .../ConnectFailTimeout.cs | 40 - .../ConnectToUnexistingHost.cs | 51 - .../ConnectingFailDetection.cs | 132 - .../ConnectionFailedErrors.cs | 146 - .../ConnectionReconnectRetryPolicyTests.cs | 36 - .../ConnectionShutdown.cs | 60 - .../DatabaseWrapperTests.cs | 937 ------ .../StackExchange.Redis.Tests/Databases.cs | 70 - .../StackExchange.Redis.Tests/DefaultPorts.cs | 58 - .../ExceptionFactoryTests.cs | 113 - .../StackExchange.Redis.Tests/Expiry.cs | 89 - .../FloatingPoint.cs | 163 - .../StackExchange.Redis.Tests/GeoTests.cs | 187 -- .../StackExchange.Redis.Tests/HyperLogLog.cs | 41 - .../Issues/BgSaveResponse.cs | 23 - .../Issues/DefaultDatabase.cs | 58 - .../Issues/Issue118.cs | 6 - .../Issues/Issue182.cs | 72 - .../Issues/Issue25.cs | 43 - .../Issues/Issue6.cs | 21 - .../Issues/SO22786599.cs | 35 - .../Issues/SO23949477.cs | 38 - .../Issues/SO24807536.cs | 43 - .../Issues/SO25113323.cs | 39 - .../Issues/SO25567566.cs | 75 - .../StackExchange.Redis.Tests/Keys.cs | 102 - .../KeysAndValues.cs | 208 -- .../StackExchange.Redis.Tests/Lex.cs | 98 - .../StackExchange.Redis.Tests/Lists.cs | 35 - .../StackExchange.Redis.Tests/Locking.cs | 271 -- .../StackExchange.Redis.Tests/Migrate.cs | 30 - .../StackExchange.Redis.Tests/MultiAdd.cs | 115 - .../StackExchange.Redis.Tests/MultiMaster.cs | 175 -- .../StackExchange.Redis.Tests/Naming.cs | 258 -- .../PreserveOrder.cs | 73 - .../StackExchange.Redis.Tests/Profiling.cs | 596 ---- .../StackExchange.Redis.Tests/Program.cs | 18 - .../Properties/AssemblyInfo.cs | 35 - .../StackExchange.Redis.Tests/PubSub.cs | 427 --- .../PubSubCommand.cs | 33 - .../StackExchange.Redis.Tests/RealWorld.cs | 32 - .../StackExchange.Redis.Tests/SSDB.cs | 27 - .../StackExchange.Redis.Tests/SSL.cs | 285 -- .../StackExchange.Redis.Tests/Scans.cs | 358 --- .../StackExchange.Redis.Tests/Scripting.cs | 513 ---- .../StackExchange.Redis.Tests/Secure.cs | 83 - .../StackExchange.Redis.Tests/Sentinel.cs | 109 - .../StackExchange.Redis.Tests/Sets.cs | 39 - .../StackExchange.Redis.Tests.csproj | 47 - .../StackExchange.Redis.Tests/TaskTests.cs | 120 - .../StackExchange.Redis.Tests/TestBase.cs | 324 -- .../TestInfoReplicationChecks.cs | 29 - .../TransactionWrapperTests.cs | 93 - .../StackExchange.Redis.Tests/Transactions.cs | 754 ----- .../StackExchange.Redis.Tests/VPNTest.cs | 41 - .../WithKeyPrefixTests.cs | 131 - .../WrapperBaseTests.cs | 893 ------ .../StackExchange.Redis.Tests/packages.config | 6 - .../StackExchange.Redis.dll | Bin 0 -> 357888 bytes .../StackExchange.Redis.sln | 129 - .../StackExchange.Redis.sln.DotSettings | 3 - .../StackExchange.Redis.snk | Bin 596 -> 0 bytes .../Properties/AssemblyInfo.cs | 39 - .../StackExchange.Redis.csproj | 70 - .../StackExchange/AssemblyInfoHack.cs | 7 - .../StackExchange/Redis/Aggregate.cs | 21 - .../StackExchange/Redis/Bitwise.cs | 25 - .../StackExchange/Redis/ClientFlags.cs | 66 - .../StackExchange/Redis/ClientInfo.cs | 214 -- .../StackExchange/Redis/ClientType.cs | 21 - .../Redis/ClusterConfiguration.cs | 519 ---- .../StackExchange/Redis/CommandFlags.cs | 66 - .../StackExchange/Redis/CommandMap.cs | 242 -- .../StackExchange/Redis/CommandStatus.cs | 21 - .../StackExchange/Redis/CommandTrace.cs | 98 - .../Redis/Compat/ConvertHelper.cs | 30 - .../Redis/Compat/VolatileWrapper.cs | 23 - .../Redis/CompletedDefaultTask.cs | 22 - .../StackExchange/Redis/CompletionManager.cs | 195 -- .../ConcurrentProfileStorageCollection.cs | 227 -- .../StackExchange/Redis/Condition.cs | 621 ---- .../Redis/ConfigurationOptions.cs | 726 ----- .../StackExchange/Redis/ConnectionCounters.cs | 134 - .../Redis/ConnectionFailedEventArgs.cs | 56 - .../Redis/ConnectionFailureType.cs | 49 - .../Redis/ConnectionMultiplexer.Profiling.cs | 75 - .../ConnectionMultiplexer.ReaderWriter.cs | 34 - .../Redis/ConnectionMultiplexer.cs | 2245 -------------- .../StackExchange/Redis/ConnectionType.cs | 21 - .../StackExchange/Redis/DebuggingAids.cs | 458 --- .../StackExchange/Redis/EndPointCollection.cs | 116 - .../StackExchange/Redis/EndPointEventArgs.cs | 38 - .../StackExchange/Redis/ExceptionFactory.cs | 242 -- .../StackExchange/Redis/Exclude.cs | 29 - .../StackExchange/Redis/ExponentialRetry.cs | 58 - .../StackExchange/Redis/ExportOptions.cs | 36 - .../StackExchange/Redis/ExtensionMethods.cs | 157 - .../StackExchange/Redis/Format.cs | 182 -- .../StackExchange/Redis/GeoEntry.cs | 242 -- .../StackExchange/Redis/GeoUnit.cs | 28 - .../StackExchange/Redis/HashEntry.cs | 100 - .../Redis/HashSlotMovedEventArgs.cs | 49 - .../StackExchange/Redis/IBatch.cs | 21 - .../StackExchange/Redis/ICompletable.cs | 11 - .../Redis/IConnectionMultiplexer.cs | 253 -- .../StackExchange/Redis/IDatabase.cs | 1078 ------- .../StackExchange/Redis/IDatabaseAsync.cs | 1040 ------- .../StackExchange/Redis/IMultiMessage.cs | 9 - .../StackExchange/Redis/IProfiler.cs | 131 - .../Redis/IReconnectRetryPolicy.cs | 17 - .../StackExchange/Redis/IRedis.cs | 51 - .../StackExchange/Redis/IRedisAsync.cs | 41 - .../StackExchange/Redis/IServer.cs | 529 ---- .../StackExchange/Redis/ISubscriber.cs | 98 - .../StackExchange/Redis/ITransaction.cs | 33 - .../Redis/InternalErrorEventArgs.cs | 54 - .../Redis/KeyspaceIsolation/BatchWrapper.cs | 14 - .../KeyspaceIsolation/DatabaseExtension.cs | 68 - .../KeyspaceIsolation/DatabaseWrapper.cs | 731 ----- .../KeyspaceIsolation/TransactionWrapper.cs | 31 - .../Redis/KeyspaceIsolation/WrapperBase.cs | 845 ------ .../StackExchange/Redis/LinearRetry.cs | 31 - .../StackExchange/Redis/LoggingTextStream.cs | 141 - .../StackExchange/Redis/LuaScript.cs | 284 -- .../StackExchange/Redis/Message.cs | 1299 -------- .../StackExchange/Redis/MessageCompletable.cs | 48 - .../StackExchange/Redis/MessageQueue.cs | 118 - .../StackExchange/Redis/MigrateOptions.cs | 24 - .../StackExchange/Redis/Order.cs | 17 - .../StackExchange/Redis/PhysicalBridge.cs | 850 ------ .../StackExchange/Redis/PhysicalConnection.cs | 1170 ------- .../Redis/ProfileContextTracker.cs | 238 -- .../StackExchange/Redis/ProfileStorage.cs | 134 - .../StackExchange/Redis/RawResult.cs | 364 --- .../StackExchange/Redis/RedisBase.cs | 340 --- .../StackExchange/Redis/RedisBatch.cs | 108 - .../StackExchange/Redis/RedisChannel.cs | 261 -- .../StackExchange/Redis/RedisCommand.cs | 189 -- .../StackExchange/Redis/RedisDatabase.cs | 2702 ----------------- .../Redis/RedisErrorEventArgs.cs | 44 - .../StackExchange/Redis/RedisFeatures.cs | 172 -- .../StackExchange/Redis/RedisKey.cs | 318 -- .../StackExchange/Redis/RedisLiterals.cs | 109 - .../StackExchange/Redis/RedisResult.cs | 389 --- .../StackExchange/Redis/RedisServer.cs | 818 ----- .../StackExchange/Redis/RedisSubscriber.cs | 347 --- .../StackExchange/Redis/RedisTransaction.cs | 487 --- .../StackExchange/Redis/RedisType.cs | 46 - .../StackExchange/Redis/RedisValue.cs | 726 ----- .../Redis/ReplicationChangeOptions.cs | 29 - .../StackExchange/Redis/ResultBox.cs | 148 - .../StackExchange/Redis/ResultProcessor.cs | 1456 --------- .../StackExchange/Redis/ResultType.cs | 12 - .../StackExchange/Redis/SaveType.cs | 27 - .../Redis/ScriptParameterMapper.cs | 411 --- .../StackExchange/Redis/ServerCounters.cs | 68 - .../StackExchange/Redis/ServerEndPoint.cs | 727 ----- .../Redis/ServerSelectionStrategy.cs | 299 -- .../StackExchange/Redis/ServerType.cs | 25 - .../StackExchange/Redis/SetOperation.cs | 21 - .../StackExchange/Redis/ShutdownMode.cs | 22 - .../Redis/SocketManager.NoPoll.cs | 16 - .../StackExchange/Redis/SocketManager.Poll.cs | 428 --- .../StackExchange/Redis/SocketManager.cs | 481 --- .../StackExchange/Redis/SortType.cs | 17 - .../StackExchange/Redis/SortedSetEntry.cs | 132 - .../StackExchange/Redis/StringSplits.cs | 10 - .../StackExchange/Redis/TaskSource.cs | 107 - .../StackExchange/Redis/When.cs | 21 - .../StackExchange.Redis/build.cmd | 1 - .../StackExchange.Redis-1.2.6/StrongName.ps1 | 3 - .../StackExchange.Redis-1.2.6/System.IO.dll | Bin 0 -> 21144 bytes .../System.Runtime.dll | Bin 0 -> 22176 bytes .../System.Threading.Tasks.dll | Bin 0 -> 35016 bytes .../StackExchange.Redis-1.2.6/build.msbuild | 8 - .../StackExchange.Redis-1.2.6/docs/Basics.md | 153 - .../docs/Configuration.md | 195 -- .../StackExchange.Redis-1.2.6/docs/Events.md | 14 - .../docs/ExecSync.md | 5 - .../docs/KeysScan.md | 61 - .../docs/KeysValues.md | 116 - .../docs/PipelinesMultiplexers.md | 110 - .../docs/Profiling.md | 208 -- .../docs/PubSubOrder.md | 20 - .../docs/ReleaseNotes.md | 68 - .../docs/Scripting.md | 59 - .../docs/Timeouts.md | 52 - .../docs/Transactions.md | 118 - .../StackExchange.Redis-1.2.6/docs/index.md | 58 - .../StackExchange.Redis-1.2.6/monobuild.bash | 11 - .../StackExchange.Redis-1.2.6/monobuild.cmd | 15 - .../StackExchange.Redis-1.2.6/netbuild.cmd | 12 - SNETCracker/rdp/RdpClient.cs | 47 +- 317 files changed, 202 insertions(+), 54024 deletions(-) delete mode 100644 SNETCracker/libs/rdp/AxInterop.MSTSCLib.dll create mode 100644 SNETCracker/libs/rdp/AxMSTSCLib.dll delete mode 100644 SNETCracker/libs/rdp/Interop.MSTSCLib.dll create mode 100644 SNETCracker/libs/rdp/MSTSCLib.dll delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.gitignore delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.hgignore delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.nuget/packages.config delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.vscode/launch.json delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.vscode/tasks.json delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/BasicTest/BasicTest.csproj delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/BasicTest/Program.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/App.config delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/ConnectionWatcher.csproj delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Form1.Designer.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Form1.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Form1.resx delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Program.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/AssemblyInfo.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Resources.Designer.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Resources.resx delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Settings.Designer.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Settings.settings delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Directory.build.props delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/LICENSE create mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Microsoft.Threading.Tasks.Extensions.Desktop.dll create mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Microsoft.Threading.Tasks.Extensions.dll create mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Microsoft.Threading.Tasks.dll delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/App.config delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Batches.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Config.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Connection.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Constraints.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Hashes.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/Issue10.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/Massive Delete.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/SO10504853.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/SO10825542.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/SO11766033.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Keys.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Lists.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Locking.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/MigratedBookSleeveTestSuite.csproj delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Performance.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Program.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Properties/AssemblyInfo.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/PubSub.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Scripting.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Server.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Sets.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/SortedSets.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Strings.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Transactions.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/redis-sharp.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch.Test/ExampleUsage.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch.Test/NRediSearch.Test.csproj delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Client.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Document.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Literals.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/NRediSearch.csproj delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Query.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Schema.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/SearchResult.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NuGet.Config delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/README.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7000/nodes.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7000/redis.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7001/nodes.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7001/redis.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7002/nodes.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7002/redis.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7003/nodes.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7003/redis.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7004/nodes.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7004/redis.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7005/nodes.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7005/redis.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/master.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7000.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7001.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7002.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7003.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7004.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7005.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli master.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli secure.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli slave.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server all local.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server cluster.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server master.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server secure.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server slave.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-trib.rb delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/secure.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/slave.conf delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Client.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Document.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Literals.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Query.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Schema.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/SearchResult.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/StackExchange.Redis.Modules.csproj delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/Throttling.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.StrongName/StackExchange.Redis.StrongName.csproj delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.StrongName/build.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/AdhocTests.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/AsyncTests.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/BasicOps.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/BatchWrapperTests.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Bits.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Cluster.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Commands.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Config.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectFailTimeout.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectToUnexistingHost.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectingFailDetection.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectionFailedErrors.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectionReconnectRetryPolicyTests.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectionShutdown.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/DatabaseWrapperTests.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Databases.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/DefaultPorts.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ExceptionFactoryTests.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Expiry.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/FloatingPoint.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/GeoTests.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/HyperLogLog.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/BgSaveResponse.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/DefaultDatabase.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue118.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue182.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue25.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue6.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO22786599.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO23949477.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO24807536.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO25113323.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO25567566.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Keys.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/KeysAndValues.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Lex.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Lists.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Locking.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Migrate.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/MultiAdd.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/MultiMaster.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Naming.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/PreserveOrder.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Profiling.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Program.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Properties/AssemblyInfo.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/PubSub.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/PubSubCommand.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/RealWorld.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/SSDB.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/SSL.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Scans.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Scripting.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Secure.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Sentinel.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Sets.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/StackExchange.Redis.Tests.csproj delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TaskTests.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TestBase.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TestInfoReplicationChecks.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TransactionWrapperTests.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Transactions.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/VPNTest.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/WithKeyPrefixTests.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/WrapperBaseTests.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/packages.config create mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.dll delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.sln delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.sln.DotSettings delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.snk delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/Properties/AssemblyInfo.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange.Redis.csproj delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/AssemblyInfoHack.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Aggregate.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Bitwise.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClientFlags.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClientInfo.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClientType.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClusterConfiguration.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandFlags.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandMap.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandStatus.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandTrace.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Compat/ConvertHelper.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Compat/VolatileWrapper.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CompletedDefaultTask.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CompletionManager.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConcurrentProfileStorageCollection.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Condition.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConfigurationOptions.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionCounters.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionFailedEventArgs.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionFailureType.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.Profiling.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.ReaderWriter.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionType.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/DebuggingAids.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/EndPointCollection.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/EndPointEventArgs.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExceptionFactory.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Exclude.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExponentialRetry.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExportOptions.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExtensionMethods.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Format.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/GeoEntry.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/GeoUnit.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/HashEntry.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/HashSlotMovedEventArgs.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IBatch.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ICompletable.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IConnectionMultiplexer.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IDatabase.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IDatabaseAsync.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IMultiMessage.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IProfiler.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IReconnectRetryPolicy.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IRedis.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IRedisAsync.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IServer.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ISubscriber.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ITransaction.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/InternalErrorEventArgs.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/BatchWrapper.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/DatabaseExtension.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/DatabaseWrapper.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/TransactionWrapper.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/WrapperBase.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/LinearRetry.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/LoggingTextStream.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/LuaScript.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Message.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/MessageCompletable.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/MessageQueue.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/MigrateOptions.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Order.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/PhysicalBridge.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/PhysicalConnection.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ProfileContextTracker.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ProfileStorage.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RawResult.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisBase.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisBatch.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisChannel.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisCommand.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisDatabase.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisErrorEventArgs.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisFeatures.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisKey.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisLiterals.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisResult.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisServer.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisSubscriber.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisTransaction.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisType.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisValue.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ReplicationChangeOptions.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ResultBox.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ResultProcessor.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ResultType.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SaveType.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ScriptParameterMapper.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerCounters.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerEndPoint.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerSelectionStrategy.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerType.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SetOperation.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ShutdownMode.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SocketManager.NoPoll.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SocketManager.Poll.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SocketManager.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SortType.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SortedSetEntry.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/StringSplits.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/TaskSource.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/When.cs delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/build.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StrongName.ps1 create mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/System.IO.dll create mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/System.Runtime.dll create mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/System.Threading.Tasks.dll delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/build.msbuild delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Basics.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Configuration.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Events.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/ExecSync.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/KeysScan.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/KeysValues.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/PipelinesMultiplexers.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Profiling.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/PubSubOrder.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/ReleaseNotes.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Scripting.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Timeouts.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Transactions.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/index.md delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/monobuild.bash delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/monobuild.cmd delete mode 100644 SNETCracker/libs/redis/StackExchange.Redis-1.2.6/netbuild.cmd diff --git a/SNETCracker/Main.Designer.cs b/SNETCracker/Main.Designer.cs index 7e77320..96e38ec 100644 --- a/SNETCracker/Main.Designer.cs +++ b/SNETCracker/Main.Designer.cs @@ -30,7 +30,6 @@ private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.services_list = new System.Windows.Forms.CheckedListBox(); this.chk_crackerOneCount = new System.Windows.Forms.CheckBox(); this.chk_notAutoSelectDic = new System.Windows.Forms.CheckBox(); this.chk_isScanPort = new System.Windows.Forms.CheckBox(); @@ -50,10 +49,10 @@ private void InitializeComponent() this.label5 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); this.label7 = new System.Windows.Forms.Label(); this.label6 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); + this.services_list = new System.Windows.Forms.CheckedListBox(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.txt_log = new System.Windows.Forms.RichTextBox(); this.list_lvw = new System.Windows.Forms.ListView(); @@ -101,16 +100,24 @@ private void InitializeComponent() this.tsmi_help_version = new System.Windows.Forms.ToolStripMenuItem(); this.tsmi_help_support = new System.Windows.Forms.ToolStripMenuItem(); this.tsmi_tools = new System.Windows.Forms.ToolStripMenuItem(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.groupBox5 = new System.Windows.Forms.GroupBox(); this.groupBox1.SuspendLayout(); this.groupBox2.SuspendLayout(); this.cms_lvw.SuspendLayout(); this.bt_status.SuspendLayout(); this.menuStrip1.SuspendLayout(); + this.groupBox3.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.groupBox5.SuspendLayout(); this.SuspendLayout(); // // groupBox1 // - this.groupBox1.Controls.Add(this.services_list); this.groupBox1.Controls.Add(this.chk_crackerOneCount); this.groupBox1.Controls.Add(this.chk_notAutoSelectDic); this.groupBox1.Controls.Add(this.chk_isScanPort); @@ -130,31 +137,21 @@ private void InitializeComponent() this.groupBox1.Controls.Add(this.label5); this.groupBox1.Controls.Add(this.label4); this.groupBox1.Controls.Add(this.label3); - this.groupBox1.Controls.Add(this.label2); this.groupBox1.Controls.Add(this.label7); this.groupBox1.Controls.Add(this.label6); this.groupBox1.Controls.Add(this.label1); - this.groupBox1.Dock = System.Windows.Forms.DockStyle.Top; - this.groupBox1.Location = new System.Drawing.Point(0, 25); + this.groupBox1.Location = new System.Drawing.Point(5, 0); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(876, 138); + this.groupBox1.Size = new System.Drawing.Size(743, 125); this.groupBox1.TabIndex = 0; this.groupBox1.TabStop = false; // - // services_list - // - this.services_list.FormattingEnabled = true; - this.services_list.Location = new System.Drawing.Point(41, 14); - this.services_list.Name = "services_list"; - this.services_list.Size = new System.Drawing.Size(107, 116); - this.services_list.TabIndex = 1; - // // chk_crackerOneCount // this.chk_crackerOneCount.AutoSize = true; this.chk_crackerOneCount.Checked = true; this.chk_crackerOneCount.CheckState = System.Windows.Forms.CheckState.Checked; - this.chk_crackerOneCount.Location = new System.Drawing.Point(750, 19); + this.chk_crackerOneCount.Location = new System.Drawing.Point(374, 20); this.chk_crackerOneCount.Name = "chk_crackerOneCount"; this.chk_crackerOneCount.Size = new System.Drawing.Size(108, 16); this.chk_crackerOneCount.TabIndex = 5; @@ -167,11 +164,11 @@ private void InitializeComponent() this.chk_notAutoSelectDic.AutoSize = true; this.chk_notAutoSelectDic.Checked = true; this.chk_notAutoSelectDic.CheckState = System.Windows.Forms.CheckState.Checked; - this.chk_notAutoSelectDic.Location = new System.Drawing.Point(433, 102); + this.chk_notAutoSelectDic.Location = new System.Drawing.Point(305, 97); this.chk_notAutoSelectDic.Name = "chk_notAutoSelectDic"; - this.chk_notAutoSelectDic.Size = new System.Drawing.Size(156, 16); + this.chk_notAutoSelectDic.Size = new System.Drawing.Size(204, 16); this.chk_notAutoSelectDic.TabIndex = 10; - this.chk_notAutoSelectDic.Text = "不根据服务自动选择字典"; + this.chk_notAutoSelectDic.Text = "不根据检查服务自动选择密码字典"; this.chk_notAutoSelectDic.UseVisualStyleBackColor = true; this.chk_notAutoSelectDic.CheckedChanged += new System.EventHandler(this.chk_notAutoSelectDic_CheckedChanged); // @@ -180,7 +177,7 @@ private void InitializeComponent() this.chk_isScanPort.AutoSize = true; this.chk_isScanPort.Checked = true; this.chk_isScanPort.CheckState = System.Windows.Forms.CheckState.Checked; - this.chk_isScanPort.Location = new System.Drawing.Point(517, 22); + this.chk_isScanPort.Location = new System.Drawing.Point(657, 18); this.chk_isScanPort.Name = "chk_isScanPort"; this.chk_isScanPort.Size = new System.Drawing.Size(72, 16); this.chk_isScanPort.TabIndex = 3; @@ -195,7 +192,7 @@ private void InitializeComponent() "0", "1", "2"}); - this.cbox_reTry.Location = new System.Drawing.Point(663, 100); + this.cbox_reTry.Location = new System.Drawing.Point(578, 93); this.cbox_reTry.Name = "cbox_reTry"; this.cbox_reTry.Size = new System.Drawing.Size(61, 20); this.cbox_reTry.TabIndex = 11; @@ -214,7 +211,7 @@ private void InitializeComponent() "40", "50", "60"}); - this.cbox_timeOut.Location = new System.Drawing.Point(663, 19); + this.cbox_timeOut.Location = new System.Drawing.Point(578, 16); this.cbox_timeOut.Name = "cbox_timeOut"; this.cbox_timeOut.Size = new System.Drawing.Size(61, 20); this.cbox_timeOut.TabIndex = 4; @@ -253,7 +250,7 @@ private void InitializeComponent() "700", "800", "1000"}); - this.cbox_threadSize.Location = new System.Drawing.Point(663, 58); + this.cbox_threadSize.Location = new System.Drawing.Point(578, 53); this.cbox_threadSize.Name = "cbox_threadSize"; this.cbox_threadSize.Size = new System.Drawing.Size(61, 20); this.cbox_threadSize.TabIndex = 9; @@ -261,9 +258,9 @@ private void InitializeComponent() // // btn_stopCracker // - this.btn_stopCracker.Location = new System.Drawing.Point(750, 97); + this.btn_stopCracker.Location = new System.Drawing.Point(657, 90); this.btn_stopCracker.Name = "btn_stopCracker"; - this.btn_stopCracker.Size = new System.Drawing.Size(108, 23); + this.btn_stopCracker.Size = new System.Drawing.Size(72, 23); this.btn_stopCracker.TabIndex = 2; this.btn_stopCracker.Text = "停止检查"; this.btn_stopCracker.UseVisualStyleBackColor = true; @@ -271,9 +268,9 @@ private void InitializeComponent() // // btn_cracker // - this.btn_cracker.Location = new System.Drawing.Point(750, 56); + this.btn_cracker.Location = new System.Drawing.Point(657, 51); this.btn_cracker.Name = "btn_cracker"; - this.btn_cracker.Size = new System.Drawing.Size(108, 23); + this.btn_cracker.Size = new System.Drawing.Size(72, 23); this.btn_cracker.TabIndex = 2; this.btn_cracker.Text = "开始检查"; this.btn_cracker.UseVisualStyleBackColor = true; @@ -281,27 +278,27 @@ private void InitializeComponent() // // btn_importPassword // - this.btn_importPassword.Location = new System.Drawing.Point(348, 100); + this.btn_importPassword.Location = new System.Drawing.Point(218, 93); this.btn_importPassword.Name = "btn_importPassword"; this.btn_importPassword.Size = new System.Drawing.Size(67, 23); this.btn_importPassword.TabIndex = 2; - this.btn_importPassword.Text = "导 入"; + this.btn_importPassword.Text = "导入密码"; this.btn_importPassword.UseVisualStyleBackColor = true; this.btn_importPassword.Click += new System.EventHandler(this.btn_importPassword_Click); // // btn_importUername // - this.btn_importUername.Location = new System.Drawing.Point(348, 58); + this.btn_importUername.Location = new System.Drawing.Point(218, 51); this.btn_importUername.Name = "btn_importUername"; this.btn_importUername.Size = new System.Drawing.Size(67, 23); this.btn_importUername.TabIndex = 2; - this.btn_importUername.Text = "导 入"; + this.btn_importUername.Text = "导入账户"; this.btn_importUername.UseVisualStyleBackColor = true; this.btn_importUername.Click += new System.EventHandler(this.btn_importUername_Click); // // btn_importList // - this.btn_importList.Location = new System.Drawing.Point(433, 18); + this.btn_importList.Location = new System.Drawing.Point(305, 16); this.btn_importList.Name = "btn_importList"; this.btn_importList.Size = new System.Drawing.Size(63, 23); this.btn_importList.TabIndex = 2; @@ -311,45 +308,45 @@ private void InitializeComponent() // // txt_username_ext // - this.txt_username_ext.Location = new System.Drawing.Point(502, 58); + this.txt_username_ext.Location = new System.Drawing.Point(374, 52); this.txt_username_ext.Name = "txt_username_ext"; - this.txt_username_ext.Size = new System.Drawing.Size(87, 21); + this.txt_username_ext.Size = new System.Drawing.Size(133, 21); this.txt_username_ext.TabIndex = 8; // // txt_password // - this.txt_password.Location = new System.Drawing.Point(214, 101); + this.txt_password.Location = new System.Drawing.Point(54, 93); this.txt_password.Name = "txt_password"; - this.txt_password.Size = new System.Drawing.Size(128, 21); + this.txt_password.Size = new System.Drawing.Size(158, 21); this.txt_password.TabIndex = 7; // // txt_username // - this.txt_username.Location = new System.Drawing.Point(213, 58); + this.txt_username.Location = new System.Drawing.Point(53, 52); this.txt_username.Name = "txt_username"; - this.txt_username.Size = new System.Drawing.Size(129, 21); + this.txt_username.Size = new System.Drawing.Size(159, 21); this.txt_username.TabIndex = 6; // // txt_target // - this.txt_target.Location = new System.Drawing.Point(214, 20); + this.txt_target.Location = new System.Drawing.Point(54, 16); this.txt_target.Name = "txt_target"; - this.txt_target.Size = new System.Drawing.Size(202, 21); + this.txt_target.Size = new System.Drawing.Size(231, 21); this.txt_target.TabIndex = 2; // // label8 // this.label8.AutoSize = true; - this.label8.Location = new System.Drawing.Point(610, 105); + this.label8.Location = new System.Drawing.Point(531, 98); this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(47, 12); + this.label8.Size = new System.Drawing.Size(41, 12); this.label8.TabIndex = 0; - this.label8.Text = "重 试:"; + this.label8.Text = "重试:"; // // label5 // this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(431, 61); + this.label5.Location = new System.Drawing.Point(303, 56); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(65, 12); this.label5.TabIndex = 0; @@ -358,85 +355,81 @@ private void InitializeComponent() // label4 // this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(610, 22); + this.label4.Location = new System.Drawing.Point(531, 19); this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(47, 12); + this.label4.Size = new System.Drawing.Size(41, 12); this.label4.TabIndex = 0; - this.label4.Text = "超 时:"; + this.label4.Text = "超时:"; // // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(610, 60); + this.label3.Location = new System.Drawing.Point(531, 55); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(47, 12); + this.label3.Size = new System.Drawing.Size(41, 12); this.label3.TabIndex = 0; - this.label3.Text = "线 程:"; - // - // label2 - // - this.label2.Location = new System.Drawing.Point(14, 16); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(21, 100); - this.label2.TabIndex = 0; - this.label2.Text = "\r\n检 \r\n查 \r\n服\r\n 务"; + this.label3.Text = "线程:"; // // label7 // this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(160, 106); + this.label7.Location = new System.Drawing.Point(6, 98); this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(47, 12); + this.label7.Size = new System.Drawing.Size(41, 12); this.label7.TabIndex = 0; - this.label7.Text = "密 码:"; + this.label7.Text = "密码:"; // // label6 // this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(160, 61); + this.label6.Location = new System.Drawing.Point(6, 55); this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(47, 12); + this.label6.Size = new System.Drawing.Size(41, 12); this.label6.TabIndex = 0; - this.label6.Text = "账 户:"; + this.label6.Text = "账户:"; // // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(160, 23); + this.label1.Location = new System.Drawing.Point(6, 19); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(47, 12); + this.label1.Size = new System.Drawing.Size(41, 12); this.label1.TabIndex = 0; - this.label1.Text = "目 标:"; + this.label1.Text = "目标:"; + // + // services_list + // + this.services_list.BackColor = System.Drawing.SystemColors.Window; + this.services_list.Dock = System.Windows.Forms.DockStyle.Fill; + this.services_list.FormattingEnabled = true; + this.services_list.Location = new System.Drawing.Point(0, 0); + this.services_list.Name = "services_list"; + this.services_list.Size = new System.Drawing.Size(96, 472); + this.services_list.TabIndex = 1; // // groupBox2 // - this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox2.Controls.Add(this.txt_log); - this.groupBox2.Controls.Add(this.list_lvw); - this.groupBox2.Location = new System.Drawing.Point(0, 161); + this.groupBox2.Location = new System.Drawing.Point(8, 523); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(876, 491); + this.groupBox2.Size = new System.Drawing.Size(857, 129); this.groupBox2.TabIndex = 0; this.groupBox2.TabStop = false; // // txt_log // - this.txt_log.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.txt_log.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.txt_log.Location = new System.Drawing.Point(3, 415); + this.txt_log.Dock = System.Windows.Forms.DockStyle.Fill; + this.txt_log.Location = new System.Drawing.Point(3, 17); this.txt_log.Name = "txt_log"; - this.txt_log.Size = new System.Drawing.Size(870, 76); + this.txt_log.Size = new System.Drawing.Size(851, 109); this.txt_log.TabIndex = 1; this.txt_log.Text = ""; // // list_lvw // - this.list_lvw.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.list_lvw.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.list_lvw.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.col_id, @@ -448,11 +441,12 @@ private void InitializeComponent() this.col_banner, this.col_useTime}); this.list_lvw.ContextMenuStrip = this.cms_lvw; + this.list_lvw.Dock = System.Windows.Forms.DockStyle.Fill; this.list_lvw.FullRowSelect = true; this.list_lvw.GridLines = true; - this.list_lvw.Location = new System.Drawing.Point(6, 15); + this.list_lvw.Location = new System.Drawing.Point(3, 17); this.list_lvw.Name = "list_lvw"; - this.list_lvw.Size = new System.Drawing.Size(870, 394); + this.list_lvw.Size = new System.Drawing.Size(737, 319); this.list_lvw.TabIndex = 0; this.list_lvw.UseCompatibleStateImageBehavior = false; this.list_lvw.View = System.Windows.Forms.View.Details; @@ -460,16 +454,17 @@ private void InitializeComponent() // col_id // this.col_id.Text = "序号"; + this.col_id.Width = 0; // // col_ip // this.col_ip.Text = "IP地址"; - this.col_ip.Width = 106; + this.col_ip.Width = 118; // // col_serviceName // this.col_serviceName.Text = "服 务"; - this.col_serviceName.Width = 84; + this.col_serviceName.Width = 94; // // col_port // @@ -479,22 +474,22 @@ private void InitializeComponent() // col_username // this.col_username.Text = "帐户名"; - this.col_username.Width = 83; + this.col_username.Width = 112; // // col_pass // this.col_pass.Text = "密码"; - this.col_pass.Width = 100; + this.col_pass.Width = 133; // // col_banner // this.col_banner.Text = "BANNER"; - this.col_banner.Width = 100; + this.col_banner.Width = 104; // // col_useTime // this.col_useTime.Text = "用时[毫秒]"; - this.col_useTime.Width = 100; + this.col_useTime.Width = 82; // // cms_lvw // @@ -545,9 +540,9 @@ private void InitializeComponent() // rdp_panle // this.rdp_panle.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.rdp_panle.Location = new System.Drawing.Point(214, 9); + this.rdp_panle.Location = new System.Drawing.Point(207, 12); this.rdp_panle.Name = "rdp_panle"; - this.rdp_panle.Size = new System.Drawing.Size(10, 10); + this.rdp_panle.Size = new System.Drawing.Size(1, 1); this.rdp_panle.TabIndex = 12; // // bt_status @@ -570,7 +565,7 @@ private void InitializeComponent() this.tssl_notScanPortsSumCount}); this.bt_status.Location = new System.Drawing.Point(0, 655); this.bt_status.Name = "bt_status"; - this.bt_status.Size = new System.Drawing.Size(876, 22); + this.bt_status.Size = new System.Drawing.Size(875, 22); this.bt_status.TabIndex = 1; this.bt_status.Text = "statusStrip1"; // @@ -677,7 +672,7 @@ private void InitializeComponent() this.tsmi_tools}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Size = new System.Drawing.Size(876, 25); + this.menuStrip1.Size = new System.Drawing.Size(875, 25); this.menuStrip1.TabIndex = 2; this.menuStrip1.Text = "menuStrip1"; // @@ -764,20 +759,63 @@ private void InitializeComponent() this.tsmi_tools.Size = new System.Drawing.Size(48, 21); this.tsmi_tools.Text = "工 具"; // + // groupBox3 + // + this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox3.Controls.Add(this.splitContainer1); + this.groupBox3.Location = new System.Drawing.Point(8, 25); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(857, 492); + this.groupBox3.TabIndex = 2; + this.groupBox3.TabStop = false; + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(3, 17); + this.splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.services_list); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.groupBox5); + this.splitContainer1.Panel2.Controls.Add(this.groupBox1); + this.splitContainer1.Size = new System.Drawing.Size(851, 472); + this.splitContainer1.SplitterDistance = 96; + this.splitContainer1.TabIndex = 4; + // + // groupBox5 + // + this.groupBox5.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox5.Controls.Add(this.list_lvw); + this.groupBox5.Location = new System.Drawing.Point(5, 131); + this.groupBox5.Name = "groupBox5"; + this.groupBox5.Size = new System.Drawing.Size(743, 339); + this.groupBox5.TabIndex = 3; + this.groupBox5.TabStop = false; + this.groupBox5.Text = "弱口令列表"; + // // Main // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(876, 677); + this.ClientSize = new System.Drawing.Size(875, 677); this.Controls.Add(this.rdp_panle); + this.Controls.Add(this.groupBox3); this.Controls.Add(this.bt_status); this.Controls.Add(this.groupBox2); - this.Controls.Add(this.groupBox1); this.Controls.Add(this.menuStrip1); this.MainMenuStrip = this.menuStrip1; this.Name = "Main"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "超级弱口令检查工具 V1.0 测试版 Beta21 by shack2"; + this.Text = "超级弱口令检查工具 V1.0 测试版 Beta22 20190321 by shack2"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Main_FormClosing); this.Shown += new System.EventHandler(this.Main_Shown); this.groupBox1.ResumeLayout(false); @@ -788,6 +826,12 @@ private void InitializeComponent() this.bt_status.PerformLayout(); this.menuStrip1.ResumeLayout(false); this.menuStrip1.PerformLayout(); + this.groupBox3.ResumeLayout(false); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + this.groupBox5.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -806,7 +850,6 @@ private void InitializeComponent() private System.Windows.Forms.TextBox txt_target; private System.Windows.Forms.Label label1; private System.Windows.Forms.Button btn_importList; - private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label3; private System.Windows.Forms.ComboBox cbox_threadSize; private System.Windows.Forms.Label label4; @@ -867,6 +910,9 @@ private void InitializeComponent() private System.Windows.Forms.ColumnHeader col_useTime; private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel4; private System.Windows.Forms.ToolStripStatusLabel tssl_notScanPortsSumCount; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.GroupBox groupBox5; } } diff --git a/SNETCracker/Main.cs b/SNETCracker/Main.cs index a35d38f..b7aed09 100644 --- a/SNETCracker/Main.cs +++ b/SNETCracker/Main.cs @@ -21,7 +21,6 @@ namespace SNETCracker public partial class Main : Form { - private HashSet list_username = new HashSet(); private HashSet list_password = new HashSet(); private HashSet list_target = new HashSet(); @@ -798,6 +797,7 @@ private Server creackRDP(String ip, int port,String username, String password, i server.isEndMRE.WaitOne(); Server newserver = new Server(); newserver.isSuccess = server.isSuccess; + this.rdp_panle.Invoke(new deleteClearRDP(ClearRDP), server.client); return newserver; } @@ -817,6 +817,7 @@ private void initStatusCount() allCrackCount = 0; } + /*使用转换过的dll后,此方法废弃 private void regDLL() { Process p = null; try @@ -837,11 +838,11 @@ private void regDLL() { } } - } + }*/ private void Main_Shown(object sender, EventArgs e) { this.Text += " "+Main.version + ""; - regDLL(); + this.cbox_reTry.SelectedIndex = 0; this.cbox_threadSize.SelectedIndex = 10; this.cbox_timeOut.SelectedIndex = 2; @@ -1094,7 +1095,7 @@ public static String getSid() return sid; } - private static int version = 20181214; + private static int version = 20190321; public static string versionURL = "http://www.shack2.org/soft/getNewVersion?ENNAME=SNETCracker&NO="+ Uri.EscapeDataString(getSid())+ "&VERSION="+ version; private void tsmi_help_version_Click(object sender, EventArgs e) { @@ -1177,5 +1178,7 @@ private void tsmi_reloadConfig_Click(object sender, EventArgs e) MessageBox.Show("ok"); } + + } } diff --git a/SNETCracker/Model/CrackSSH.cs b/SNETCracker/Model/CrackSSH.cs index 96a1250..adb0ba1 100644 --- a/SNETCracker/Model/CrackSSH.cs +++ b/SNETCracker/Model/CrackSSH.cs @@ -12,6 +12,7 @@ public CrackSSH() } + /* public override Server creack(string ip, int port, string username, string password, int timeOut) { Rebex.Net.Ssh ssh = new Rebex.Net.Ssh(); @@ -46,10 +47,10 @@ public override Server creack(string ip, int port, string username, string passw } return server; - } + }*/ - /* + public override Server creack(string ip, int port, string username, string password, int timeOut) { Chilkat.Ssh ssh = new Chilkat.Ssh(); @@ -90,7 +91,7 @@ public override Server creack(string ip, int port, string username, string passw } return server; - }*/ + } } } diff --git a/SNETCracker/SNETCracker.csproj b/SNETCracker/SNETCracker.csproj index f001b03..928497b 100644 --- a/SNETCracker/SNETCracker.csproj +++ b/SNETCracker/SNETCracker.csproj @@ -65,6 +65,10 @@ Properties\app.manifest + + False + libs\rdp\AxMSTSCLib.dll + libs\ChilkatDotNet4.dll @@ -84,16 +88,14 @@ libs\LumiSoft.Net.dll - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll - True + False + libs\redis\StackExchange.Redis-1.2.6\Microsoft.Threading.Tasks.dll - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll - True + + libs\redis\StackExchange.Redis-1.2.6\Microsoft.Threading.Tasks.Extensions.dll - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll - True + + libs\redis\StackExchange.Redis-1.2.6\Microsoft.Threading.Tasks.Extensions.Desktop.dll False @@ -107,6 +109,11 @@ False libs\postgresql\Mono.Security.dll + + False + True + libs\rdp\MSTSCLib.dll + False libs\MySql.Data.dll @@ -135,24 +142,21 @@ libs\rebex\Rebex.Terminal.dll - ..\packages\StackExchange.Redis.1.2.1\lib\net40\StackExchange.Redis.dll - True + False + libs\redis\StackExchange.Redis-1.2.6\StackExchange.Redis.dll - - ..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.IO.dll - True + + libs\redis\StackExchange.Redis-1.2.6\System.IO.dll - - ..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Runtime.dll - True + + libs\redis\StackExchange.Redis-1.2.6\System.Runtime.dll - - ..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Threading.Tasks.dll - True + + libs\redis\StackExchange.Redis-1.2.6\System.Threading.Tasks.dll @@ -309,25 +313,6 @@ - - - {8C11EFA1-92C3-11D1-BC1E-00C04FA31489} - 1 - 0 - 0 - aximp - True - - - {8C11EFA1-92C3-11D1-BC1E-00C04FA31489} - 1 - 0 - 0 - tlbimp - True - True - - 5QU* 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 diff --git a/SNETCracker/libs/rebex/Rebex.FileServer.dll b/SNETCracker/libs/rebex/Rebex.FileServer.dll index 4ef564fe4132cf85c5418e66c167033a0a58cc49..4ed11bec8b9d39d27872d83cdfdf566374c6ddee 100644 GIT binary patch literal 266392 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%0Ax9X= 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 literal 263320 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≤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 bsN=x?U0j(~>-prH(`G~_DLd6%+Sc(OL6T~k diff --git a/SNETCracker/libs/rebex/Rebex.FileSystem.dll b/SNETCracker/libs/rebex/Rebex.FileSystem.dll index 25199cf12325fb374ebe3c6e63bfb6e1ffb4be57..8a4d7a156b251ba78a04061627352b3bd739e44f 100644 GIT binary patch literal 521368 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 Mx%sT=bsfKd0DM~(2><{9 literal 521880 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

`~vxP%H!|y_oqHAh58RvpETD> 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 z

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%0AC4Gfs~w}H>0Wb0>vLTO#POIA zZw|#DGR@T%B(=o|8B>i=7FIvWJ+_hW9MDiZi%E+ii=ah{nQhoT_iC#_AhZk-_i3; zlznR>&pVZ!b~*22LHmDW3qKd^t7fFMvXL-Si`q;Kw35Px9#~(_W){ayq#+ERYW64S zU>09D3Z-40z zzWVPLU#i)oH`3U{jh%V%r9s(jH@b)_vk6_l1SWvW+D6 zep>R`2QY)nquB}RW?bB>Nb~Uhw5G#6(0)NIcK-Lce^c}W$-^mXjr6$MMKiU~ z2QWobgqftk6?-!nmbH53msQ$UD-mmUMReAvLM`wOLlI+I) zN@)-_$_ZWY_DyCTuqE}4yOU6E;&1XP{ItnRWJ*+zx3AE zY`cyoAnsNapgN7On^f=hxxo|>expCg$8J)ZmtE95m+he*iE=QdKAOE8{|9J1w(T1~ zrDj$&$B=cin;7xu(jo#NxLjHTbeC9tfL?2fQwKVQj-%V~XD~ulnhs8=W~W!<_Q#Gf zAK>Enq4>gZJv^zB_=bQV!4T<6v#WSw#evaF19^-wd{aa+5F=Sp1mFnO{$9nSaB|P= z;u{d%)S0Gz;u#?+R9YmOm!14LJn($EHHB{~OeJ7B5?x$gwVRNUX4o}>HifjbO^MjF zxrMPfrC2!RiQU9K02jX{30@ztlQw5GbFXDU7hf^xTF$)H?T*`>ut~%hbP4|5+28iX z(QfHR{zNB zERPkB8mM-=bm|C)8_gHRQQLg8noK$MXscu5H%cq!(lt)|cCerSalhod#$sMQgAnmj(=rEwOaHC6fj` zLOZv$L?c~vC6ut^ZA&ywx>$~hoiRL?58P!1%mU^C4JTw*a~J&qtcAw7J(~=1Z1Xr7 zNy8McOtK?)8=*q_NJ4}&L^$mjt12Q5Y0H3cXV#=bYD2a|vNJ8>+T`TCN{ct0>T&TY z`!=G{jC%B@{XM7NvvvzoN+Ika4f49Cbo^{XKvx_?+{`@psoLjkB#HBcms;lqLixmA z7y3H&I(v3Fq{%k;R|JOW*%K7KkLPEj>Xt}&xyZIDg)i$p!Bl{B>(CXsI-p;z ztT~foe?Y7nAjh8X0se(H=MJ<%F$Npt0$2q^XJYIFR3;naA3)MJhCiUUZ9)Pz#@6dL z0%|8=8XD5J09u)i(F0htY>XR#WNf2<1J=14-58hz(BEwIPJsGmqgw(&M6U#bh$aPs zh@2nK}ZKrkRI2Z8}%IS>p8%Yk4(SPldO!g3%OkbD5afUq1028886Fd!iT zf&tkY5DW;*fnY#b4g>?jav&HGmIJ|nup9^mmX1I$uyh210bw~146JW~U_e+71Oviy zAQ%vq1Hpi>90&%4C2+M(BKv)h01Hy737@%@MFd!@kf`K(E5DW;* zfnY#b4g>?jav&HGmIJ|nup9^mgyldmAS{2m(`gs1`h*^#Kj;nmf}Wrs=mqKdGlGqC z;3nlXr9^CU%F_#HQe}r`hV7Z#v^$#0C|S(zmaS8pCxLFU>=QQ$5#jbxL7)mic^aFS zh8?jl-?TH(A|-N@P&{hH2;g7_D-X29%ZU*T5C>0e69?#+4txa&(JmeMHUP+C4ts0* z14$}i*}u}kI5Dvw99Q?!iL2Y)%;UGo&>+@W$MY ztQq+Q=L6b7ezCV|z&2HTpjs3sh$$$@Ip9&#wsP9h!w zR#ybt0+uewdyTq_SiVqz)}|y8OdxG$O_M2t6C@0(sU=0sv!v2B9is@IkXTW`gH$g9 zFF0@x$sp&EN5vJ1c_5p2}t3nF^5)n#odDFRjNgBo`u0_X6Y<`A+~eAmb

l~{ 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 %3;Mn^j!(# zB)WXT09b%7KS}@}I$doF@bJ*(A_*`Rb@`nEFbDQvmb`tI@j%SSXHZ{uydafn0;d!c zGY25f;`Kdw{wz8DEcyH7+&wp-&DCeg%V){KXPM(`yN>rM`SvX1wT9E0GN;#e9r#mn z=2`ONS#sf7^4{6J1>iew%kvAgpu(AF$&aU_fBkur+j2Zx#@hzAq2#l(;*nLOYS*Ko;fAvtY01|07qGjc|8JnUK;aJ1Ms~xM(6-15snc$z**E| zp4R~9Rgcjz0Gl;N$ADS!snu}jhz%7GZGdWU@>BBhQ}X#)=CE9ici8FUX~iaRN@;z? zNNHV63$$~t0H;5DbP-T>o~s1ZpZBWPYewSQf+H&dJpzvF3^+~U5f6}94g$+>0e=wL~BK71)BCuvN*Qap@2MNhYNu52T$bwhDm*zp=e4E&T|D4?*$Cq*0CW*VJ8Hc9M*wa?Lw@KoJ zq;Yn$4!4|oZcTsdvB9uy8%I62c*a%y7jg^I#-725pZRtfpM&lun0{gvDL+zvAFjIPt+EiF>t!*g9^_ zO74>+nIbqU^0JU06Lz`fR&H7OgwqY*TP0tIl5#GQF*@4u=2r5wE{T)4y{F3@n7HLF zZgu2K&M}oKIUkzixbd2fSg-YAoQfz(@uf49yIYQiO6MU;;@4=xQ`&Cqlb23Hl*CWs zR-a$yh{PP6BZ=$9DaL(Y@hVd~l|vGKeu;sbteQs1hsNGJnvC0;jdOoXr*lZ+(Pk45 ze0@FwOJ{XR;(>CG#%`vTex*Y@B%#+GQ_HSnXp~&{NkUJ0h{~+S_mzAGNpcQloYAaH z=Rue8Ahb32ELOVDaHrJLj3CK}o~z65z%y2pa~l`WL+v(l?%Q z5m#nhZg~psZhfWIk+as)a#j-mcys>N#$60kX>}`!%f_+Ed9;dMgHx9zajQDlO*sk8 zgZajBWWCOTpz$+RI#Ey(h5y{3omTp4X|XPeZ^xCHZC+;1M3W?Om^s#&CNmRO$z!}E z)hMHeKY2+Oj=c=UgN1U*lbj?6q4sfmlLhmPlCw5R9B>Ye z_Tw?s*F8y`T&?;08XvGRrQ--oXDDXb%{N@li&ImBEsss(9Z!XmUDoVz>bBLB8*Xocw<;YlE-6P0XSQ7twv=4$OA3~F;qf%Ikg!EkzBV7o%OQJ>lIuE2RzRz? zeIHL*rgLtUFrRwxIMdxr!U{?3L+1FY-9q0k^GUXhJ%($X;ds>K%Gc(yxwFUB8QMOD zgUcoHjW*-Sa6K~~N?!jZc}JI{U|f$D<#|%lUMJ51nf*`)uJj~X!|wFE)!wSLHe+0nQ$jgmm}ffO2PsEkhW$JVh^S zywNd}u2o8sOw?#smjhNlw=J(z$rLWN84w7Z~2#AJM%Lv zbjr%t=4!gL=f<%l))9*zI!;6PoeZ!D!nVj)XNS}6%uID<&Y;}#z&1P>ce_2ds&ov3 zq)E}4b1ym^h1qo~f+UA$ZLJP^aS&YcGAN0|xjm{qUZw+bIw;91d`~pgU2z;)k}FBV zhUe68N8%(`KD5=+INpaH^N}{rhqgLDY&lpS&N;*@d2WMuVSO&<@tgUxhOXPr3{2(`K%@Y2YsEl^~N2B%cs@+P2a`sA^A)C9;f_&DsY zPKOuCr59Qe!1v{l*!)KxB8}7ctr; zULynYVpMlFLTi$5ok*Bm?YWsZKIfV&C&yH|ebGcUcOI=Pa1>i1cmLxzoz~`MI zF#rNSGd}<*^~}N-K#gZsx`1ys!_ot&>dc}R2nJTKKrpas1%iRqDi91TRe@k&bqWLn zt5P5spx{6-KrVn_fGz;R01W_wfw2z+17jWt2F5KA42)AC7#NE{FfayzU|_syFkW~o z&HQp5U#U*B7DJpXjZL}M$$51V)k@&0x6FCkpsa1*9`;%QxFgga&TFdgUhmV1A+lA7zhS9T_70XDu7^+gUhNMTvp*qfnb31 z1cE^hE~|2IS(Ss!EYAai0lp9j26#Up7~t=KV1S1Mf&oek1Ot>72nP5qAQ<4OfMAe= z%c>k)R-s-%FhHb$V332$u(Sce0OtY(gB)B|<>0a^2bW>c1A+nO0tg1?dmtEK5`bWU z8Un$ItvIc9)J;!NCld^yZR z`k?@-t1k*5ELmA+DZR>Mngw*&+ETYH^~zGGEcMAUi&Qyr~n!jp@=>zq6Gc)IKb10p-nn$nHA*9hyuk$ zfY~t|wN5O8;OWQ${Qs`Zh7Ni+*Xh=!UM-RmVXI?{m}r5Yb9mtr!R*kTe)Le@+BTU_6wDgGd4p zH6lc`oKaC46e3a$jMBIe(R#*4X=sSZVtABBhlshu2yvK}NF)meNokCTXi?*&G)zSD zFhs*nuOdeCRWx-XS~TJd!%75_ z5!@JAB3jhwipowT0f^GtiD*#_PKmz}k?KsBk|;$)i(03Z4s#Kah03mUl8cBIb(Bl# z7?=5~S;9lq@hu`+l*YVd3m}q*A!?~AqD3t%h++~+Nf32pi-;DDXvTRhA}JPrPF4`n zqLx1;216w82o^y!i*e_)l$0kTUKquR16oA1s1sUBOAQfk4{L@K6VamK!WavPKqUqP zYz0KLDD#7oL_!2!ED%a(vWRF=++=AB3d-U#fU;y zSw3SfOT49s7R6td*h>*vvM46)7tx{^$tW)8t1OcV{iC}S(V~$r6Z?zgVTh9ai)c~e zxhOG3QW8YT>qWF^a6TORQQKI*fkW2(Bk-ihUi)hgZ-AOz|;6)Wwl2(XlQ39uuGDrlHS+rU` zi)c~O1MGVu2|$!qNJNW9rbL1*BGs`MrG>MI7L5!OJ1!y%mfWcXiD*%rddapVCz=aD zlmUr|7IkDq>BI<;JPc7Q0}(As0#G^{LL?+zAq~2Qwh;-ztuQ~f9V^&NVcn96wd#Z)|NoEm;Zmh z>iillYc04(h*ur+a_NwX(kT;?t;+T~Tc?wG)~OScn9yvDqg5o`rL!ln+2oQVGzuWI z8ihbPkYX{3y31h{0!fL|I=L;s9xt~xI?~xoHByM0eG-1aNd~D8asto zXB)CTTR~{yj*lwOh~uzw-WsGuobi<-*Bs6u;&d#BGYC+nI-x;;OqxJSfFzpYM1XL{2@L`? z3q*7ksg?+}t#cVFM>2?LSH~m>IQYxC2m((2V)i7!UIlk4U_sYBI(88XCY$Y# zDWYN6JybM8BFbm-P_cLr(Msg6mFi405Pt-Js~$6I%hj2#Ki9 zdM13ff_gp6BBwTzT}dN{>6q^U=X)IqZKM%H*R(5u19&2?lIBddgAW1B=mc?N(jvZb z$?>c%TCksQ*3U=V-!CqQTy4inHm5s11=0^2c(1N0OflQy8@Ibq3NYL1St3XqX^ z3jBd9QQE)@ljpplkf=VuXZxf}k@8 z$^cY3IYY*Az|9kF*U@;r=zsxY{pfjjU3{JgaXq70`;4NR84>Sw!_=EAn)!sfeT2yc zoc%Jw;Q|yIBkXNu({9C1;f?NQFz+G=UEB`n>;oSA!-+=V7K>QTer7#6P(mI)w3tZFxIpNhG865GKE- z)m~mW6Q@(Om*(9X?*8^(+XP;k!@OBy?~F4+Nqpid1XX@-1G5d;kHDjdZm2YK$05WpE~13gWe)6$}X z1sEvoXdI;FT%u~SE87cM)=u96$ewokOJ__(;6B~t41WZW!OxI!XH7LXSZH;y_WA1;@f%<4rXGt z+aKtvfWCUnK$}?o4o2uRU`mPleUp>e-7wj$$bA3@mNMaWG@v!G8`REyW`Y0`*=HWu ziM_oWgwe5V0?4pqz0}#7XWSs5&T(LX4wdu1mN`7y4H}sP77t+CbHLi|7fmnTwOz+j z`!L2F1K}im*3p94#)Fuo0~Q6)WCu)22d&Kw({>h%0Pc86i-1^CWRKJx$S_5K^omNS zsL5&Sp#}FgM*I~^UjePk+*crUBIG3962Yh%W}q498SoC+ij_a$TNqZAQ6-{qW4ki6 zMZ6`woeD?9$#}6PHbnfj&xonfaN`pLhX2O24j9%O>@bkI3NH*WSl-})0Sea*-nXI! z3N;)qa9&Z*G=Wn}YvV4ZJ+w}swQ+9(r#!8VyOh?(U7)pbZvv-04(E)CN0kw6dJ{4D za0dcf#iUdrsUjLY<{KV`cHRm=J7ojV&e5Shg7v`I_XaSLWL)E=Rf`Y*?AR4St>WVdnNKj~=M)R1(NP)tDkTBR+F+pfS4p!t+!y>J2oM$vX zG8*3)zN<77Y~A?7IGJ6 z6ojHpsm>{_Mdo~JoSpKt8ziKV5(F23SRpTJ%65Zzc^biN9%}MwTs8xA{M|2o$?`L& zT5gFg0L`_fuGR4!i8(TG0Zj17fCR#R`WOIP;8-UBmV?aO0-~Nnw*Yi>M3QwJkzxU1 zJ&3RXr-Y8kuYfQigjZE#7fcC0+x-6D*VKq!(V=y3&a9Q!qb!#6`idN11aV`4RL595*o8F2|uLPr;VXpvs$V5ya z6N#=p%0h{HQEM={>XK6c`cudQ-C~-49hqxBPZKz$w0laV2sHN-QV2>}M+z*mCUZPtpQ%{42k9FzU3*u9Bv-?(cKQTIO`%OW@Mus#a(l$V zfToYUBw`ZMkxNN8s{fbnoHD6^27PmIkN6m{n(vVvR}ra1ni4@uWGGewO{*v(YfMYn-N086K?$zjMAD1aSW7u^OB`Z-${z=UJNWR|rFXv#2a z*hmpQK136(%&TWJ#P<|HG3Pk*DpWJX5{;B#D4>x7DM3F*5|jVY`c-0t(_FQpvP)uX z0n#|h@__aX*$l-Du_REEm{;qxks%QsNic*WHj1<;LZZlpA`YT#tLWHdfC>FtMXgrR zrd9Y+iN5{yU+v5Fo{1U^Ix6+whZ0>&X(ga{1D zBVt4)EC!B!0t!S^C*VWV(h0zlhEBkj zAT$;5p$UNnph~DM;7c&^6Y!y_b}E`35ja!!RF=ykzKA7rWyLI#fNx+q+v|nMT2fV( zHzG-eH&*|%6NUt|gNFWF_G-*mo7>xJW%cdwzyf(#vzW9*no?3i>KF3tvsL+EJ#@Na z##zxqRV+9$pPi)U$EqGFpobrAVhOVo+jU zVo@1`%Ggu7m31?!-Xa`+8LKRXHfDsr$KEpLmLf)S1d!ClF}ReF`h*Qi-$@HJwMV|$ z?e*|7pMU$c?^cz0XNcUa4 zrUc`fPC-B&7`HV>n_Y5DDQd*RO~Alr;T8iV$d0T zPKoLmLCztZHm*Eoow4eaAc8NqReeiW!d9%?X=mEY93)e6TgDthufn?@LbNoyfO_H< z1ymNF7(-AIUj#EKpw^l#_MjrUt$s$gh$hJBjs%SGOM>=@@GCN}h`UI+B<9(c(Mr=N z#qcNY5=cp@TsY-ympOz>W*jGwGU1Hv5z*e*7y*TcjlsQ$cnc0DI*(KT$mQ+%t0=s? z-XBFkwzeF?Hb*dy$i=i&f~F1of+oedG`6J@wKZNP=A|Oq8&eVsQxR>BClS!r_z{8N zW{4aR!C0IMXixlzKoCr2P`y~6#`si3dxjOkg@`~bTnGk4M4N^I!F!0nGQ3BGIR`^L z#;CDH7153i=wgm4k^sCJ(7n9A7{KI?8nLE}g{nxhs6>P*F(x}#|;^&>|P(q1uMIXm0d+rF^?U>AUm#rR^&L_ zK{G3hCJ_23&l7O0o3E;Q5CSC$)k7}|d;847_nomP;2$IKM8qeEx+WBD7*QB) z1XWcczPmM1Wl1FB+glb@Rz)Jdzm-vCVI-o$7Dtt}k%*dG9|>rzEWL(AW|ei4fUiMl zyB?C0RRp&Jz6#+jr3)=uO#SW{s@UY}*Rk6njgX7_Ci=5;u4V`{nRXL>pdu=6U6y3BYplc0Mq~t9(VNffa?;F% z?ahpd-c8=Oj|M*DKo$ctB$4AL`sYJjVq`-aKvP$-Q3UcX9dBzg*{zA!01K-%X=u9N zaFu!S95|)43t6}HxDjK(CQ}nt48!ydTmWNc6MObe=m&v!Mc!RS+)Z^R{2j zi2#Gb$q-t-`N;xgGigKtm#iy3?oF@q#R@^RVn2K5J8^iS)dlXMT z7bfD3)Vy&wKIuO25`GkF#&;2BP6KbG6^(>$(`;D0898nAZkEr_n&<94ZM_kD#26-E zBh-Cv9N3!A@Mey30rLP~oE2`|(%x~P`|6J8rk7W!)M`z14fyhGB>q44-UrUE;=1#^ z@AY4`T2I}#C8UOK@nnlcZA+pBaxB^4&>#UXmOu#c$6g4uo*HP=`a^dMb=xTO`Uy!* z7S?!I@!$zb?K(z z?>*VZ-kHxQv*=H~`d_C`ojP^u)Tz1}$?K=wt3LAYnV2~;WlvDr9LofKu1u6~C098{ zCo?FdaUdm*@2mw=36D<+k5=#X*$Cyp9>ma-`t{NjcQK_(PRjW#_G`)EdFvbmTsNGN zG8^OL&?T2Q)2SrFbtegg(PYy)iN1nkqC*FF%*{?5PZzGLBQ<75d=&v96`WD!Vv^eJ&qvIJ!l=k z;s^pvxN!sl8)F9eNX#48w^W(2_fJp? zb4^9wI58V;D*9(4lT0nsnhJ$?67Dye~Gy~a~(oi6P5ZduY zLRv$i(0p^DkfuUVYX14wq(D=AE^}zOF?&eK6$p(s76>UxfpZQhAT_5o6$$`^mO`#p-^bPxll+;3i(G%n?Y+#X($ky53Tqj zA+4cMXui2nNaF^HWCBiF<|MO9X9j2BP6=`=++m+CGt5bL)lF#KXPD!NcOQ2e_UTH) zoQ`?9*07JO9Rw81iqF*!0!Rj2?bwGjM?hJSu4Splt&V+|M(o2fVjqSPBqAGNo48Mp zG|cJH7n8+(T<9Qx9DzmcKE0eUC%bekzV_)^l{uXPWAwETn=b;?$c2u5T<9P`)m-S< z$Au08w84dreO%}ufC$Hhj(uF{AV7m$=-9`F4g!c!TAgh~nhdcA0l z{bZFx(<-tg0c2B*@LB#8P+@jq*xwUCa>f3>is?N8)r8y$t0#bPE0#WoR$Xkoifu0e z1X&F3tC)5Zpni-Vt5|mvKxoC_zKRG|)jL6RXxOV*t5z|yCxEc4&->`1lsPo*Rejk9 zOH%^u1^1~U0~Am&sjISWAq8O>tGX)2p#*?SpY74ddgj=mRE_j(Zd}djrq!HoSk1A+!Vv^|bz@F1Zb%n_BM9`i#vB_k96`V_ z4UQn-jK-dooYMvm!#H9@AZm|;8a*wEN2H>5wM)ZL4i7Y~4>Qf7F|X?DOmm#aRJnM8 zhY7^(3p`LaJ9Iou9IjyCfyDKRCaG1cdYVq^)T+L3C3R|5SB0cSt?K($(xO&5d%y$5 z>-$#HmR7L@#RJ*vIVovKt9qnFn$fD>Zj<)2s`sd*{jBQEV`)FDdVWUQ&#GQOmiDu% zCy=H2tm;iAX+EoZ3|U&wDz=h%=&7DXmZr0+w~?jYtm>I0DK*VZPfATQ)ss@QDsw$4 zHLEh&lTuUnGVst-neIuUDf2y(A5C6F6ddPe4H!vFc`p|kmatrOSfq&dE3scYGf}zX zK3^!@Br&BCpadQuCQO?GlhLruCR{`g(vTa zi%%Wa;nHDkNe;0RRI#iip7#O8o9?-b^`MHqEK%4W9$@!5d4LI0#e9}1tPu}u3Az_W zR~18AqIhul5OmH1-|yExDs(uvd4p21xxHIkLcduwk7C?jEfmb`<}#6%y(ud#`fldh zW0x|+8jHg&WQH{rhY5hWuWRwXBa=L&;ftCUYsNrnkq}_?`7;ovQPnxryj5(8@h~AU zBi_S3rlwY057JVC-@W;s1)r53c$uCUBCGWzOXgaGfNhS=KT>%`nby*%h8)Qx z42ps44`WJZ`UTU?pqjboeiZ+zyfSkYPc}_VK_u!%Cg|eRqERL(X`optL$$opaX-fg zI4mUCW+!=XM7JgDqWu$TjiI|_X0gG3JIM@AnkbMwn%{>rdBQ-t92}LsU}fo(YuW87iVWRzQppg;Uf<*O6+F zc)$Pk=xEKAs774Lsj?`N;WY+XE+(HIDsF{37GvzJ6X22z9zGwWKJN{cc^ba- zV5b!FKw@p`lcVoSn^g=@(d;v2?!ulNhwB#8$Zy2yCf<=*#1R~(E4JrVY|jPI-Lg_k zJlM-wNH%K}!dm_=&NXp3&$^5AOdO2o@8TR22jls>IKRZr6f(FionL7dGE6m*Sz?d*|-+g3iW{xhU<9D5uWrPJl>1Spo-x-9&n|HwlQ3vzZaDO&OV-d zQcqBW_*Y#hYa_tAD01NSNh?iF_ja*vDxrLMhldV)uW zGB(G7_inlgG|X_lp^9z;O>C>e>{D@& zwse6Tho{94adv+6eGFlhbJ2Sa>g}w9SYL2W8lA-vHU>xU<>()WSBUTBh+hwAPTq^r zLzRnV>axvHF3=-8JCH3TiO6imr-ABPLfvg*fbANtaJA9f-vI)k)` zV0MeN^!SIhROJeSFvA%S-n-jsCgu{f&B#6b6c-bmx&Cbl>Cv9+m+5TU^x_Z{Kk z&{_ME-}v-|?yODEqFBcfpE)#6scD%o;{Y^-T7^yz>%~pD z4*A}D!5a=rDDLMe%PhPN2T}l2RZyntxEkxeX@LixsF3;gMtikpMtkiHG1|L#GygA% z_6AnGcP!e=ou7$m`^xgz%*@0A3@^7&%v5>&Nfe!~eVALg#J!WVQ{fwXX|%);PH*lB za(?nw=heEDdz5E#LRE<+*dCZS+Vo8~bEZvGGE4G}uzp|>%JaYHfMFW5r~^Dy73$nR zfzbtb#%hmJZ1daNX0Y+%qx7i#e)%CRCBYqiiH$(+Y)zR1X?QKKqYUGu`xt zV0(^CO=N1zMzaj+QzC~r^O~NWgk{X{ojx*yg{RmDy$`L>_|1H8B-f1wblG?vI(*}V z-qfU9*BqJLpQ&Kyjkc|uw&kv9nADfwx-i?t;*DXj1ohEXc>F^2y%=#GK!)b z_C%aE;wwiGxy5q=MGX5s;#imQV}(d+nG!B1>^kD{d}7A=pRI3G6pdHNhbDkBJd|jq z*#BE@Ue=-BGXGth8}RcY1~o8)XqAhq(L0E{nEzE;<#>}g!Kv5}M5EEMh!*+<2iJb1 z>u5zaM{O5J(Q?){;Jq$Mi&k=v6Bs6<8|ewBVE7J1(L&*RDir7#hT?Ls#X_n^epNg} z{8jkW4Yp;(?Op5&m0<{nMb4tAxasBc1|kPrGk;L#S4s)5*TeYht< z^=445*u6la;c_&e55SOhMg++u@HvBHn9bo%<{_c&UB|djFa1Hg%Mmupa6vcNBsh-@T z3tVa|=%Wi=+V*55_tLKLCSn%$ql;YnRn#c5;=2OY#?=OSN_5Mz{f<`pG8$81$)?=f z?uhhPw4(8!qfa**>E02wg3RTPww=3_OF1Xxt3+KqqF`9&E|g83=_p#Zoz_Jkf-Jf) zOUK*ErTzt05UtFn`>7QzQ!h{-8m^*MH{uh8y4jQV_<|dWgHiIok!qp~UD`RJU$P4f ztIlXZ5MeO~%x)IUL{aS{YO0YxY2es;;)*+I_(Qj6KzA7;Qz;%)!0-5q<9`^hTUj?$ ztxAW<=xWxq;?^%fm7^b}E=`;t6`2k+w;Wxd?rXwg!%mrL&~~-KQH85D=8rDFnY?`R z$oiq_a*)4{13SjyCxuvr_^PHl$Nx-OamhybqHA7neMou`f}7sr@?ta8yvlLf-3^$H zRw<9B+%A3*s3@yR7}b8k(f4{NK#KxKdnvaWX`;)(mBf=Ycmc&O&GV*gZLRWoZsj>! z9xPXv_*L|t>j73IBk-{t0_?zd9Kv~jz`7(v3n89UhZV$gnZUb1)!^D_ZL~ew0hbzM zR$Pm3J27jc=mM<)s;9+VyU?e#UUQ<0ucqu_cwZybVcucg0grh%EzC#J+j%{QUU8(r zZzE3qY9L;vmC<2A{ftI5<5Z>@#;b|XaEFUplSE@K)rzXm2t)O@T2aHo&1Qjq3fnB) z{hsIe(TtY!UNcaL;01Nm-&lK8`}<}Txn)(eT`WnRkO1K16em?Q4tjuKV(v;SO>2zq!K90(^#w3N%c7q$c-GAkEp$weQ2eM27Rl-Om4x>jiSd(G~o05 zJ_E&@wLS#_L@Ao&PUO|pA;U>=L7YAHOJ%NRKYK z$>>-3G z2811(MA;YaVKKat|F^PGd69l60{3++TX#g!#zuCoMNhN9!8}IqGt7Tg>+Mdo%1L*3 zB$AnaB^E>%o@>F9R48doi?hU4C&Ms92AU}^T6!25)PK_7=EvlEYB<;CuMyKx?N2+Lv z+Q%pxBFHXBo~3E9?;?i~>*cGwEEe7IdKT*Spm#h%>l}^Hq6k|oJmAVnYylG5e{+R= zAtqZ&tX{+(mL;#`lq1oh!=&iYx05KTMp`o%E#Xz_$Vk~N*;0hg(>#e47RIRWEW%D{Bbi*m`E*VG!;iSY{5)8QZ*BcAclyI`7CqXIs z0-M%amt~SSQ={M4OU8^)8(oKV=h}>xT}J38lvq2XccFOFc5$t(lUL#HhEOUn`0Ffo ztuNEBmGl~0J(F6xlHXOAMVHwm)|QbA%hnI-oovN&MP`mUO2)~Llk2}Gm}3lDXf{%# zS6BKCn#zTZ8|>lI#+AHz)UE_7r&ZPzhH%HdBJePwtp3Kc4lz=}C>G_XhsN4L>9i}J zg2lcy>7=7^OhHRh>j`=#VIlZh+y}Zb|dbDPF}O9orqz zB5~k{Z};4N)#!#D4z1Nb`Tu=$YFOgJvX%IE5sw)M5*CWLZ|yjcTX!l3F@T zE+RH97&>bZuC>^Paq|m{-^WC?zxv10S#e@6hW|j_b!(K@(?_*${bT9$>mOmiDEKY0 z-$gLr?tMMI4m6XcK+WqwtvtSD^sYmX{S1tj9nrrS|3_a>V_7EC%sRd|{|ucCXFu6V zfyqCV<0g~z4t6qxMCRqYFh!8a#$ONQt zb(46Q-7`v@(}7g}(2WO};Zxc_Nv))@%c|i0nXy0c*Fb0zrn{DR?rDh0@5slj=IpLG zqxxOq2Q6xQOM~Jwt)HO?>QHf1&lSBoJgXSZrsoYN+%cW7kv~{uD8|&5G&kCkWGxXw zTb?)_?-XW(27?+lwi4h)7OGR&(tZ%rKPO!bR4}W!o)ihm5~+1!5)_}p@Ihj{5Puyx zG_#_$jl#P>vq^EaJTC=BV-oK*qJBfU6KH0L*^#!awM*)}Ye|s;Ui0@VgV#jwC4OHW zEz9CL`ar0`i989%x++gLRiov~wp8ivxQfxx%IW8bN(UJ8JWzRB&A;dlVLeb#_GrV? zoMvgOwgg+yCyB=MbO>NdkL~BETM6oS$T;B?^{AfA4&tfvWItVkK zvVeEn_fua>Ob)uOV+$DjHO5t&JC3e2$Ff@!6vfvxjzfNb;OS8K5cJv>9%8h4rdpKX-g|fg?T-NBRX)IPvw?28jpmDD6O}I3CpeZdVF`}i8sw5Fc zD?NY6LJ%##gbnNFXe+(hg91Jp+{6;7Q}J@Ng|%T6MS_0cjOOn6Cq3ud*& zl!Tj{YOmB@Y=4f2z|$_!=nHqso#ij2U97acuJFoa-s!MJSaEH-H7i<);VALrY{-?G zw7bOXvZLkVYRZctIXR-iM*OA59T$a~_K-6VLz-))sLiWsxYG=^QtR?iR!~G2d;qLD z89%GoxSZJN0tp|2Im}kcNS4-7mS+0RD(yLPBV{BxFIFvDLwVSmx`IiJcCkBbtry3V zG~ilQovyCd5S^nPgXMbQ&DsR`b;Z{$SOkSyY)BhWyMCog@(+91^L8dlD#t;tHosFz z;@_-N-vcXA^zsd#zvV+;U%mbK*Eg@6e(h^FMzu51x+rR|MbYUfiaLupg!kMywmE8# zq5^+^yz}ZizE=CG6F>jj9e+PPaMQ!LO+51ZulE1_Z=C|9{Pw!n>IC`M7e%_~Qx4h#&{_&~WOJ6zqulEf9+@5!S;e(&} z(4T(egTDh<0=f8wOkY!v6UR(*HF(rys4vJfBN z+TI!0uW0LxN4s3iV6k(k7w>QziTo=rA+WX>55~R9aZw>2?ColcN1QkAYX`lhj&iY3 zDs@D~QfWx|?%%eo+*v5~UmlOfWAR840uhNMEhxu8w4~fdU9?c@@}QKXfvBS#5!cpL zC@#$ap$3Llm&(QBK&0paauz!^vg9pCrFKeHKcL~9D2J%)kqGBGy+eBz0FRnL3qcyUM_FS>}^ zyNHNyk8h{);t;KLTSRZ%YvmxsLGS79DO*$VVE^Ub+uMIRU5m%#2@p0(W;N2=-c^WK z&_>)_l6SST^wL56LvqS4VqE@p&OajmdgmX*KRnc_AsQa)ApZFFWH^_W>9WQ(9%Y~k z#Zo6|F7@9h;7g^h4iX0AQ+LMo4GxkHL+7CC9#o$PB4Jt`iF+Nqij6Dg4#r*W@t{S| zo7)j@aJ`y$KOF*ZFz#C-lo`c!M(WsLN5tq3cC0sYSkDmS+l9mE;u~#S&uFe^GzpBz z86z|#&tO|;|K(8h2>-{5oyCE2myzNKq&S*%RbA-6Ty8vK?wIJHXrm%jEFt8O(!HJ` zR}{7Nk~JO#Ke!e#?!3v*hzpI8vrpJzZbb2XGJoddQO!AKQg5-xd5*=k2Ybrxg_4^k zon4}_d6k^^l z3Yae1(C-qFIaFGEP%zEMgX$R6E6}z80W^7hE0EO|uOus~7CU>o#iR5`9C4j^9o-z&=(%nR_Jr$gf2Z(XVDXZ`Jl#QYQ?a`PekTOh{rDOO>joKAmj9~2q6Nu`zYB=Vb;6;_DRy z(CQeE_Fqn9G2Uf!qeuLz2p{T&6H#Qu6&a<7svD1M&nUh2pdum{(GR~kwbx-Iu04%^ zMJq(XXWKlF)$cGN@!91)fC7Pgg!a)+?Wy4q*IrorM5c6=G@IP3x zcIW#qx4sR!i8EMCetX(_3OzlRWiXzI$CqUXZax<}mJ1yLTL3I_@2`ETKf>>@o{XuD z_NRr8+GpcITJXIAg98+bqoj8sMFS*e%rK5J7L=qb0w^NxDuJ(hT*w)lwi ziXB7IxFBDg(MV4ohXk-IzVS(ZZ_=+O%_obU-OQVYa>>4ew@(z^}_Q`_aV8$a>$WJdbWmud~Y)$W;>v%rXc6gC;XD55Ra2d6w8TfP*FTzzUC$Al&ZKs<5ln-Q^1R zF6k>IK#2t=GYNL9nKT+t0M(re(4JKCGS9uIH@0F*(z10M`3muE;!{#=c~$e8>={zCCSXN2*>B2w zwU6;qYxk~XlX_n3TNCHI)3z~|1$RaquG*||N#|M;mNGx!!_0TdR9Zk2kGeE!a?X^S z<}QoPIw~>gt7;GXiOm1YT$mqTmO$qXgEeahy}GL7<`g{ufO*1MPwZ%)!$KKJEM^6vE;KP zTv4qZaV74+AVQSPxZ7{sp_JO`q$D0Av(rQ^7rmW!%t+zdW35z0&bH)khSYDzy@jhR zY8w^aUYV;ceqI^es&v@WG;j37NyDZ{;**%mXjp=GKb$OWy79UHpZS@V)=@a2GP2$mdQ1PA>He6*es2Tl4qjZ_{`({D7M z#mq&0ZNN^cTv>~Oqp>oxF0Uyr??Kwh;B#pYi3x-t(6HmWU0RcDq6|>2>sgrA6neGB z`;tfp&7;t-x^sQ*f!8PCNyPP4Dw^)A$IBZ^bVhA#Mu*s%u`^wn1CZ8j;07{)_&6ti zITXt6v2I#+#DEM9_&z5j@FqiI?LQQSt9*Y|3>+4h^@v0)KP1Jn4iSupRh>oJ6gPT2 zky^wKx>;*$@^q>MKa%Qer+Xy#XreJ2)4>$eVq;!d9#LyDz+@=(MujlN=&YM2ko9+& zGalJ)%3Rpj*6z`o6&DS)Abf?PHb3i%F`zaO1-x}Y1e1)vI^n!2yh|OdHcG%P#JU_} z_8k{k&-^U+zphNq4pJNk_~67u`jcOkznCa{(c!DjU$TiYP6?63VTn|Kg|=sytk4HQg9 zt9^&TOnn7p8463XqPdb4U06c-=4z|47BCrd`Zy{D^{j8PgOpruTVLCT&DE6kIUps z<1+b1TI3t?K!<##d^SfZKF(!xalUA1HZ2-zi^qJ?kd2L4uD_zM9<+ve6r|+hE67wj z(S$G~6y#(vRNH2rUS=d{qEHfd;*6y{YkSXU`;o+I-zp9nQ>{H0FRX+^FFq$#(86G$ zo4~0%#j~H*rbE>zODF!xLU$q(ij@u#TWkmq#o8U_D~DF|5y`TvT3I8gG-=pv0-mCE zLF?SwQ%kJIvn<=J1~vT(w&x5S+YhgaOxg5lQa_XA(r;Vm02e!fX0k98*FKFTG1NU; zXe$hrlI8z-t0F!k5#)%}0DkW;+2942cua}MOj`JYyz}i5YIF;Kk#0;QEFbj>Oc%B)zpU*J6U7yKDJiC3_DvNu1^Cc63%-{Pb4Bxi zRp?q+YyPj9`-xoM7L6jCoFcmx!3wC#x1zp+`Z=B>XSw+c&Bxz$Nc+Ef8$!c$6}-eL@Vc_4qMc$ zqQ;V_Ig3j6nw5CW@VD@w!=L>o`$H(g4;mU`H)w03WvE~@3LuxM*ZvRuaWy=g)S%x? zrV6?aq42cpdPRg$5j@}<@o7!8)J94zL28OOy#zcAExD+9;jyIRi5yus!VN>i^ z5;9vjlQg2=v=LaAYs5ThBZSgM%-`Q7(K7*y{w;irB}=mc;A~w9X-kA|i{>Dv0P``w zA@buxX*JXee#95m(87}maQYRi3CROdSvWb@(m&wO90@4WT>J|tPI-g=g5$ZN|jx|eKBc!%MHb5E= z21w(<21u#H4MetqFrdT=f~S)KwIG6kZvj}6j?+k5PdpfglJU(B<+I69>Q_Sp&B3!bU$i0OjD^@g&3=SefBKKGtuG;oP+_G!U@_vKku{ zaNgRd`xo*btJR`|qF+B3 zChL&U=yK)rF9YQu94tPcU{k+tZ%jOOfKt^&{eqa)Ut(dUWD=B^v?lRF8)_2Ftkvgdr+K~%n=Q`IV&jD`H?A1OHmz;Mr7H&h z{E9(De|`WUx>YGL_zn^oFT4a^1DDi#UZnjT)`&8#qb+FYT{Ac$DWHaW1^>&TC8H0D zY3sT0)ug3tWR|>KKHm~Wtffruq)(Zc(30A`q2&V5uS*GO}&kp{BTVOdYHG?dFpyXdHLt-7cNq9IorWovX^I_Zn6%^bo|nUWno%33iRKPXi1T8j&^R=v;gIc_ zOz+t4*rvALo^0h9h9M}$V3OaK5_vctPDH^Wj89nI(HdZh(tTlHA;)SOW$|{-wF^sv zm>_+(mmyG<2brOl&Av|;LgVZC=f6V>NH;5VtX>|TY$~7do3SUx%Y-nwN zU3*n^zhe6`Yv$YL?Im`h+q^5}b((^*yrvFWSTC*N}FpbGss#4VDhjQTabkxG!RxQFq&T#qKX^lQ14q%4mm zzmM~qSzav>nsJ%VWD?;>7HPl9t{Z_30T-r4jl|n8g=J00cG7$+Ogd(&IF6>t>FR!x z>T-KJKn5~z1!J{EavNw4z+yK?EtaZE&iYDR?P3|)jtJ|bSp7cFuZL_tLEgL}O%P&mHq3&Q z5&xDY_;kXb^pgmegC$ATPCiy}b=aZhr7k~Om82#8YH%v)FjaCY1y+je$Pi3M2A>9k zpS-?61=0@7VT;r4=L6hVL${)WCn2o@zn1c#jL zY9bqJ^1G2`eQ(ae-XXW9^or=x1t!-{8ZA-*KvbA+LJqBKw&u}mt?nr~Js_o9iEyFg zr)Au&<8q5 z%NKaOiyGyymB6SL>3W%eGJ7tMcu9{`+3 zi$W5+_d$oXE8vF^iECpyMyK;}cU<2}Bm7I!tVyf{;mv)pXZ~uzHJiiwR_on|AX;!L zK%GxTBx!WWsaW4Xq=A!3qNoVa99)zqU`C7et;*c3j&h#UzfkF4*p&u$5l#a)^e^0$ z2Hukm+|<8tgF8to(p>G+iBXWGC|4nMwur0b;#58VTEyJ|MhrHABa34L(nktli&UzQ z6nGX%mGAM9YQaaQbqaQiwC-UmikZ?bFQm;kF*2?m^TvK4Jl%O?JIl zVGnn}i`!y^tq-==)7o+Mx+yfE3Tt~>*n0Ha>xi%;!eW?ND}&TRM4 zMdgO6IjS;%c}gx1cy=39)gw$N!y^o4%PZV6>V{Bdk_T)p%`}3s3HWJ@sAM91Zk4y( zHzkQ_#0{AUsPfcaoQ2!lI~iJW#@bT~ACPl|BQ%Df(xYFEMHl=?czsJ($IAYN1zTm#khz~9UE?r8Ca%C9b|o}q8%|w*!Jyt; zU0RWsP0L4?qB@mr`$GzOuTukn%I{BvKeA0oZ1 zl_jiu6zO}vi#pq?urqM=rnBx5tn5ve@I;30o4R}d=Ne}j*XsU@?hWhyi{72MR(D@? zP5Os@>G#%Fl$fWpJOtBY#{)S@c)u!l*R%p>>Z+Bl(7hflN?y_}pjq=T{ zpUBh852T*0&jLJ z60~)2?2TBsi{V4INzhhp$jA8YQFaHH7AAXKS<#qPGFmRnpjLk08a}u6%EYnr^dWp~iSDEgdpq$dvE9@ZEEMJ}$ebOY6u~Jkg9lQ|mb+aczQV z(Cw#n=w$&nWJ%DEbI}{LrvTdSQXuAYA{{lwVMH?0B6chuYqS-}(x>?cSLJF`f2FI8 z$Gw@mK<4N$=@5dxMYL!Q0%@wt`ru|-z84UGMW|M+BV()B2ZZWu0c~<@zGfqd8)+Fk z)-rY+g%;Iv7qmOMz*&DFmb%7R#uAf6G2WICVY~y=DK=N9_HrdjmeD2uOO%9xQ+p9k z*nG^r**0QJ5ICR<&V5tnk?~4ySRkx_PKEFD|43Te;WeF%+Ee+73HqgR4#7*(QbvnT zYvddDW1J7$DSbZb#lray7uS$*O{CPMAw>HBuDEie{dJM9`ZH`&d48&kDz@U-$?Kb%X43-pN zu#xw3$K#Qd) z2=bjfS5#VKw(MBL7{c(3N#&sYu92(KdR^Cj<^ZclNd~a*71dCuZ9)b^jhP;dCy;)x zsItqY>n_4 zb&fS5kgEfYI3=n9K36u>7@A3of3K*t#%#t`Jw}hzz?)mdwCZusu4XQgD&cdLYN))@ z{+tOHG(em!6fhA;ES_jaWXq_u-fY8;HDy5kcu~O}QhC4S>gh>q&?!-rE+654i|-I|`J^l@kRu;-VwiL5i9xgdO5HNY^%@UN zwwRfCWxJS7T$7cnvk7i9z%8FvRl3BaYyyrMG-qp|zX3hjg#6`!!Eja&&Q#g@1bx{u zEm85-*MYXTxOZzj@d(|}5Wz%FbRMX){xOc{B=Gx=yA+GeN3j8Jq8((140Ttant%gW z(Q10vvSqC8&Iwf$35#)2-(XKqT>p3r67FdtVR8yu3I>AhX(C~_6Jk%9A>q(g0||!& zvr6gtWJ4CH#Rn}AIb zijM0~mxU*v)r086%9CVhm1Nm`2G>lhY#d#yv$p7vtAa^sw)5G>Mtj$*<{BtsYlt<}vq zK#lc0j$fV05n)x1?T~3N; z2CQkpquLz1%eL0Y?y_lSwFx;{|D49b*+Cm#UjUT}%~+a;fPk%q0VZM)$n&&8T*JCY z%y|iZ@%lDZRAbf}3Xe%Y0wbwM<>LAm9A_EHbC!`DwNu7}PLY=DVGF|6ikCK)deo}J zXd0Dzl-3AuW^plizv$o{%fmaCgO@THcv~)qE#TFH=RwK0nuj-^)(G#ouVP%iiR&*q zc*pbbj_2T|Oa|WZW-?Y?dEy{qyqR%~XS$FFB;SR6n%NtD+1!`ReVK<~#B>viaykZP zsnZuYkJ7&?t4KS&me0)UO0eaygp?X&ebYCH@03`3Q*H`sT=!kgxv7yf)}I&fF$uF= zZe;-DE?dI{qM00uTqX|XhjjkMx-vAJjyNzRm86~_B#!Tnf|0O*ySme|c&wWO@N3Bl zzkWMqa#qsSCx;|gY_PF+X+54yeDzs8fs=;*^R$LXrE8t;`{mO^M4q&iWwJa?#gfG| z1*Cx!(Fun;4_H8+YdOW;xiWAm&0bNfzmlNGe#=;`at^x0opyGwiB>l~EhFo_?!*=s zpWSVX>#rK&zGkkONFTRHWsbM^mJz%AFHhc)lV#nUv$>kX*KJmNhzH(t%zKV3F-yn_ zrzav9Z*Ev#rL&mCd~JT1Cw?^0?82~6OL z<2YvD_KexT5Tg{6i4!!?s#Qc?=t}fhC8cS}cf+ilyf$;lVL)P_U77PbF|*2}5OV>^ zPQ`r*YpUX2iLv=5DStT4;d!jf=HO!LxvHoozf}osQkC7OB%^uldXR_4%1NeTI%aB8 zOumLehhNn&xS|Orv^?%%91kQBp}e}9ls9iEZ`}lPD9x46M1)+v(ll2lqD60zh8lXK z!;chZ--O2B<;%vbO7po!U;ri=y4QK~aiLBRP^dE-6Y^zR8gFWQJmkxiPV!}ALcUCW zToKX;W@AFWOz9+FHYViDlpbrUZ!F}?luq(xW12^f;cujmo(q~Woho%#WvEdsI92wh zWipUXG(kGiViav(+AxY1heh^~sJ+~#pP>MJXrh!SPO>$k!mSey5QmCnLH5MH9i8@%vX1?S+aH`|o_86kb;v(3hnAeHV@Xr zZ@je&15oUX;hVr9MMK8^+}`-aG$>suDysX4iokm-T{1GBh$pN<28yuSG^+spYK3EF zvcj23Jp-r$D1MRx{&&2Sf^ZH?rX1pFvbJQ*j}ZGZAuYo&cdbx@S%00myKd^}0ZDf; z+GvLK(h&BIj-itizp^uG@HE}_$_U5BVOyD0sgKt1d+O%xwUB@yLiYeHj6X)5PB81C z;=GD66+$Jy#3K-dNpNWHsIy@Ml+UZje_h@&})S3x5`@?D~_tHsAI7`xkS}=U%6KYILZ4hGPqrf$YcNxK%d&M z04wh#au7m_jzb6%>r*T)5uH^q(T}LG_ge0OHWi*M6o0C(-RYw|2y4>j{jCpcMAuf5 zM!1S*&C8{Ey-(;gdhDsqSze{+%h+WJfk~?C!$A5tso`^= zO~#B#Ke!l}1Pt}rK=O?UA=8bcF1R7&w#oi^pe>cR^q`4YcxEttgyBc<_=t2+eT2(F zrB19&p$b8RD<3SnhtowP18w#wF39E<$UvLF?8bW=x(t;8DG8?#`E-w>Tsjros*-|} zh76iqsAzArJ6QBxg~cZ+t>ehr=d>wkW9H1+8xoA18hg0i<55@*Aq^Rm#V3Mf%DMq> zV<$7vHrUm!3RsoXQFp!3Y8W8R^*ShP?QWt$Z;NR%s(xlsJb;94$U7V9qTDy0#h?wd)%NuvOv{Gl&CIYJdRbYG- z!QN!`Tnxm)1ue}Y-FA(0`Ng$)Yam;NF>=$l^fc7XOY2Z>wr)QHO^FtXuiY;tzAp`cNt`e1R&oJuSYs#+F0D@aI<4R+5Bfk7dW6GFM8EZ@#_bK*T z_c2kxSD^s?evMzv!1M{OlBB1KOMHby{~n;;$u)`Vw7txek;AYBh5n2yGFVz7*X-fz zQu>hjt6T5iBXkyW9y;*ZOBL7TPk;;y0Du_vMY5arn;B3cNur8j`t}^ zHm5z@T}nboi}IEvWiA})-`2kk)d2T#L^KO)i^DA53rEg%f5x&tasigC=gfhGxp1I| zT6kUKh!ikH9A6=K;fN%I3XcRo!$M|N-DH^KHnRg};UO}?j{CPs)CKq>lI$0b@XxY8 zRO)I2RD$lB&r<1-kkXaM@VM|Bd`1Y#o3LhXsasB|zpHb&1E}JKPifyk`|51%8GGUH z_-f?lVXEaOl3lL@!vyr@iEJ3P2(kU!=z`UyiX4!&XApAG!aPF@ojfMTYjWIy?cWw3 zA3}vk&D$~+ZPTsnP%r)D<48a&tqc9syLh}ihj2}Z_5OIDE*pHdy{lO4rZv1Ms&sSc z2p_fC22z2kC)CGV5dt#X6)NoC)<--89Wqkusr?|Kzz^SD;C*^M8lj4ROZ34QRgB`k zS>&@t$2W-L60ffJ9^Vk(&O|sqir^s}#K+g`VRr|g#x&@>QGy0aLzK1u2|tny7N-7fqSX+*gvytpOtEZlCdVJ~PqPX5{n37_oa7q{@w z-!O&?F5GT!3s^Pr=oz4QtU@RO}&y3in(?qFbM&PS8hv zc4_iap{X$V-ES4|MiH*q+Ecnle*6jpe=Fbczmy|BwI_S5IMe86IQi? zlEk|oukm;PlIE_Z`g)kYJhCg^1;fC@0^S|9!9IzhKKm8V=YH_1y#h%e4|+(;19v3l zf6Ab}b%iYX+*M*49R-Dg$3udAG~T*IbsAlm&yX(Blkw@+_?Q@aLhi!t zqAsgaoK_#0QL`sl#Gk_TYq~z`biNGkP)qr*64@!e3khV4R{Q!s7eD%hmR-ymWK3AO zOZGuMz4~PV$RYJJme75Y(9L0=UJw!2w46&KWL)ztv(JQqkK!7P8kiAT*wIQ62In zpc*zks7b(A18y_b5DG1T>P!-$kOby4NrY^-ni&YUoz6rwWSDQvFyD~jNMi=Rh~;6< z4heq7*6qD)JX7yjue|A~xqyvYpHJ|_8OjgZ*3pI{_4W9Q9GX?wkek#ZQVltTL7$*a zR|p78O35N6AD(YWKN1Sl$)9X>S=L>J)dlVRwe9sRujAZsosULXI?r{vH;4?IqSb4o zwR|I5Ul1N+jlUM(c4F4rYq1M|4n;Yor(WsF2913uNg4}QgJR!6^rq%di~5V?vp}Uw zv|5wx?Wu1{`^3^XlKfVZ-?24f>>Me&yZz1A?p-NYc+CCqd``E0hmmr85;PvO+xH9K z1T0wShkD$_`jyC(#_?x+cm`Eq^L&Xt3u5}~;}2@FI9}tQ_A}`qYLyXysM9 zF1}7i9EbNHw>ZRuDz@{rfWBpF9{2Rm@mXHU(bMWfCN_h!oA)M{qr=EcX-AAb}mw5iZx z3N`@)sUB-tBzO{tih3g?4OwOL4p#fJtm`T?WGTm7O0RG$TsM}`}a_t~cU!Mq* zwbPOwSJFEu%H+utr=SCj0! zF^rgz_s1v$&`y9$T?hEFA!Q3yJ`=YsKigese zk&eG?F<&+JYv#UU?yKgSy~lC0_ju6e?}P1%f3Vx!UUU1*U19EObBD|=o4d~3_2zCc zchuZ1=596jGIOsmce}aQn!D57-RAB!_f~UnGxtt&_nUie|4q`6O-`?R^wn){r&XU+YLxzC&Xg1KKX_lxGf zXzrKIeaYOH&HbvmUo-a=b6++0HFLi$_e5lFySd%w_L|#g?h12Pn>%D~+1z#Jt~Yms zxufQ8F?XxEmzjHox!cXX*4&-u?lyO?xwo2oo4I$IyWiY<%$+j#u(`A5&YAmwxwXU) z$`QM$pN|0O0WcTgzEW}GLCw6{)5#oo`hw($laGZmBa*qD{D}EIp@}lYTTrgPyo;%g zJ}ppG(fGt-yMCQ$XHzsydDwO;JL6Nyu8f&jbo;YPJZ{^f6OW=gG0BD(sbp}-kKQHL zK_PW@@Kp6MTxA%xLK~e?q!2|suhHkWjOiF(>7#N|#Ch~-Uj4e}#DLf`ivM8lWbaBl zg#qbU!WGepz_(lclc|A7M$?j!);I9oIFA9D3wKCxQBK;9eHGX%;pK zO4p%j$i8WFgk0n3KE}x}v1y;_CU);kikFiI>ZAY~x3B&lKRa%=F-AOwQ=eU-$cCm#~Y0ZE%OC>qdeC^iJo z%ZMGB=$xs8FN#h+lZ9^qvU#>Ngg1}?c<2Y53^5;s3+SWY^jsS{6b*aLx8AxV8C zbJDbE? zoeope3eeG%dcHBhmPOWebx?Tm1;$!+$kkDvMJRCMEO7$L|2{`p!wr;nJd(+sfH)9I zadM6=f(gXQ7h~$Su+*OBVK#AKWEq5~+S50;dMii|U`aA|-y%H#QpF@B2_MEUwj#fF zS&qeMm*pN(avJJQQSy?HjBl5iPG@1IkX#o_dsaP?Q1xsg>WRgt-f`14rloWSUwe+l z;@NInjGm?6t`;5EcRQs7inFtYjlqVElbv{pnm8`iQG`Af!Q;Tf zb&hcxcrS;l!*gZ4-?y`$8BxJ3ORUJQ)C>llD% z`4Pr#!4X@M3XheE$tVy37W~=Z@OzVTGF58Nnh0${7FgvoB$+bBcd}N~dsy1h>X9s` z)V?1TwpM}sQ(V);9ED<}crSAZ*ZPqutvh#FZS&M9HMu@cJk0_%X)B8Aoq-+?8!bv* z-y@tjMh);V5k5zyUFTZUX4-kwiB}BoubTUsV*uYy7=V7oNxr7UlP1`mG{Nqq33exY zExym(73QuscgU(aS$5UfuZvli#OT*@n!tB*gZW3z-D2)mb8TLpyuy{;o|M(Ei@7$5 z(XZv-Y3^=w_nLdFxwn~Xg5XIL1W%eEcyh|(51Tt{?wq*~m|HXVL30;fiw`F)>eu2Q zHJ7iGw!!>|Iw6^%J{{km__kwL^xfFj$>b61liQQl7(VEBkB4n&_H5hJJ%#wX7V^FS^y`3?Jsj|~rb@5h7p$>4n| zc%L4|x?1(Dj8E!YK*K|H!+cP{$;W&>&xI0agZDGR`~2|G031Q}ER)^V$rsYf38l@O~}R%~#SkV6QVwtq@4m;-rF9$-ND-%ynVsDB6wE^?@;iTgLhr5F`)whs^Wq55JG*AQwoA7(nYqXy#ydZ@2!$xx9$F`Sh# zE0qQs_B4=ViMNH_A!|v8yhYSc?Hr4PvtmgU$^{AZCLM+T`bF{W-8{g`2Bky*^Sj8Q zdt^ASZ|v@5Ij)b`F>xJ(6!t3hjV?~#z{8++aCqpv%c9GWp`~@v`a5G>_FbAFCm(n8 z>!zRN3WdLr{K{-X;aA-+$Qg+4X{AT?hrRA`%RF}t$COUe*Ma9o6SLg0rT-Saxbi&z zwFVq;@;+NQdaX6%lrb$_twIyFra4PpmLMmjI7?kt&299a6RMqFdoST2)!r-MPX;RC zxS)aw8sZa+xb}#d+-w-(6;zferLDaDh-VZ^W68(f>(tJD&Pb%y%GIbrly>lL8x!?d zAsvhRqub`Mtb57m&T}`BABG>a0a2j)h%jnCP%T9(BDa0f9@b4-JEK4xXkfF`?S8e( zWj3s{he6kILVW601Vmg7hXU&rXfHy&kfZ11LAm~}=*}A%`)OOHB^|m)RI6-2g%!8C zbT|^{51LtheO?cs|0uD|Pl$%sM>j?9`{5f1)j8$wT}G}FOtejvu%W@+6y5*BH{~_V z2dVIG`Y+wG3=GQFjAUyk2dz)`(IYfF^}{zSs_|A4>f=E~C0QG2Ky+N9{>j}GP5+l{ zO#OA#unz##sNNN=o&0{=bTrZUIICzymM@}}#*S)-qT$U;qUV64{$CpojlPUdv|kdB z02fbvzc8G8zBJ-MVfS{fGs9^d^bO$6jfW(0%~g$zPC=@PY%P*;Y)Ez8$Jn_CaHYYi z{l)8nxI#}I$!S|YV=ehTqzrWY1HGDj`)Et^MRCp~sLTP}TvARj1-_~g)&3#NHyZIE z$~!`x+5RezR<;uoXA!km|FQJ>^^dRT z#)rX{qaVjfpz5bzPp<>TNNK7WE$Wm;R21$gxlBlJEo=5@c8S_r8QDoOdo}c~+>#yk z6s$qp_1)Wl5G5Mo#vo%sH1a0_U(5~SW+Y+;RQ$Bf&tc~kgZ`N*6 zm(fN{tAa&&a(|6aXLl8Plw$VIW2O~G1a-15zaz+Ms1`dVC0B}^ej}ZcYFA-V_S^A- zX||+emRcGY6_d1pI$+=FTHX zE53^eCvu#&#lRhcyU8MDph#3^7XBO|n?3_eR>>*LC3fxz{w{FogkvXjT(R3K&`imj zFNP8HwBR_h=1$g5V?(R$i>8RGbas`x_oS(_$uy_Z!S!NuwOX!YlD5!z$ zuWv)LXG{6Ec!zDIY7e9N;~3>(ljG~#oF4Fr0RS79A@De6XA7T-$K8iO=*dkzX!^$K zCNUTU0?$~+Ivg`-RZlnUa=UWfr>}{enoYhYBAvmhS>2K!1U`_Z@9|)IsPr3j&Z1~* z`PA&PuFj-;$_aqVreg!8v-{O?!NL(02hiFxd{e}tYR@d|YVTio#QlrMv`?vDPI1|H z>r4nFbkpT0G_Okimm9&Ow>2}uCrH%p9Qak+sr~L7Jg4^S2=3H=87ZLeZV_0i_))87?uDVb-HH<~tomV?CzwRqFtz!z>Y=4zob{ z4PBA@YKAlykcE;|xqc0w`?=l2DPm`Q%<4U+;Ia2Np3q57yoyP1kiTw1RGF;auv*hY za+D7FG(C?pWwk1}&oXGe$)+~$cEy#Q6el_U{X3}Gu?)AIgle-&0P%qD^-YLyxZs5{ z&ug?SHl}WhwzoR32-(zR*vPq6wfPecKPfIB*owAfYF%4Z&xo`*w`$6Xk%uVZHgi6I zc5&X?s$jl5jyG4ozc+eP8Uz^^|FOPt{}`V@lyu4@xDlpKX5;m#@rp zng<&!h*{R%OE_QK&-D(zKSRc?++rZRGHorDexz%;9Tu#GQ%S3HXI$R^%Nk{Zeh6FZ z_|#%NI*cVQW<^*JV_r>??1x8X)lES6XOe{DTe*C}aXU88TXjbv$x=IE$A(xRmn^T9 zld}pQDLwF7PC+_okH#Jz8pfI^ViwC<8D7QNn$AVZpoch^#vSlJmO9% zS;)?$zOy>SJH^#sx?Sg15W2?_0isGvV4M69jbI=ncCzVnew3E340N12*V8U#>dl)kB5wpTSh>NuRBo(23y-Mvdc|7cNBxbs zj08|cT%z0bLq!QB`b=+$$vT|8!NV9q*P^jfyu<3Gw)3!#oQK#2BY;1x?(o2l6JX|L zv_i7M^xVo6*ld@a;Us1w7=+rWBN)k$1|h-^8!=|=Ij=9K(R)Nly|k;7*5rIcEkgdM zo-KASOHkzSqU#B#IIh(=OS>DNI$P3L#q?{DlQ#I1Aj1x$pXsk3u;WE}`WN2AGRtc3 z{QdR&tcX5-rSfJXs$ch+vihXDSqIc2;4xAK&;qp9`R5s_Bpla|iLab`ewZmrBtw17 zMrND}nT^O7W}d+HHIPiO)Ga#${r1;Sh;1d_xIVc|G93We#HW<1!!C)bWmVKC-C$29 zgWbQ)!jz{+%evrQGNiWtxw~14r`O9}BWbrCYZ;I03#OPo#(Xw76Tpucfz+NEmUYrF zrn5#+bj!N_0xZrAhB_+7V;!@8GiV08gPi`hi?)jiaZQS6mFyZEg)A`K;eO}`eH|9= zjF&yb@JeEV-{D;l;_Bli*m_5gJ^|LlTZ?FfQsX)EA%n z0lnrMb@+74lzgSq#_A#kI49d$u#KZt0KT6Kb+qs(T3HR%zfG1uP%@1&LeIXsv!4s z)FbQ~I9yj@3FKTE#s}?+7uW~gPQ7Bq^`YZaUz5xUlJ{V9zAMs)i!j}x4$iWLir36+ z$HjbupJ*!xS_gm^3;WK#;; zv#+oK+oH~uWQH-wMGm|Fu8*?tz=F@R*lt#G z=7SRzt4GMf)t zwo18x0>kkwoqElfm^#61fDd6XMW2$KqPOFVnz5%|Lr#M@<>5gb-$k?hPdaP&-~8~< z3j34L3L&f2uxR$ti@mCSQ5R|#&01p74viPfLgpwUpF}r+GykY&or_fd)tYrlZ{3ld z4=A2n@un$pPfesjNj{b>d33`0B|~tL5%9Q`Ry*Op$CN%T6EE)dUp=xofAb|?+^ty` z24O5-+@Fsbi5GX~CR$Itcxyfjg&uB-dEE1qc=1d=ks2RtiaDK+8IKnin_?cz$1n@0 zvOP6)#f$5ka;?k9@SyBHnI1{FSgbWhJQ~11oJm8zi5E8{X_a_!E?cz#SiDW&`b`ij zhAdM@@riixPO&qkC^BArz+D03Wx2fn&P@DV#(!JJe>memlksl|{`x(^zgWxoAIAIY*r%`{jdZj#)SD^2YWXZoaI zV>;Ubia+ja*V|QE&zX{9`ip05tqkyLW@c(sFjpfHr>(}*zQ&PU`Z%*TQ(nQw^vA6H zW4^qJ1dCS~6WyN63y@Qpx)jWem7nW2R_m$Fv&%JMk%a#{Lhxyg)Iy!>44icy9RJw| zMu_59=B@##B6A zqh*Fnp+d)atilZmG`bbQXjb4tszARP3_50H-Mh^dAcjvRB%|HHn$8nB+-do;DQ;z4 z;`Tg-&NT(w8uKibNkIGg#QNZ9v0Y%JB_=k>W#A{Ode854y~6uV@S$S&?|IOBPJ54CKh%QqxR1HjdvJ+8?UM3@Om+#KZtRk7VHY&qLnk0}x zST12ALDsGmGrN**LFj3>@MmkY*8?2u9?w)f-X}?)?`$V%VIt>)y6o9s|7Zy-#s2y) zOWRQUW!TN)$JwfMvUO!UWsUzi`iD;oFkVxzH$W^R32OsiFL(3Ins&Qnw5wW+PfL4K z`<(H9tjR5fe8Nw?T?=E)BaIzb95j*r^q0oVPqI;-qeWdOB;!_6B=g^U=md*?7 zPdLTT;*)y5hs{P?cX6m4ox+e%%$*+D-Lo(xKHU{n4DfVvDvI?o_vnYsKwo=AyLF$r zRb^nFH6??U!YZB%J@P8Wxr?6xF4|x(v#`=ylRDLqC8T|kMldY}+1%>TavO{UTu?Omo}vVYS%T?$h{e7Mb{27R_(}7RFG# zC@sn27bKUf7&-#Qv1(;P+GHk=XDG3gX+RM})bql#E2EyPcS}Rhv7%+YOORkc+>i4y zESJKI?Lik`!lw%KYdiR)(xn1B)4)sgT;#C$<@2m+J;U!7bgSM~qDUr)v<}2(FU?4C z>F?$wfcf#E${{^T?x1q6Gw)ygS^}JYb#KKgJBKV=J>ou#(RpI<<;oF&5=O^}|D8wdy#kOZ+onNutnONuF zT!=R8nb@9EEG`exirnfW3 zg{aR;Y*GnVAc{5?qV-oDIy^r;dG|fD<@ME(GFAN8Mpuv3f7PB1<(W;>n+|P?qH7A# z`KtBm>G1;-M-NTkyW!@E>6ytx2QR;$b_&tn(uy=``{c~wsqy*i$k}I*q$%Ysy@jZ2 z&&1Tk_{>BUbrdjmg#&UZQ~#~*LL}SQD8kcio;8Jtii_vnGCh9yxJDn(g2i-ah8;s3;{H~I7b%3t=O{O?Pd zd?DqIs}4|zEonJRYlL&sc^S?mdGFtMFv+3wx244EJE>fwzq{`@EhC_YX zLAXn#mLYnoeLb)ifXP{Z$!@f{rgqCSO26ITEm*XI18P2>vb)VxLe_mc>%WdRWN4;8 zd-#>H)EpDl*IK46nM}FI=yc0c@J&)`iq~u+Zh|ars`F+m;jh0&*hp`p{Y}x2MQ@MZ z#$Sc>XB{OAVAYv{PxGrF0vSr^+lN;&YESVpqd3D*;!u9-=p?d{qke9i8^F5c(J<3sH~)|>ytjI ze&N!OqC#$z1KgX^)Ejd*W%g6faoMdlw!V(WQ9bv#J_x1?Y3aI1^Gj?zy!G`aC_zsom7^_2QycA6rYRPq(fXE&&LwX-dF{!+Syt#Oo~duS znW#OS+-zPtx}>w?t);f&`5n>d&d#2A-nu^4{qqGqdIECT68i-aIoT>7?c zZ`=0X(S?&42(NnY<_ks#)k1e~eC^cu{Rbz@2PS4_50!UMkKZ%Cc@XT8*wx!-;qu1v zyASP~pPHPR-@JPCJSFw?F5k1`${n|&5>C|OzWSxT#mZivt*t5BXua^JEb{o+L|eVE zoPjR%6uCVSefDo2`Bm32;|s@r^|?QN?0vuT`+xn?|M2prgJ1tQ`|j$RU$N}i zRsZ&Z)Bo&O{@vUc|M~8-e}C~GZ|?Zjmp6a(18@J|f4A`T6@Pu`!(TuD_uqZl$WLzh z!#9`K{zRelyI(!Lulq|s`N!LT?JuwSH-GbYFI;@rfB#VFQ)45yKlRwHm)`nQKR3Sr z={=ucR&D>z*-w0-_@*yioXu z_V%`7S8epI3SZd1ZuCu~hVuI}#jA&BMlVV;6-NhqTV|U+ zJU%+0CN6649qsY?+uBBN@%}=g{oSLL(F=Wev~Y4D5AS}#JNhGOhT?bW&@2_v+MC-U z$J&Yyzw^dd<}dxHzjo~SH#WWXh0p(slWV5$vKcm9YCo@i#YLz8=-#;PqK%)47Qa~; z`rwEE@ZyQT%90@S7ZT(EW$nkFyz>{|IsBzn|I_a;TrmI8N7_E}ozMO9z#n{T_|HbJ zKJ;f_uD<8s2Y>bt9{9x47k}p`P7J@c;nI%|{LIzAw0p_z|Ifc2Z@Xmn6YstCmo7Q{ zTOWMaKmGEbj(z3s=Pv$@?`;21fAuRrxA6my{_0=vJoB-C|ID-h{+m0_{D@!0=-{n?XS){Z^#yDP5x%D-56CW0AHozQ6q3AHV~R||#zbj`s}e(A1%*fLu0cn@rEEMa+<&wc4{@2}kX zzm6Y!^_4ZBKlzphl#MQY-cNbQ^Hz)H#J#>rA;0fpPnyYH8DLqdDmpsSa5mF)ipa$-PgR$*yp92VVQw_5**#;+2?<5 z?>eBGSl2Ct4iY*@@4ZbD=}0+Xp(-8eMWnaTMTO855Tz*~pn!B#1SvK|=_o~%BGp3? z5s_X+@lGPa;PG6~z3<(7-dju7VzK7WOfvJ&|Lt$@Z+{d1c6|RCY^H>B;4zkpmAxQs z=yOWav*GYw9XnJpXsW|&=TcE?#;Uh=opNu0(}P#iC6e4n2d*x?wHDN+s7q-f^GYfj zu%OhA~1Hw$XvjPOPOgfh?)F8jKDZ^xuK^ zWQyqr$5v*jXh1_JnKbnL>b?gu-C!DbzvzTW7GE0-ENFY4)n zw6KZDSlp9r_1IV+?{M48^}N#~l6`a&vV{>n2k+8F)v;zyo5>ER4`N|69E8mfKoW~0 zAnfph8UKf{1OJ9|04*9$=+NLw3J`;TAozHI8+we3&;hUq;giB9>M(xP`T=|rCIUeJ z8%%+~iN)Q3fB^J6qE{&fdePV^ggp@m1Yl$Nvpv!937|iXlTa8C1o*Rfv$&%;vG54{ zcAk=6_O=LdM=1=Zqd5c!xQqZj_Cvt`8Muw-AoT9a7x=`0FnV_yLNHt8asX^F7GN(p z00s^XmSP;$(h!G9<1Tygsf1Y6>Fp}H!zSQhsR&W7$p>Ae7=;b-UO;ji0 zb6;bjD{0HJwcU!~_vow2z8rmPvavojl53o&d^18qc;wW>!s6@u3Gt`zC*?qo@(43&pPi7WvF^>~k4`6Ym8@vR*A@(> zxWP=slV!u8JkYwSqkVA`=@{@?FuD1@6!e_NR@`TyQcc<#$~!4UBkFq?K1z!c3_UrD zzmQF1N&jZ7Mo`P}k!XY!RerrM5&2w7eKb!QXTVZTyIS{xc9C*rY((kt#pm?gurT2a zAWS$FWUc@z>2K$YKVY=q*mRZ`K#jwm_rTEfgL#MWk`ci6;Ji!-u;FY`z@Px`s|+B= z!18x8LKv8iUl=cT-HC_l@Rqf=FUMW*YroWzhPz@wMo1WjkH<7dwmDg8qgd}oqRAIN zc&gsmTKjT;uru4*OE=isHw;E89};yUnhM zxvssctg^YpKs)4u-r|I=>Y)k?(1aGv>0t zee{E*$^>$?UoZc>Y=mbf*@4&88sZ8{FtmV3DfRrjTik}=3G5XU%L^Es||E>!E#Tebv}xIcBT zKf#_C_0Z+g zBnD~~wV>x|&&n*C@MaUve>eXIAFJ%8vH~K?E~Onp-2=9MO=o??x4K!wRQJG>l*{GoyFPS!3QIF zz`hnRW$()hBTWMZ+AR2Mvdvh|B)#7})uelDTI)(cH}NM0+*JiWxCo$PaZbxj6~=(! ztc0X=drUy_J0U-$;g}NWo&ep@<+0D%XMg_hbhTaexI@t#JI$$*( z1s(m@f!zcH%X$dt7`Il#p2|OkuouM#Anr+h8`Cm}O=U1!99y_o+ zRUKUK+s4yZk&Fjf)A>+aQLWDB+HQS7p-a6(jn;=LEY`U~^jR9m4J508jyGo+Yh!+S{%3VmVE+S!YAv(9)_vKkyhe&q?V!lE_o?bZyi3l;Gr=CTmDR{Z;W>G1K{z#e$5dZP!x0 zX&#Op&DMHj`SA_3K?+)|H3?`PLfE`=M)iY=@NMSK)cPsGloy- zPBjKCv_A3v$|z7D0n{2!LbSfJ;$hL&=6j`k`1G9e;EZ;t#4xygx6>|2Hv|Askzuz% zmBYB5#y#zQyd-=vO9vx#e#AJG(J7jf5R55cUlu$Ih?3Yo7?f~0$4Y)(QMe0AO%+24 zexSif|3CzU(4Rs>2(qGFFfg%VpMZ`U{f3yB0~_D=$%@0iiys0M3Xgy+{bJBu$T6UJ z&Z+X_I2rqcBVojrGS>O}*BIlb*%HarJyzV`o1OxuHk{*leJE%>4;9^#qgfXzOTW!h zf8qVH%Xl|C_UM#9hvk!6h@AX1c9PvhyU=0pyC4-i{>vWC%`z_G+@u#&r-%DZl-UC` z&WbP+Tjk5T@X%h@V-7!41?rRQV8q96M?AE1S+-@XR?36$l}jos%hB)782C@e5W4Du zuCvH~lMP@D!*^uEe*p)78pk>I6msf!AMh5aYdnB{$)2|*H%PjjI(SozO0&`9OO&F4 z5fwuRp|a@bqRW^2AK3;`n73+2`M>#HO^fH!Y@MjulWVV>DlVuTnT?daN7Kl=c-(ZJ z0q&`5l6~u3E~HO{qg`us*uIA;8g72uD$T4gQ|Ks^Y4-AoN^Y&5 z*njAT7xHc5TkCe}dkx{olbLJyLr14x@Z>$e4>_3~kYw&qKg;C%P&GvHU){yQeI3L}ICCwa>GZb>wI zH9pb}7a-lFs3|&x`8b|>M0G1`0C60SE8W8@;(O|{ruSPi>2iy)eIbVlr(sT4^59r%7 zDO*WDq@3JUY55`g;gmwbEQ?|LfeIA~B6!;K7wrIFr=4@*B~F?18ZXptJ-) zqVJ%VCR`Qd^PXAUb5U*5|Kw}ZeG|9>2R?INa)S?9De==zektSk_ISFr z#}#sqq2AeP-@BZ-*bA~Qwa0U=SFR&v`_Io-hj2)?bWg8mWU-I2%!TjIW$!wzq^0a} z!YhX@aIJ((`0-V}X?hR4q`*z@585XKs|L-N6g`(RjRU~agHVAiZ97upPX&(px_Ez$*nWB z?OTcT;3twR>*dlee?-B`!&zz9XM6prDu9;G@p{yKcGHQE%#pltwRqprUe~%2gMS`p^Zx%d%N~ zcCEbk{H^)x$lAT$e%<;W3O1|qFQYClDmvIB(##V5Cg1vs9mR23s7mc3CIxpEtFqaDV2FYAk7EcLv z?s#NW6eE&C1UZ9WaLK2xf&4{h2^XjTH3D}fpTlZM%XPnYfzWRG8M@^@!-ppgnHAOL zX}vXt(v6ylh=loLwHlOX=za9!H4$yvt*n#6Uqsy9eFY?4b(Gu^p|!NZ6#QQl8{WqL zroySq&m}cCgDMc%7|mkUiZ9^MBp#Ldcs^kZF~?q*l)p!O14w>#aJz1-^N#m1p#WmSg?6S36V88nPe8Ni zXPoE3vCLyeM>5YNEm=@G?~RsjqSJbuUQ75vUBB=>i5dGl zqn*kW#_{WRtY_ZmlZ=goSh=gnb|(5|-v?-PUhjmXip1B6v4Y zt}!C-!-vwd7dqma-KSrqR?2g7$Ys_qUnyLU7;We}<=sRqT%kM>PAO0yOsb@_L0*l} z`0`Ytd!;;GYxGRaF&7p${vs(`nO^^Z0?S*YyWGhKBk1m~aX&hQE)9UV+ zB1^EYj0lp73B17!zsUOpuF850TBKCgw$Up(SN&?Dhuxh;nU6w{%KW zU}Lrnw#XX*&Xms|9FHG)EhoU42fI700ZYJqcX5)E&qb0W3cxE;J|K! zrDNLdaxkW1Z2z?Z4!v|i4@eRa2Sl@kvjn5~ckT4GtIrR+oW+sga{hDc=dTul5jaKQ zQv2Sg*L5S2zZX1IT@ucb4GHzL+f@Xv3i#-J_|P>2+Mc>;61YD}R|*L;ZbriP)A>!` z7Vp`|Yym&81s&}^k{|fQvu}EM=*Uub3+mij!9|8i72%tcmdiQ)#>XSP0g+)2Tc#6S z#>A=2ahBeT>nRV(KC>kpY8{)3BiL+5C(b}}=!3jC~nt_Rz_0ytecP^P45uR?oGQ&#{7b)`M%dH|?6o{Q# zAa)|K*xCK2^nM$OayC9MA&)Bh`^k6m5~hXtZ^IU}i6sNNR)`(Y108(?930qg9sb)h z(NE#86dF^!K2+-*Y{=w&h^!_~5w-5i5a1Y}@p(iSa#hQJ^^LTWLk}O9JFqd#9{x^Q zP!pl+&KNThrxM3g{HTC}^#w_lVkHZo&^jwpZ+{EfIRR4njgM-)euupF+_5&lNXm{p zY~r9(3Q<&9TONkXCMmxW%U?Ri`z&;XPG^IW`ba@zffHcs?aAQP!;H@pqV+kzTxf2_+!*`9W$izU<3V zewB1GgLz?-NK>on$iu4KXWxueyc8%8RxvOQx}Xmu)=4Hf(9oesFjI}UD9_Va;rV9n zc1$`J{+hv=s{hX8`fmZ9%2(i$17rZHEJPM8O7ff8^&`8=$H^9KWEcPHd0`;zuexyo zSO^6n)fI65m)tl7?6Cj@_XL0B#(j5!pd^hsv3f9aSS!GagQW3- z*>}O|5Ak+4HefupgI7!E@8($Nq#f=o6x8BwFTa_d~7 zL`u?E)c2+NK9UD-D!jC-)l6oX3>%CwbpIl><=E-1Jc%Id&pAfD%%QpE&^FTTI<7D5 zho>o;*Y+%Zsz_(8g6UYIYJIhG)a2^p5Ou|a7EEU2xe7hb0zKTPM?)RY*xjhsm0-B? zCWE)soMzg)NOglUNVX`Ova_OWKpH34O*^hkQX*UdCyoOsIhTJ%khY;7FG*W;}%3}cnX5$0i3 zjnz>QUGHn}P8?A72R$`2&{H$U$i`UU?}AGRb@2BUwP`UpDzwLV=m=jdgb3pZW zFWqzZoCvk*TgdRf#dgPySm&*~1EZW;ms8#ynf5Dz^^{;sj8XRm#oDSmeThUoZ`C~?CR1rB1VZ%#BpJ@eCi3A$=2&v>kraH)7#Is73IA)SrO|Q;@-Px zK~*id)q`I-Dl9a$+8UgxNATRs$Ugt-lPbykp0TdcNk+(#&YP_aT!zG~^Gn(%o`({+ zZOkeNttHDSPX4x{olQMzAup>aW!B)+t%Xc5u-JYqDHmq!SgN(GiOZ%Cn=9hX3mNn^E)_@MZ@g%s%;}om4TWP!*O8n*T9Y}}pKkjx= zuhp-#tbX}V-^Oc_9}c*u(tQE)A!+h=jAOm*Ao#X9Ryhg$UpU4s3pGgo3h+NG@u6xj zzT{;uhW`zVOublF;GO*&2Ue3&D_YM$;uhn$6lpVmtHG|x=#m$NNGP}hXMwePuXM*` zvWase>54z%rmVcR{j19Q=ykSLl+g51M);-l_WHu30<6oD!T*T=2Whe$18As5XlSPtMVNno@?By+AhNfssT!}7WXt% z&7WskPLNyl$KX*_>oB@uO(?tS*AU*YtmBnmhfCSHeAOSDA#AiOEIN_Mppkf+le}GF z3pBhMKwB#f>^8AQK;jo{)BLZ^z>L%QAqw?El;ky@ejd=rktTM3n+UNVFG1G`z+<<@XWW^T1(4 z`jScHG2ZYciJW~82&nuL0YFB*Rxci#8`fm>a6$>dBy$@-V%jmC7KM00H9D)u+PHNV z+&kT;#xfa^PJmw|lSyS@Kk^)|!KNXD&T0h@#g4 zlVT@WOjNCTs*Q|ZV*%t_96D@493~Egtx{X|Ls+%y?=Ly`^bexFtwuT!t}%L)Rwb07kOdk3s7jPZdIWv0ghy`eWDXHu+?#bcZ4 zj$6b$B-spcMAt|AoheT8C2`Azu6E0?3uP$LLy%>u%MwU>XA+Qr^%A@~OT|6AvrOJ? zdUc&pd)8?M0)lU$PK@!Py;&y>6D=c!c`#yPm@CCSyK{)V+w^LfpaNkw5g;%b6T{3| zXM;{?XqD)-kfgC2fO3!LR5LQN%c&{6$mf%xo~DltmIm@~4X z6kVfY73U03&T>X4Rge!{FZj7LHZehYB^`r3^A?=36-+qn1%Ju3*=+lc=?|rm*5hcw z**^xa&avX2-Fb$*+w|&sfMcx3@dyz5Gsb@=9tlsqEKGD@q>aElLEN)DYvkRgSHlFy z2onlj!(@zxc}h$WbQGo~H^!hp{(?F~X;o^?9dM~On^SMGI(fEg9|&igtvoylkE(w% zo`bo8oPP=(`GLHDDjbO-IaXDrF{(OFLW6u_v#yc%$J&t3re zs5m;YX~=p1bi@zjb!6ap&C8#B@=1-05wg|kRGZ8vH z)E(;jXCah)?}08;)?2Oq4_k2Qzq{|YYWpE-rLKbQKU*gzy*5Im6S|b5Z&Ub?8p^oMCae>L>)@>V5Z0h~!1kX5pHTO?a3q;YR2HEs zxz4$KOVc07DZi+R`U@$LQG+=}x}nb)0|z9r(Ih$le8dmrbmX9;K=ca;tj(uktUKUp z#uf$&-Hct0L59Ym(7BM=G!6yjLqNgU>5EjG;e!P=P&8aE>XZh7f^e1G{P*2YJ~>d( ziKc5Maz#K3NY}pzV5SGVL;dv#Y#g0%$FhzCE%`$~W*I(FA=>`MOo{r>z$dD|z4$~u znUJ~^{U*aFszudig76YNo(`W_1o?C+-&;iQf=_5%6n@PoMs@Q^5*zJ26Q7<(U~N91 z7N0Z@h0bLu4&W06*6@kp-F%Xi27#yKlYo|LW%-nbJ}o|xDqVb<13vajd%9gDnd%<; z=P))V)jk5g41*NfU)+#ZBkF&tod}!S>2kieNCyM$gwlg*>7h4DfsE?bPLkMkLwjnc zQu9R7PDC@@fX8&vbNuJiVNK6*vsx-eSG3f0P4tvtB$yO3vY&=(n)dj>&HAj>`%SAz zc~@``-~fOO-B$orRKRpO+m3x zDbyw=R9ig7O0jm>%M(ORM=-Xcs@j71ILZmHz@z*S!`)EdP#KSZoZ@|;F zDh-tOtX0j_s+6r&DXGDD^Ss-W`f!V7j(`Tjf zvpf?!6ryQ(piIg#N>tV#!T(?{wW#n&cvJLS2%VOGFbysEn4?QSc=SoY1%IEwkGks3 zpd-d_qF>p$y&pdhVIRW}Le};71j6{MA(Zloev{&0`f?0)g03l%!!?K+%vbVz z$RS5Ad&wciPvnq&)Tv03s07L(A*qVnc?sWJPQY`(RX)lJs^y0s0a~ifs6ki79Z#j8 z6Pp2)t2t(bG;qpB4h2Pu9_3IxUd5{&b{A@?+C6(hPuhu{~l5qB?6)8toCl4(~R-dQOIvoRfhEIk87DM$cDaLt4YotZgp@4^rD6 zqZ`&Krmi9cwzhx8VZs3uwg#*Qbf>i)2>CY%!m-WiC#p?J6QZas6eIseBrwj`rq0*F zS+$449e87AoXJn=F!{-ElV6-Vzc}OkH|hLiucI@Xg+(kA^vl;D_d{HX^gEQNy;O#X6e3rWtw36S96WDxkMHlw-+ zCz9B3uzPT#iLz1O+9c8Pi&z`PE0U9JJ0a4v!qoq*vH!=-~n6O}fK0f>bhl@{hVj_26HxT89laidUz z4&R7EjPn*asl?7fcyPb7+qs-&z6qf;0R|0$2hLgWRazSiya4bpXP*JyttsfY7|@v0 z=YsD7^z-)sO+A(3LpDI?LANDgMz_(Q=(bn~Rrl0E=OGn!5U4{PM6cFCNJ$-ZJ_1As zF-Gek%-snal)jXxT@QrAop_Lr)F+tycIgwAeKg`~C|hkI|AuH!4uVk_WfF6`v&n(X zlw26w^O*L-hOJjGTvs%1!=a5FHPvNccH33PN-Y?*u%r{kI%sTZ-araW=# z^2DjjL#xr{NhT@p?fWioFC9t#?X4p(K&a7?OfZ9vB!9U`_Vjclflx`%Gy9c0nd(UBTqF)hUi zLq}?asUrp3E*+W0_Fw5pfi7go>c}+o|CNp;brT(lUT_2aSYv9V(a9T4AcwV*8f_CY zUZfkUOWa5&!FWs16oDu1^cNs;Wt#9 z6~>Dd#)}oki}h^`aa`2Co=%w4hx|N9gfiIoVQ?USI@%80oL+DY-wRBFc)@Xz+IkCe zCp4)H?RK68Ag%Wy)iy>+d^ctc!5kf)ym=9vFMp)O$F9K#fct_$%NT8cx5y_{i4k9m^3ujBhpWd~)|z6NeB z038MgkC~3pMA_lzboI$g3`sO>aR4^fU?^i)4e!hK<@=oQLz?lROA_vXSci!mF4Dlb zHvSFdAC-0uX|U8)F9jf3(d>}*YG}aPJ$o)p<<3y+c8UuDs;zIrGm#_;RZ1X52*eVcy99RUuGmJZ5)rX>u z01<7*qb3WZJPUpUZYTUEp3_UP#xYN4coZ3iB?AoH*$l;+yQ?UfrY)dk zaXeyK3$3MRSxfeV7vqs-fQ9us*Sb2vRVta0WP{+P34)h7PZvR7Blr$v_?HM8@}_u> zT1(exJc%E4fd#n&Ed{?d2CM!(*x+J_fxZmWFea;pUqt;99_6Z~Y0PgK6Mmf$D!}|; z(I+I4z&~!s$%T4jc{QgqwK+<)UmPaV?gGgTJZzYR( zzzc|Np)8zWN-RaEpa3Iaxenv7kwOG{sI!&6YUe7xwrs<5_iS_}W1tkcmCGCSKNWn; zC>u0>wubO^EET;nJ;ZMiJk-38HJZz$bgK|4qU6AW>x}ePR!P?kbCj|84NBd#&KGW`>OAu8c7rJ3f9Kaq)oM{Src{SMyDYb zn^n%lYgeJB+SEF`3NYnR~PR4_1fny-8te*a2kIRp0Y*+71*IHcNC zi8cR|s5?fgqQ3-^E+Kj@%99~XcnC6=l&e~wheNasMrlM6FDMZT!K(-gQ;k$NnQA}S zu(*b)SY7-EK)WIQ2H@u3AllA3c-x?7aE1y_&}4${55I=OK;i2FIsB9`%v5K#s(ZTS zUIrBHoZ}yeq&a75cL`hFoOQcPwuRB(Bm#qv=BrEJ4#{y&%rf>l>(#E zwg8M)X`EbC?eNnmZu@i5RCdAmO0AX(7FOOlItf2RiP_x~^iT?jqZ57>L4$c4wq1j0 zFD8;}kh_KQunHS~9W@TE;TF3}Ix#M(w#C8 z`)bsq^JYABYufZ|kic`&K~`l#M+j2>7X>M4`KCpgdb`mlK+(XDK9v#{3kp@OC8V(# z>K6Sk0Z2KmzR8-8et@jKs*QG^Z3+T6A3cspn#m3S28!0k5otbySgNQNc457uh{tdx zho>;GQmA%rm5Oyi^xX=Un+)2sDuvz7$)w_!fz%+P!mq&5{3d8OG?;IlLV7tB2kR(1 z0jlD(zKZD1Tj2&HGhkrwI5h!-#U24uaoS8-UmAW5xnf^$m(T0+%@l`;tAGi=4j|Ro zgHexnxqm3ioStXG5*aJUi995FFvD2rXUsP`Zvj%xC;yquH%e+ND(s2MY)GH1tW$el z^OGLvWbAviH(dy!7}{+^_)WV){3P}psQ?IR9A7`5HqWuBImjkq=o_h^EFX~Vh)HP}|s zeX#cxz1g~((z6ZTDi=COmY1V`&)PUo4?T54k+2ozXeA=dm=rrmqHn+}J&u0_tI&-e z7QL?p(4^w1;$c$JBk_dEEylP|$=9X^^T8|J@B+ltFInN$Ja@3~q31#Mx#9T;tF2fO z12c+vU%*NlSo0tmn0JVP8$J&plH#!DiZwT9LPH*&ENaKdiX+e~vU98?eaEV6p=Qa! zT8DF{L{9EQwKHL{hiI^~8JA=;mXN79HE zBduvfvnsQoGImvF8F{3j#1gXVw`{wve=PH6WTgp3W5vAr7Fe5PV6#tppj97WGGG&J zLV5nbBjH&1Z9J()t4CpiVO88pF8mIHYEx4Pb?S?tV86>G=!2?DiWNs<;d79*P;u9V z7$jlcAgRigX;u0w{nZL|e81N2MgJZq^$Hblzz)ApH@Zt*nM$rw@}Gffxgmy%PV+MA zI!eU!)L>afp9IiK*FG1#b8uit?6lY|9rL48pO;MTcL5u-ouEkO}d}aT4qpm>oeU z$JrS@aLh}jvM$4Wg1E&~hgDMuQJYZTo}{fjOKn0Om8Zgc!69*%5&>LX zbi%7qk2#Zd+Rr)j!PLRj#dCEW`kZQ`hTjB6h%K}yD$*Y*e;!=H0+SdT*mNKt1lpOF z1wH!H;3szYBAt&kJr`IW0K9FH+nj$N5c7Y4M{uyM^-)&l7w?yV{&PZ85X~_J3o!Zq zrZKxL?zJ{L#-c<16|7I89s9yR>SnE{&u_ksp+7{4<#bbk=l=)+dU)CE&daFrbZ}V^ zJD?XF;|^!ylLooCAVxzkSm2Ik;;mG3;d*&51E#M*|^$_#My z7;P}0vTl7MODCY#T9%~YL)o~sjEZuj9Y}!53NNu6DZr9{>imG=CPFd0to>-jAR` zN7##*v@ugGM1qX0C=B#OYjA_sbFqEX!Ttf)`UALyHd#^C<^xpAU47IlSj-TlN0>$! zG2rQ-X3_HjK6))4A`(GtoMZ5i1a)<+Ci8rg`Rzz$rr1>s!^Xm&pawcun|(~eDeO(h z3@c@fi++QhmVxtm!VyZF%!1lCh!yRT34H_QV?$XAX3XSgN*(3jjQA{&U+)EELiv~} zr$C@Ar8uV4QQ7>7l`=tMwn@(zu~E*LJTvkdO&aGvQACE9SbvW-!m0hSDug17?Im4v ztg4=4c|y157&uQO3de*n63|XnX`O~@c}}kRdIUJOYQGv3Zan~&blwJ+)8;d}8YP7f zB2fFQ;X{c#x(;zTPy{e~I2^s5iKmf3*BKLtwTNu}6d~bjBpJDwu({uqaR;;gEP)$7 z3}@hV-j1}*^%%0~WZ};d48*-^Lw*eyS#mO4XjtcT&!rL0xpcb!!G=xsJXDi^s?E8= ztR7hc#Ot*Hi5E=cUNEi}wmH8t{wXur!i2!sfu+3Qek0fre?}?E6aGTu7q36kjthm( za|sm#uelrL52)w?RM`I|lKYR~fr*2=2o3D50EOQDR|vXSW>9Wzs^se7#PXl%_`04= z8IPW5X%C9PDgbMesZjW91U*&GohVc2p%dx(m~p4mG1X?e8A&4mgg&t~0821QpmCC< zLLScf{|B!Le*^r$)0k%D6SXA&?C7T;leXvwfuVR$L$xUvi438CV;7~9nGW|y z!S_?OB~r|e-;N%moMC|I0Z1C0(?PW1zZ;NceLx(*0c$qzMA#;DC<3R?Ujc(mSwh|P9&S-(BbQ>@E4E*M>OfAE9oXhhp$^NLP{ z(|?pHqg&wAmH_n1sH^EO605@J5sv|m+T{-G%;>nkgq*G4;o(hJCZaDPMW$?yFSK2H zjdk>EtO~4;*ykxr6GQ$wX)3Uv=46cx)v*}mKO5nF`Jm7j%RUz-S1F_v0C<_ z(-qrX3%0q=J4hPn8r%9ZU@azX+6)W71pv(tAPmEXg>cK>5y#H)!}@N%J8mR$2f)~T_L12;>a~maiCn_jW(q5=G zrE8O^(a)KPt_Edf?e{}5d~s;_ACAMsp~F5BhlxXn-5!UD17W1iLcB+aQ}}0KGSdp> z5QN2PZ6xE7b`0a_Cm?!Dk!Ps+QMmNs(ybo=^nCcA0D=w1f59tZ|70#+EV&ugFjL`5 zrBcoBs#HQ+ccUL7qFyo<3Mc$8WUqyP#WVaH9<9IQ;cq}frQ?RvxDG`i7mp$To)$1r z8Nh&tvAZe*Qc8w{BTIUt0|(PGVF1&sh2)hjq$n567~IIgiG}*A@EK>JOS6^3>hQIw06WIuZMk?fbO~@U1R1OhR$aY@P#MhN z8|^@v@PAND(tg>Muwv0$_8oQGo>8kXsJE)vR3q}JEg0K@QTR{RV5oU5qANq;Zu(#{ zkiq#_2%VpnTdFv<3kIDgnkI}1GQHU&1xyFSND&;4Xzr5OJ9-|Y=OUVupFN^6;vYpc zu&{bk`B`--)EKPxLrMKzr0{^)gD}SW>nRqxP8_AnIC`+a17T=tW0iDH*BmIq%pqGw z{2svf?*@p36St?Fm|dA&t-#hfTeuJmCu#nQGs?6VD-<`FmUY}v!u4vUTCJo_#f@%59HwX760oaM)fgZ>k9IgykE9G64VS$_rIckpHjQH;DHCQ+m znS2*wjJO(79AskNyI0JpiMc(EG5rEmXjODSRd3oE?|Z$>B#h6cUSJ;<1-MZ3~lDOdWs zDFMST2@>uEX_AcPfl(vVk=ly^|{jb-wzTNZA7b;oP!k$qgkd%$f3IrioRiwXQA9E`5En^>} zqrf~bIKWii6;m`ewYFJ;r(dCiBxXqbli-I5J!A`oYP}M$xw&dzWurzMGN6A`To+) z;tN`3@!c3_Bfj%z#+Sj3dVeFqmznJC4Aw|s%=8&jZ4z`E8uCe7apyDcp}Y?NfU^5? z*m{`ruR$_wYG6(*K9khJZxQ?|IQ%UHA@n^9_#RC9dd|qY|T8Y7K)jd~FbAPY1UN< zl_(&)Q9XOilnFzalDu+o$^bUx!-WAO?Sx)98;{t4Z4&MY!%-;>}hTw!Z8J^p6rv%H-1;-n$!x7YsxbLH&`7Ef{6ptc4 z8+?LA?9hB(qk)ABh+Fu231sEt-=(!`Yd^$o`vS;?YfQw=fq~RFCpPdV@N2yZSv~CU z{}$q+YtbsG9COZY=go*{O#lRMNC~!Lc!s06%)C-4JApeW2m zLQK~59X9kIiZX|9fMy=UvP3P~jsjbgNPsIghNCy8zHP(;8Dd)p^e!>n4!z!Ehf9z{ zoc>Z%4(&%6RdU{iIRfmz))3CJE<-FPM&ChB>@58*U$b&%2Gsc;y|XuTe!zEM9+vmc z55?(p?w7aQ`3c{(4!~g>VF$}iImNw+kQ~Q<3m%;Z7}VyoT&S&+lRj+Q(pJ}~)^e0D z*@7cfYH8&bkvmAe?PwdGlP+U2;?6jt1wv#c9# z0$DoWM;g+Y?FAIZ>NeU7Cb<3_a3rYNLNO<$o7U?S!LN*jnrSEJkE{{)+O~hpV&n0p ztJ_!p+_nx!8ROJlf`X@y7W&#hI?@C21$+}E&{H30kRqN%R|w7 z$n%v*zghY3MBQ~6Ntsxi`z2D0__rZ$GYu`+nB=9_4=f^J*(4ncpboNj{?1^hA)3K{ z)yq*V8c^PU2OyPTy1WH|& z*k9pj9>w&kP5xGe-%^L(blv9}2HK&3mLRgg)WocHd<#fr#)|rke02LrimG5_iYZpZ zRRGpRnFdvmF2v%y*K0^uG^8sOr^>ma-iK9`eOOIcG~@am&KyA0FdW2rEK}lBldg*q z&lyb?nYeVU+V`c5;0C!2UkaKpG35(``RO$(`W^rnrsS(fbYNGld5l`Z?G~U|w56w)@iBSVE{26e348K9R`NuZ% z1F-T)X$#aw&CgLHW0H#h-}(3d&4AcX#OsdUU%FE;B;cC zm6*x30{cUlEVH=SUyw;fmJiQFZDS#=@78M2Y2-KP;eLDG#!mouv|cAr=pAkv*;S74L05< zi*%|@U0&U=e6DtB;aE55cO z#c<}#(Qr6cpN)Ev9(GPFZC#Wgt~eLWKBntja7RM)oqttPpWLsUw^~TgKdthEvy4vR zz$&Y<9|FTNiVpoZdx$+4TS^DP=$C}h-$bo2&iW88Boua;;1?rUuc3JuZI8B&M8nwp zzkXw{vfyZx@vJ#rI5w<3;&JUrRu0YnYE)`W)o}2u)_D|hIL(Qr znj8*(Ntv=H4-ql;b*5;35#FSWX|s4~dbGETXCataU3R4Lu~lkVndtG~paVXKn|{)X zOmFl@FrwZU?_)~i zdL+hm&6Rk78yXkA@s9_$t9DBD-B_*TnDG#n#Wr8_zetSycw9Ieg`^DI;X#?RklK`#1%Ozb1J2i) zj45_|WQ3gX+`(#A3V*6C+&#cB4(F1xby*_*gyJX#W|>&($R)@@-g*<@91EPQ&FckX zDp7~ONCMJouFG?82ewpa>SE_y?vKPE99@ss+$fCPu$Rbj9CbX==Qx`LXslG+et;c0lmpOcPya{I7I2P&Z2&`d z9MjRQ;xWS>R7jfUvj`M0pCC-U|I@s&vZ2?9!~vop?yqr}I1om@oQXI86xJm%Z}}6_ zs9+SWnh;^;AV7Q5EtqO(G(;l>KTX=5?LR^x`!iujxY=f7^nN__dM@n`uz^_5pnQcV z0M*)@)*8Gp_Y6)~JMqZS-jTn3sP|I{>z#VA@h zFQ$pAnvyi8Ar`lJT!eCv@_0rpw5?WIXPlMdfI0a-aG0T(8KI_iTX;YWH)p{>Wjzyh z)AM~hoC20FhD`~F@$GOOJl;bWq3CkTepA)_Lzv%Mh3<`t{e?{ws)Xa%ibR3OMDSS9 zWhi_IETQ2?0_R0HAg~~T*oL0vn5&sJy&AK5EuIO;IJX~tAGwP<_b}%l0@RO2>M{di zQPa@!d(ZbLbW$gLkV%GdeOsLM`OKO(2w@NZL8u`})myhN+7H!2cW&*t#p0zn+I^Qb ztiykA_5DM;VQcv+S_IdU{c}J*wz&x{Y+rdUVQP5b5Oz?C>gBTekCbDgS;lgdaRST8P3;By>p(CV%!#$3 z^W4dm+loefyE`D*_U9^tt_sPi|t8deEy1+t+K#^lcuYjCjiPek<}NQ335)&<1yzv+R9{R1(r3lY+~h{3Fal8WTQ^$5`J8h4BHE@SF& z_VZHHOAvref9Io>BBZ*Zn+6T$J- zC!S>K0i`$HH&MfV$)?E|O!PY|3BpGjw=??U)p{mt~ zu_4cgvSRGtoM{xbaYbU1)e$CdvP-5XWWK{58Pp%5esrlRPYxNjOn8HqP65( z2!`zwr*kd?Dy3=c9=jZl2PsEdk4;#mWt!h->x>vrF+avr*c!kFl9rEl1v%n4>JrfD z6qMh>@(=pA=qo5JI2P9mya0aOC-6eP{44MjJY;KX2P1h;BfPxss5Z-TxU*f_D8}Xt2r*L;KV=a*pKD;)o87Qmn05k>TKE#YVNiZ4Uf9*} zGQ2uAGNNl&czKW}7?U zP;CL*W&%)*uNyCK-o_Xm6>etP3^)EZQJN`NxFr+AQUQ-I7#Y(T0cY}u8WfS$wnz+I z5hcif8cut|QTpmdhTz!WA5kIRb`GB%{sA7Gf+pnVT8!V^#x)u%%teL-UogRA!+IQk z;=%fJ>~sv?{8Q~bLWhF`Roj6h5oTZeH92w5J>tY2|Tw!s6N}9s^@|^wv*{?nB#Xeck0ji$czA<+&q{glnM8+SKrKdW%x< zV9vbr+%H}&N`X0~DXy#JjTfiAt|a3Q0prxTizZQtA(GsxR>_+JNG}k8iVYnqmP`Q% z?qg!NYGZXYw~jP|o}s(3*$j${@WkDUVAf%Fo)LDecOw1ipk)<HsG%^`Bmu1n5}|W-|s< z74sIIW+2^-;uMpiVlr0Teq%hI%3H94@J^2kb|%I6_Za*IDVaWX8`50dJIN_njHr@Y zt@HBE(#1MVhtSwYnL+z!wex9>JM;%Dx)bY>fx@|7iPn)-%%_o$=`}1vs&zuDe0h2R zcD#60Y^o}99*;>s`DtBO+Hu%sp994CXY?J0lbG)ug*MPfSFY2`*Idz_z9`FC45(!S z`Wa9k)q*epPpm^f6Dv+^Q6XHdH*1{=+~|jMRvn`-j-#5t1OnA2n2jzHx{W}b`fAl? z%Bg#II<+axki@tAVbx}VM#D+jk{;QZ+9*UF&MF|BuS8Yq7}g3gd?higm;ozwlze+; z*D-2cv>Lwo#!>s)7l|s9O=!n@y z*`KjnIg@%SINL6{$8ii6tClgiF{F{}^*Ds9;uoAS*K-!Ht>JOf2p-QI#p4*PIW9gz ztA-2{YbZA!FTJaay~BuUbSo)mkBrn2qvPXXU&Gq1+5)R?gb>Y$enVIS!-$?|oPHiW zlqO-gBx!I@G3KxGXF$cro3Q1GplCbL-ChP7jyD--NX76t6>(!<@@%{hC+#FQIKhnX zprr&o@~lzcUxXN)NfK6ds`Y-|(j=qwvQ?bhsSimgEHXH(1qQK;H7 zR?;Tt&$Vl<1<-@os;oMM{AC;jC&5;JmN5{+6;E0*oWiOt2HR>Rlu@@jFFq?ppoH#KZC-pWU|VISK<9)Ot8i}3~pEpFpe1! z7soLrldm`rs?kF*=5ILJVIf24eKq z;7vMbD!D6BAanR+IRu$HlLJV|GUS-0HgAO22z~<=<-N;9;NHdUSr2O0y|W@v7@=PV zQ(Ia<$#JW$32{t_9us$r7H7 zh=6Qk)^YAN5;57f0NyT3i|H?`Ww7Jj!P^DKLKwC504CV5bwA`tflB;VLJ`Rl$lI7C zS8^rkGDlt|Nh8tXU#Dz6RLRkT@p3N5V!d`zpK^BC&JKEYXKf(9eexRMl#EU|K;*rg>e5B2HrnZFrcnF5NY&HS_Bq%lD}3a zixk1Fk)A(^%=&gMsj77(j>xkdbXeCC|qFx2ZHO-9`V_WDku|cu&w~~b*gZ? zqfSMXUdGV8nK`MjO_Huf`nZCmrL19K?Q$J^KAKE)q|GgflJ6!m#7>jT3AkP7Cc z#=s%l-+-W!oAa@9joWiEntNC|{+aM#uX9FzvGwr{8YK6)rg9Ap)0YcxX4DMfZ)Er> zUFqeP^hS3(xJ4j$hrLO{uIS2}+)j8C*sv$u>ln6=^q9WvmHsM*VN7s3>xzAnZ)Sm{ z*J991`X5;j^PKTx4!{5)xyF<8p6oBcLaFQn?)t8q$?IQC=(wv#4f&U7r|<;EXI)0~ z0l1v;wJ2ig+0J+q@5#&JBKr}y06!nUN&L8|z}1|M=C?ZIro|D~;Utcl1S1?PxWXCl z5bBxE_}_uaZ`5dr_dA8#yuN~;5^{0c*cbP1__wh3@om zR4db;l?!qY%w(-n7)P%FA*W!M@WX7$3dZcnJrH#W4z#1=#4&D1w}_)=N8f>?picw$ zHaIK*erufuHew+!Z9e?N-l%?zdU3y#vYPO7d{_;ZI*Z1kCw~QOO0G=ZmX%xYL4L*U zMxGhSNj)$+%m?>*!FQCj%{pM5FLb{gtqEpf|9!~d1I@Xk45?)MKTJ=_>(|$C6Yq|=2dd%)a&P8bU`l@GxI1Y zS`NN&D9yCZC3qCCuv>Q!A<~DFx{FxX@J<9ZU!1Kl)*zGXv7ANFm`vi_T5_dw!z&7| zshJ*!OEd=KKgO2ZMRlFJaBFYTkYYulXp$FdQ{{q=H)HpE7u^uNDoV@K{TR%~)_UQ? zV_CE^d@#Ef4T~^dt9i8&cl_Rp47kCJ0@qutFI`?J)(<`MY6KSRlPe0C?;pyV7V8%- zM|-+-nOCeIy&MUTUs~XnP^!^l{dtVrylhUf{!F^gSvF7<(Ortvizg9s{tCA$bDf}A zU&VlhD{!q&ynCCY$EtL|?Sw~Bb+t`?oO z27c*pDqc*QpmYBiIW`Sk6Bw)h1HRm8;hlh9J)HIvcs>eG^has2a3%Q7i=+OMMrr-K z>Xn&{|70v6d99D5I1C(43;zucX#o-*egfVJhVP>wcl@(pWT5J&g`bR*ehLngQC8hd zZLnHqkl(G&$7zh*&|3B=b3g}uL>ql+Hw``wK>t6XK}~b?>CixNUk}$kF=sy1NdK(X z`=9`En|k;Lym9&KCfK`i1S;t)t4`R-q=4b!o55F*4sz8adxb6~yiH4xE0~vN!z%4} zu}p`J1U4njbg4hhv^na3+E`wV_wxuNd=v{ziQRL>Jy`J8pCs0|7Ge8dln-$D)v58K ztd{^Ou8EJ`#>aL(HbXxGM0Eo`k?I78(C)b>5ZpZxy@5bn0C8soLcF-Q;xmvDjia)z zK-gu#u?3mL-6p{W?xML`6}h)U9aC!$uW&Jb_#9l?ViD`L|KK9ue4V&>D;ss9*{}s$ zGRU%DMziIEdrHAuIUeM=XDiCan!YX@hXVEJoL5boanES&hR?9?WT)?hp9coJI6$Aq z7I@L?%tSBm=$HT?pG;7|czN^hU=n;)a*squoj)9Vxbch>W;&0l4VC z`XFoaB5MTwW6w3B)}pJBWqbhE{pe=6qTBGOwY~_Lq}@E#a%@Ne`Metb4diqC7|zp% z-RcS_x(mr0I>g^XG2`bX9*OQoFlNNhkcr!IcIZ=+KrP8PWUD~;_EypF4*tP)+~D#NjuT~*a>L80JO53FN4eIY6_JdQA>}?U4Yf2 zki@ci42k_iA|w6g))kOS?+|pfzCIQK{0l?I05!gK&neJ3VpO%ai}Nd4%uC%_ zB@1l~$LhQ%r+LNsRCy%}^PbGSv`>fw1Vh-745LkEJN*2!n;Y>oif%3p_e_D;QTnx7 zzmAq{o4$&Mln}cVoy^+)0W?BwU(7h2S(m~M{hkJ60=~uo0t9_`1lwVZXIZ?V-0MgI zz>mc?exzf9`35aqYVi#w64WG<&CB6=o$1el2T(!DCG`_HPbdG~+5D1A@)NzMRsOfK z`6ZX+Kc4xow}ZjB!`cetPfl!JxkZ1#zID4JNyv*eOiTWV16)AZi441!msJ72Sh5(> zWsO24ttJ_JmSocTPueR#L;gj6$%OpWdsq|5>b+GwM3zGs=TIJg1Nc#A4K$s{9C29vm9I2USG&|uI)E6C{O3Sxcrp%rr{MU^{3OZ zpqIyGk)i@{V>vF49Ff7i= z+{3|xCXKSuaS$p88V26`G`JXE^QG`7ATu)n|1E%+$*qe|dQ{odo`4?mzlQ>n$RjiP z!h5nY``g;Djo#M>uQWwt30Hu9pLlAw9o|b1<%0|1)Xx~3M-QOZ!c^@1l3GKlV+|qA zjkH)ppx+MfBZM^m2ilvY|Do~Un68Q#ov3G{2Fj0^4DAHcq1%o)P!7VL#W3!Dd9m)Ou*wNIN_dmp})Vr$%GY&r&EB_aq0@%ara%_Q_!UB7Z7aWp+WqN}N+yosXwp9lC)2 z*`2fbl1g-*O{YeF3eK1)cL4+7pfOm-G#URn@RKHxkLS=ixU?vDtl=yr#&+is%y2q5 zUE+j41)g9O3^WV8;1S2Z=Zv`TRc)e_m}`HAgj~aSXj`C#GKP0V3h$H{-f_6XEgk{) zaqnBwjpp*D09?%Z*iGS;I28Wk428Pk!%`f^*!oNb%!aTz9i`eN+rsjI-c+S4>7oB- zWwB=TT)evWFctK=rY-{4ccn_D7?<)LXD=+TTqeCX4Gi|m; z3hhkgE(Tp;0hY5DQqAP-g)Q~#T5L{_EErhI8Xk@7;9A(nYDIw6Iu?yYUyIwsxF{a^ zoP>|yfmGe+Gb&i?kWg8rI29Sy7RuM&sU%cVos3k_)#oBvcp}}ka4lX{e1br#faPyn zpC4(HH;GX6MmK{V^>XV6NWED(x`Ko0Dd%L#8Xp`)Mrjd~OXR|G!@>nPp}<}Rn=Ol!cj1vK;R5bXOPLxE?i-5>j_&W zKWvA;08n$!SKj{wfWxA52T!iP9}nfE3K8c$Ls2@#W~TjY%@6A#zLcW z@vy5{1IP8t9$uvYUmFo1*c%Z}0a}?Squj!}5*q%$vAiF<)uj(WcGxd*E(M)e!7UzW z3wI$}IamPtJRI2XpzmjfIV>J;&{`X}M}>JmPGkrcR{{%jw-V;QxS<*w1*C3hm*44L zSL&VaD@SiZ`g}ppJB!padfs`sRXN$}yAWQEbq+81o1${3<=2RLK#bFGvr&XW(;f<-k7yfM%eupifFp|Jr0&}mAnYZe1HREY&=cUB z4_F~VY#DMv#s_~;b|Fo#tk0pHV{8SR&C3zpd_TM@IEsby7gTowxo9q+u1%ZM^vf z_*C>Fkg0Pa@+n7V1p4YhS-0t2#Nat{i4VUR)@Cx!2l!YB1g%j3$ zTomewv^JYGfajp6IgHW^RoEuue+?8a2R~N+H^lK>n`4cFbr6L2O3E_6eF;d-ITU8W z!&7Z?vbJKqk}C~)7dlHv#mO0bP+6WNt6YrUd7k+B9Kxli-$zf3X;uLn@qdd7U>Wf* zs8=zqlBb3{mmqPImUCU!@CqDZWLVO2U!X=LQLtW@Ds82@3_F%ty78^X_i5qNDTHe} zI&-Od&WVC$Jhz6O`39pbCN(L<(Lpraqw)ml=quUt3OBTW7IXuRKZ95ECy*hoEx6WK zf&6CBuiE@Kxa#GSyBN!A>}OQ_VnRS?^K4Qao5d2PxgMz0OwSzmS3HbuvJ|8{ihHM2 zci_ywt|tLk>*esBBy6!dCRc7ouLsm_t5i99JHqDalH{X6w7}|8nE%(PDJ^KniO8Tn z1q;_tT5ZaM|8-XMe0a0fsn$$&O!cY-0piF3ypkh_>@LsL^@yZD{ths4>*YedyiTf@ zbdmjDe9~NcMnTyS$1RMm+fnaby&3qqg%P;D)mMmnSi&z7cTK|2hC3;Y#Ox|e2w zJ}dqx_%eYDV3y-%&2jXY)-nx#RCA(IkPVK5MSN9EL5DdgXtl0r%{ zM_%ZN50d29$qMz-JBxDZra=y0oRV8J_4SST?1;3iL0nrote3F!!1!=9_a=2kQqARu zVVFs;zW#R**G5KXDs|32&0$h zaeWFF-utBmPu0DtZVG8NQOS=@nLNA}*YL;?5$m?2QwYY>tlr};PyMx(0oA4!stgPa z>JK&GlGJKt$h7-G9Gaz`9qg<0iB77_PE~;fUfqxCQVZY~O|2Pp!>jaZbR^_aqz~sxppx%7KQR$xgU3siD~Gnwti0<;r`QZH7i|`^e53- zEFyf2$!c+*aW29twX`0(m(j@c_Epnu9-XwhTadwg4}+I}YVB`E<0H7Lh@C-pNIoKs zlQ%hN6+{X?1vMs90daU@4WF|xBjUSJu)bJA4}_t9-tym1J~=F7F@0D37WT=};0nWq z;2dRZ*}@{&l96-}&?RKtGoYo(Q$hzLZY9_0790%k94#?r?ufwd!FS*U4)-u0jRwIn zzlwz)Cm`PiG4TJ03Y4bv6Z~>zGy=R-z1ObyYA7;>bL2|!QMYv;+62d#dfe_=eZy8B zI<#jpdLi;@>vqCQ_Atr1F2F3zz}^!&&&S$?^sT*$R}oQy_z4nOM1X@I-~7entv&sL%MSz9y~Z&2(GgYjv&y;}SvpeYcM#OXa-QWLS2l25 zyy>psM*}I}SYx!t&3hrAMLa-s01pr?n1jdMd3X$S9x_PA^Xm2QVW8M|PE26oqAp#(=%w(da8 z!a-*sCkBYEH)a!#v>r#J+4eew$$r@zC^_4hM73{_C*dx|X&~)msY}Wjh0@W{VSHjB z#t@Chf_5+IO9lS$?;1p;wb+Ch;<3d!1br$ zN_wE4hO-do8mdbl3RcZ7>twyb{`k&Xu2{w{^@9H(l9!ROuxG|X5jz|5!4JIP`sgoE zJ5@cJBE6OD{6w3o;HwND2A4e;6;8yvR-PUyW$tX5blujEP{8JC3)_mIqqLqbSfxR$ zb|Jji^Ny%$hh)Ty^@ZL-TjL#3RS}g2?FY91FrXkm*9S2Emp>I;X4jS%%qng*dfq{? zZp?fNB!?6^{n3zW^irhI3r?97c5YdJbRA*@fL?gU@`0d~>q2Ph`7iWk=cu|oTRoeRCjZK2EiK9r;#|>bD}e8vz&ur0SRJ!{+B?N z#@Q_rXB$;P>!%>ewwqFXV*8Tb3LYGv8f2E+PiaZQcRpy@(RQ5?ndfpzh*K}>;7{sN zb9jPg0r;P@Mxej0LEY`}e-Qd&Ec^E~dl1HR!lwYG)TFJqp2xf6Uyrz%4BFi{?wmc7 zITwQ_=FZx5F{}4xvgsyCQ^PLoD$s2LKwEdw;JX8$cT7Nh3y&;VNFHOJ(>7QFshYca z=$2y?LIRoH{T-9lWK5#atoL6T+p!hxUe?P&w`vnRnJ^6(T4jvNgh%^7-_tXhk5i^% zeJwS?hyMxeF(CxXp4)l`cv42&{kBVDbveajier0k7FyC=P(UF9gePXOmCin8erg_XINxo%|6PY>F;Tm!A&{) zDnsIc|2e9C3vs}V{i+p;_pi~b&#!Jk{40t7?BL{muC*4ij>jy)9D5vcW-aMe^45Va zv?60w`;B;F_#-RQOTH1@ZiJzXev%1fK?Rj2UH3EP>P$1;G{X(bm??u3SoZ%1ZBzQgR;pI>Lqi61ctblH9QW z4>BZece$bRG%hl@m8B;GHFpAf4(axFHd;`rMCm+76Ye_^9>!gH91 zdkv3Ao>xD0{cD(I=EAduu<>PZy~XjBm=dhO#{BuH7ls`8?sGb}m}`~%_%1lCJ7A{4 z#!MWaW}S}Lb+UOrN!mutpOaD`#mXsKRBlV;qp|c#H$s zDaiK8IDox^?4gVUsP@C{c*FtJ`{9k504o0Qb(sJz(#T%QILmt&z|E3z0Q)A{VHpQ- zEl0Ll#sSHm$~b_1i0FTGnjFkEAK`+ls5o2JePpL4h)G&5nu(T01pa@TYX1u&?L`

t;4X$!u-!+llIPx> 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


tnUm+%Vg_vM|Fb#57 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μSJ5ZapW8wxJ+4F`*SJA+GnyMiUY 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 z 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%0A;k4y6RBj4$w z|L;MKegttRY(qp0P$M^pJMS|4Gw)-HwZJ{v(N^gRP$N8f0!zLUG^hl0(Q}}io(G+^ zR_GwwD*Xf0=m@A&1!&Nxpo=~O-Gp&}cyiz=(4sFvo2o#Cx?@BT?vKl?WL{;qc8mBB z=1Ned5>TV(K%Jfk4SErD(RvVfXa-gK8r0~58_!py%V-;Pg|pW<`!i>M1@R~tT$#Z$ zB0!bAxZTu46<4f9Rz#e(Mx8k#uKcLNM1dN`f;z>6cq#?+F;Jz)x&110A4d*=8kKXTf?3H-@)Gr(K#jV9 zI;DbmwiJjyL6rt_JBRryM_vOp+6wCQ7HH7hAYNY(uP=z#7sTt!@lzbX@P~F_eNi6* zYSbFUowK=8)c?NyF;{-VmB&1lxK}a9f91$9Z_(QbP@~bHPUAq_MV{k#ar_>R=Yj@J z1M#d9Q04h5w36E;Aod^5)?M;-oZZ0LS2$aDY2W4SF3#?)likPdW1Rh*vnM&?yhEG& zh-LWWyEUePSgJTsqYfaJjUy!-c@D(B4PxI06?z3!X)~zN>!40=a(pMpcXPaqBTdZ) z4OBYL?X#TynzI)`ycalLvp+XzpvlVbx$+uU{>+uXf_T_WLos)Y*$`C87u2XJh|e+5 zpcbG)VW3Lkphgi58#K@QduLG;a*hMtk+7eEaA%Mxbpcrl?&@sZs5vSxNY99hXVC0z3yh`pENHSfOKWq6A#-{#79xpEg*{&DU0bNn!<(mz3sj)K_o z9RK6ee#4blxw4uof2>ov&%1URe&hHcU(xem5ce=He{F-_MG@{m+)liHmQmKU*p%yYN3|ooPkQpDnZaj{CFu)?F8| zpWvGv{Ig~FpH+(9G=6{mw?6+@E5(-o{VQ8{3B|kPuh-@8ujzkYDkm$xr~Z2F3Yv<& zu@KZ~F^K!SMm1W>2DK!ff9@gy$L zP18Vy)-)59Ye9|HfjVsf4SEH1(Pq$1uY)GN30kxr{QdX-m;lkkZ6Kbg=AlYcxxJkE zG^o-uAZ~5}>huD~MZHQd{aag;)4svkZJgc3{E8#zL5(hR zhq%3h`5Lo~w-ER1`VnJ6^aiPOkv*4Jjy%^s&o$2=n_YMVrpTcJ`hwX6x1l3 zBas{tcLvue0n{lOG$;jhQ7WiVA5f(Mphg*>PD4S1Mu6B?L6ydX8r=cvGzr9h1>z~X zphB}il^)>sB5pqnYV;UKp5e$EZvW?3>i>>xN`%-N-9U|cfOyUrM+R_2+$$XSuxDm5 zCo=1P|JH4naP~#!tIW5U?=e4M9%9yy6!UEWYIGB*Qxni2f6zq%pqpBOCIy4|bq3-HFb?OTmGyrr_I_RcbLEMHHRB0@z(Rhwb;z$m+^SC{o+w-{nAh)09 z_A?+p6F9P-BQJCN0JqCQjSg|-Q;vMbkrSX!r$B?g1Qogn;uDqIc9dw>2l1p`5YJcP zNONu{a=Rn9yK_4Y)TkFnhA>BSd>pqQ<@Qo;uVZfF$QEvY5rt0>I>YS?9KXzM=l8xI zEtbR$;^{ifrW|R;?O<+)aXX6HiP@jygFuZ2b7UMxZsW)u9GS|T$6N%e^bn}gBcM)8 zK!ctDUGx;F(6gXQYd{TmeivsC)}d|C2F||E+5Mb725YGVz-4q1kX=$KJy+Don zf;tTV4N3=HbSvnlVW3GPKx_dJ-^d`okwI($5TBeNzL7zNUT80BUIH~L1$Ej88ng*? z(H786Z-98p2dL66P@}z|PWwQE4uCEy2i_m4jPmOx~Lb3=iq@VjpX*7+@1t#l*5sE z9C?r<3**FoScJAg52KCe8gcen&aMGJlgclZelte~a628;=vI!5V&2ZYn>md+8^pIQw+p$w znA>9RDlPj%`#rAN18Vd>sMCJXpo3t|nX5`}UjkM77S!lpb+SeWQP~7k$sg1xfFq$C zX~U6r9Esyd2aY6zI&}u|Y)T#j!XjaY#30Z$sEb&$O4Wm0(E+bE@+(T^*_7;wdtU-0NR}j%iPpa*+Hlma7zr}0j>(n?~z?n;JM5hEyWyop8UagYI z;(5QGHjV&MQ`5h*w}@X-HQQG7S<@Er->+9~y%Vpg6jRkyiuJ8oQ>Xslvo%wV#FEr( z0jIJy^7|ze@!wD7Y=OE{iO8RA0cTog3poAP-2%@3Ci3Pf!pi0Tyc8;0<>fG$#Iihy9n!L7jGS{EyRq z&6O9p@-o+a&yi~!`5DydSB^VJ7Y_fupPKUw|2h8edsoewC19xbE@JK zrsfQD-5Rkc)YLfpkCQFwEb5;FHF_RYXg@~|a^xSNPDeoejsq2{1aT$-)aVST(^nk7 z%<(H6|BfSd&vpOI*0>u=d(b?b$ys#8vVEHEP6_jX{I_K>QwLhJz|afEq=E zI<*H4N&xX26U46-5WiMZ#M$7RIX-~n>D2>I zp6gz~*+rav2-N8jStFLA?z!$KxpDr~b~*ZmS#mU87ruG|C~v<3Y4W60Wb z-ESkS(z~EWySTFMx$gZOIm|WxiH0fqgp@AU2RY8r0fjY*3iTbgii*7^DZn_g~JaHXVX&SfZaC<(eVbqqGst7dr z=}0bGg0`EMfhMg0Eh+)=yi-u6Qc$B;K%HI#4SEA~(RR>H@AA6rMjKBe1##UC)aYYS zr=y@jpMfqq3A*VFh~IZ0jz&O@z60?o3L5k?dc(Fw8_z)QDr&qyg&K3)AJnJ?s8bNf zYmQE9-!+LG?*^*W6T~k;j$H7ny%vzgkx5*057$fqb-It^&L_;I_}V@n;>t(4@^P*y zMz-d&Wfe!(a?N_K*$C>ind3FbpS8V}bNmw!J%AdW0ChSI8uS&2-*^1YE{uF3pE&HWsi$2A39v*-^s zYdP`?*Sy9xZ-6>&=eV;amnGD$`yP%T1XVf&YV=P~r%yTV)K}K2|BmA~K>X@S74ouGsSzMFNH4{OdayWh;$7gbUF30mhgBF4{ za}>v-;`p=nb$N!fFM;^20c!LrsM8h@*XBTl-UC(I3u^R1s+jg5$16B~jN7NV{S~Ou zd5+Y5WsUBlA8$~lMj$?6I8wJJfg@eGraRZ%4C>T}<26UNwOed3R}SOKkz6^JE5-M( zI3BL8oWPZLbLC{NoCX>+9dyxbupB;hM&i#8-s&pOH=ob(pGU9=j+ z(J6BasM4FDMsI^U?F0?l1G;D*=%x?Bnz=j2|G)pGP&@a3qEe+#L5)5Kb@~FtnMTk> zUxPKT)bD>s)V@+zxaK;j(l0$~kCa?JMZ^X*@&+-+qt53{Q;r03O(@rdgE~cW+;=%8p#wg=^}5%iO||L0ofd&)Q|k;YcostKM8wcNyk#q>yVKsx#GEj;seY+Q>C^ zr+R}UJGo{L*X-j+-OrgXIC73_E^*D3Kh$`qiEYvpRH-?rQ7aJVpg8VqfvTk1Pna%T z*_|tI=E^=G&QXId$^dI#aq(NM_V-uqD>ag9ZU=Ft2Grh-K58_xT zO?(a)aeOJqpXBzl+(LjS<1@VgsROua1qxZOny&Ny+_+f4z=k^I?YmTd{ zIQ}j38uQXEqMs|ELf5(d3y9Gay~G?15TEuSKJB^PoZGFqUH3YI(>}@BGo1a;SN1P+ zP2Fqsf4u%H&J5#<=l{F1-$ZQxx>v)+ndh2oyUsU}vnA`+h~rX?&zk=AwQOf9=R59? z+rMsaPL1>VCMs*bPn{mbZ`l8~JmPp#d94IZhDksPh?AgU_$J_zbF>>&@TQ*WJ^cX~j_)&Y9rz-#H`tXLI?hsl+=7 z=SDECi_fP1*&LmBlQS1l`S<4HylUcT>aSl@vHX9Xb*BB#ThEz`(~nar&dUD1t>;WD zj&S~0wqD(-{{Gf;=JNNqp7>;_IV0zMrv3f*(f`h;;{R;E|Ffx_E&2b~XP`L#`Rjej z$%^y62A`e&Z|{*mu95Q&GW&@mkhUPk5`Y@D2X*QI;tUmt(E^}KGv?96!nNGu*CXUf{?#Ag+ROHyJ$3pB_EaSR6H7!1TOZV)4iL4#U? zE(!(}N&;~$71XF3s8dhSpk5$Gu!AZM0&xWp#Hf4Fpi!Vg<3N>e2XQqS)ah=}pvj<% zrhzzW1##30;;0qGQ7ecucp&})0>t$}ZYK>C?am;U1XQRevlp`;a}e`B=5kP_Ros4; z+q*$rPvpo6j-2Lp-75~y4-!+o1md^?ROoe%yv31sI8w%u{oMYR+uw2f2Dd3)Osj)9 zp93n?5LBsgx{A0z$6Ii`HOJe5ILpnEB#w0ENH-8$o8$dCp3dL>P^VR(LC=9MdI3~uBZv|2+}_UZcR`JI zgF3y>@qcjqV~!u?_-CL&C$Xk3I)k>Gsz8Ol1y%YE#9zU1gfc`#2XS2q#8%=+V{W(P zb}+XixE;goWNxQ$`(|$U0Wppm)G34GBRM{n@_ zs8Rv9i@Ci7#BX_yJj0PS+}^D(RyYLp4;G@9dgaC{QS@8QS_j+AiwMdqs<*)mv+MtFxKWgOWLVr(9Wv3VT-pN-7? ze^dSMk8ah6h*vy~Spur`BDdp*igpr+zh(k;>IUL(fvJDW(bqG0u}YpShUhk8t}<=6f933*sy;h_kpH{}=OT z5Ti!9Jtjc3|7s*{w-I7qJwc2+;&wl74+8NW!I9w{8O4!tAV&Lhd;;@7kG8!VH7ZT! z%4y6+9C?`Ak8%465T9%yKG{HgvVj=61gf+S)aYeUr%j+iuY(Hh05Mt##NU!|>rnE>R2)DTIN9z*DSbwmD}HQ`=fE9rfZhS z_5c+c%Iy&#t`TtLPLABg?P=Ve&g~7%S2?l;#2IXkyv>oF9NEK>eH=N&kqQvkgFu7M zfC~MmtcxykjX0uKxe_BVxd+h?&Ln{N4g%e>(s}P}A1~^iu?{vHIxuW8VrbD)bZfeKv#RjLLxx(4cWgX29Wi1;la#yWyJ4FoaLoB05UN9lqZ z6>?-H^BIn>;r3qU2OK#FVvhoK`X`9Lq6Kk2llcpX@7{@`#sGD)K>Sq&GZ4h5F1Pz| zdjN=$>L5m{gBYm}x@ZiDC1gGTVhOqZBy%N4p5gWz%hvpbNy61#ZW1J08Tm+5bBjH(RV%BB;<&Zhr=9bQ09*3}{dlSo2-he2%CWzwz-)0mSkK+ID)jV2?|66GObb-Fav6Q&GKzrP-BvR>4pDPJUANo=0 ztz?j@4pf4ur8*0d)@pCG+o^jf2v4e?rHsc^tCa0@KvPwJI-=E6x8r_qs_I2&^jT^{ zI zOtTbmH{XU#f2GKkpam(Vt{&hfv{%wfJZpC)i6`#Pqyw&7wT{Yl*97#?);(S8qa?ZK zY8Kx!ZzlD17oa`beV!W9boV-KJo@}Z%>XxQ8OmdbPeJ=UWhn2tKSiX>U4iyT?yt~3 zigrG-;rdcASzig_ZWZ9CdZ|)whH0hB5pxf{#*vQ7H|7cbh|<;aHfGX5tChBtZngZ3 z?TUEH-*&~v^w($N4x%lMl_Vl7X_gg+_F^j%^{cHIEdM5s@5HnIR^kqE@y2HgYbAN(k!3;D%*%4M$FenWl`0ut5#SiFSnxit0nEYRJg-dfU9WkdQvX}mb+YPz z4>kftR!sFpy_xP2s<^XIDDNAk%GmnzT$9wh>KD38mD%+lc8Ah~^=GM*)C1brygWmx%I_xQ+A`*~v@Q^ox=XVPi!J=ij{>)&ja@;1Tii03e_ zq(^j+eGM9b zvl?tiWL^VbYZ6}5PcS5XL4)SjRki(1Q|;?C@}@c9IB+GVeFL20d!ACz{zP3#g}&?6 zG}&J6i+jiL6LI>>$N`Rsr{WwZyYYD%!gCzL%QJ+RCmZk0@OndddGcso zlt(8U&p=!(TOKdZdG(vd^Xdg@Vt=@fR~zw^|Qr?S-Z&6n5r$JSfV+zxiNcZ2_G{z3ir$~ytr&e#Iy@fp>& zRRzt#vJLY-jdj@swh7+hy_h-$@Aq!6_6t7gE%ugb?@8$S5KYn+2LI-r&vRJ}#`xrG zc1WU6C=CtSL;2cWc$UO58dRmfYyfMPEYh&=qmRC?VZp)_%tkIeiVAqeN`(Czt!)m zwuZSqd?MN(G0%q2Mf*FZ(e`n)gP5sp*P%TU+=w+j;aAMu%3Q|W!7O2xG1oH7nFq9w zBVMR~K>M6|HsT_d>N2-~;P!7|1@8$5wD`yhs^s=r<|Sq|^9EDreb0;O%bZCqquMqL z;P!6Szuur`q1+Z*ep<6gv~iCdWm41%v?oW+QX>_ywIh{jQTxCz?B@`l6ZK-VQe{EZ z%gv^!%c2V1*J))G-u3)SZCAwm>wwlHdPwsF+R*46aAI^3cprFOn;f+ntky15L)34t zuPCoXf2Cd5&PDqLjMsmNuE2gWwth>r)tG}cNso`&2i^j%q-SID1A=IK4DJd~AA&RK zWXv9#sf*9dBU*IqCcM^bV`K1Izk<5}WvJp_KnJuvv0{53WLCsprhL?&r=?)O7E5)d z{ooe)x?lUtv{(;ppX#+(4{x8@qEzqh9@FAAeQf*NTa+r(+D}3a?{)g@_7&)}p#46u znE7P;7wR9;K5oCsXNvk&`|T}u>(Oy9)K5^vewCnz{pyG&?lpTv6Q4OF^he|7w>+YW zd(j@y-i{Od+uk_QTX~$=C&it759mLl<}@{o|GDLLZB7)mI-=hiKf2X%eN23ItJC_t z_%Q8={#N`0t+0RM3EkrJ99uw{-oZDhJ6^$km~S=B!Y7G%BI|Ws+;!=ycD+N_Ai*>+ z1W&pa?8h7$l%b0I7#-2WlD-K#qPI)>A?Uaslk_XHo4pf*1-k_+#@k7!g41}78XDEq zJ0y+ga#ib$=k{LJ`r~=MSGAo!AATT%BgA{T2Qs)ROT; z*sGd&?$}lBc|7y=s&;}|*{BQJm5us^wlx}e9*K4$p7VND8;9q+3a$hf<9V)vZ-fp( z&-e^fUhI4h?G2qTgPS_Lts%bE}fwBEQM?kcA(=yx%44!kJPQE6dK9k0KMVivQ|0;JwBdY(9D8=a5e^gYd(zX91Mnj`N zYG&$3lCq+@V+(JupRYaAe{s}nSdyh2Db~(w>-vXj`P%0GJEG2OZ}i_6m9OpW|B*6D z+uOe!?c@EAMjhaNb%gQEfY9iM`lbQx!HNM%(Ibps2Xu)(uK5q_gNV2T|8XsPV2qY; z%*2yb7Vwr_Oe+U9L8O{;OpD3~dBt3%3Pi5b$w7@`iut|2*bsYihUzuAPy0T)xGUjO zBYbdXi|tBJb!htq_}rKdR%=u1Ex=Y9<{d;+2JdaZT@hTMEE;?e?Utw%-z;b1#F6Tm zI7|P+F7>hW=kcTiOMi=5jlVLp@IGxGe_RV4))kBz_7#>nahO>0Zo^7_j%#_`o;z$5 zvb%;&08cQl4x5IyGF(*Jc)GxGt<~_w@j-eO`U%pH4lnfy(!WABNEdhi57Nb5|ATaK zxBnnr+~q$=7te7RVQ87#;~QcbE|WiVgs~vA0zHVx2;=R{Z{pj^_79m}32X4V@lb;J zHjL3m&}Sn)PFTjT_%eRQmthOfQcIYxVGEz9)8vIaVxOjfv3t<2rlE5j2G@Xa`H z?8LD)6nbFMvD7z6|aj`+B07W0$0)iSe%vFVz=>V)*jkzEN8CH%1b)JpZo`~ z9q`GozcBtFZB>4VUgf@SY#qP3<3`-GdS^%R?Qk3vcdS03i#t`L9(Sk~pLK%b9@L8K z0_qRw;=5)o??0tV``cbqMCJUJ2e5}MN97mxi=Eagdq(2(Q_sH*pT_#5x4qHnx+?A? zeVtyt?IYzny?$FoC(9*Xg@&NrxeqVf4(0vqGo8!${adCydfShkcktf0gZKR1*glO@ zb|^n)Pp!9u_u(B}*+(zAV@!*3t|{kusgf{ZQi~CkGU4--a^Ay>Ia|!%n8k9c>IrI> zKKjR#9_g~%_~@=nT@rX7=;#_=uY!)~Q>IjQJ)%E9z_Y!N zgZt<-c%IHPP4XiRH!lld29k+(IxPi<&{JS0ZB)EzG+twG%A$9`Y$`*%oNEqqO$GgI zn{7|*ei=Xi?eau#zj$V;8+ZBPSsHt4I)1^v`{V1Swr2C4;M zsJhS_TS@h6fUTrvfD_eaV2=6;n5+6W^rk$u7dS)R0M1dr1Lvy=jl5}rx)3Z<4}-;O zubaGSiTVJzOuY)OP?LSVsYERWSF3)Fy=kpFys=5^Rq^UE)Sn%Kf?HL-=)YyQZVa(1I8w)199yk1+i zAKIF0riGyXIM-Kd;fS2l zHe#vHYEfvP)8fEOS`v6gO9893?x_Es>#u3IAaX>Epl#dN%6) z@jD;efjNMA4~RWVUlol#N?#q_h#ukiE6n$qUojO!RQfRk46(%mji2pC6vUBGLu|Kj zL+q20hS*}UhS*{WhS*}shS(=ljF#ALUAR8g5L+zG5L+ypBNL5X9k8Dp?}NFqrKUP z^0H_f=4jCl^k&g6^kz{Rdb4Ohdc(Io^Dz3fa9_od;4$=RQ6>7ca7V>+;928G@SJf2 zyksbeIOD{fc(ejel*6ZLL!Av1(PU zw$@$TtANk@bI$qQ-|yZ#2|U`@^Xl^i=6lZX?CbY@w{vd4Mq_usMsIJw!x;T)|DF9B zv4f;x1W40oiv8L<)qd@rM*nYIi`_~8OMuVme;M#_|0{qm?tc~VrTwn~zOw%w;A{Ku z1-`ET^}sjvzY+Mm{l5)7(*I`QANIcm_{aUf4}53;TY-Ppe;@F@{ci*QMgQA@AL@Sx z@M!=2z>oF+De!^*cLD#g|J}e(^}h%BQ2+aY|I+_{;J@~N0QhkK2d_QJtUuxE>rOJ8 zPI%6B3(U_>P#+&XL47m})W`G!^=`oe&HjlCG)GGoXpT-<@TJSa01G~JJ#)Q4=^La! z$^7wxGjBM_ym!GS;L!yKZeYzXP?_I%X@2JXk2=3usPY#qRP2chRl*V%a>_!D>gfwr z?;00-u8Y0E#jbZDm${IuT*!4U<)(#d;nsy};mr%x!W|2R^LH=&W7_bKF4w1Au7_N% ze{r?^tIPZFLe1~j7CKD6&|z{{+K*hWpSfI*x?E;Jtx69FW1KjkmMq`gRO8kGwf|;U@{R%Rtlb0JS$hYBi*6qf z{<(8N_~+n&`Zziu{4+iv{8Jnd{%N?nW?fy+adjPbb-mct^-@>YD_vc$b#=YY)%7M< z*YCQzj<~x1aKKR7AG;dg>FWA3SJz*-@;~ItJnBmLn2UX2K%@PS1KP8n8ql77Xh6I5 zUk0@IzwJip`!4T~T-$!;+V-d`#|&ze(t{d@1%n!g69+X8O9nN0dF6?a1$r{pw6R%gYL{4 z)Oj>MsFSNWsFSNYsFSNPsMBh8a6jkHa|Zu_T!#mBTD^Giv-n>+ce!u%fR0qycc+6@P7gSa4@rlT`>44@STIZww`4EZ18u0?;U&$_!ooghE6gc z8vJeG(ZR=uPBzVxh0pJC@DmPx#lc4$>|3VTvmLzNLF-`C!B;u>83&i1qLg%{D_0!aquw*m#$En4Gs=DxX;0YgL4kP%E7le_*V{o z(ZPi)U0w(8a&QW`&KUF2lfSY}?gvkPzjOcLdDtS z_lGAx&$+*#o@|QtQ2xtt?@L{hmV1Bd4HwFNPwK(+pM-F^`u_WbtMu8l&wu0uA20X* z)D3C5ivMZ|m#gnBp!NF~zajNi+!rnV(KTy1;_gpfeC@focS9$BEVv)XReHJir>?nB zuIk@9;L{z%)wf)wlY4*axBA}^zU3AUFDU?Ksi5BYTo}KN{REi~aY*xJoBi z`Q)l!2bYBUa20;|WdAK!^~+WGkq|Cd;c{L5A^d3KTk)Hg`Eukco!t9VsS^%{aJkX9 zt2cZf4)Jmo{*KdpIdY@#`%{ly`Hc`R_x{w@tK=$vc)3q6_x{wYuac|qgSc83hl6_r zSK}d9;c}HuuEynP2>*BpmwSKep{wM&aSZX_2;Xv*AI8X)w-8t9UK8Rs z1$Qg1*2%%}eK@!;!&QE{u3aJgXmCGHwl`mKE zn}T~VxQ9c$T&0(*`I76#D}*1xRXK8_aHTsMz8?;*SsB_9+)cqf7~I3bJrdlb!F@Oi zzbcFauB#7M^R#KJ50|TOx$5`95H2_RR{X<5z8`YcFS!ag+hW&^AK&+Xikj%ZKaIW8D_H3O^FQ<+|@@#jesFxzo2xu8YT2_|fn!SM8ST(qot8(&0wm zYTwcDEjRjBx{qPOr1dd+(7Rs??h$NlTsgQZ2gbbRDqMCdZXSbs6xX#Y@$L2p-%2k# z6{R=%Fu%dw6x@TsJsjL4!95z>hl6XzL;m1y3hu$+9uDr2;2sU`!@)I$kUzMaf_pHy zhl6`0xJQHgaB$5;$RFHI!Ice$`gb_EM}m7axDN-{VA-H_vYn8-DYyrNdpNj9f_pT$ z4+qy2L;m1y3hu$+9uDr2;2sU`!@)JBkUzMa60YV?-n> zM}zxta7{VX7u-$3Js8}>3D>PFzFoPvTBk?Cx7_GkjGhl6V>p}yd53hu$+ z9uDr2;2sU`!@)JxkUzMaf_pHyhl6`0xJQHgaB$63$RFHI!95tgda}0ihr2z`%^>Ld@P-E`#WVWfI>QKQihAn z{3ZrAx419FJq`CoW<~1U)QzcUrfR7drv59nw&%*8TY3)kEbYCzcewZ7-Z%ArviH&6 ze@j>U-rM(3-{t+q{?GQ`e8M|V`1lDYF1T{Rjs-Idp1a@`3*NZkfd!vm@S25xxbSZV zzC5sHaNmj56JK%S2T%O`iLYMt$fCy=oq5vMlm6tS&z$tFlLi)N7mqJ~>Ed^t_P}Xh zIqm1CEn9xk@}cF=UjEz5A6mZn^b=NGzhdpmZ7UD2{PUIXU-_w(Us?Ixl}lFLxa!tb zZ(8+ttG>Q!;Tdbsxa|ykM*WPJpYaE0JaEQoXWnz>zn!`DtbJ!S&wAZi51zGr^`_Nt zTK(SDf4ll?t9#aLTa#UL&zkqG`OKOhtXX^Z#b@Wve&N}#Is5%*zu}yZobylTeEyur z&N*xC%-R>Ny>IQO)_!*Fch{!Q9XNOCxgR_CljnZ-y#DjAxZqDO_|iqEU3|vHcVGNR z7e9RQH!gnU;#1e1weBz1{hxI|Ubps=O_$tpN#&APTyo@+4`1?sUGl9(a zpT047*MQ={il1Du?#gXf?!R*E$_K7|!_}X@`kmK&@|v@* zedyX>UORZ*dDs2(bx*tg``5qphELt_+#6qf+#;`}?cRa9M>c>iZG3#uJIn$hM zo?=dCEv_`{%_?&xlHsdq`%UIt^K5e-GT^6}N%K@wG?$vH*=VNBWu|5>Hw|-zc^;`> zV6HN+GB=nvnN8;R%#is*j^jVahUst34)gcsR^-MzkzwyL4BOw@Ig-Yx<$?A2mOq-Ko@1fc>eT0|!%&14nvZO6=`D zioMIh$z@9O{gYlWV9bwtUIMHxQ|#=rSK@!(vU`9pU-o+7>z2J4_`A!F0RP0n4=np5 z{QXPr2mT*d&ObRgy+Sq4E?c+An7I`y|Ai|y;=k9yx35r{?{?6q`OwPU#QG2)`?o8V z{$Ez^1Acp@+VcwseK`-D(SMRLpFBfpE?$tq|IixM@`!_r&X)fy2RAzSbO)b(_BbhT zKS#CSb&g8TIG8`@=Y$ts_|!QnbK3d;=A2U&8}s+h|F-i~=AStDuJcY=V$6FT{J?oi z^WpQ<-;cW32ORu_gO6@iuGElVzk`DgE^+Ww2Uj|n9RKHDb}hxJe6L4#?q0{}?Nndx+IbuP zWA%D&XNK5^_NaxQbMQ-hw64DD{EPN#{C7C`zxJxN?{_d-GrzcWzBRLdpXO!E!KrMoQ`^4h;OsJ$^OXKK67JX4b^BGqt@}0aKJP&nQgtCO-2WC*zIy+C zz~6K5ZTrK*UE zs{C>XZ**|CgU`C-&k4^t|9?IED_4LApRHc>9#D+~4xW5K?L6JVGY@>7G#4KD4shK8 z^>m|y*EzWLfW~Lo!JQ8N@SyVk%)#6u`5!x|@_TGt%R(F1-v|) zGglk4#;V4P9Ng&O^$z~~zW=z!n1A2*9pJ|^O0zgCxGcB&I{K1Rjd$kM3+v!mPBp&O z`Tr=V)%64C|Ecpo>e9b`Os~3mxF@f?`}10*cjmuFxE)u>*!V5i8?$9X{+lQMH~wU< zq~Bwe?@j)MmOSd<(xUulJ9vYGw>!9`sn(wD;6?|xIp}dw5({~}^sMH_8^JcstAWpJ z-Uxi~7VWH8H`UsAG*!!o9rQTu6VCr#2Tzz*>>3BJc5uYOnuE`G(Brx{IR87QHE!>B z{*%vC-fQkwYcG0^{Fga+or8YHhn}->(Gs(qvu*(=obE8_%)^o!hy)eu-6duPFvVY= z3q{Yz$)_`MC6HGm%?a*gL=MYoxPX)=V7H`Oc)Tjd**HM#YG4oFgZOVtok;jTAU5J= z5$Okk3(S7xuuIJCz!cw$i9Hd>o5iUmgg*<|V=lzbb%D798Q&6fCs6FzGQ!7zOU$!V zrx1G=kk|jsse~7ROU%L4X@nmD_HceKC$THa;6IdFPxu_L2m6c-!0$ql@NOOS2)5TyBR%F3s2A>> zm}`MQGS>rtY;FYp1S@Oq&zLR1pFyYaRuoi9kNLS72L8g_0(=a5C1oB5a%T*h1tKH0 z3;&YTGw?43a_cxXf`6HVr>6E1a*BherS=oP+`$#8XA*uoFlAPy?!dp&!81~K5pt%3 zt5XLEKg+?hvDM~x!ctk_+EfmBZYmEvFI50OB{c~=KUD&5NL7HBrlx?`rRu=zQ%&Fv zsTtsnsX5@L)ZM_FprLqiFZF!j*3=7tL#Y=5?@s*&@HwfM0H2$B8Sr_jR{)=%dKK_+ z>NUU@r0xL@_uNZspAPIXJ9=J^|5hNs`_=PC{JVfXW;a%7yh#n@4aA-|;~xR`n7uu3 z!N1SJ{XM@=$ZZbZj;%Sr#np2kvCjhbm^*sjhW}1r547Cd@jn~L4fdXQ01x)u541gh z3e5Dp3z+SBH*mD)J-}Sg`+#FT?+504J^&o=`5^GMy?+I~r}wXcukZZ`@D05m1-`NO zZ-8&={X5`q_kJAsJH7t^Jkt9K;Gg$?68N6p2Z8VH{WS1>y`KSop!c)1>chRC!~fU4 zU%-E~_lx*H()(rL3F)r@7pA`o98CW^@Wk}jfhVQE0bHE^7H~=WJHVys?*UIvKLT8q z{vq&`^pAn3rhf`NE&X4><>_AlSEL^Uu1x9xR(>GOb>rOyXmp1u%xMfz#LE7KPPuS#D6+??J3yeYjAxFvl#aBKQX;86N% z;I{O&)cEZ5_4w}srp&?gjrb1$Qznz%jNbye;hEloKMPEmvGfrB957|Z)7$aq9W17Y z2`Q&b->GVGQO<)Qefc^Mq9Gpu(laRa9cMx(2m@>~z z--Z7<4n8k^0RQvT7I+w41n=UdbHJCU^T1c63&2;VCxNd@mw>NMSAefcPXS+>t^@B$ zH-W#Eo&nyQo&&xveK+v+>E{C9kbXY!jp-Kv-<*CC@JRYMfNxE|1o#K(mjUlfzXJG| z=~n?in0^iLL)a>Cw=;b&t^ND->+yfw!GB1<5&whf-v<73`pv*k^CR2b%H!v)d0Q?0 zR^aE;_W{3_FDex!hcL9Hzem8Jo-+O=qeeVNa(D#1e zg?%3YUefnL;MIM91-zl}uYp_oK0H8@DrvusbeSd?050G8o_jmaB0#jyx-^cOa z225d3_Ye4Q2l7fq-zV@t3&^e1zE9%66UfU8eGlS)Hjp>{`#z2TATVXJeV@Uf0rF}< z-)HfU0y!)DK8Jq{m@N7SW&A}TZ?N`#1%DaHdlr3P#a{)c zOug^l@z;PU)9m{?{su5*X1L42nFUOlxxR1Vp9Qjt`o4qz5Rg^W_dWd20dgn5?-BgZ z1E$Oi`hJN2Ffe6a)c0fjF9fE{Z}j~X|BHbs^OC;*!vCAVlzCa-FYsdxg8vnLkKung zFlAoV_e=b*1o8qxU#f?-2jrKQ`nb%)Z*BJCzqhXs|8D`g)!BCf{?|G92JVxv>iPzO zZ|PeE{Jp-#z~Ap%3VdtdGSc7IcPjor0G?(3t>+U^0blF+B=A3a9t8ep&!>Uk?D-7v z+dZEJez)gy!0-2b0r-QSF9Ltm^JU=Uy?;sxXK-)mEb!G|0oSDe8hB3nBfxXh9|hi? z{si#O^e2Hw(w_tVLHY~8KTCfR_|NGt10PC%1^D^&SAkzke+&2@>F)slGyOf_H`9** zzn%Ue@Vn_B1HYgCFW?W-zX1Ly{TT2k>0bhWmQM9;dh5OPCew+5*biL=F zdVbjR{1g6j!7mqldf=-A-y7I7c*o$g2lImygF8?9z~Z^(?_K`A8Bq!y>a@> zPXE2r*RI&I!mhY`#c!>6$BMsS@q-m7uDoRBGgscT@~Tw}S1(w*>fA4#d*1n*&o4Z+ z{?s2|^uW6N*WY=0_VVXm{hL?6{p!zM``v3leBCwIAO7Dd^GMGh1Aox-P2dlE*1bQ) zsHG3dTD;Sk16 zLg?8Aj;8I0YUM3tDBCssai7eb!{1@^e55;}jUkX{#TUmv)*!{W|vMKWx z_kD`{En8zYLr*E)O(ES)A>9@iZjf;L^jkyvABOKAhVLKqtp@h>svPb>2lp|sn<5?q zzbX8ee6PYHZN?>qeUFJEO=^LG`0&*1Nc{QVVwKjUxX>FM65tw{IY!e3!UfA5R< z`yKr6=I@{R`#ImItW5V_$)8>M)1KnFKka$ZxsRrAT=;nUb^L7@cs#x7DUYW!{Jo36 zQ_p`ieF=X%&VM|8?gfvh>-@cuzmHy!?*05gfA2T>`^mtSq~D(2c#YYU%j9O)jf^#_ z>qd*k#HT6Mvz1!0kO^TsbB&owZL(0#hkz}WQmIllBXjjet`wYgTPn4jx$f4=XtS8R z!Av%%r_8R*L@wJfx!i2l)XR;ce4_$6fiZ!+$>$mesxwoQrXG2wZLyh)!i!OOF$yU~ zo^ljbHpAscu2!sMCv&4wd-jgka&}aW9xi8Vxl*p&Fzd37O3hf~>H`$zD+!d<;+h$q znVk@r6etSNzxw!=aa%6uqA_AT6jK(c2vh~81Y8Mq`CO8weABMIjm-F5OTPROAU zQm`Qe&s3q2GZ~Xb2S=|qUdqT7Mol)ukZi8yo9f4|W@Fdb9$U`mhGw(5YNNnp43(z~ zwMyA_Q$xD9ke%F8Y0_y5WT@f#ZnceZz^w5@V@8U(TvgFbf}C+=rUiJxNjSbexooa5 zoin!<%C3!@r){BVGsT<|7GMC&FnA-m@~FNiVC|-0-CQ4Cw;CCGGF@p*)2?R8xEVcg zz|^|ub$Z5_0A|%kYvyLS$vl#+ny}zTa`n2pHoUb^uU6`=_N}=w+blMAS85D! zVT|D~j4}L$F^0b|#_$)$82-YTi)Hu=W77gN0<$zGTX9RmFWq%}bDF2Z*qp#2K;D|+ z5iO&}HmkLwhS4^t|^F?mXYVZzjVEas0CUa(Ps+8px`Q$jFga%>*zDM<4 zKwvOqW;^GMO;%U*1ow&OnKBnGRJA#)t*4Ze=FsscFDkNVtTnsJUEQIKlCc?MvrHNy zJ!8j=%_EZ|@lAHVK9Zwswle#B3nh{ljGZuc(pYMsq_VLUW2?qa8C!GPx0so$u*qtZ ztu3&(QYqFwK6fd?#!{lZ8J{g=&18d(9wQhbm9VzeX)34(1n;+JZZu9yd{x75i-pl$ z)m+Uj=eFo6l~FU>x0sP;wW?*n5+nJcoC(F5TPx*)(DjgTI}Isls|pbar;{jKVQq7~ z(9WXSQOWPfO@pE-wr;GOmxg8~uGKcpM7BI@CaTjJ<2QL684v=PXPu97YoKYY$KIo} z(=!YWC{n}VYuZ~GX|R*?YQUuGoi=tx?u=>mh0$anHrMCM**&>Bh>O)%JY;G!Byyo! zY_XWJY&3AxoHEZE5VV~$_K?X~lgXG&*6g-5TiRT!*}2UPs?0Rm^`JBB8dJ*@nvrKF z@=U9!Ig=SR84i;%lgXP5$h|U2sRfgnFquh{(O?y+qhvB=u!tYcdagE|tL?NbEAMrv zmVtDQ$T1al1DYY;d51o|fGY&t;?F$16a;jF!;4}yWW~U?hNJ9v0SEgPmQe2#Q zp7NrzZ)dYuOiY`ffxWeYrwVrD%6TR!N*pI-(ktpN<5@A8s>w`6h~9vQX6HKB!+e2i zZL_XLG-tA7GZSW*Rky#!d0o>Qm@r$QI2t)$lsnM1J1fnG^T%n0Jrbj-&t2{iuWP|Z zUImXNCnNfF6QX74V~0m|VvL0|!!3XWw(dY-W~7iW(~DZ}X3KF?%vWgsc*)~|btAcK zlkd58TXMBfWUlT?+)}8H(@UBce6D^!9*k<%WNIc;H<^aXG&Rhl+K`YAP1cZGOI2I1 zLqtNIv65Qtylyjfc<@| zhee*=1ft7<65EN2cx9+SX1h_zR*G9#q^43mFf`Q!7d5mYp?EUWCNpC)vnJzCgzfeE z=4yetb^~w0qL7y@|CS=l-Hq8^Tcd2(dpBC`bD4;x5_aezll2>VxSkw}QFBuPDytsR zLgmri?5?rREJ3p6p$knmYqC1fisL2=UZ@lctWND`s0g#O(h!1$TuS0+&{EBeO@g-e zRF(RA|E13U#PGGC*@T*h($dVtALyRt$t;c8ak!**a&!XnnsZ zR#KM@hd{PzvePCzV|F(i+X_XNE!==D?iR@_YN3&H-hI_#g(DVvzGj3pD95#Rd@OJr zc*ayH)yGJomSQdp&fdxn zbK$5u%C@xn8VdbjUG>bE{u2#jmqR2{3b4UeD4u&;v za^oiFRuR)VVOW0<5FqqIrDRR6Y;qL?`x=_*h$&Z$Va7!t!4;X@l;P9@88E^G(Eg^$ zO`F_|$J{$JZf<>riPU8PJlP%C8%h|N(n;L zH-V^v850^Sk+fpqPTf)1ik&p@s&K0CsidKdh8b%b*i@KQ0!jux6^0ac6lRnF<|boc zKVd#$>R>zxs~8wg*iE=fzN#iaA$Q8;Ck>oo9$Kii)9S5?;RHkil{g#8L1F^x#$&`* zB37asDo9HHhxmo0oQ?KgTow^-^oTuV#;qC8nDMNM5M-;gSu?KXQ<^j5;F~csp6|p> zt)vtqY+k0Ug5h1W@kujYjL=1ts!TN{GhR016*FE{@~jybD*+lGuNm;!c*Bgha78N{ zl~0@T8Bm@<;y`kmawysoH|L75D9~O`oV6}&6y#Z@D#*4bDyslCgr5Q1ITpo{;t-h- zfrZK;Z*l@B$9+ZU!lQ~d60Lp)=p3E(JrE)o$*gp z=lS{siNSCLNdre>2Wvh*_n94sz^LZg%7Cl@v&>@U@EPaiO5wCKH|01wgH(c( z+cSO@FC+!ChZvY)F^Uvfpvb+oIVLX>t*8&NWw;CfyD1kX;g#FvZp z3a#NfvjTGhhs;fL?u;@8b_aW529m4*#lxA<;7F^2q-G$+ z;Oq;q@-srfo={deN5HJyyeT+_BuJ+{Vj-N}cF0VyA7>!KSQqe`BF|=vhXCed z5=PccjGBp@nHVz@dE+=)#T3oNxS2o_OnQjE@n&Nb%2zQ^rsnf!$QbNf&C$d#N{^! zVrJk#f*Z(#YoH9}fK_~n`q1RG71|2yC|BVQS35diUmjPx&k4q{WG2dHqJqrHOiY=H znxVQ@RbAD%fQ~BS;uA$5cU=8wRU)yQInW4LUBW7Dk02!J3Wxefj-W9d6Tbs-EGD4! zog8I#wS|n_0B&j4Y6v0{|2JY#VA1q$SZOn9(si$T1wTK2)nAp%m`| zhK5}cAsl6)drqj}(>PXR{)GF=*&^Z*#$GB8pWMrKq9SgCFm^IjFEsQ?T7wW(nCyj_ z&D632+Ka4mNkZfaz0-gv2S8EDZ>o2sj;nOI3?17+9knG0>^jSfQEN!2Qc#v`_$aZ8 zEVQdOFC%*lK}=}bWX4P)dmc4N?kB-?A`V(}VP|ZN8F+57^1k5x|vSZeEm}kjxgO@2<^!UMB{%CA+<0@&GEJtn|8$dNtSWv4y%`o+xndS3 zDkuoL6T4%`ivYJ3YV}5U3Zw}QiHgH%=C)aPs-d#>NK1;j8yyktpD$gVZ42k^)ilb~ zohS?+lzs_CU03|JW;rXOE?3IrYBLOtm+g&D)&swu98JHw+CsF+jyI$(%W)H^gyRge zE8uwXew#x8Bu3t4>YNUT!snX-mwMg^l|BD#xID**^0~U^CS>UjSNis8@-6abQ6OCgTxeN5C9?O1oBq^QjrN1*#N|s6SZk! z8Uz!g2vh+j0puK`2tNT;0R$SOh(I+g<=G&!#4{F!czX&$yrv3IA&Q!aJd*~MU}6PN*n^G_=rLU1Tis9MnzdMikh{HY9$44K8O8rDc%y z<3T-#06&8SpX55F5d5G!!EK41om`Zp=XErf+t#&&qULak`tk3 zP%~uEEM!nEWY8^SP%dOp3S?l1GpGeJh}+3b;jEqvQuhozTm~8;1BsA>9lAOMl(G^#8B63uB8M*u{a(u-3;sq#8e%&1a4m}FZModVM-K^ zPt3R)QJQ3sk~ji4)D@*^3sa&t3b$hnqD;q4qe41|HpMp)(atfX{sMFA%aY{qNp&3IX zhUSZy8H47l1PSH_VAi10LWxDhoI!DgwhAvLPMH#??-W){@ltXlf%&m1HB70g*o-Mr z6ZFRvHpHDGWWVDmxRD#hd>y@EhSCamiSX%;PV5@$*0 z#P{VxrovE6VV7LVm^E3rcEKC0W=Mg+KL;aX;Wd0SSqHHHx#Q*#*Ba44hm z(8rjms0njaMk}bDim8x_T-tF=%#74aD3?YJ`fQEKaJwjo+yzsW9?DcnucbGKAu|6@ znqgTT%j}T)x91v(FBKHz8W|%m# zC^KeQ4FrTRsxtT6f`$(HQc^Oyy;#XeJM87OYNrff5u=tHAvN26M`ecGTV>cy6`=#I ze)@X>j*nq@XHCtTTE-y9MT(0Ix;AF8%_U~e)UawQU`cPV=&cnEt;dWYOn(DyJ42br`iSM<)^FX8yR_fmE7n92HER zxSaq8OB}^kO`YScW-vhtvbN!ROS0+u$*SPifL|V7Fu<_+W$!9iMKNo+1tTSSS0?3{oih7w6 zrpoYM@NY#kQzFCurmGBf+G>X1XD2<`8b#G%De6YD)#{3F8Ud zStAzp#xz43nm2WbOt7Ka>xU{V55rv#L>zpPMX2l$`E(W>f@2j@KU6nOH=NkuXAD|) zf|>?JI~##L=C;xp+LqxlY!N&-s9Rgdi+z5$GyeocWvhGe8wT&BY=plrg zt{Y@>oUw#4Bhv=H0o;mo4Y?X9mEZ{j3xPXnkg&mDKJsDYvI(T9qX}6&uZ8M@c?oFp?Cz%?k7ulZxRcTx$_mbI4*&?NZX04g4ugDf}p36$3vC4+;AS=SV>=O5_dGcRa3G*^VUMf_MvNKoiDh%R_#Eag%iAJW-FNacc;?f)G9ds=uW6z-AWjL zbSD%|7R)K>LgI^AVRq^UrX1GWmJoXaxY|`h9tz;9R|%o$Oa=uGX=?^f9F`knTKH@D zYQnJUwy6FM9J3f=*dWZj4a~2&+ZxxPU}oW8VOqK8O2D+?sw+GwS`_ZH!eA1{#W)z- z8Vnv>BRnHq68s{@OoYuL-8b-u*fNPFtij*G6~YjfYjAh4gRp;iVGwnup`wS~gVV!{ zJQaB^(p=ce8aI<*v|yBAjl>nzxTgeT1Wz=F99Qd;TT8Gl@G0;oa2s=w7d5UiK^a2= zuIGeNN8P8dj2=uId~-IwrlKsa~vTqBAGY7e>&Vve8kg+PJ?g7i65G7vJP!>t%d z7pN8p7HE}24Fh=sp+RKX9GWo@2T%l%0hZI=>b9P)>v6u3fXi^YwWn))y0-^zwYrn1 zOL-to5^xt!ck|f4d~hpISM+p8PnYy`OOJW9%$sGZEE8mz6A~(LhCeQZG3b_YwhXXk zWG$m=8BP+Bi;=Vpo@Kl&<6{{W%ZONdPXdbMs+XmUmY!HOR_&n~L{gWkp%gy2z~)jb zQ2rUVf=K(;Xwn$=2PtV0mticIRxFyVm@00iBofUQDV2h@qPx;H6N|FSr;bvR-J-p+ z(Eb+fRk=nsD?L-qWn*|?gk>XRf39!IpID59(sm)$D-M>C~z?351B+G zw{kF6Xm!Y;is>n;9gAwGgHUcISJNP6YqZaz`LSqzEJ_~&7-Td*cxWdA9xKuZ^^X_y zw9fHXLG%R05XmK^r&P2<7VS_waotMIWT7@9H8Y0p$f7o~sEsTdBLe9tY9l=K7Tu9W zV`R}7S#C>!)MH|}Rh;5or{TQrOoQ+@)e41<1)!p*|ITSOZcB_^eL(y>)7iwFCD zGBDOC*ep6Ti}KFGI$M$SHBA6io<+}R(MwuXk_4)8szOu6tXP!O79F!i#T#1eNyn%j zO&B^`64O$ot`>o-Mb;V;ca8@0YPk$RayrD70E=?dav#8=Xe3Ypbcibf7W01#=}(|i z(0DBVEjlubip-)Rvna@jR8|^~W=zUo>3*g6wP?jGN-+{JMkvPcP%g?bt4rOe#;i^P z&H&3{KqM7%NZ_GX9Tcd?EZQ-Pa?GL|v#7=_nlTdSgI1s%v*^YwsxgaZ%%T`0QmM4J zwU$tjS@dHT^_WFFMj+YHkXbZh7KNBaA4VYMpcAtwzAQ%j7OQ=W*}lbYpGYc@E(&9P zi?zPRT;F1UE1m5)wf#2_06nJ|!CAFdM$p%Yj#SZqpTE~1r{ zLC1WOEQ~xxlol&Wiy37LBYDoEm0V?M5onWPXK69Cv{+hNOf6|x#8tGCGh~?QS?u&I zhI$rDJquf6G0vk1#u5`fJXDK~p2aN3VsB!hS1cAMM9>!OPOPqwV|ijRJt2_6#sI}) zfx-u)jvb1{*2L;oHC81S^A93u8@3x3F^h#Uv+!jE5`dE1A{XI9F|-Hu40;nKQKP^B z7A*}Pr9;u<^gnrcQhe?c0hQDDzGs2;E9d)NxI-zgr(x^lg_%oWuCH2vrgmG6z9b-oJwuW^? zGo&*6K}_3Oa5UIYQ2+dmEHxlva~3TYfQw!hO_oJDXHm>e7Li+W@q$0L5UMnb8jV0L z7*--WG(K3#sKa!xm!e>~^GN>y$TIUt009Un^N9BV$o+KP9Ds~7kF*VdTr-bw4S;Mj zk8BOV+Y5O_X#m8UdBkY|M4NfUX8>f7d8B6mHdBkS*JTfzYT7bw5pcY7U ztcxiCwE!U)KrKKJMw_QFTC{L?m;qDf5bHTapIztfV5*Bme!|>Z^<1L8-HLcg?cdusUjqiM|^`7p?_QU+k}zCGjm2piDu@M;A-jTsK_hHM1Y7j~jkA32#VWnr-gv6g{8 z%RriCpujQ^U9$9ZhLjLe&Uz9i!x`|&CJ)jFD{ua2wHgbRB9q7AUGezPKDCRp0ol04 zM8RUCV6jhdCXup+gcQj@fn*>&GSD0u$c>E5Ib_KpBM#UH3Q@%dMNxdNa@t}t5wc6^252e3IROh8^2j{&q! zcZvaQJ@=4@?h50RhEFP1y}1mKNwM(c<_GzNJ5 zP)^LCH2a>=N$VyX`7E0G6NvOZmj8w`_Z=u+%^R_=H+4m2CId{ax10 zBU^@t71DaFfTS7?)-7sJKEOX%r+^;#gSy7Tgg{lL(Pu$oI%2UMA&|N;9ZadMF^x(n2K0zMJ#qA7V{8`K?o7Fl+|ak3*m#UgH4FVD8yowVKD}= z*nn8-Lff>yk^}5$+4X#o6=Yzs39%S|Sgbz?q%3SeEJh#} z0}zV^h{b@zV!>fC;UEDOVUA(3$FLY=5J2BC%dnVaSS&FJpmt0#EVdYY&n0uEEC2D9;_=YrWAb8LJTS_RumR93X2KFbU~sC3@I#@6c$qoi!Fu4n8IRBVKJAm z*h`Rz?qD@xF`M8+MbJmACoJX@1gJb(i~$87DwxJ$N5Ka@#+t%nPGPa9AVA%h=mAp! zJk*E5fW>0KVlv<_t~gpI7z^#mjYWEJQqwZ53M^&?&df=Nqy@=Ha4nrGXe;Rk;f+adazaZ!1N_ ze3B@OfwYzI4TBhqMU2G;#$p6x#Z8KN6winuj58Bzuh-S%3!SGx^R~B6G$LWe$;*1 zsCdNxj-ZOW7Wx|pwA$P1K}gd2Zly@}CaS^LS2v-JQH$oAxENXZ8RIctf7i#q#N(!3 zee^GlImSVs8tA%Tkr09YiVrRESG|*q9osC6aaJPze96?Z(2?$I4;ITVC5S~m4qv(U zTCBVvbG3`W=oov2g!5T~Cv)+bPfo&cI8}@Jmc@R{V!)-`^9qELdAVDM?JVgzKQZr8 zo)&p8%!8#*>w<2y$=VXR_3Dgp^aPznGK3_KKib3LX^{$9ghC>DvDx8|U5G%)A`h~N zgDldZVgL9SL&gavg$BYQI6eLt1tdcj!4T$4{Lwe0LKdNrMJ8lnvn&#!jJQmTRLCL} zvdDx8fa@5;6v-kSvdD(8mCNx$0tg~AhIx`jQskPfp0w@$R^Lg(Rb`?z*|A!Or-<}G z(X4xv2)+y-7lLNt%mAJ>a|>ytD&3xTP~y|AHDu;-7wr#yH)D6P;kz8Xt3K^VzIF34ODIdjuVWgd5j{vab&d?+PR@)i& z2>{FO3_AsY;dX|-0>E@S!)^h<(q-5m0PdGIF?z`rFg*aUkqej~0C*d$fc1gKwpDGN z7c3l=dY~>F?E_63b|5d%)IvLuSMSY%YGTxown&(8pyVCUyuMr@JqzK^=c44ZmA_=n5eaR|}gjQdp3O7-YJPOe|ANEJ48|kFqWpNvU!sTv8BIp{bMk}R0aP{dw zT$beAtFq*GXa!nxyHqz1#^1 z$^1dWtqQT#*q*9Phb854+czvP=XcTGGMs~9JEoXzH*G^e!gQPv*UiY_U!^+CMTHzy zShJ$O;gW++h)H%Y!R!a*nHFnLi*$|vHV5i8i=KMUtrTn&HC&JI7}Ml$Bv-32 z@ruKP=q8I2m~3n;%pxszkro?BixH&7aM5D9Xfa(J10%YDbvwPGw-3GTDV;1u)0K5& z2l~;7I||Q@Qy|Quq4LAj8lt4dc`#g$+Z@ES(S#@L%ZKOpa}OxGlmeOB{^hMT9laK% z;o=HuG!`sJN4oL&H1}+(Xr(Z3Le|L6+T)&i=h@nbrw{jBsDML4zs;}?u3*X_&ThRm z8Mm$;y;Zs{(d6r59bMG78@OF0^@{PYkcNVPm2&*F>+EpnwLVAmFm{Edp*OGgI({EZ zC!bJpQw`O+F_1!t3WBnXK_8ebk4e83^QFk=B> z^WlB@83|-C=H=i-Ct1Q644^9)Sb_miOqQ?(1E82JVGRZ#e+g4C0E)>H#$f=Cuo9MF z02GrYtiAxC+7gCa02GrY47C892_;d1B?OfK1g0g#jsQg3CB%yWwEz(!KrKK#NYi-f zA_E(pk%!o=uuXS4#=X&vB;?{@@Q8!fQK-ekY+p%S{DHSmQb3g(gx4mL>_;R z69URXR&9|&TcphvipM1bjLOG5MosK)F?(XY=CHz0L9=t=cR}z#;6vJ2X2~)fmI2^s z!@^QYTr~N46Ss)%4uJP?i&*cdkhxLFj^Odd5~9+;m8y|k7F%D7v9HCX)FlU?uTnBf z#%S{Z;?2&H0MVRlLsSGmTJ<^d$@2a#iEYB4k=isNe>Gz@?T7zYt&WYdHNs>KA= zVuMN=?v_=t4FT|oVioHU0J3`wpDf0y7VA`tc`6Bg2dc9OJ!i(TsLWv5n9;lSdbl2= zMi)am8eKwC3BV|{gwPRyA!&&=04z?5nh(^iwloGt?}sI<~~kn$OHGHp2dRJVnS8$tGi5uR%!w*pfAL7=XOi6|*Jo z84B7$KwIc%3;9fr3{MTBgaM$)5|fNUuf>>`C>~kOV}}Fq1SA?NzufS!+|bcjR5TV1 zjYUCYrJupb*QIhPD1xOR6Fz_%poEMa=D$SIz*$x*02Q1}+b{{X*aQ>BGr$D|>41WO zhE8QObQlU-EQKwm!lXk9G=@G0z{4(M=yN8=q*0TxG={_?KrL3p7BgZJWBjbz0VrTq z82~+&46QLTwpbZkEQ~EC#w5nnzQK6|a6ZiL8z{d3nAJB>e*v(u*LxTwmJyK_P##?a zfGv_o+W=6XStpn*Tg;U$rpgvuWpZ%&rG&NtfU2Q{b^!p7FB3j2nJvtV#ctVRxJ+X1 z`Hf=!2H-m2CP#6tNI1t70F;!0 z#QfP}`b-qB>edJW_-mG23h>%xJW9l9V;yZVkG9xHTMVRK3KvUuEVoOL-vB8D8AQyd zE%wtH{nP~KPDZ~o!Kp)1Ug4QU1cQ(3u6cAZ0Peu%83_O+f1Z&590H(E0qCV!^dtaC zfjl}9fUf?c{{W1OSY*nu(zcjsTkNzghT6K&$(!?3!!6_z8i#+T1EC*+ z;N;7&*-6ESV1vo8aquSu#5a3B!!elQ6eIzL=q0oh0Prrr zWQGHhj8cWBVa#a_}3`or-!?0%9yDhJ;^=gydu!DPd!^o2TV+2(x_Sqf0pM2{kpu9H@lf zyf{!|2^B=($n-%q!EQ%Ex})ub&{aScw``Po))H3I6HEHtfTX>{0j|MwK^rU1$QC3v zPG~leB^+qF-vLP6*bX6XBm!S>fI)We{U?(}VabFL%~@T%67}Y+RdPH&+Vz^;b)w{X zF@M(ERdvUQNePe3J}XzN_?v5cYrI1TC3(yo+h*Mg*w1gYp=aabJR1M#;Ipbf?+UWL1ggp7#a7>wLpK@m>S_ z=HKHX)3FmI+BOd&NHlPs*id^Lst6Ufg}HQ{yVWJ^42)AIH)otQ8R}Zzy}ezNyMvRd zlcgk+C&QKAJq6x|)VM|pqcm?+TZR_OBZHT!x5{coDFZs&HiSrWZzk3mp~RBA&5ta( zwC-i+$4;UGb{`w1Vw3@AclKUCv`hChF`)sL4v_iB;a?V`Nvr6C_b7Nj&ZHv;`=|{J7es zJw}vrbz^RqW1e88Zo}a&VS9+uv?Fqts3XW*(S3?wKT?)1O9Q*B>_cyN zkN>Mz-U6WWmC^QGuDH#ZRkbWU+deRwf!AxrZ7t~8B5YZl^qUpP^AE#gk>$aBy$HYD zXl^dxt09ozlS5yTo3=$54EJ7jXAC3S8DxtZV+}P>{jUZ;RDrAxkX?oZE!}67suj?c zRAqT}f8sgpu7IxQwh9a}w4^hLzJ)e+$AorjdfMij=E2f<#jfTtvV`C_WAsx6jogk( z1?vR=DkSpwa=GG_D~U@BJ~Sfb++y`XY_w55$K7g9D1hG)a8~nfT&2|*u17z)S@t#` zZovH;QLW5Rl+f3yvRhda^{I2=ll7w)VO)r8$(a!B#ar6z*6yG{_fsVyTjC~(ugV9+ z8M_8In8IjQ;l|D**A8GaR4hP9r`BXPUVJAiJ4nt^oWN>@;@!0JVTygaD}& z5OgBc=QpLA5UPNp0Ph`4W8&m2Pn}qWPaZ&+#$*XlMf6hV;rAkH1@>^h>3_pE)&zwe zrXNDpkE6#Cfz^wCM(Q?QaYKoP^fmf<%{}}=dc7+{6x)_;gg$}ND>F!(_2W~;Iivw- z_C~khr{uU4i2K_L-Ucpu{3zl&qoyDZL#W^+N$v-&wqqBOC}78k7=)r8EQ>?qQ9$8U zPW=9C6tTC^!0fJ7WfZJqj5kci=P7DyuFeBCPWaQE4@^4R%qDWVM)S+S_0T(>PVA}- zq&b=^VR#%zZOvtx`Md;8aafp{tp%<|bC%0&+$UplBxBN#e&{#9u=>zXV)446^Cbp3 zjHF|v8ihW%K)+0l;2(Sqpz1;Q*gpYKj%kErBQ$Q8B5y!q)J#gOb#A{H0G`$%BwLRL%!s+!rPX+#A}2-JTtmp+^!T~P%=o@)j5GYgz3-vwK~LgJ)C}-qCD8Xf z*#gaja$>JY>(nz}ew<$|TSL6sk1(EeY6T;7^=4e|jx!?2=ZQtDNN-f9#)!9L@$ohb zU&ypuC6n{ivF3F@pth4Xp?cw4 zSt8tr`t79U$B(VKF!jhU7#?E7uXK#WQsq!wYpdQkLX1YskGr;eyiL*1x%$=^h(=Ng z$qL;mty-)SHFKIPKeMBt1T7nlzMq#{NIz#xc8DIjm9)a=(J?n2;buzZCd|Ac_78U z4Q3;25zVM;Z*&N0&DPmgFWSq1>BQyzK8nOJjbQm=9I7)(~{8FRYi`zS5F5K-Vah#m(3!@8vKkfJ_BQ)Uf_LakQS<46|I1}+-Ts6Ml-$VmB9sugwuzgWWpF(<5HQ;r1}jPJf{!6m-; z9H!+?Be+Jeca8f7?i->#TJX`PRV)1xhtMCa{2l5J4&t7SEHFkEkaA`?FhZujjK7)JfPU8 zbj_FBWGgT>qDFogh!BrFbn2Cixj6atgezuI5|Nm`OSFOOLa_=Lg7EVmQ!k=F{HFIb z+eM_}g;x45lrJQw-f3T;N1wNZ?tMa?y;}GC-S~O>Y%5`xK#}ZYF0-`8qc@LeP|An) zMWZCN=+_D5tnjpP)wL=)8YX3?;=aW@I-afh$IGK@QMj7ln37EH1kI2iHPLXw8QLYZ zrt;reW4z0bSzq5e)q3Ntw8kStk07Jgi8j^xns2V65h4HeTS+InSv86%h*q|zKs4u= zA<;*zP0xd1fI&(Q3~v+1#^2nUs1WBgRB z)}dTKpF;CGD*bBjJ_vpLE(rA1h19W^+`qYM$S+pYL$y>Xl^+Q+CxGia7> zXA~MH5x=x^md)xdVQe)6sBec&>>qK9=hmw-*HYfOXY8H9da|7BjSHN+@iC>+ZInA!f z@h7$SwrfTBlQ_l^TBmBc%JBqgl4r&CsI^LbUG#ss_K^7D+PIX{uPc6d8s>>XHg^tMNp%IBEL{Uc@(ifqrNlw-XDX>SUnk@hMV?IJ*^XJg= z7L_QV*+OW1bNYy@;Dw zgcNP;Xw!LaNd%b}8$}yQ2U9UgR?bCYHI4NDtAe9~&~3~w3So&HEeHP zxJ8Qn1z{19EHo$NJi}t_6fNzd)Ho00w^~PUa*OYxRFSswo2s3AhEcLYRo z7q!;i>z8vgw9a2d>aDV-L8jPfvQO>(=5H1+^Vk}g)G{S?*IqB(tCnJJ0g59dOESK z+L!tret>d=aCp&e#OnxD9cIyPzI;wlI_!sL%GWF$9SM5P3LhpZj29sLZ+0&ShuRs( ztY^JESprZ@oDk$O_O%mr9xFaNVPZ00n4s0qp{QRTdvHl5LBMx2Xb}O>$&hJeBeuAW z$lbVym?Vqm{Y|$Qbzlfn#Uzho@6O-c+6@sN>J}-}i_0S-r8_oe+2Wn0{YI`kB1zc> zY8O5e%O5(1>{uIiwot&xZL{QCxO(V#R$jx9*}>QHh#&FLqx?9XkD@*@(uz z6YH%B^C|j;`U@ffyj&_`wmcCK5m27>@OVq2iKyJTjq=57MEE(viXx-D6qTCR?&(S= z;v-7oW|tFM_`JlP*QkxNcU4yFYuPZNTB`|>$k5g>%dt8}^XAh@Xdx!tV_1c$wO*tW zuK`-O<@lwc@#*8z@@y&RZ(>5bQmcuA1ZR;1L> zhDZh*_Ik-?4ulE^S^ z-U!{r>c=Zy{N!?#RQiQi+CS~gN2ngACat;r_t4Vbo*t$)=)$;Bo7F+CFYYo+SAI9 z@<)3^$Vju`XR^g-FG}{<9DZBpf^HXH)Stwb(~|Apl75q^VcUqWns|%*EgG}HqR1jj zSi=`>8Y%k1raAnL|LM()JGz;fh`J+ERV+htUq?71+0~74SI^X7CfSEunZXFJnzK8x zL{wS}mmdB_=TIfZBu|V$pJ+Dy?9GS9J7+FN$MIYzI}@k(-ByiKAY<7lV86P8}MYd*^@zx3CeTmiEBLmC_4IeFlISS??q5aTcD!aSyfSM z{48*wdH7LjcES_UDPEo(%j`v!M6?LB*xkdNYe|hwmJ>@fd&HFTE8S2rLg&)vi)GyB zD4V!MkAWjvS7)K8RYl>6YZ0%aP*F3&$t^x&;Y}_K0m~xMijh7}x}TU&h(^vVN`{(M zNfGV{R3X1E?n;|Pw3Lk75rv}biFE?qG_P5$Hi#D0fjCe6nTnTAhxc3Yb<`O&LmEx- zP-c}MmCf{5RDeWtV!>5{S?%MZo^55s6|RS-fk^slJ4EF4HXcp*vj*axL!DoEr5mrkT|9 z?s09452bake6vhCG+6;|cC)PUH+N~*#k`4Mx3Wu+_S|zN;zHYZkQequf{HPE>$&0! zAWyx3C6K9$M4M|hs3bEOb4%v%3x=3bFp1*8*J;1TO4gY=d^-D?%qQ8Y@9}YRoUbEJ$CZR@ zvAldbXm(nX*p|{f-lvlF&AN4~!!FVZJ<%b}L43z%>WXH-uQ&CiUEJaA{(Q?k;)?K# zFp)Q%QvI4et-K(B7*el0!`thKP-0YyU%Nb;><&98#&D)xQJW&+qEK-6T2t;=$P%}0 zo>JFF$DWrO`|*?RTWt^RzeBvH)}mJyCj~$nizNA?QHc&c?NhJPKTfX>>>-Ehi+bt_ zm1LRm3W&4>VnO(w18VZbm|rPTZLzTs^Xhay-QuJF$D@CCq$5=SG*)?VNG#*0rZfGa zt~DY7nzx(Pj>$_rdTOMv70DnxAi@ARi5fl0 z##D<4xp>8zRlXMWpi_`1Bc$$7nRU!W*6_6akkMxOy^QSSG?XW~uL|dao1ELfR*(C9}-$k!vZp zg+&*65pNCRmUXsRmqfI_tNwdo6l(_K7_&?L)J)7$lEQr5RN~Gf2{p{kjbW#Rij3s`@AlpUE~=yJAHQ2*3$U;Y zD(Zr3i=u*e=|qhppknVWHp(I-NJqhF+`E>ji5gq%2__nQODr*JG?rLmOJZ+PV~;h~ z#PxX?P@Ss`anv1=|C<;Xc#vW(OZNd|C0A62@1JFJ*-tmSxMrDQG6%IJ#_ zcSN~1z#-xDZ^~h(M@fjOTw6fg=5NZqfG;?&O4bqw*JNi_Q!K8rFNL6FP12KOeid~f znpN+DuSu(MAn4M*&(13RI~tb25FHKDQy6nQNKfH*Cj{5~RS@*Wz{O!0TXQ}B77aB0 zXc5W-n{^OGSn1l^U@KrOCdc0r!waQ4VmMz}Dx`E<(zN*-@_C`9)*uAQ8|^%GOAzY| zrJB8@REf#;!sH;lMx$S4^{hn67p7&|1TIZWiLE+Dp+RZPNG-R{0)X)QnocH zf>=X~zbo6kbi18ELv27wf8VM^qYifV0_HjabDdv;^AaQV0`xReFE3jH>y1i7FEO*1 zVT<5);QWQYOE@oCy12#S(qf312v~BD(ol56+@Xc4G+X@pnnVjZiLvitt0b%W1uBlg z$h2elc^Qm=$G#t+c!?k?=nR;gmnP(kFAev<#!^v}b;+x$dO3>{r$kw(72^mMVu;wI z7$Vjvh9VrHNJl8j5i&EqTg+)@`_=#~_Lq`uLb6#P?xdxV<|Ij)T*AM%FMyz&Br%a@ zD9VwrYI&5Vy`6hO1_U`AyhID zk`G4|8L11Rpf8q_lq~TjU{Y;Kj3u*KNi~cFa|z+E>X>Bub?O+$ap8;e?`KXs= z+{t_T$LlLi@GyPWV92pu5%s>g?AOt-zv~eHx0{}6{p*dt#&#|z8#KVxR(_MU+nay< z_JQ^6`9WJd`pxOs;NXO16EEGGAUA#!niglex?zUf$J+BPm+kLa@so_^-z0AcTjIWV zyF5VKu~E0Ro6jfReR$|I^}4~mx>gK5J4S767FjSR$I@HjYS74C<#Jb}+*PeGacZSW zCZm9y0&)b5N)u<$xZnv_PNw#vR2iij6}34vzH)qx%G$`qx~b&k5RF|8dbz8X%IXy= zncCH)P;1p{l}e%2d+EJYoWkIzGwKu^ha|a7t@l!^T(nv(0xq0ftyU{Jz=2kgUBgnS znA)V2>Ag@714pk?xu{vKsN4@h7Zo)^kmwbzdM`kO;gI3tW^$G3!*pt$P9KF>gIQS~ zv2s_PtN0F!T6*sX0r8bNg{z+eedvd89KP|WuRZQ<@a=$a7kqo*8;WnFTBR^_pg%Py zH}s}IcQ2X3pY!tP=ufGY89Fe4J5bIp^ha@BSX>v1>p_1M*Mr6Nptw-_qqtBO7fNxF z^ha@#EH2WuoFPHx&(VW7=g!OIGBJWR>d)zTnZglcV2CyvEUc)7ux>P@v4=GAVE}s& zuMJt%hK4Sb&6k>N=x$QU^xbtjxmIlu2cU_VsR<=F(VMhL*7wrswEAoei$Sea$qe~~ z?l=syj8$$1?dT|^Z%-7YQ(}~jYL!yo-q1#Fbmh>Pmt2FMwlP=*Kckk$+d5UJ^E0YV zGDI1yGh8{D&S0G@JM9LbYpV5nRMY`PJt2c=eDity;GN?T`rC8Re^D_jp)&wuk1;v&be05#~ zry-CA$0`^NE!;V!Jq5AokKCv?5e{`~f=#D3ST_-Ddg~4~F$DUsWVv;sjI)mIoSK$v z!YRr*>6r=1rpy!*ejmzYKljQsz=EI5O*SD%vIU1G(?Pk(L8kWUmV{i3DIZ__)GYm; zlxZM--V+A{;W^oqn`KE#ODQzr7cg-85zZ9KMOK`lW5Q`g^h*@EL7j3_abS^@n3jPP zixQH-5;+$J9|MmDO0KJ`@-f64jOfH^gY}#~7Q=u6LC4WeKc_#v^`cROxe$*(>kWpo z)8dHS5N~!I++j)g5vS8z|5Taebd$5lr?{dTA^?UogBr;gctOVSNCCY{Z2+!|K`>HD z!3Bh6G=ho9L5WnH@)GfbA_P6lqF19XJRnx31nek?#5TC9{S;tLDC4If($pDLY8}Wx zFzC@yeP`++;7_QD zK8x85>R1`~mi>h4Tqo+uOvGVuAcYdNBOajX$W=@Q6;xVk%8*sun4iK=K{x{fFtZgZ zqHLW(-Au+cX>MVM%e}HW=_t-J8st?K4SYF+U`C~2BdH9v)Nf}12m*bwpHZK!&!!PE z8o`UG2!>6kV`BseJ?T;mWRS4j7E^jt>3*zqKQ-YaK`&TXAPr#`utp(`cp11LSR|(~frf3 z9NCFlh{po#p?X13!r7*9f#4%_A@L^;7sxBMvDQ*t4~lEUg1sr&&qYlGjR6wbqV+Um zh`!+KMElkma?AwqE4jG7TWEc^fKKhtY4n^XrVXI*03{?oP6=MXDFF$m1R-%sSGuU^ zqNa<6F4z>np<_fZ=qtMC%}}SJC>jwJhEOn4n60WrX_Qy)O;jh+86red^Cr0mPpA(t z3yiam!}?1@>dO%9ff>vm7@>$OJd%hK2$>MqWCnD4nHxu-P!JfF%CH(dr6>CsJL-@I zU1x94KGafvX^7E;mNg+I(6~`EN)AYYkm&;UKtNzEA~s4=tUDH7jH;Tx5SS6e76FBh z5@}t)s)N~|ih1hi0v_nX7MdBvys#qB1W&D|Du>MaWbh==W2%;2iCq@|xzYmZrA1XJ zsT^m9R-_7x72xRxz91h3Xj<*G$};KfWNW3?e(lo}xy63UH+hSV=Hu89=agyO&_ zx&thIcQ;6oM!N_JI@EUug=&%7i&A@enlvQ@NXpTRF4@QuYY-)M(uE~ou~CdF+dT|& zCH|+61=l5c04USP0(&worX%n>S1-&bV0HRfVh0#)q9DDn2;?Ngjp4Y3h6D&h3wS)8mhbvl`KH<|he zB4AomGDv|aOrNaPf;H;1Nt}nCg^ylXh5Y(#4;KzsA_+eiY8M0%2iY8S1V##aAu$|T zboykFo=8pf=tsIAswD*Jh4p%26R}>1H(*IfVR{s=qE!LQvz^>|JLeJBRD>jsA_idx z3h&kn`}D$3df~7^IIbqC%1`AeR`@`j z=%w#fPA{BBckDNDRL@~hgo}(*TqXRASyc8rm^KLGhFF=TUkE6PVb?K^E-(rZ?s%A7 z9c^m0Y&k*mY-u)PrzJy&x(r|V>EAzJ^w*mv*N8rCfFdQox9>zO0qeMSav?#!g&*_IDdn< ztYXL|U!$}CyKI}SxCbQ}{h(@!4Wz^_q&-o^K+#S{GI&y25SQ^k*7~AI zVo;w=VKP}Q75`lz#9Nor8i^ZASP5A1&k|OO2`gE`YQT?wmatk(Sj`f?L7(u?621`= zzF`Sl&`%~Q{I~BcNT=cfRsN*gby&|aiq;fiqtqoYNSXHr$`SeQtuS0mmkT{+ad9GO1zzA zay`?vKqAM)$P41_ig>#&-flCEMXl9(Gr?{b(cMKaE&gCNhESV;@(0<-9)t!6(QiBc zVH<&DXFX(3Kg7}xc|t-(VZDG#$ewIZJOF6{^bjWd1feS49f+)9N za715W(SV)|;jrQW7+Xc>>aMd47*tB}V<{dc7kikD;C6s+vwRpq%2(C7hGQ({nAq|$ z)=OBaN&d9nuovFTvg~D9Y&BscgdSm?Y7jy-P|yrQ0{-necd?wis2Pf<%w#Pxl5#`J zfEUTwwg3p^I+!v26gvAO#>J1BDxpTe2F3Z2DU5`99n9mTS}GuU-}X}g5oDJFBs!S2 zZGn)pF*I@*SfEAF7`dxl=nmsAZ1t5?uvd~*l$q-3Zaq!akR=BNU_4+wxd$VzBubyt zlD$QsylN>p7o8B zkRKhVKn0Z>?EgTfbrHVg0s!a6KU6BUQExZ<7wD~4(pCN7E`ZShc7No3gj|xTzd$ne zyQ`q?!qhK}K?cAF6ZA4e0r>`07%?O2(UI#wEjJo$WTuJGV54cNEwLkHiDgaK!ob@*B3z{|YmH_0 zLCcY9FI?5zdW+qOEA9?ymyY^7s_Ke;A>x>gzCd|Kcc}l?>FBI4Jd^00wFv)mk*cK| z3KW&}6M4AEK>^256;YTD zMo_sI=pP0!U^y^QRh~Q#R3%6j1q5HY9IVV&O|f>IBZ*NRfWfRXQspQtTnte8plX7K zmBVC^>$6#5R;Rr*+_CRaK$8r)d>fh?!t$gL2Fp2+9&?ni{SJy{!)>-R zMqg)h9bRdSrG**hal_~mQQ0gQUj|PAv!e;|%pyd+jANXig)lmpEa*7wa5Pj{et-$$ z(L~h@CBQqY#urW?nU?&}`fRbr(J=IZO5nJGUx(am;2?HN5{|*JPb4KA(+iL-7SMqpZ8nSL18D25L?RW)8u#s!bk1&DhN?8TCY+x9MJcOZ=ri=^Z1V4B; z(Lvit;9hSVLm}YB9s;&txMbEe+ZeSJ0Pm!9a09To05D_gLX^UY_<{Lj^hIisa@%<` z$^&D_2kWCr6b+@)MZkxDcI%QpTny(-`OhQMPgDIcgin(zmd5 zrh{M|WKm4$)eC#^0L_jv<3b+=V z2MYSzZ=4#!7mdzU$svTG4of;kV^l5fCOIoWlL>rBEQSZ8r`^Lu3BV*;a%2QC7`1?$ zL?I@{0K;(lSw}MuoyHM@a%;8Pl}d8XKk4QWG|L zkpB)a=fhj+W6~fJ7?jp;O7$^8aY4_W1r%dB6F3da3H-68p0buRK~R>mN(tmLBsZE) zs@)+Sl&akkZ#0;|f#Gj-s+uT~Rqcp1l7NbyU|LgVppxoi^pVdH%k0I=fK!TR{3@Ri z4DLYrX@Q~y$!Ca1atC7F6o*6f|AD-hQ4SQKu`rSXAovy!Io1-OkK&NU4hdEcCrI#Q z6n!zYelSRw`%<4RR>nC91q@xR3w&Ct3yhS?c!@BJY?UGmC8(E}tymP?mRxwnJQ)50 z0y#kB*OW?RB-$e2?`0yBy~kReQOnW*r{D|ag5BNhso>KXNw90w0SOaV)Jl8>(0EEy zM~niB+4vC)r({T2_OYWFY{#L}5<901KKA^Ku@K9qNXkaeTt}qQTWl7rTx8*ti!cM) zb;JP{R=Y?$$l!oYBpeYP#S;>1F0H>d_}GgF!e}1|QY;+PRpi>m)0OdVBb=`!Yl+hv zB9w$KFmpne9}y79N-mKVHVS~nftHq$69x23%Mzi3@nuF}V75}DcIGa13VB3~Vn-9h zs68D>CAG~qhANUs1^f`*$C5!~tOD1jQH2MZ_%g0w$Q0hfu6yHUT#Wr!I89mj(KGyD zcp+_bDs!WXv~S5NXYpng)JOaqSKCBZ_x7$buD$d-jrhH?{yF#&OA~&R9NVKxZKT4l zw3XGoV|J*c8;-l78<3w!48c*!|uG262mnhrM}`r8`R7*`gz}$PFC; zNnB73a|9uCnFDaf?z9|R0FUfbUXHj#c5vX=h#rj&X|u%vxepj@$t( zH(J)RfQBQ6XtekR`K+K&BITT78*uIRKpfKA9C+fC*5?-Doj~ZDb9sI3zOJ zW-#&Wky+(|Ar%0QB<=yUF$UWl2ysvsrAXhFn9B5swQ8^}LWGti0opGi2`?1}KDHm1?yf%q5jN7s=M(BY0JZ@LRy20{QEEbNFQ|G{j! z2&9-GjP1{^Fbz^v5d$4<izdvx0YU@Dow$_awXl2#vuy56=RRy%HLD&NWOtz73{g zPlPx_Ob+wrHpCe+9l6tmjCXV=+fjK!XFW1T#(`Y6z#)$-dQ0Lo_LE_g8p$+>qXIBY zxo8Z+N0gm3@<=9{Oh=K?knKTXNNmCqBiXt%9Y#&csD|E%r0GavCIM37?R9-D)zuJ# z43z|UqXgO1pPPO*m^v4@;uk2zwGImMoJ#GZAEJ>`f!MX|&;pzPwG{Fu9l zK?%FSBd|Y6?&0A9PT`@$UM*Ohc7b%rH^W4&UD)j6!6v>h^#UyTs{QWEtR{E{3BgJN zf-#~5Zp3|VFs`$SwL({e^@*2CoR^N>I}~ke#IjtVE0`kzb%pB318r6U#G)fgpgrcq zOxaDiLM>UJFbFTO>lNaGdg|I)R?Ar}r@$VlO?u&+huHPANM~8kdU7Jg!BN0`LoA(z z^pN93PA>X}w4gb>tib$4TD5bzs<2;*2K!YI$#Jy`U z%fZ?VTE3x=h2uutO@)1O*vzJf-y8Nb zF$(*)>{0Sal}1eauU^Ggux?S!@@nAFe_w;VGH~{iENV42(1{S*16W4&f>Md)5sPFK zy7Z$<5nZ<6f>gB<@to317kY0)i9eR$jyq>nZl;9iGK7%Xs}gXo6}#%7Vb&xzs}te6 z)6mdcObC-n66j?wUTJ8Z#}+)=^hrD0^)P!XXqO&VQhhdCpKYg^9CTXT_%72R8h$#; zYdg(^h|>t*AFC;d8tb(ex`u%SkNsX_zq{D)TKk>sf|L$Xz*D8spo|8pvIgb7Fxg!g zN!re-*~q)IE4}tbyBY)^Pk1bB7ty?+WMU9{gJ+tNxZ!0AIpk`6Hsi+^L6am2fjS9l zyTMSzh>}fZ;kF#+HU+#WMBPkkxJ|4Vo9n?F z^v_Fm%2}*dk|qp2G$%gUDfy)pwHuUCDr<2~ad_L1YWm0ZIAtuZrK5~%9i5Z}of%57 zvugg5H;`H<T4z#MPJyma`<`Y+~<&U550Mzq*0;Q=k#9UtQDs*d)KBUW?*Q;3Np zY{xlR0f}^Ydk+p;%wJfibaD;7mI9F`Q0`irAyK^PG%`*ZpJ%~4%f$Cg)J5FbYB$_N zKU~j3f(aqE%Hx$1nH~v(i3qDxN?sNfX1~y$15z!+Ak)#3XekJaZx_@oE!`siCVa^v z#r-7+YU71RrOZXcs0iCy899a=ZR&4AEzXaq|$219`bTE|OoHUHCN4@sYeKrU5_CEA}h9lreR z5)Bw08iJS)B-uvNu5>2<+Z92I616@SV)Rey0mK2;4Y*wtm_iAl1KNAeiV~02fXDLC zdl7(&=dK2o&@uw=4!w8>HcgR02?bqTiK<-TZNiOS$pjXlGdv{?TuE{Cj;`1x?3jb1 zizv9n2y8hCK-88Gnu82Y)rk)@LE^e}5W5?SFc7 zWhIrk+?8mbEmJi5!d@klUJ&|;9`_MN^rp)UVi-slSK_@`i80g37lxeR1DM!9*#&K8 z+7b4Nk^AhC`zWWaH;c6O79*v{8TQ8+V(Liy<486qeqz^sbY*}DhX}4?bU8(r3v?l& zot(sSnH;@<7OKM#lB1l|?9reYNC}V!Fukxuvlp?gg5ByO_=Lw}BR!pb^DT}|2Z8qACS(6?fwY_Se|u|n=&N?)mv!D@&wt-Bps@r`>Al$| zwz*q6*-bjZ^5y4cHls?)I*gFELjUt>I(Kx+E}b0r-#tsTXUPK~i6rRV2|Cn~wrx8f zi%8^2d&b4oS9iMxy?Wq$O5}^@`v!59N@tRGsRwb^uR5Vc>1C7RgW&!z|IU+j`v2AQ zLpn-)fQYX6oLTV&fUhQyqHvOis@L-lpB;2l!?P4JY}3# zl+{V9$FV~)u69gjR$)$B|I|EF?W6!xFwchv2J_}f=q!-wOO&o7<7$erotkxSZ>lY3 z3k@)(WagL{^ypt;Xix;svz2iM=d7J^)I~Z@QWEeQq|iqMfpi7QlUvW!K0h%%Evc2I zuo2G(hw}6Zjbyhd@d<$OfQ~+5dRTB+NT@l)j0iCYh42kY;lo42!%{3sk$i+DGAzoH z5*e0~k{A(e4haj3ObSa14~tArPD}|kn^O`Kqs$4BDSUD;AC(f47?G45nG_ik5uB75 zX^Ai=hXtF1lPqE35lLoCSYl{!vL!SrImMEkk`S2?7HSUT%@Gmd$$WTZusJ+2Ig$^H z2uVl@wuD4RMDiBi5*!hc6pT8Oqfk>wVlp3@l8_u_wuA$u6h7FDRzgCuQBmRHme7dA$nem_#E`IrL_P_hP(C;~icdhD$zc(R;fX1h z;P8-?kd%nz(5Muq%7SvzaCQkO2Ok9R9y31vL>ryu<-6r1WVOxAh$~34WaW|Co|=<6 zC|4G{h+YmCKYb`{lAcQ5+dJjsxV|x&IkD;KZ4%NlxB3qP;xqc3>BZ}H91og z7W%(=!7Kq_aPV78!Y7{kg4y&!JmqVFZ}%+sFqan#r&yTsxuL#_0JmGo9vJQy+wK=i4>N)^9h zEgobqp1s8~a4VJ6j117xd0OH-Z7^>Peab_g?hT894!G7v>{jucznaTC@zGB2mMO!)eX5veq0>BEZ2cQzw z5UMQ;^-xdxV}-(RoUj&3#+h&^Z4yeFa9}K9FC0hJQOL|iBF-5MaX5!qPO^ldQqkY zQ?pn4tV8`z`q2V0VG@NiC6Cbqc1j%TjI z`%$u+cX>y0=bZf9JX2ds9+{$H9u1-l3h!Eu3^C~mc-bbz)Tu>ua9B91OSYIgrS;FC z>+abxu4!C%Sf1@>YpHrS zcX@ngDVySjY`jfY%^7(z7fxZ5d19btS~-rG;dVTn{?M{w_ROXGw(VJTVSkf4_h;?N zA6EI#212W~+$V1=^Z5Nzx3xq699?a~qR4yxGb1;&D7VSQ`mOPb%xCQzH^W`AC@`JB#E8cqmqS0iBd(EP0ZfsNXZeHb;g{RO>x!Lr!;=|6n*>F*nTPFaXKh6HkZQ+i%gF}~Wyfpot#U~$}9e*Jxm$-%aRM`x$i}M_p@wulLwif+^BT2Rl|Tjp}$twRc$HL{d^@WQGK+}Z?P+W zZ@%r}UwiAPd^kq8DLSC{%IV!hy1zdsA$fJjJswHQr(2dClvkVKHMLuY;Z|Y39F!{i z!Y1ntjPwAhD!TZ2E9J0O=_u$alRZ}|6>^o8uS?HWlr{Kjys5~)$T+G}YF=K}oAvAG z4h+gI9FUY4l$1Gu9+Gm>`2@;rQugG#^IctC`wQ-vD|~Cdx~m$~#s%*r%gR@v;<+fF z>{L7{E0?e7$Ry`0x|f+PCo6&XrY34C-FdB)U!mZ;Nnx2x*@}PnEK)#sB2oo*L~Oj|K@_^qJ2d-tpx<)4$nW*AOoDUT^W<=ndl zMa{tN+~_;;#tEPNTHkWlnFKL^L4q=_V%2#|`+eTP?`Va|Cxyy|V`eC3Jl#Ft`^4kuhP`nIX&Ej{Vefq~D`@A#=T_Hv6KzruT^-5){FC%X)VIA~{Yah{HG9Rl z56)F3Qdut~K5)$euONSamezc_?pl=>fJEZD)Cn z3Xc9cFuvbc2}AGQ_TMwAPAQb}!X9bLi#)FaUk+meo~MH&Esa=HJyU!}Qjin3lM?W1 zpfk67laHj5Zr*0ew`G!YidBFCHG}giAs=V9=U`)KGCQF?Gb6pw9LL8{S%r5)sfbD9 zl%lT+EG=z7LQbJ625&;9rKI7ccd%env{)D3jSMt34`b{z#0-`xeu#bIk&lwt=YO2P zzlv>68}84QUr}$>&+6?*Qzv)m=b!!HeDl>OySJ&H_|EFhJu7#3_=Sh>pwtb=!k5&q z+Wy3+cQ5y?)z)q6v|XC4$%{_(@@PBHV`9puG@=5!9)|HaAJs~syhj&8W8<%Pvt zu0$>Aw72TPy$6QPy0mp~_jhdNZZ--(VB9fHRb%{}_r5a+Hp)1)W=7M`S|v>FYs|V? zVd%*ZFD8sB*qK^+g}$KD^yS;TH1Bl$>)<1Eb*UjsFbl@;+?f6 zK;&}XSm|XsiGA|aS`}pgUyH9+seWXSd z_}vkapM&+5STAI*d;n$FE3sP4^XHA`O1v*3Fmd#fh|#`Pe4sfHUQ{RESte_B=Dovy zu`Jkn`uc|3yyk99)L-%yA?A=$oPse|?~#@K(-uWMEZQ`0#ru8u=*k07f$N>)2=oRY?lg0lz&ot<*Md){XT!|<_E{W95%1({Km^h1O=QK zvT@m$INnhxBlwgvevcUb6Z-`rCL$Ha*a>y ze%z+@gvUAk2R*GdW#_kHy3z5^#yzdQqNQPz$Jf(b&cwQx`zySz;?(!;Wq0Q4d;45G zzo}NM&fnD?(Z}=4ZFw%*Thq3UskW-hpu3y)#T>fRdQsywAC6d&{Kr9`s%BfjY~B_y z9g-_AO#Y9{i)Bc(#nN<97VqUGJ-eGp{HW*LB^2e zca74F<@nc!g6aK&slR3WFUei%D(`p#e99}cfKvYu^I*4aaAXVg&5@7MFKk1ht+ulL?h9}aq}mTFYL zLk*5@)`x$W)bhD0;mPfQoBQAC9P#$fg)7_ z@9U$HmE^Z;@6O=|46m0l=w|Z69Y+jnf0(u>YJ9@g``Ooi@A;vz<<8)$<1%WkJ)ZRK zvpdOMsx6xLu{pTr=?8n>`fS7L>bYw^kBOH5vRq!Ne46WD11`-T9`8LV?8MM6+w=c8 ztp0Yct=7A|&F!oMw+e;KY;!w^xV;XHl1AjV2~q3iG6h?X9U75v+SSdjH)(KaND(%t z3VV2ACkU`4Gb^bN4SUegyTyi4u1}X)#_v5pEO_YWeg$%$8n>@rZ8!8;)^}^;H~qpX zgN5+jvwS^iXNftO=^4T1u%0|rCI6z7dC7cYNy*?9+7Px$h@7ad#EDGo1%*y|2?Mgk zUsuT)n1=Tzn7)Ip?O3rxi)`u{(9dq-+s!Vpyg&K($3uQ-+v8fRnS&0wK55`gR5bfuCQU-iX?K7!~uORgqI|aK2E^CTB9sO zVSEV=W16dmbbUs(bZEp`NK9hHm_b6TjSk*ed8MZ6uUphkXym_VcP1tKhE%9 znp63WHrZ8HnNL6NkRb2$<>LGC^;`<#=GPyy|MHB>&ptZet#P9tCY@^e=)I5&h1$or z^G8R|e!fG|VaDR4>7Pwb`@j+~eB{=CKHGQgZs2obi*UP&N8Xu9)t2me_&9G!txFGE zRvxxs+oyrc$6ovL(&Ad>hbBCno~_?_zWv-*7kmG8QMaJpXNxVSUyglpW!I4TZCk`X zuXsLIHOcL0>IiG^cM6i@_VsJ_e&_GKhwLc4v-|sOQJ@h1;)RD!>tWxS_cMC!-J3V_ z(CMMK8lSx0+8T5kuirF&8`{}idq?#Bvg2pv$6Yf{(!^%mAMktk zA^ep;)5cZLbu(l(U$i_*|ESKYSt~1T8~=NcPq=0K-P?S1(EO#kSDnF6&JXtM)_S4E z_iAC2#G0RE?A#gg&hV=0@zK{#AMe)KZ&3UPb;`T;`7-jIYKAX5R2=^PTBs*qV8(xF zpYgf__ab*a+Z>jmJoe7?%9Yxef|&nz&ml6p5c?B%z%io>=5Vk>YxrN_gRh*&pC`FR z#eTD)`hwW_4Z7!ZZzpIwOrn$Qo{ec$ZR*Xfbz{E&>{#mR@lD#@92vP@zoYse$=z?43(joYZSL~X^W;bC`0s0V z?sU@O3S)xbUfE|x&xLbpx7Ss;`N_$I25}wy4j8(+O=|vR$?^v&jhZjb%DFu0a^HPk z>$eY2o>FmBP3yTUKUbT7@LT!dxq~LZZP|9SLf*#cQFTtKTYog^qltl^4vMXkdSqeV zpp&|{gFo#0VaTTANxS0byt!k?wGg+T?|f1D-iO~E|GL|U4bCVR46gQ7jpac*vvz#f zcK93W$8MVzwVRp4gWl8|q{MbZ~aO9Pbs#}~lAuS=ORMz@=xw(N!34#5C zgOV&cd_$2Ngz+J~xu||opmS+r2!B%=2A_XA%Y&VmTeBb1zRQ&{8J%bFzeDm1V+yL4(y3>u{}aPe|k=3ceUoOO@&S)tQ>7iVjUtEFRUi=4UgT zD2%7~|5o^8)l}CLYlBx0*nF?v8%ZG-;*$q>T-w%O_t0ftSo)AL<$t*P)vsS&J#G3S z+jHO4yi;p?o!JyoC8pp~!J2)wm8LHi-)XgdbihQN^(Xz4)4c{}wCkgbYZjg1vGQ8v z%vEom&}4f(F&3`2zPB{(-qYD@-OJa#Gwf|mqgijCFTclIz~SwY9t#5|)I0apy`GC? zE6UBTS3kb;$!Z(6Ju8^fVcV!xw$Z(BH(K3cZed8>p!e3FGHJZCe}AXq+Xt@9=eyM# z6W@6KfnmEhzf~Fl7ucYa zC@*}(S8|ApklZ~=NQDsH9m2Vb*^_L@&H`O&(fyD6bMNODp4nsER%dB!%WJ)d2KM!a z9kN)?l)IaaJTyxla=s;IM!?#_+}|q(X8sX#Y2e^r)u9)h8MIx__c?lS!h@>|XSaD= z@VM#C2li;W_X5#PjPW936eQ=-jc}V^5^V_G)k=EF$B?v#)lH zU7kF;^UaF8-%MO@I_cgp=i6VlF1h+NZA{9iDRo=-ZTYKb`%Q_x;{4m{{SUrzf0D8A z=zDJYAD7Enw5REsH5Uf_7%H^r5!|EK^7x;BoBZA3EpZFF4KqFc(|3*E{&hdjUYVM= zt$%p%pCj(p`R3<852jnUMgOpN{g`d%Z@v3ni{WpUA3x^!>BpXXS9(kvP}H=~g1CqM zxBa?dil+LC_a=Y;;p%>O!@DX!UZdSRInlG${F(=rY+HI~{h;~pJ?#GTvCU69Jo>6- zjYkJ2%*(LqQZ97jZIy>RWPG_2GJfS;#AP}LhGhK8{Seg)k09i#M`{a|KIh5 zK%;e%l8b~1Ww=B1u3E{uUQua=;&oci^zTSm!k1!)K8Up;wkMRj$H)17-;FCTH4XL+3XLE{bcH`bcc zA?s54x1SuDw{Vr_aber9t4=x6<4(}nI^)eB&&!_ldCP#*_1iP&)QOvG(>3C4x+sS- z#JnZC0L0aFV3#y0U3o+q$XnvUyE%iTxK zZOaGl=<()=33GxL+thIqbg7*MfZ;qKhRM%HN0B6A}rd ztI2L~ea~gpq4?Aeu@85T`FVE5IWKI36E>9u`hRdwNaR1?69NOe*wy-uJt18((gx!7 z?u2wx$IQ&UlD?Yay&!BGNH}lC&JXs1QwA?CoAGSlMK`Eq_g>-HdgYkZ#y$czCRP4+ zOyDhgmC&=H$DAHr+RgbWr*|dc^WVGNT`61EFnek61ebS5&8)=*PkX1$?qr`<0UNd+ z4_F^`J?ZOn2O7I|{rFL0<@bO8Qg!~!us#EtL>`*xdO3PXq4CEbmsQ?;Z0f|jw{NCD zTJ}j)(6H}oeNzy%W5oO$H&%Qwe*d_g1Fro%ea)Ly{G;Y1~2iJhr zjV}!Mcw^gp>bKhbsa+Qm|9nq_L-)U$)#}{n8I|sDxfFP&Y*ky z7Vdqfxj#ALyQ!n!*>URLs#b^gU(rnLyJkdT*w})l6@w>K|2{anau402w^r@_^GMxW z>yBMG>^DIF=A;LcchCN<#mxfAj$p<+cEZD@cz;>Y{v$>J(!t{lf(^hM7nSS)#n5GxgqbZ;<(<~e>|GDQS;O|vH9-vSH>wG z@BO&`5p8$pua5WIK6rQB!S2@(MMu8j#%_w(I*`*l|mW+ALA|L#frd@48=?@I1*D#a7Uc?8u4-qs93p!@XTrRw z1-ff-_o}(SnRO#7?!yZ^D)+h_m)fj`OVYqu#wVYq*ICu|;@DvwvzPx7cDPw}SL1;e zfqtv^eRF(Z_3_5%Z*AV-+AB@x3rqsqn`v*t87 z-^Z`@@aNM!-*da%Wq8}4J%0c0==J3p&DVeS>--}fHY&T^cwQ^3_3j&WT6v#awZ66I zZrRN)mcD87f|MT{OYCnaFtx3elk0zr(KQhnR}>$?hZThsnMc(x_I8!!ugXnLz()2! z(dorl*gtj04U$+WSn9ic+JDI%*FY-E%bfu%%N5ku`zn3MqOrjr{IcqvvD5OA z-!-1~{OHDYQ%0`d+421;S2o>9`0CJt85g$gp8S1SBeyH5+TLBKZ(3Ci+c5?o-F$mM zhv2b?tN$7)i+FIpQ{BOJ^%K^$Ngo`ds66Cd&6EloE}ZOssH(T+^7Wr;?x~kQbM~+& zyEoKHU9x@X>H}ZwPG4|*J2!ibcF@FoZ9ac&ZZIn2!KEtg6{BWt{;}zjO9N-+^wi77 z{%~u4=G4olmw$Vyn&q}{kIMSp`>gAZO>17Isru2<>?$jpb^7|ySBJk?(mub1p@MDM zfwR%=g5Tda)wp@$SaqX$3;N4H`L#yt`3Ix7*!q1jwnA{LUp5|?xB4SE)q29I)|Kgv zAO6SKrQGWUM((Uf6bbYG8xFV9n&9D~{2}v6&CnY`ed{m({I~a2O|z5A_Zig1)-2iQ ziDy(zKEg?7k=HjvprrjLO4EVC-w!_6{QBXi+fu73DjN>nQhk_Nw{@R)=T({T$AMPM z`jhTs*IzM-u-&d_jbBdgU-$N#Yi3Owc;Z;A-oG|Fv@X6%*869-_No8Y{K*H}+>(F) z=bTvinjWn`=-_q3Gt0Q|o4vOBcM|I7r=NMVeeUGDd2RG9erbHk%Uc!|c$p@TGny8+ zR7^ZE!n}Cx7q0Jbym9Z{pR26={o_^f<9|?n)&J7Su#E7}->tfTed8H1M`Le1`u17Y zl{y!9y6;W$&PZR=W6PGo!NX3B?zL3W;rya#*KamvNUvO}{#-xh@tgzWu0(XqYf$IQ Wi5owAct+=&Us!2hV$#Siqy9fI+Zw9? literal 247960 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 Ef7p&wTmS$7 diff --git a/SNETCracker/libs/rebex/Rebex.SshShell.dll b/SNETCracker/libs/rebex/Rebex.SshShell.dll index dadd6800a88cc95d2b53cb6ff86d174ff0d54b6b..e3fd50a637f99937e31d87a16cd0b21fa315248b 100644 GIT binary patch literal 79512 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 diff --git a/SNETCracker/libs/rebex/Rebex.Telnet.dll b/SNETCracker/libs/rebex/Rebex.Telnet.dll index f87f243a287448556d904834044ca9fe1d5c8078..c8d621ccd515426cccaebe3cdcd3b37fd40ffa65 100644 GIT binary patch delta 24565 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 L%*viOX8!*JxOVXG delta 24618 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 diff --git a/SNETCracker/libs/rebex/Rebex.Terminal.dll b/SNETCracker/libs/rebex/Rebex.Terminal.dll index af3bc2d6ae9e574b91e25f732141629067c0fc7a..f82f33b2ce83829eb10b2d69fbb6a3a5a241e151 100644 GIT binary patch literal 310416 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%0DFUpU3gF_?jY-VcKD}ZCCBVYTMPeTHkR) zCH$%>$Jwzp%&1lGffjd+sk}XhUXPR#R+*s2K-MS9^KH#7@XCB>0}MS^B-va#j47h6+BoJZc+F=gwuou_Rz z0EVY|*}OD)GXIxk?<2;R!z=OK3%9Z0f26<$1SkExfoFA%g~W~myGwF$+fIaf9YJ$! z8sP5tcP9qhM@tD`VfT~=`zK3b^q6{q()}gNYS!{{`Ekmy(i!Ypy^x^AcEvijE7q}H zv5xJEb!;crkyLgQ2lSQS0e$9ofQV&y`2M>Xf-wSCVnnROh*r^gQXMBHRpE2^P%F>T zcMROlHtiVfY)7lPo$|Z6ouxrlwln2T{yT}gN{}p-;&!rYMQ&8uhIXsh!{%O_EeB^h z-{{KwN=Eai^rxqCY{nhbIJz1dxym_or8M6TQG!p}{U(x_rtj=|y}g{<70ZYrS%#i0 zP3g(t-DMdo)lykk+Lp{t)>=dm@9eiPpzQ4QK7pbqCwho&TaBrwT1*zuC47aBofZxb z^LR_O*cyKjdS7=MS_vPv|7-gto|Bru(j;-ciqB9p_=m9lku|ihvJ*o`v%^kX5bb2U zl>k)d|1Pp>@Q0^l_2N^F>ye8brq4*q%v{JL@5)aeE2i}KYQ;2A9qpi|Ih9w*-g@<*-cAZ zNXiykNTEqL=`E$jQqq=IT3ULc^FN!QVK`U`M-WI3YqVISbEeT#X!WZnf3T{qlb9 z&DwgnHvL6SmC`iy5q1f)^gic&%95tBJ~o?W^=4UvSvJcon{AfOG0WzfW%JCkMzd@_ zpJM#+y`BX1q^KuJJ!$GmR8OjUlGT&0A(lQ1#7N4MJ(Ilb*@XhF576=Z5!?O)CBqbwae+RU0#3fa{FtS-(Ne9 ze*`f6c3sKQj!zx|t|sm5iYKro%fV3YdF}Y;5#X=c&JKA3HioscQJX-nb;wZ!f`EO@ z1cCs6ECTHP?f7F62m<`E2m}HCSOkIqe=Gt)AYT{lgCGzD_+t?W0{pQE1Ofh71cCs6 zEG9Sg<<34G^ywakVw@hyC%2TygEJ5CkajWZgZ1v%j*sV#?YK1(FcdrV%Xs9#`RzD0 zvNeETF3ITB7XBgg!H~gAU!k4tc!IKbfM0H@&@C3YgR+BwU&`s#FXe1C7ES`T^7WzT z60nm`a1pSNQ1Ea-HFlsbBwzx}JzWT&1c=LBa-i(8!W&aOPZ)W+bXsT^GxU%!F=S@T zjGvyZ_%XAA0b1egmNtC4*~q{zt#gZ%ZKts@L+Imy?HPKrPh?<=gTQ6K1G^o(sm^MW zI)bMksV@8Sr>xyEx{ZM~+I7ryRyRsZbHv(fqO^fkD%em_nJI2XI%(QO>kiJd_f5D* zBsW&Ab)2A$bdQSc)SVPs7`Bz_7=j^<{*3f0qrO;mrY)n6H8T^XH8Zb)p6tECx@5?P zIn;K^o*4nzHAZ@^7niM+dvTf&tj^_W>)wYvCC!T-O7Dr}-iI8m&x>UCYe}Hev~sjq zAHJ#R=|cs0Y4VgwFFK32SxbQz@5Fq!Z=}B|-p3ZNcKqcySD@QVvcgJpIRH7vJ(M7Q z97b;T72T5k+7dA3^cE~vkUf&RV_@5WJdm6@#!Ik9$36ACe(T5OtbJ(rmK7!tBBbPa zsYlU3z0X4uxffx{!RhT@RE{>}MIte|&bG?OW)8^0#v{@(o8{*Q+-Vib&9=yX@oe*q zm63C3z-&fKOKS(4yYsa5OmdF|khrZ=l&A8i#pw|`z--=|qIq z8M;Ppe}|5=TEM6j=*j&fbgFmJjTqGgM;VX;b^GyWawa@d5@ zjLNEQ`q95CZ{EaVbL7Vp!NQ=MSy&a6t@b;7q=gd2j{5CgWC_sgB>eQ0Ow6ha?TN#X-q?hk(M#x zTK<#8+;Z92aOOgRr_fnsyzGY-HNtmRiY4K5~hW=mDoXX)Vc87CMK1?OG0=IGiV^*XAzVx3p@E*4=DP zT28Xw!EP_=re>R>xtG)Nwx15;B*1iZI((BrcbhpWBQ5Tqu50%Q*!Zi9_u2-~!T=nw z*~qK<9ILZ3f96$kKS=@pbaN&rUJjtEok{)O=FA>*ru_yeTg{n$=FEO`CU>^srR!Yu z7c(!VkL6A;(^)^K^g>;W&ROsb>J-~<&fI3sw5B`OIb}mT%DYm|E|qAOl1Z;c0qKE! zyE$`*Ig?xC2G9o2bdx=ekVmU`hX`s6W5RN5+c5X2Ms06n|7=`a{m{nZsAa5FqrthW zo*)@}mX>>yX2+9|V(&-Ge$yT;zGdRmS8uU5?X-?K2Mu*_ATt4HICijHK)|AP2TLym zTnEv?(hC9CL3FV6Lcn1~9UM7Mfb&2Hcj6FmrVq5JfMbR_I0=$~qk=j({gHr^fjV^P zV+V&m60kPj!H!x2mQ6a?@Jb*ExHX1A5U^vFKoD@WEP)_k(e&Q^leLYUzI%61pckYK=Poq{czKB1`gD|4=KIiX3mN|>ZC-Jv%U*;$ymb~@(1w|% z7YZ`XlEc5aJyIjY<7+l_B+Bs54(8$U96Zc!5$vF>ArAlQ;#Y6S;c56sdC)R@x@9}~ zlF!cnWwBZiN5VD9qX%oPzD~{iGcPY9pg>}B&G*$*kiw58kJYEinEGiJAi z)|Y-1914Q1tyHL{*oSnC+f+}C^U~tMyRn>ybQ*UEDxcWa-Xb=@-t;)z(c|nxmmd_7 z@Uxcm#f+qLXQbMPIGfSqIA5?Wl0OC_mPT1I;@BDEm>EfgQlsh#*z&AO2zKO*9M;qA zO+5}HIpakNvaIiRD0v5)YZQ6UD5~-+PLCch)+=$C@t?_)1FHvEl_aq9IcHoCurNvB z#1k(ovR4ZO2}_kl>Il(7pCvr6R>7qX7#11F)*46biOVBeOQzUaJGbI=7l*&`psx@M zd~SqlhLr{nIujo(aZ4B_4_L@ymc2XKt$oH;EawEci*3bnPJpl2Rwfz(oV2!LIVU(x z0Un-Pv78fd!Pi!uAhcB{2yKN|_II=Ah$kE10mdGZ_*%cel@y5gt)8041H@bn#h~k)f z;v9*1l(tt|XFEPIjd7wg4~$~Yapt0Sy>RkS7rWu(+`q%V0({PUnd}KTeW;5q@^S9t ziE|-OoO^iUoTtLhGOSbsvOY?_6U6J~`0s&`7R;3y=Ad&|bkqtSzC`F;X7<(-z$grq%NIG#<62Ya#5(Fo662}DN_uti$vCSZ%S&`iJ<=`Bc(1d{bYLRY^IAMIzk zgTP6UoCN8Zn|+AmGu5Z79pm^-@u0Q~IFO2?DG`itoK1N^h*nODb)CJfgBAWQJ6OBb zfzdqRh^#0QAhPLrX9A?PI6f}~NNaJ9mLNb{i*r{10n%EW(llYe7M-clRy)8}1u&o#Ooj$cy6p1jvhV4sjqr zVvTc#!)chC73dgO4sjq*^ASP_gaeLnAP^2X#(_XMfV>Hy9GrCH_~^!Q(T(Gw8^=L6 zjuTZ}oC05s<}Sc9|RtxE(a;+=t* zNI-eqG{6IAQ=P^H)VT%PBS5Qa)kz~e84-Y_9${n=s7Dx01nLn62m$glJ5m$~AB+G3 z;REU=pbxmaAdYqyM>&tf;cut&;qnh)=;FI=?^2-bThXTw4wMYp@2j+$9qzB7na0WKF_A^*=Bj7HHPDEB3 z#(__9wrUdK5Ef^v;{NpBHcs^Cqq}Vr+j~8BGJu|){Bpe+2cFxlTI>77qPe> z@9*Z$olIh_i7sd{^C`VoStXFGId2z*mys!}m35*_w)GG>uG!r1mf&cwtn%`DX~5k^x;{Z!48I{? z+?Z0=PA*+BCb*wD(Zr0ec!4>K-*b#9Twv;L*kHriq*-7Z(s6Ta++1VEE1%1uob}{f zZhW@1e&Y+fQoD?P8_WlduQZe1H_7FTr}M4lw}Jdk##CogO*LoR+^+0HcvI=8ng!|K z!;EkKio8DKf&nm~K31D^`>-Yr?R4Rya6fZ`@e!VA!;@{e#`pp?#ssGGcL;xn@^_%c z&`g_J5ScA*|3qYUg?6$r}PcOEZb5{fzww~!nz$a$v50N(<9Db|RAmGgEk_zdxP!Owhw3;8>bzw`O~ zFn<^Ex3BR9N=aA5?|A--Ev`=#t^@no9$C%PWaIOh_$qUZS#8#sW5MV;v)*hl$C-_0 zlR2K$T!jo?)#u3Aj0MCCMj=A89Up8agBCQJ*~noqG?|^|OmhT%a*{dOoMJXZQ)dCi z0%Iz(d(ictDfAiOBP_6Cz=nl3jM#934aeDVj17xzIM#+0HY_I$Gd>k=wPBwP87agJ z*l-)6&+KDEzYQna_?W|uHe^=ppNJgoLa z)Ag}Vl5T@gEy~pF>FALbOj<^)X4>_nR|k4sYnFOnM(TFgeZrS(63-ukupRA zt+w-$t9ab=)UIkB(zAzwXv0nLb$k_dIyzB9Ie`m?;}}_una=mzDP4dJbyE9!3ywob zM(7ZQx@NF9oYZQF1`|u-eDRv)Ay2}D*k(3WtC504T?H!7{b#f^1MfSwbK`q$r&ov9 z)_7JcY1hmZ;3d0fgc~o98|m47W!9}Gy+=IiEibJrzs4L4;Y*Y`*l3XIO~b&wIktYJ z{c;x5*Exu7O!$kvwy9@Dt|Jj8`WB?;#K&%1t0zR#ieiahqC+!%P5Q}8>G8Z~TP|k= zSV|+$p?glrSP)V+*#rI^>zSFG+EJwk6{joGW|hua&y-GGi{2|X z(t~n^dIdF*QXO;5upGfEHsi5GVN7Y9fUi-&5jwylHUlJ0OMy;|G=DDeO7UnapJooD zOh*M~N;Zu+dh&9o;a%;uS5SG(aZjVyOXt;|N70+#ZF$*@%`4NxO#Yk*R@RMNes(F2 z4Ubkvl-|x}t(1A_io8+iwQ+Syu9ENTsV zWA+$g#izZ|;bBthp42rbc?=tci`?iKIki+hr$TB%6eULOD3N$2?1H)4WkWmzYm9}! zqa6uVE{Ev3U8z^)j*Wb}eV5~7(cX@a?B2{88`WO#jW{mC>usBzm?DZXW2Jo5qZ&jJ zNKjcO)iF;lWpa=5R>!wm`-?(Qh7q3Jn(kac4OdL`qf;|>XEI-(TbB6 zova`}q<(iY1xu`?Rm&8so{p)H%f!vpTB#srbyL>cKcMv0?;cLaKSzPKlrwU`ky>RI zY#e%iH;}qki<9H>LOIM(hcC~1d)H;n%=BZXH}=qnr5Z zaVLtqxkUoHdQ>wM$Cl^x`X1^To14o_(Abd4NaM@RVJw9qPb{H+3B2B1_O3B-^zafq z0sCE-wc))|;2!B_Kd0h28AUuLBX^l#)Eq>Ne$Uo#U<&HB2ftGel*5!|mtn@{rZB}T z!K_BQnUc#VHKNsX8tJZP6FAtI1Ba(ljH8Qmx&ys@j*Ccj&iKB>u)XsGM#m>aoXE{km zS~6p$3y7+B+LWd`x4puNQ^72JVeu&G8eZLIdTyBr~m^O8%W zW(93pW$9jR@Nmp}898&u!#az17U;;gbZD-Cdk%g$w`iA@g$D}gvPI?>CNZC791ENV zqB=Eq3h@M?HIyN}Ta|h`x+_g$cAoZq)*8}gce|RCZ3*@e>rMBLu$4m{<)vmBh0c~( z=`1y_1fe4{vF4H?NI(SlCbH2Opr=Tv9uZN_q}H^ScaIG9Z3pNUkvk|nd^naRGIUB$ zW-0)NrSGkb>}h~f&V45==95~+p7jsG& zmD#nq7MhOrHdQn|?ljh9c5z=FL(Cn0Jt)6iTTi*-3!b8%t0c)vr-|N825Hq1d#vCY zttQ9Fy|p5bPk4RkMxUqjrb|pN$Yp;*lV{;jMdIq3|J=-}FETJ@n-H^YrjBzTOfH#= z#rj;QwlH_)m*JsDn!6ZS9Vs?YwrUkS%0`(a3XzD|sTRScN8q7hOOIoySG)(CE7vni zikP!4c1~_~sP(iuwK5;x(V&&~H)M+&yOErlr_;o7bnd%mE_I*mHePG9O|OoT3P&1r z&VC?xt(|!1@Uk*_b9<@P+Lsh3?1`krfSgV-dY;Vu?FOuL$zJIbD~8uB63XuL{Q5;| z8q|4hSUtR?y@M>f9QBS^2apY3FuXu1Wlq_1q$Zv-I#0;v&W^NaQnco?>~WnfAmsC2 zfpNodFh`~OGBZK;5{*af^ih28ao`c#yF~NY^*|!# z;^Z(>)JP}mnmp!xOPm&q&S^QC4PuAA_iPfD5OT+)#-Ec4ByptKM44nPj-}@v14^mVsBE6k@}vxn2&V%{i^xtdv^bP!@_DEf zi`R;-U=$KP^Oc9LY)_G4=FP#oy~n~}5uECnI z#ZcDJ4C}kZf)U+j}(*VeqAYAQ2qlON>InB$_lml_LZJITo%C+en z8WPf+v2RY&bfl65rITWuvS?0UPwYr^Dw-6u+|x+?j){77nlHn+?`omsE3Y0;vT-#5 z|EkfTko=Ni0v_YYF3V$UqHYaoN?Wj}(j>k+0(Rrdv5g@}I`))T1eeY1Ju8Msc4D<6 zZAadk&|N=za4*GnydK?ut)PtWsV0vtdO0&(#Zy1B;m*ab!w5ChtDo~(s-PRSA6D-P zrflkPRv)KE%j)gyQ=*EDO$-ReOSRBsDfP@va>R~Z22`Rx=R#n{uHz{qU6?r~q>g4; zRb2U_Pt?{vQz)Z|+25N=^Vf#lny9ID-{nl8HBzl~pGco%Por`pkSh~z1Pe~YVde;) z4z&(6r=Z5^`7oRj7MX>(YFwDL%CmceKSr&l#E? zTD={gNx8!EC#mXYP9{$#*2^tk=d`s96SlVVBJt)JEu%Ry&kRB7(w@&^8<1%75F7G3ARB>>rFx|~M&jYei`8IO%RB5q z_gb4NkHNNjG2dNRI~$-kKwSCGP$>aH6OwQvmhF^A&soW}!Z9_oK$A#DJ=ehZO5}J1 zTT=~XX<)g&^jH_L>_0rO_tg$zyj(LLoMx6|pOUoqx`qjvJUJy7d;Mp&=dv+P@wrpF zaJlD+T#H^iEKG;tktbH6J`|kJQlg>dO-qi=(Dn&a8TQj*9(6E^lVB@nkq^(x{YH*I zL@Xr0a9^+(c(Ny*kxa{uCS})^*q|0ztJi_*DJ=>{%``jhti`8rty#(Qar~_$)&$w( z%p#^K+$8_U08atgsxmoY3x$W#VzXJ(iR3X3k)ljdhsT&@5pse+Ep=t`<_l1+C8D+b zQovAvn%eia4o%@=KhEmyK{9&H;uoA|ZbMOGCgoHx9mQ8Q8*Wp(BF!1to?yp=D8h{n z=QN@PR=4!6(vBPUl`}p_Atnrq96w?mSo|~hhLkE{M+4O1UM?2L+w3Dw=W$iPuXS%2TqZZFmGt=V! z41U#O^_u$6jL*~&13vW$F3s!STf05!(v#vu1^N|eG0DQwbl_YtbDeV84@}eKmFet!HSh%u ztPB#pnNK3R%ww7hMAT9WbDQgwcrN#0(710RKFK{2nk2yK-Baehftyk4GaV_uD`SJ> z!fVMV)o^k8T_s9p(7?`K^Rs&c=7@;$2Zd8FJcD*Vl4TxdR=*H_gK8 zO>ZXF*A4LYWiaMOo)kL2DP1=QaK^qKHUC`J{si$OCL$ni3DQ@tnrXe|7xL zA{1e^6ThCRX(o;K;Hu}%)tnnEjyH0hb)Z3f>;N@-(H^yaf7*-zjq~OvtZiekWlL#Xj zR~m-kQ~$VGE_=42tl}drc3OE7mejYV*c%jPmU>sUiT>Joc0+;t6&7GYC{GtKLJaOYh-^4iP0D4|-kCihcO zt>Xmhb@37K5?0T6@9K5!&qK^5L@lV)Za-nw+fT{f!U>r;?E-Y#JMmd*8;Fl#5X+CN zS6r#w+#J(3<3-0kcIIq^^UUXoTJ2ha<8o$_xT7F-c8(RcPb8VhRJLBb1SjOCSeK?T zvw2NUPBD8&eUib1eaR9dyTq!`G}C9h!+NU>+L<_45=yD)UFrp}3?}m{%Y6KwRVRHw z1fn4$H00ac9Qpxg@UmQa*ITi1Ql`fxYHe@3O*^@GtD}M@ORE}v;=H03H_^%Vk=+a8 zp5l|ab!6rkS>#Ni-E&zuOO^-r+|JQVu~WuiS;d_7$g_00oX){G)7*^rmQ!WiCOS#l z>NV|5b7=8Oak8YhB<6Us`p0fJ+BR~{j`wEjl%U`_{r&@LEtXw@EBR2awee3h=Xkqp zk2?_SBuzTkd)XP}`k|RmxXzzNO#5Q+EqT^i`m*`3XOLBCo~-Zj*o?U1bORBQYniB9 z1f_8xT#72_x0Yjwbx!C1v^v_g$-vwDrU8%P7^=LY@ucTG?8UMw5KL zoQ22}PMv7!W=n6czk0C-UYcu>w3=P}o=eTOyzfn^p5;?gq_ce5dYblJk9dIQcNsw3 z*v_vDnwq4stkLQu9dUW_QH&gmk7uS_joPu4UvKF!qnT=6_3$W6cndp{ejV#GbN0T3 ztXzlZ=8}fpmaa+M%~N;0jl0=!(4JMpbGv!m(S?&=G^U(n@D44=!-1#mdzPRYv2``Yn%TJ0L>>Nk2qtw#L1pRX94xpr3}!y3l?8DOnhx_4`7$oIo&Iz+)&> z94)fHp^!`ST#z(W=+|o``MQgJrm)6BQDZ{(X}1k;vEi*8E8@3L7g4Kk3 zaPr=QqDXRLpeQoNUsT0UvA-zfFY*@z{r;*VJtn>hLOoXhRC{^K1z8Um>8Zm>7)uNE4Y) zbz`Wzmf~naFdCp=!W&d)_;?#a3IG!h1q&jz08mvF41}wN1KNE!X{*EWVm&8>g3@52 zs_^p%V#!yp5~~Ys_uJw_dZD-d6@dzV&G>MK585!1u3%02rG^&~(BM_--@&T_Mb(A; z1psp^T|0O!L26;3D7=lBF8+2F71?6Q#8;4^(8kzq<%JKah4v-2ke1Nx;lWD^NZ6$= z>QenXg`jPbuIfNhuplH-iTWeO7Vto*ELfuE1wzWXjsCaIsMdQl5Gm#%G=^hMB7+x) z^e3wDQhW6)RlO+^8ubV|8J9C>S6IX@$<} zLWPwOfT=VfN9`m888xQdUsUej&lKns9)c4UoUCBAf;Dun@t{*z2WQFUZVA){+>7yWw#ueRGmbn?_0!AN8YxUO>lg_F0yi^9oU zy@=|ntSImlDK0Nj=R^i?DzAoY=}mr2puD`QiUA$+SHq4NRH4XJNTRwb5I!ORBFae& ztAN@dgYrNC^bkjRd}inX57-AZl7tG3FH{a0RaaF7$B97b!SYabRe69yC@~R9eW88N3^U36+CeH9r99i1@>U4+fap z7*jAQo=kxr3&=pvDhMiI1;!L`NRcTRqo9aBRB(#|CKtHI5;}i*0fcG_LJE!`0DVCI zn3`IC>OcGFBLCn29t;+gm(x)t{02Z7|HDSS@Cim}04mbxDK9Ul_W)CkIQ?CAsqQLeXYbRaHeW$OrK3K37)-4Uq7m(D+2iLQv{#_cK_~D*V6{ zcQZt4_?y9BjK7nLi=eFUk@O<)n%V-`p_$WI4RQWVta{&%piT>{#|77HCvm)@ZcYd zp=f?IoZ*o(6vQmgyq-`P0c&qtG!DKE!cNt!a&1x3{z+eC67<(8wDl^{6>fSd3E5dD zoGeUFTO}c3fcdMW*v(^nDoIE2SUf(GET%z!EH6bkiJWSiIZ1d?TrmuQhMXGi1cb<> za3{mmuh*c4IW^k}tb|cWGFChz$#6J1o{y2_l*lB8J;PwEDd4R%+-88n=^N zi>??GETs74e98n@ZfY$lcE12e0|$mc7;qpAq(R^pbY2me1QnM{av^5>RTOtH%q4*pCuc&Z+gOI*?=_UjQY!x8q&@$QTJ8N6I? zkhSeH{}P}1fKKCH-?J{!$5k59j{azCqPH*6!a2OHGolxADi_6CJ$+9B5gm z4AG8m&XkO|qI4l>5QrhtAsr!U68cvx%1R;FJYm127&j0}IC+;o&^J7R6dMyx-ZO?r z7s-nT1nrb4v0NeTBs|q3c8QHX!ak>4Hs9jncViIZMat!xCrTgy_flm`_+0@8X;Uy( z!8iqivYPfwjP%p_V>`U?rn{1a$=6=#yA9rz& zgV`z=fmAbPwiG@1D3yv@sew5DA8Sc1{lZ7bQXef(C#OC;k0~kti+9=wx{QbN^gBR_ z%RL$5WI=wa`4ch*pCp+g?2JX~P>CtzRj7k_>=z^-B_L;k{k2LgPgVN{k^Y|qPVl1t zlN*K}#NN~@K8m{*^J^ssX-NnfbX9pdq6Xrs%Wk7Jl9W&*@=1lDP%*n~_&5|=RT$DY ziOt2Z^lEj^Q?>)10vHtq3<4tyq~r!Gk=PH8WI)q15`m@e&|Wcyi>1aeVnP-)6dw%$ zY7UJ-TpTKnZiAiDm6B+YcLLIXZ7X+4d@M(5G_ZM_>e0i3lax4;yjn6g2$h7hizp8^ zhqNKo4PkF^7d?!8mArx9kbXrT$*U=sP}7OOyn-i-r>E=y`wTiIsCd<)!g2G#^v_eG zHO8ez9myOYd=k_W2i6h32`fzq@(^sRf|Evua0prlXBM=yD*t~kjRo;l5iEL1alz%V zLm0(M4W~O5++8U7!_Q-CoJQ6qwgLBw(vnw{`~9e!PUJw-4v@zEUs%F?I<6G-M`j}l z!T^SNiG35VnWUN14G2BF%5$-O5alCONf=2Y;UYo!eZE73`#=gJ3;m;BaDe17Kh1xX zf0Czn(bFLWm>}TaM++DmFHurj5J}z#Y5PNd31E( z*Q(2uIruUKXviK9CFBCB73q=iy37H6u%!cK*Zgi6;u~i_$PbydC z4`P_Pnr4umMkXH=SrP*TNY&B=NjdmrP;dNB2##Sc)Nl@!qfAiGzNc-!+9Fgqmv7>#UeKEeu%N^OkKT|pmI=SEHvCYpHWeI4tocn*Q_`|aS|Th_iQeC`L(`;3 zl^gEv8_y+(pOK_3o5GYqRbFj@&}gPeJBaBOFP)VLKcl)7WgpNxDpk%8`6;tt*cXzx zBCP6B4e}*tRx76!&y&yF4hi#1oNK1-Ia~c>1#9dC7fHS#1i$8rdcg{9@Q6b6>u~ZH z{QcS{f5Cnqe9a2x5Y`Lj(xN5&x`59p^Tv+3pCN==q+M@iQoV|+B5SSJ_tbhK^u<0f zt7u@a_w%PtPrhKg{xu;=EG_vv1!?eTAwxdN2-O%Aar!WU78ne+R^>>-U@zh$cAb(E zqo+c#rY~Uz^ROqKTopYK$om1AiNP0RRTESyTi|(VH=rPy>QVwN;@R z8aG)B4H~tSUjET02A&-SPB^TvV=0{SjS0#i7xFVItE)Eo3UTK#wt-`cU}xdv%P=AR zSON~&CnO%AWyXLc#uU}qR3Ml+B9dy9y)5~%`rwWdH|D+fixl~Qr?>7TH8yGJX9)s> z6&6xQkeNuz3e&OhyL&8UHd^|oXbsA7(qunlK^lwnh~+xf7#SnFS%Snu)fU7cwlNDd z^c&WH1mDS^kkp2faB@D- zKEVo72|ad5+9&$Dgl?~mjPplotr4ddiYW~iiI8oIQl@>O{~H!6^|GLI@79pwqLv0@ z&?Ueq=#!PR2CvYg|3HW&E33+&=H2OnD1#S?#hCBJckE(Q zd6gEc;J~&7|1`|nSw&bZrVF5trAhkXZyFb}WHI^HI-&iFNGj~6*(+!iFW3!TiK_K- zw0(&Ksc-~FO=Y~J=#!FfcJPS%hm|* zE3Aa^8n#GDy2-cP|B`f*PR4l4b&tuIGYitz$e~{-)>=RdGFHoiEURTf#%fvM3M&wP z!B5G7y~1iTh1FygR+A~L#uZj$8R%3?e$|Q!r|RvjGDlN)I5l6k9thi|*5YL(IlF}U zTmP6Mz`wsjOURIhOS2e?o#={S0h#e4YZ~OLW#{q1(r|JrV;?S_e84KUWmdWlrxJ)?Wo2a)RaWMTor0a!CZ$!V z!D@f1CTL`=OKm{z@m0YDT$9OhVRJy}PvVgiJHvvXbctJeVeVmAoj{B{hT&m(3|TpOzyNG6buu#=^-{ zW03SQscz+yEz$vF6>6~$CJKv1Fkqp)*Fkx&(x%eAy%P{INH{Uqn(Wa}X#Y7#(&5wv zk>mw5TnnC(Qp3q>T@lwV_L&9ixxqBrl^EF4gE6!}+SAl&nX0(!U2)f|%E7la!+~jubO@xU_{^rIJ9-l>1AAqYODpm;`&)MXNBYddG<17a{!rSC*%t(tg)oto!5Y!~!l{dw`^=H=$(k%&Wka{j zXO2)oM{=p=>3aoVR_Y9d7Oz(@&a^CH`}NWYx&+G16;+YJZ&XRsKvg$P39ms~(QvZH zMU`XVNL@;7m9+0~F!hl3HB!j1Ghb0sJD^$;dS4XFsL^a!WBI9y<9{r~RjQ38QswzG z)ZEDW^kkpJSofp}r^d?4GqCqm`Vcx&SNkSo^sx^tumfRK!~zsnolosT0>yEpkOaF( z>42xe8MbK6&?R~@l@&hbpR6=|lEp7|4q6aep2pMVYBX!JRZ=ffHxR+{G^*<0H|l(5 zIydxobZzU3rZ4P`Hg9WdW1*lk(cKQI)x_%R=Ih^dRs!mMW=8rR=n;~ozYN{@s~mRH zudel(8h4#@bf72N+R@+J8Q%##MEeKg-L2d*7ad6K7>IUp=a=%>6^2psboFSpBGIjj z!&-;(NUV4=<}(`(TAOH2?5Oi@)Lz=P&D|eXw@UdoZb>9Mb+;I5BmbuPO!UaamiQSR zJ$=zO{#@bPl`87)J_MkpQ0o$gzV7Hw^hfzRumucdr{(6ap3YAAfQZ?Hjq+%#g_BYS zKkUO}KC7H9J==wjEuf$?5j{Pzvwxtk=X6^^N6VHd_wGgexL%uO81Ckb_HXIw8)(@! zU=v1r+M>V^jraC;cCeJg9gWeNL|uDbv}vHP^U&4NmUy>?{|uISqH)+*_qJ%qK%z^1 zveIXc$^ye{4xsdJ>t$)EUu=)`YCri^Hfg$}i#u)QYN1V)(BhDl=boAY;tv=N@#N!* zdm-K8+#KRF)3WN%MT1(Eu87j7`po`IZBN61hp^eN^(vOKy1AE^M2GuK<4B3(+Xi~N zfWHOma@VUzxi}JZw4TO&X*6-5e-Bl-9*s7~`$)9WXV#8Xg-g`TrLlAsH;P8Vl}Fwd zeH{Zkqcs+LEV(5*&Y&aX-8-YL@I!UQ5zI3qm1}Q>tF;7H+q`XHfMR>Oy*LqV+tzJw zPWnJGDi+q|wMQAK*Z&Z6_DkJkCR5PqGln;aP$uw-*DYl-fk`gwRw zE%q{an8eOb@dZZrp`#{hX7HVE$DeN01P5fW%*P4>;nbZ6`po3K+-aidVb!yzTeJW? zehZKV?^=52Fe?T0_Vx58`sm7Ga=<$X0pd#6f52zvuWnIe+&B`6LpTYB6htG6q}aa1 z)@=#h;ume+X@@ox&U!6C9qcm)jFR2vQwbW0H9m9T=;<7#+Jy6brXf3FJeo#yOHZfz zK9Okc7h`HpuvDDpda6KdFgIU6;!8&x0}N7PIHft}o|}_jyRf0*kmh&kLDGg$lZysT zRoS&O%(xA=+Y$Bfsm|}U?uYXc7BExK9cte=X zPuOK`t4mpdBlQGErquVs8!)W00A6UNn$#0k^mq)7UoTPl>aGL>q>5+9QjIMxnw`9K5^G@b_9$m*TLnqca;wk)jiylH+K1S^) z3S+0ltCjl)EAv=znqWXiZzh}{s4r+w=lw+vL#gNK79U_iBFmMQA1&dGaZ9_>UVxhq7|-uU*Q5z!K@S@13+~S@ z7gHe1#bYd?QGPhNM!|Xon-rXcqG%WRldXE)qCg%{$zBBm3U(;K&J#`!DmY)ksg6Be@*dj~~OuYb*T8p#BykL#{EygCb z0$GU-e6$tu|824C7~8O%J{{Ck6#M!j1LX6N9B2LiOlZ`OR+Q?g?&WOzGU#3gU4u@NA1Ou%aP7wv9$$Vi?-p?7<2TH z4BgGu$Phz`&lK)ZB%+y@bN3K zB5q4hR~IUgB#^|81R4(}mzvex2&PusK|kWly8bP7>jt<0d7bCARjCeYVc>Od>uN^p=xNgo--mS1OJC3S{{L<0ZUnkr zdj%cx+_o+R+y7nkS-!Vv&onf!vsdJROt)d`=$eC*&)1U{p29y{@|rznlH9hjFW#F` z@dpQe=B#1plExF=PC~21q;;lRw%Nt$NaLW2tsD+dyYeOT06hXxY+3BHR9fMxU9L)BZSG&h{uOBbu1ke3^fG zwhgrRNQ;z4LUs&Z8x9@~$YT=QS5m?VjoTrUL|%nQ4s|$|o;}yPM}>N*oDu5n-D6iY zS#>(c6eA;BE}W<^-5t7C-lJ+kn^yD(KMw1;WSvv`vJ7DmPDgup5B93`NbvHcbsdn;+>Ev6=JFA+3t04=itapF?$Fv@9Dzy!<4X;KLCU+Zqz7} z)rRu)nJ-|cU%W$;i?vM7u)_>)&*YI|2@Lg&YV2w3%hI+PuMFvo)@<-jgp^lz)+kxu z00GvFMu7Phx{QOrp_g9D>D7F8=2?-PEpcEAY^$TYrE^3hrE_V2ja44%H2HCYI%$XSw1ww zdM3K9yHi%kcjy|>I+*mCvqvPzM1M=XHxX@Go5i{5X5Nq4urk`Ztxu!8pCt$>_v;g# z-H8F3kfuf(Pf}EWmm!PrhQ4+7bZZWip&yVaUzsfU?@M)xs|xTE_9tx**12A+q1JRv5SgT=V7?t|A$&$;AHpGI4X0!fi&AerZ zO8uDpx@$*HToY@Yp23Z)W8{>>iEYZM_t#{qWu*lD4Kf#!y51w>9?*d^U%waw=XIOoi8azCB*gP!Sv~ESTKH5dqQdclyo$E7au47>&(N)*f)78t6 z>mCq)?yO_&R2-T`pw-Q%VFhgJ>Be4)P(CB-GR%k`CzSSdA3nP-rvGL{o3?chZ0k!L z-ksPs&=>E7m2IQ-Eiml$EWC6d-aKz!d``=px%KmB%}&G`=gX_GnhlM1*A?yn@+Mf~ zAA?=0*!o`bCYKmR+V?_PagG3VDS&LHEH309&)BW3N{D$W=qpw^D3dY-$pH~ftUTnG zIfkq?Hmme!_9R9sLL|i-CQ^agh}8m{k+WUMAKjB_pRx$P2CXpwKHoFKS9Dj~mZx1-pDF*J)Djln!1A4qe zcl4~&Ds+(C-XFp?waK2jqw|$ACz(fi*11PmJ8n6HUQ3VbTt^rj#K*$}6;*PJ^(JQ%E+X*SdkCJx? z9r~|dM?C#ckAQF6+v2wY#_+>|)J}KWy+(QVvC`sWnbY3~ zQ+r#Fx=d$=>O{GJ?9uA2dkcb^>K)kTv0-tNZ07BCbpHA6Yu{TX-c%K}lUDXApqy~L zH$`Tj4xTK?9ru|DD!-GmZ*ly8?U3zLbCEDQhTU1?Zl)CT(tMdq%Wgi)MNplYt$xX; zlXp7Ad+y$3609T8Kz>~wO-fYp4r%jlRhlcFlwF3SEQv!Bm2_L8j&IT#f2};b(OPF3 z^I4?o5IXd$lb|xkT}AD|Z!wNF)`4_8n(}a_OgdlJo$Ra8ta`K0+jCNb&U8})T=Ds5 z>S^kAjg$P9Ia*ssQt2|GI&;SV&E+D8Ev7Z^?T(O9$Ma|h*Ur#+wZdi8WS?joO+%nq zPim|)$-{=zz0SYO9M$E{n9C>BjO?1t6x3(BU~2ePsRt9ETZTth-t1OKiVgIdSmk=# zznQa=MJ<`rm;e8Awd>%=a&hO$wf|SAwGLjG3s1h#G+c0-VS7bluy@^^cz}j*2UH?O z$P@Zbgh_5hNMO!lsdD1v|`mR=}_Vfr^Blx zqwQ^>Bf{!f&;R5o^1*9!yCS>wnPVDK`r%b~|^RSdDZwDBM2$-Xwxp4fpo6qAoTd_;RX zwab#VY8)o6*3MOSO0q>#+tBcD;aeuo@A-PC)`wG@4ikOpUH9T9nWRS&5%J6E@J>EmoYtgVCe)SV3k)*N)9zC9BLw|%l$>1^oHk!b0Xl} zAH6tVgVaD(v>0nvFUfLF)*(SjiFIfpJ#HGc;C`U-qSJ`P^`t0dPN zwg*=imhi{E3^~fAE(QwzmpPHD410xiGN3l2=5&XU9!Xt=5z?=%J7x5kEQ95}ZH>;$@|!Srs9++ftk(X0oa!w8@xn%n=f) zL5#0J#1L{ofpa|(VsTY%>_n1jm0q`%1DSeG8`+f`AV{jpt$*dcuK6(6S6I`8JWiE9G<1o z-8E8YR^}F@c`hRmOQ(4^g{6JB*f$TUJ)q$03gpX|k}qFMzI>@C6+ERtUVW+OlI*5R zZt~VBw3wG=+dn)OYnUC=zuArUXTE!j#pcEuY()C|oQ65GX4lWES4tbNC;n!&#pceQ zJEtwt(ioeUXq+=Y(bhPpt*v=pL;b8da~fObw9K8;*xK6MHoLyQt+{!AeY~+P*4hx8 z-!`jxUQ26ZOXIA04K2-$iFx&{a~kR!S`u^S&TFYp%xRw8(3+Ut(%P12ZHqU?=gh93 z6RV#$Z*FUBZev6J+~(HC*qnK@;%yCyS&j1=V~JRzVcxu!2FhriPf4?yTVsuF@z(kE ziMfE(7Hg=dmRYms&YwM}A(ogADDz{@^JB4iqG5JC-b%gk`uX$c&P~jo*W5UFc60Nr zIq~LL3;$-v8XD%u;*{AsXI}H%=C(w`+*xh2+UB*+p5NwHW5VZ6!#_S`7j`CVi_Uug zK614=rl)(U=UKgei#(!y)7VyHJA;+gw3GeNKAdRH`aawXxVt%dDxG$M>ooki)@@02 zW-rOS-);ZnZad0n_N_Z+>H1}T`0Q=(={tRfw&@bkyl9*n@;R5mS|1O^eDruvDW3#?ktwU zXGHt!`s(DOW2J!eRu$U47nMF!?hRu{InKSXF*d8Ae)i%ewTl~O&##?5r+#kj;-yV< zYU`KPH!YbLYnV0fNUm=g?=uw+&g=@t_)KsuZVd5$ITM|KWq~DO1)tJ$bm%qb;qt6> zTol^W)3>Cvb5*>f+jOz>_ON)R zTh8C6-38|HfZp7{#{;u@IL@pyn+bJk_d2tJ1AC9*eFfn%p7rm+f>-{gBg5Ta1RrBP zNA}~oO#4q5^rxS_pCvr_C{<_fd-K~0CLP&M^lz$BuFU-sy3bz9m+Tbo-(3YWfYk>~ zniZY3V|Ym+n??ubyZ>gR$ASY?q$%WeT6ZfdmTX?fP=_pV`lm@si!NHO%D0w8!G&(e z$%aYhH$m%e4~AXwZ=oq2R>yIanYlF&moZdET?ajvdwpivCqbw7tG|R1rQB(HLQQOc&i=<>qMb%v|J^bn44$Org}}kI@pDCwNsAh>Op6&a5hk>#aa%O^dkz;eGcA5 zdHuZULO<`~KBaPfR!13HAegBp(#w^!ado;)Dqr%FM=N@By`JfFj3MOru0vJoIw(f! zw*EERe)aO__vq+-dN!A&qsY-hS%jAG=a%m}z<4%oXW$r#_G)r4J=^wzMvX+LI{JSp zut&M)OLSFhf8nw3|9c+;?_=P747`tl_c8E32HwZO`xtm11Mg$t{}l{eUSM=r$z8Ml zUun?$?RYmB=#`m<8ezloyp&XqTep*~yaS1rDCV=?o<4h+Q2qX~YJD!P+-K-B zn;_Wwa7vHH5}QmUqU_=NZWX#yLOOIT-N!xjx8PhAibc}z+dM{aE zSh85kcR)7se1#^E@{OgVeI@>s&u1Qa-}!+;m3UBjrr%Sc_|$F+?`8ic7E%UPyP0R zanJqornZTbj!Jy)@*jR`>y4$iKC<-5b3XsTFRwlA_Gka}vyZ)0*ZsS1Hn#04)C^~u|Ru;Z!Et@-+2Xa2mt@bfR#-*nczuYTWm&k=v>x#oBKK6~`S>8H&8&jZV+ ze9%|^{g->2LrFm|Zk z_b-?lJ0KR_J$ZN4h5K$980bB0=FI*x>iTzfwKUhU0ZK0|eVwtm5=RS8h;51;S5(xV z9K%?Nt&AO56k^zL!inFv&je-fCx2^J_LkoM*tDTU{@A23BPQ$XjmIig#k7Jku@WzR zAQ0Q=J^OqGN5@vg_V?anz6&dJ;cXSXv4e&Z`1jDD0ScnF0}CL>!Ex6tSoiAAS)cgg zIp@7ncj)8a`L_!v_qEv(#`QP*6pWj8)eEOb0@G?AHW$6NqUy41{&QyH57{Kh_=N<0 zX3~^f?l|?+3#y->{&4#Z zwP#)a`9H1Peanx(bnlN}Te|!CV>%!BkK(5v+SXqAhfDke^RNHnr62z3Bdh-N>g1Bg z-v0Zy&zbOvJ3ck>j#HX;Ja*us=#j51K5pr?pI!a+3ujMReB1ZOHNE(6$uAj`xNmyl zi*?Nn9f#fjkxjqa`rF5Te&+A)JK+n1AG+q(;U8W1p)U^H_R8Zw{KIv(Z|-I^h(KGZCuJK0tU2Cz4Er7oK$wqEoE2izURNjefNsK^>yF9`Pn7E zUc29-#S6dl!Iy6T`pfe_zwYrVPd@%1=U(^AhaTT_T5A0751;!VRgZikIQ3(%o%PlF z+QYk_`_ir>Z#+7F_2#PH-%mK_*^mAre({cPZ`tpQ;T`*4`-O)$9JTJp|Jv}Qo646R z@yI7W{*mvk``oS*FPO9O2fw+pIUX(fc5M69@T%tXzWkN5wxsHRpZLyy{`rTO{>z-_ zE;+R4w7!#0J^%Xu9&^{cmY#ay za^Hn-F7*W`1Y&D5YzoHd@!jp)x2r@^sb#(5oi!dHet)cL-_cTvea2MV{sq%x2gj!E zK5+Mx3-|ZfV|@nBnY}IXS+(tREKipV0mI!VHqNVrGj-Ga9M+pNU-*h*)0I42z-)2L zG2y`H-~O+C0~_Z5b?epN zPMq+$kHx;f8b5m5kN)HS zIWuQ%y7lA7eecm#3sS$_dHz0c)!cRWQGclZ^apmOVto-mxhlMx)=$2_0Usrhg%zGa5tvvXw(mN&<9wSDL0nQwgj*cW`AO;2Z23=&~M%4bTx zvijdAzkJumC+7d@@`m&Nc*!d}?t60Ahs@#!mmj}j;k4c795&&hV;;EvrtTAuIcVR{ zUUJ`uR{s7Q`@HfmS5Geg%BuJU-+JlPw--GA)?FEwo*b4A%DhunD8Z8uFnu zlwF%2J@$vI!b@&Ar~c5ZQ@{G!wd4Q&>CfJH(uo^yc=aCN8>NBhuKPBh{KGltpZxVe zf8-};*Z;WeoR#;S)OG2<{`|NvTy*KSul+nyf6oz@-15TGFE9Sc;AK~qt@+(wuANkJ zV&9i9?>YPao1gpqH|sz5y@$UvfAS@N?)kyb&i}&x2R(4l!z-#!JmZ5~$L_uQkjp68HEJMx_yzK1kGkeqX>&$3q%X^7*3DwBE$^qy@W^PZT7-6H9&@ z0?cJ*x%$u>Uo__}o8fz@{+ws#KXdFa|MR&m51i;9cjU+JU;NvK*xg4xd(uUdZ@uTO zZ$4K0#Kf_3XQ*$mdPYNi;|VcTrOCV7ZfT7*=Sl|epbg=9<2ccw9w&;f@8GBk4xs4j zm3pI#`#Lyf+Uh$TBEXD2dv_|d3;pc({B2ANEFZe^w|_nRTgM##o1;Iu{i&k27Gx6@ zPJyxHN3*~>VR8L5^@n-qd|YM`vfEek`R~ z>85D?miYF8gs0+_R*rKKx$=c4^aLvRNq<(8IPBN8D6O#J3FV0#k~q-UX5q-;6t+{c zfPH6;as-8O6dX1!7XBLEQ4hQOj(=UT{^(CsMM|ETw)2VuHXhRR+`R`q+|+;iLtm>~ zbHZQ8J#@y$ntaom?z!p3rLVvIZ)bgT;PC^VzUM0Ae`D3}zIM;QEtz`y6PuSV_}-H5 zHbwd;q(0hl&!PXmYw{g^`yI4u>;8AwKmXTb9GmqF&6hk5N-cfS)NzdXvE&aW9oHGLHSUqPXfn$+o==}>C@yeUMyJ2_i!n$;3G`Ot1 zGaW@`6I9b;D-n#Kf`x|30X3>6T!2t?3j@>B^#hd^D$tHO{FG)l*4F2ZpFlEc0>#%| zw)2&9kB{B{%9bzv<>$rK_peSBojh;zXV>1i&!xYq`grk@?mu?@cGKChm;c;x>4E*F zk)ES&`@;P2n}^(e-Cg^B^JBj~{u*=VcgL*ymnZ8#8#?KbGv9jg%<7FRZ%s`6_0A)j zr(M(i?QhRJ?Yt?Wk1hVq^FQ9WsCxT~4)L1UoH6!;k97b2!iDQLj2-{of<=eEecLtH{P?T! zouwx}w(`O=e(|%WqYt?H_YWP~^o<*z*>cavj#&Ns3mWeWKXTxIw{CiMd_&JM8*lo; zMYs5$K4kI}N5AlV%MT}9+;HMur|df6)*EWplu!8mHP6NuEIqdRKO)DKe*CDnKL3S3 zwH-n9M76BFP3{e*!B7GHSC zbD@=&eEgCtYCpAo$^Kh@bnC$OXUk7)_~>yTo%P_4TOM6;!(op+@|#(u-+%4q{a*j* zSAYDk8$Y_>rv;xo^MHSu`h~i0_dfE~W6nD$^w-h{Z(F@9^g=~V-|bI$ior%OwGPn) z;Ws;5cn&$e3R4H--={oa6PfVbm>dWiSV0H2&5qXYf5c8qfzo|FLD{OmxV zH8uFcLZhOmd+7<~42 zls9BCw`JezxVij;<0k)b! zb8Oy@o6kQu*fa58emd>B-A`Q=xc$Oorrr3-BLY>=fA{A*|9#4qqMv-Z;hwIqy*}fh zmRT>YXzeQdNJ^6J?ci8FwjY;v;5DN`I?b?E}L>JX@(( z`VF0IHO@ff6;QSmIa6X$xe`5Kd#V*C*L+X+Ow0Mzn8JN@hu?Y_fR9BRyrgS5fUzME z6r)Im1@aH)&7V#q%%+Xu7gC1ya+Fl9xrCgo!sdGU7|kBbKbhc)JS^y5+{Xq!U_X74 z!JuU#8LrFkt1MI8;!$5A&0%4t6;)>GkXgel<#Btcs+8#ku_M9@#0U2Rajlzu^nY4~ zKvZAJ;5I9dxd~_7vWtLor`X{N0qeeH&i5cF*E8hphVD!2zP~enSaLLH3NvNKm=J#I zVrsgXGLS?5;WI(|5KM4jvV;RZ-&`&dR_JW}SuJmV?i)Mq24yo?yErG9*@o&P~cPusWLbYoGqKt6i9P z;b>rfxJU0&_iDcPJ)A?ia{G}0&bmvKMuA7eoP9gbIK_|edz8+2;CF{)m2>pm(QFN- zNX{xplWTM!_6}U2+w?_)q=F>eLAHYQ=7CBezURxd? zL=1R*C>q#iyR|Uu9v^B9Y%%~YrwtzpUe6-TiHJeKDTEvTu`}TE)qzm=Pszu|9evxr z#B3yc)JkOe#g6$p&erwCCB*cs;pVUIO;~ByA&px-@fNyELUu{WE(zI6^L9zdE(zHs zA?x5Bh(dlA>E0zFyCehv+q)#>|CWSM;ox3W0sp%s1ej>Ix#W0E;5TpxH3|7}wTIemIiaH~dV$J!zcEEI zC`R5C)eJ+6t)Q8U$m^1<5SILrUZKr8n37-BElv(q>P>L!mgSUX`JmRo8I1nP_p<}Ju-`Nny2ycD173h!psCO zh!orlBDOUQZO{@3Foi?7w$ASQBn6=bHc_wB5(@a^d-6BgTAyWAMPz z?gS=Zk5McLCVUC=*mW9iEOWK;W8P&&0seHsv#9;NFGHJaj2l2SrW!);gL%?dUHzf2 zf(9wdCl?YXz5pmdNoxb3V6b;F*Weh>zm)%fw^4=wnD_?n<=cWRpPOV`vF`?I0csnc z2n!OJ{rrJSh!~K$vVG25-S^~nC|jI7zEtnq7Q+zxRSOPNw)3F>jg=6wAFqS}`T3`> zDzsGz(Y6Ji{*1m1JiuJj&dy;cs$tuzf^4)vMBoUZ__6T}TJa(j z_ipyJH9jj$T+rhQ??V^yn(N80US;37)f`Y~Gu0MRAi>Ha9$PgZl{$ZYxVrUM7l@95>IIx-^F0t9@BbVJZzRTMpZag>moC77gx~`3!|||qUM%;H4}B{2Ic{Fg z0%+iJ{&V#6qaiSITL_$O*4dDx?u{P0SBiQEOBD0)bTr)&0v9^Jw^UNRqqYBes0Y ziQPKquG_;8^|P29JkO>>62TB)WIu-wF9okM;S}p%P6QBrXbckSB)3*a&UEGnKRpp- zrX()QUfthm>l-0e5D`9+Mp6W>57g2{1qltasHyigP`OzDVmn({gEukMTu@)M3RqHc zD}UFtO4QZ8NR&!BqP0ZsI8*B=n10@yII;*&qB~p*S)9o3nTe)nO)nmiAgE~e3wcJ^ z8&@Y*LaCY2Iub&3mRv1mMD<=BDX{jcn$_q z7})T+IsDV_MBkOaY=~bvzOTa4{nSBwMQ~Yw6bA1=>wF<7W_3Uv6sPL6I3^-({+x@= z2EN?Sd~H&OR|TnVL+3XdAREAuUVd*cw2ib-s(_J;4-ZA3JoXgq!$T&q{9caJQSs8g z2gU}0WXxzKU30Z;kd*Awe7~?*u*?{L$~%3|XPyHG)Rw90)5+C&d7E0Us(U~2(?nz#yr_539MQGrsL=MXYaq#xQ7PhZGM||dnF|ZW@bIse zM5GgnwP$n7MuW9xVY=RWXQsTBQ0zCx2J+i^^4w*$^jvRgB1qIih~%rArHE#V2<9X> zYVz&I-sJd2Z^~aCaHguhU|jz#p_Bb2T;gz1_|bS|JOV592kiP5uDWbt0`%AgJ~6Ki z3HwnR=e#MQfTUW%E&mdYlib`F4%&Wz-=c9}93VjCepF6Hw#jMo0m8I9-i=UOIu>I| zM7pa8fjjdKIsK;IZewbja;gxQJ^L`xI5ASGC6!l|y(zCa1%1g(Xha+4F0P>dkKfEm z^!!V8{ccl`y`Xv|!u6iq{ext?X@yD%?YLL3-zl4qd}|k4>}AH0;O<0ys(BWbHS@-S z4yzGOm?MG8;pE0=(GzKEOZf-&Z=B&vQI-TQ@DzyB~Y~F=k`cPxz%yhI5Z6^g0a;rIPN@X*rYevME{h- zS=+P8I&KtCkL&e~FDuc+ja3W~lsV@{(4c9!2J5K#SqWsSRB382Fg3D}Bn258p7NI- zK^k~b))Zku>h^ag&&$g=0Zi>Qz|?d$#zuem&yq_JmHU@MzI}{{$K3t9ybbXGUk-w> zg)V=GH!MyUTb!cy`yI1|la*)|O~?nf+VB`1S#%|bi*6fPKtc$>P_EZch}o(gnwf%M+o_@Q3~&6VRH?{k(MB}& z`W%`ex?FT1ZHN)`1fdzp*>Ni9s(Y>Sc;y(Jl72Yu1>J~Cbw^BVPpmjvd5~9L2UK}J zG2s~XX{8XWo=O7s85tv zJ84iF!%^7&OZVtRxVSk(k7ag6<#lOc1(}(C5e>c~GUeQ98gzIlgge5bp#sU|sh^kg zF(`&0T4#t_%hdgL_gN|>lA#s$(mgZ;r|7#hw5%!hibHzZSw12_Hct*&Wk$uyJ8=&d zC0QI~wded$bDu?I5HZJ!L%z|zb;|E1&0O@ V;7ac-4M6A}T^XB9&Ahd-{{-u_$@>5R literal 308376 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 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.gitignore b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.gitignore deleted file mode 100644 index 57de190..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -.hg -bin -bin.snk -obj -*.suo -*.user -*.nupkg -nupkgs/ -packages/NuGet.CommandLine.* -*.sln.docstates -_ReSharper.* -Mono/ -*.sln.ide -*.rdb -*.aof -*.orig -redis-cli.exe -Redis Configs/*.dat -RedisQFork*.dat -StackExchange.Redis.*.zip -.vs/ -*.lock.json -packages/ \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.hgignore b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.hgignore deleted file mode 100644 index deead95..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.hgignore +++ /dev/null @@ -1,20 +0,0 @@ -syntax: glob -*/bin/ -.git -*/obj/ -Tests/bin/ -Tests/obj/ -*.suo -Async/bin/ -Async/obj/ -*.user -*.nupkg -packages/NuGet.CommandLine.* -*.sln.docstates -_ReSharper.* -Mono/ -*.sln.ide -*.rdb -*.orig -redis-cli.exe -Redis Configs/*.dat \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.nuget/packages.config b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.nuget/packages.config deleted file mode 100644 index 3683a4c..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.nuget/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.vscode/launch.json b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.vscode/launch.json deleted file mode 100644 index 46c8bca..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.vscode/launch.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": ".NET Core Launch (console)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceRoot}\\BasicTest\\bin\\Debug\\netcoreapp1.0\\BasicTest.dll", - "args": [], - "cwd": "${workspaceRoot}", - "externalConsole": false, - "stopAtEntry": false, - "internalConsoleOptions": "openOnSessionStart" - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach", - "processId": "${command.pickProcess}" - } - ] -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.vscode/tasks.json b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.vscode/tasks.json deleted file mode 100644 index 863a30f..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/.vscode/tasks.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "version": "0.1.0", - "command": "dotnet", - "isShellCommand": true, - "args": [], - "tasks": [ - { - "taskName": "build", - "args": [ - "${workspaceRoot}\\BasicTest\\BasicTest.csproj" - ], - "isBuildCommand": true, - "problemMatcher": "$msCompile" - } - ] -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/BasicTest/BasicTest.csproj b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/BasicTest/BasicTest.csproj deleted file mode 100644 index 8e6c4fd..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/BasicTest/BasicTest.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - StackExchange.Redis.BasicTest .NET Core - netcoreapp1.1 - $(TargetFramework) - BasicTest - Exe - BasicTest - win7-x64 - false - - - - - - - - $(DefineConstants);CORE_CLR - - - - - - - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/BasicTest/Program.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/BasicTest/Program.cs deleted file mode 100644 index 567bfc1..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/BasicTest/Program.cs +++ /dev/null @@ -1,38 +0,0 @@ -using StackExchange.Redis; -using System.Reflection; -using System.Runtime.CompilerServices; -using System; - -[assembly: AssemblyVersion("1.0.0")] - -namespace BasicTest -{ - static class Program - { - static void Main() - { - using (var conn = ConnectionMultiplexer.Connect("127.0.0.1:6379")) - { - var db = conn.GetDatabase(); - - RedisKey key = Me(); - db.KeyDelete(key); - db.StringSet(key, "abc"); - - string s = (string)db.ScriptEvaluate(@" - local val = redis.call('get', KEYS[1]) - redis.call('del', KEYS[1]) - return val", new RedisKey[] { key }, flags: CommandFlags.NoScriptCache); - - Console.WriteLine(s); - Console.WriteLine(db.KeyExists(key)); - - } - } - - internal static string Me([CallerMemberName] string caller = null) - { - return caller; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/App.config b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/App.config deleted file mode 100644 index 1f6eeef..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/ConnectionWatcher.csproj b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/ConnectionWatcher.csproj deleted file mode 100644 index b9a01e9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/ConnectionWatcher.csproj +++ /dev/null @@ -1,129 +0,0 @@ - - - - - Debug - AnyCPU - {6756F911-BD09-4226-B597-67871DEB8ED5} - WinExe - Properties - ConnectionWatcher - ConnectionWatcher - v4.5 - 512 - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - bin\Verbose\ - TRACE - prompt - 4 - false - - - true - bin\Verbose\ - TRACE;DEBUG;VERBOSE - full - AnyCPU - false - prompt - MinimumRecommendedRules.ruleset - true - - - true - bin\Log Output\ - TRACE;DEBUG;LOGOUTPUT - full - AnyCPU - false - prompt - MinimumRecommendedRules.ruleset - true - - - bin\Mono\ - TRACE - true - pdbonly - AnyCPU - false - prompt - MinimumRecommendedRules.ruleset - true - - - - - - - - - - - - - - - - Form - - - Form1.cs - - - - - Form1.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - - - - {7cec07f2-8c03-4c42-b048-738b215824c1} - StackExchange.Redis_Net45 - - - - - \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Form1.Designer.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Form1.Designer.cs deleted file mode 100644 index 0ff89af..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Form1.Designer.cs +++ /dev/null @@ -1,579 +0,0 @@ -namespace ConnectionWatcher -{ - partial class Form1 - { - ///

- /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.Windows.Forms.Label label1; - System.Windows.Forms.Label label2; - System.Windows.Forms.Label label3; - System.Windows.Forms.Label label4; - System.Windows.Forms.Label label5; - this.connect = new System.Windows.Forms.Button(); - this.console = new System.Windows.Forms.TextBox(); - this.endpoints = new System.Windows.Forms.ListBox(); - this.breakSocket = new System.Windows.Forms.Button(); - this.demandMaster = new System.Windows.Forms.Label(); - this.preferMaster = new System.Windows.Forms.Label(); - this.preferSlave = new System.Windows.Forms.Label(); - this.demandSlave = new System.Windows.Forms.Label(); - this.ticker = new System.Windows.Forms.Timer(this.components); - this.label6 = new System.Windows.Forms.Label(); - this.redisKey = new System.Windows.Forms.Label(); - this.allowConnect = new System.Windows.Forms.CheckBox(); - this.connectionString = new System.Windows.Forms.ComboBox(); - this.clearLog = new System.Windows.Forms.Button(); - this.deslave = new System.Windows.Forms.Button(); - this.shutdown = new System.Windows.Forms.Button(); - this.deify = new System.Windows.Forms.Button(); - this.export = new System.Windows.Forms.Button(); - this.reconfigure = new System.Windows.Forms.Button(); - this.enableLog = new System.Windows.Forms.CheckBox(); - this.disconnect = new System.Windows.Forms.Button(); - this.bulkOps = new System.Windows.Forms.GroupBox(); - this.sameKey = new System.Windows.Forms.CheckBox(); - this.bulkPerThread = new System.Windows.Forms.NumericUpDown(); - this.bulkFF = new System.Windows.Forms.Button(); - this.bulkThreads = new System.Windows.Forms.NumericUpDown(); - this.bulkBatch = new System.Windows.Forms.Button(); - this.bulkSync = new System.Windows.Forms.Button(); - this.bulkAsync = new System.Windows.Forms.Button(); - this.flush = new System.Windows.Forms.Button(); - this.clearStormLog = new System.Windows.Forms.Button(); - label1 = new System.Windows.Forms.Label(); - label2 = new System.Windows.Forms.Label(); - label3 = new System.Windows.Forms.Label(); - label4 = new System.Windows.Forms.Label(); - label5 = new System.Windows.Forms.Label(); - this.bulkOps.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.bulkPerThread)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.bulkThreads)).BeginInit(); - this.SuspendLayout(); - // - // label1 - // - label1.AutoSize = true; - label1.Location = new System.Drawing.Point(12, 18); - label1.Name = "label1"; - label1.Size = new System.Drawing.Size(91, 13); - label1.TabIndex = 2; - label1.Text = "Connection String"; - // - // label2 - // - label2.AutoSize = true; - label2.Location = new System.Drawing.Point(333, 48); - label2.Name = "label2"; - label2.Size = new System.Drawing.Size(85, 13); - label2.TabIndex = 6; - label2.Text = "Demand Master:"; - // - // label3 - // - label3.AutoSize = true; - label3.Location = new System.Drawing.Point(333, 76); - label3.Name = "label3"; - label3.Size = new System.Drawing.Size(73, 13); - label3.TabIndex = 7; - label3.Text = "Prefer Master:"; - // - // label4 - // - label4.AutoSize = true; - label4.Location = new System.Drawing.Point(333, 104); - label4.Name = "label4"; - label4.Size = new System.Drawing.Size(68, 13); - label4.TabIndex = 8; - label4.Text = "Prefer Slave:"; - // - // label5 - // - label5.AutoSize = true; - label5.Location = new System.Drawing.Point(333, 131); - label5.Name = "label5"; - label5.Size = new System.Drawing.Size(80, 13); - label5.TabIndex = 9; - label5.Text = "Demand Slave:"; - // - // connect - // - this.connect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.connect.Location = new System.Drawing.Point(808, 13); - this.connect.Name = "connect"; - this.connect.Size = new System.Drawing.Size(75, 23); - this.connect.TabIndex = 1; - this.connect.Text = "Connect"; - this.connect.UseVisualStyleBackColor = true; - this.connect.Click += new System.EventHandler(this.connect_Clicked); - // - // console - // - this.console.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.console.Location = new System.Drawing.Point(12, 261); - this.console.Multiline = true; - this.console.Name = "console"; - this.console.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.console.Size = new System.Drawing.Size(872, 312); - this.console.TabIndex = 3; - // - // endpoints - // - this.endpoints.Enabled = false; - this.endpoints.FormattingEnabled = true; - this.endpoints.Location = new System.Drawing.Point(15, 39); - this.endpoints.Name = "endpoints"; - this.endpoints.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; - this.endpoints.Size = new System.Drawing.Size(312, 160); - this.endpoints.TabIndex = 4; - // - // breakSocket - // - this.breakSocket.Enabled = false; - this.breakSocket.Location = new System.Drawing.Point(15, 205); - this.breakSocket.Name = "breakSocket"; - this.breakSocket.Size = new System.Drawing.Size(120, 23); - this.breakSocket.TabIndex = 5; - this.breakSocket.Text = "Break Socket"; - this.breakSocket.UseVisualStyleBackColor = true; - this.breakSocket.Click += new System.EventHandler(this.breakSocket_Click); - // - // demandMaster - // - this.demandMaster.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.demandMaster.Location = new System.Drawing.Point(424, 48); - this.demandMaster.Name = "demandMaster"; - this.demandMaster.Size = new System.Drawing.Size(348, 23); - this.demandMaster.TabIndex = 10; - this.demandMaster.Text = "(timings etc)"; - // - // preferMaster - // - this.preferMaster.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.preferMaster.Location = new System.Drawing.Point(424, 76); - this.preferMaster.Name = "preferMaster"; - this.preferMaster.Size = new System.Drawing.Size(348, 23); - this.preferMaster.TabIndex = 11; - this.preferMaster.Text = "(timings etc)"; - // - // preferSlave - // - this.preferSlave.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.preferSlave.Location = new System.Drawing.Point(424, 104); - this.preferSlave.Name = "preferSlave"; - this.preferSlave.Size = new System.Drawing.Size(348, 23); - this.preferSlave.TabIndex = 12; - this.preferSlave.Text = "(timings etc)"; - // - // demandSlave - // - this.demandSlave.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.demandSlave.Location = new System.Drawing.Point(424, 131); - this.demandSlave.Name = "demandSlave"; - this.demandSlave.Size = new System.Drawing.Size(348, 23); - this.demandSlave.TabIndex = 13; - this.demandSlave.Text = "(timings etc)"; - // - // ticker - // - this.ticker.Interval = 1000; - this.ticker.Tick += new System.EventHandler(this.ticker_Tick); - // - // label6 - // - this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(333, 158); - this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(58, 13); - this.label6.TabIndex = 14; - this.label6.Text = "Redis Key:"; - // - // redisKey - // - this.redisKey.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.redisKey.Location = new System.Drawing.Point(424, 158); - this.redisKey.Name = "redisKey"; - this.redisKey.Size = new System.Drawing.Size(348, 23); - this.redisKey.TabIndex = 15; - this.redisKey.Text = "(timings etc)"; - // - // allowConnect - // - this.allowConnect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.allowConnect.AutoSize = true; - this.allowConnect.CheckAlign = System.Drawing.ContentAlignment.MiddleRight; - this.allowConnect.Checked = true; - this.allowConnect.CheckState = System.Windows.Forms.CheckState.Checked; - this.allowConnect.Enabled = false; - this.allowConnect.Location = new System.Drawing.Point(525, 209); - this.allowConnect.Name = "allowConnect"; - this.allowConnect.Size = new System.Drawing.Size(107, 17); - this.allowConnect.TabIndex = 16; - this.allowConnect.Text = "Allow Reconnect"; - this.allowConnect.UseVisualStyleBackColor = true; - this.allowConnect.CheckedChanged += new System.EventHandler(this.allowConnect_CheckedChanged); - // - // connectionString - // - this.connectionString.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.connectionString.FormattingEnabled = true; - this.connectionString.Items.AddRange(new object[] { - "cluster:7000,cluster:7001,cluster:7002,cluster:7003,cluster:7004,cluster:7005,res" + - "olveDns=true", - ".,.:6380,resolveDns=true", - "sslredis:6379,syncTimeout=10000", - "sslredis:6380,sslHost=anyone,syncTimeout=10000"}); - this.connectionString.Location = new System.Drawing.Point(109, 15); - this.connectionString.Name = "connectionString"; - this.connectionString.Size = new System.Drawing.Size(612, 21); - this.connectionString.TabIndex = 17; - this.connectionString.Text = "localhost,localhost:6380"; - // - // clearLog - // - this.clearLog.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.clearLog.Location = new System.Drawing.Point(764, 205); - this.clearLog.Name = "clearLog"; - this.clearLog.Size = new System.Drawing.Size(120, 23); - this.clearLog.TabIndex = 18; - this.clearLog.Text = "Clear Log"; - this.clearLog.UseVisualStyleBackColor = true; - this.clearLog.Click += new System.EventHandler(this.clearLog_Click); - // - // deslave - // - this.deslave.Enabled = false; - this.deslave.Location = new System.Drawing.Point(141, 205); - this.deslave.Name = "deslave"; - this.deslave.Size = new System.Drawing.Size(120, 23); - this.deslave.TabIndex = 19; - this.deslave.Text = "Deslave"; - this.deslave.UseVisualStyleBackColor = true; - this.deslave.Click += new System.EventHandler(this.deslave_Click); - // - // shutdown - // - this.shutdown.Enabled = false; - this.shutdown.Location = new System.Drawing.Point(15, 234); - this.shutdown.Name = "shutdown"; - this.shutdown.Size = new System.Drawing.Size(120, 23); - this.shutdown.TabIndex = 20; - this.shutdown.Text = "Shutdown"; - this.shutdown.UseVisualStyleBackColor = true; - this.shutdown.Click += new System.EventHandler(this.shutdown_Click); - // - // deify - // - this.deify.Enabled = false; - this.deify.Location = new System.Drawing.Point(141, 234); - this.deify.Name = "deify"; - this.deify.Size = new System.Drawing.Size(120, 23); - this.deify.TabIndex = 21; - this.deify.Text = "DEIFY!"; - this.deify.UseVisualStyleBackColor = true; - this.deify.Click += new System.EventHandler(this.deify_Click); - // - // export - // - this.export.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.export.Enabled = false; - this.export.Location = new System.Drawing.Point(638, 205); - this.export.Name = "export"; - this.export.Size = new System.Drawing.Size(120, 23); - this.export.TabIndex = 22; - this.export.Text = "Export"; - this.export.UseVisualStyleBackColor = true; - this.export.Click += new System.EventHandler(this.export_Click); - // - // reconfigure - // - this.reconfigure.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.reconfigure.Enabled = false; - this.reconfigure.Location = new System.Drawing.Point(638, 234); - this.reconfigure.Name = "reconfigure"; - this.reconfigure.Size = new System.Drawing.Size(120, 23); - this.reconfigure.TabIndex = 23; - this.reconfigure.Text = "Reconfigure"; - this.reconfigure.UseVisualStyleBackColor = true; - this.reconfigure.Click += new System.EventHandler(this.reconfigure_Click); - // - // enableLog - // - this.enableLog.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.enableLog.AutoSize = true; - this.enableLog.CheckAlign = System.Drawing.ContentAlignment.MiddleRight; - this.enableLog.Checked = true; - this.enableLog.CheckState = System.Windows.Forms.CheckState.Checked; - this.enableLog.Location = new System.Drawing.Point(552, 238); - this.enableLog.Name = "enableLog"; - this.enableLog.Size = new System.Drawing.Size(80, 17); - this.enableLog.TabIndex = 24; - this.enableLog.Text = "Enable Log"; - this.enableLog.UseVisualStyleBackColor = true; - // - // disconnect - // - this.disconnect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.disconnect.Enabled = false; - this.disconnect.Location = new System.Drawing.Point(727, 13); - this.disconnect.Name = "disconnect"; - this.disconnect.Size = new System.Drawing.Size(75, 23); - this.disconnect.TabIndex = 25; - this.disconnect.Text = "Disconnect"; - this.disconnect.UseVisualStyleBackColor = true; - this.disconnect.Click += new System.EventHandler(this.disconnect_Click); - // - // bulkOps - // - this.bulkOps.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.bulkOps.Controls.Add(this.sameKey); - this.bulkOps.Controls.Add(this.bulkPerThread); - this.bulkOps.Controls.Add(this.bulkFF); - this.bulkOps.Controls.Add(this.bulkThreads); - this.bulkOps.Controls.Add(this.bulkBatch); - this.bulkOps.Controls.Add(this.bulkSync); - this.bulkOps.Controls.Add(this.bulkAsync); - this.bulkOps.Enabled = false; - this.bulkOps.Location = new System.Drawing.Point(778, 48); - this.bulkOps.Name = "bulkOps"; - this.bulkOps.Size = new System.Drawing.Size(105, 151); - this.bulkOps.TabIndex = 31; - this.bulkOps.TabStop = false; - this.bulkOps.Text = "Bulk Ops"; - // - // sameKey - // - this.sameKey.AutoSize = true; - this.sameKey.Checked = true; - this.sameKey.CheckState = System.Windows.Forms.CheckState.Checked; - this.sameKey.Location = new System.Drawing.Point(6, 109); - this.sameKey.Name = "sameKey"; - this.sameKey.Size = new System.Drawing.Size(74, 17); - this.sameKey.TabIndex = 35; - this.sameKey.Text = "Same Key"; - this.sameKey.UseVisualStyleBackColor = true; - // - // bulkPerThread - // - this.bulkPerThread.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.bulkPerThread.Location = new System.Drawing.Point(52, 26); - this.bulkPerThread.Maximum = new decimal(new int[] { - 9999, - 0, - 0, - 0}); - this.bulkPerThread.Minimum = new decimal(new int[] { - 1, - 0, - 0, - 0}); - this.bulkPerThread.Name = "bulkPerThread"; - this.bulkPerThread.Size = new System.Drawing.Size(47, 20); - this.bulkPerThread.TabIndex = 34; - this.bulkPerThread.Value = new decimal(new int[] { - 1000, - 0, - 0, - 0}); - // - // bulkFF - // - this.bulkFF.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.bulkFF.Location = new System.Drawing.Point(6, 81); - this.bulkFF.Name = "bulkFF"; - this.bulkFF.Size = new System.Drawing.Size(47, 23); - this.bulkFF.TabIndex = 33; - this.bulkFF.Text = "F+F"; - this.bulkFF.UseVisualStyleBackColor = true; - this.bulkFF.Click += new System.EventHandler(this.bulkFF_Click); - // - // bulkThreads - // - this.bulkThreads.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.bulkThreads.Location = new System.Drawing.Point(6, 26); - this.bulkThreads.Maximum = new decimal(new int[] { - 50, - 0, - 0, - 0}); - this.bulkThreads.Minimum = new decimal(new int[] { - 1, - 0, - 0, - 0}); - this.bulkThreads.Name = "bulkThreads"; - this.bulkThreads.Size = new System.Drawing.Size(47, 20); - this.bulkThreads.TabIndex = 32; - this.bulkThreads.Value = new decimal(new int[] { - 10, - 0, - 0, - 0}); - // - // bulkBatch - // - this.bulkBatch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.bulkBatch.Location = new System.Drawing.Point(52, 81); - this.bulkBatch.Name = "bulkBatch"; - this.bulkBatch.Size = new System.Drawing.Size(47, 23); - this.bulkBatch.TabIndex = 31; - this.bulkBatch.Text = "Batch"; - this.bulkBatch.UseVisualStyleBackColor = true; - this.bulkBatch.Click += new System.EventHandler(this.bulkBatch_Click); - // - // bulkSync - // - this.bulkSync.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.bulkSync.Location = new System.Drawing.Point(52, 52); - this.bulkSync.Name = "bulkSync"; - this.bulkSync.Size = new System.Drawing.Size(47, 23); - this.bulkSync.TabIndex = 30; - this.bulkSync.Text = "Sync"; - this.bulkSync.UseVisualStyleBackColor = true; - this.bulkSync.Click += new System.EventHandler(this.bulkSync_Click); - // - // bulkAsync - // - this.bulkAsync.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.bulkAsync.Location = new System.Drawing.Point(6, 52); - this.bulkAsync.Name = "bulkAsync"; - this.bulkAsync.Size = new System.Drawing.Size(47, 23); - this.bulkAsync.TabIndex = 29; - this.bulkAsync.Text = "Async"; - this.bulkAsync.UseVisualStyleBackColor = true; - this.bulkAsync.Click += new System.EventHandler(this.bulkAsync_Click); - // - // flush - // - this.flush.Enabled = false; - this.flush.Location = new System.Drawing.Point(267, 205); - this.flush.Name = "flush"; - this.flush.Size = new System.Drawing.Size(120, 23); - this.flush.TabIndex = 32; - this.flush.Text = "Flush"; - this.flush.UseVisualStyleBackColor = true; - this.flush.Click += new System.EventHandler(this.flush_Click); - // - // clearStormLog - // - this.clearStormLog.Enabled = false; - this.clearStormLog.Location = new System.Drawing.Point(267, 234); - this.clearStormLog.Name = "clearStormLog"; - this.clearStormLog.Size = new System.Drawing.Size(120, 23); - this.clearStormLog.TabIndex = 33; - this.clearStormLog.Text = "Clear Storm Log"; - this.clearStormLog.UseVisualStyleBackColor = true; - this.clearStormLog.Click += new System.EventHandler(this.clearStormLog_Click); - // - // Form1 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(896, 585); - this.Controls.Add(this.clearStormLog); - this.Controls.Add(this.flush); - this.Controls.Add(this.bulkOps); - this.Controls.Add(this.disconnect); - this.Controls.Add(this.enableLog); - this.Controls.Add(this.reconfigure); - this.Controls.Add(this.export); - this.Controls.Add(this.deify); - this.Controls.Add(this.shutdown); - this.Controls.Add(this.deslave); - this.Controls.Add(this.clearLog); - this.Controls.Add(this.connectionString); - this.Controls.Add(this.allowConnect); - this.Controls.Add(this.redisKey); - this.Controls.Add(this.label6); - this.Controls.Add(this.demandSlave); - this.Controls.Add(this.preferSlave); - this.Controls.Add(this.preferMaster); - this.Controls.Add(this.demandMaster); - this.Controls.Add(label5); - this.Controls.Add(label4); - this.Controls.Add(label3); - this.Controls.Add(label2); - this.Controls.Add(this.breakSocket); - this.Controls.Add(this.endpoints); - this.Controls.Add(this.console); - this.Controls.Add(label1); - this.Controls.Add(this.connect); - this.MinimumSize = new System.Drawing.Size(540, 430); - this.Name = "Form1"; - this.Text = "Connection Watcher"; - this.bulkOps.ResumeLayout(false); - this.bulkOps.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.bulkPerThread)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.bulkThreads)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - private System.Windows.Forms.Button connect; - private System.Windows.Forms.TextBox console; - private System.Windows.Forms.ListBox endpoints; - private System.Windows.Forms.Button breakSocket; - private System.Windows.Forms.Label demandMaster; - private System.Windows.Forms.Label preferMaster; - private System.Windows.Forms.Label preferSlave; - private System.Windows.Forms.Label demandSlave; - private System.Windows.Forms.Timer ticker; - private System.Windows.Forms.Label label6; - private System.Windows.Forms.Label redisKey; - private System.Windows.Forms.CheckBox allowConnect; - private System.Windows.Forms.ComboBox connectionString; - private System.Windows.Forms.Button clearLog; - private System.Windows.Forms.Button deslave; - private System.Windows.Forms.Button shutdown; - private System.Windows.Forms.Button deify; - private System.Windows.Forms.Button export; - private System.Windows.Forms.Button reconfigure; - private System.Windows.Forms.CheckBox enableLog; - private System.Windows.Forms.Button disconnect; - private System.Windows.Forms.NumericUpDown bulkThreads; - private System.Windows.Forms.Button bulkBatch; - private System.Windows.Forms.Button bulkSync; - private System.Windows.Forms.Button bulkAsync; - private System.Windows.Forms.GroupBox bulkOps; - private System.Windows.Forms.Button bulkFF; - private System.Windows.Forms.NumericUpDown bulkPerThread; - private System.Windows.Forms.CheckBox sameKey; - private System.Windows.Forms.Button flush; - private System.Windows.Forms.Button clearStormLog; - } -} - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Form1.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Form1.cs deleted file mode 100644 index 33ad0e8..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Form1.cs +++ /dev/null @@ -1,621 +0,0 @@ -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Threading.Tasks; -using System.Windows.Forms; -using StackExchange.Redis; - -namespace ConnectionWatcher -{ - public partial class Form1 : Form - { - public Form1() - { - foreach(var file in Directory.GetFiles(Environment.CurrentDirectory, "Interactive_*.txt")) - { - File.Delete(file); - } - foreach (var file in Directory.GetFiles(Environment.CurrentDirectory, "Subscriber_*.txt")) - { - File.Delete(file); - } - InitializeComponent(); - - demandMaster.Text = preferMaster.Text = demandSlave.Text = preferSlave.Text = redisKey.Text = ""; - -#if !DEBUG - breakSocket.Text = allowConnect.Text = "#if DEBUG"; -#endif -#if LOGOUTPUT - ConnectionMultiplexer.EchoPath = Environment.CurrentDirectory; -#endif - } - - protected override void OnClosing(CancelEventArgs e) - { - SetEnabled(false); - } - private void disconnect_Click(object sender, EventArgs e) - { - SetEnabled(false); - } - private void SetEnabled(bool running) - { - connect.Enabled = connectionString.Enabled = !running; - shutdown.Enabled = endpoints.Enabled = deslave.Enabled = deify.Enabled = export.Enabled = reconfigure.Enabled = - disconnect.Enabled = bulkOps.Enabled = flush.Enabled = clearStormLog.Enabled = running; - -#if DEBUG - breakSocket.Enabled = allowConnect.Enabled = running; -#endif - if (running) ticker.Start(); - else ticker.Stop(); - - if (muxer != null) - { - muxer.Dispose(); - muxer = null; - } - if(running) - { - console.Text = ""; - var options = ConfigurationOptions.Parse(connectionString.Text); - options.AllowAdmin = true; - options.AbortOnConnectFail = false; - options.CertificateValidation += (sender, cert, chain, errors) => - { - Log("cert issued to: " + cert.Subject); - return true; // fingers in ears, pretend we don't know this is wrong - }; - - using (var logger = new StringWriter()) - { - muxer = ConnectionMultiplexer.Connect(options, logger); - Log(logger.ToString()); - } - endpoints.Items.Clear(); - endpoints.Items.AddRange(Array.ConvertAll( - muxer.GetEndPoints(), ep => new EndPointPair(muxer.GetServer(ep)))); - - muxer.ConnectionFailed += Muxer_ConnectionFailed; - muxer.ConnectionRestored += Muxer_ConnectionRestored; - muxer.ErrorMessage += Muxer_ErrorMessage; - muxer.ConfigurationChanged += Muxer_ConfigurationChanged; - } - } - private void connect_Clicked(object sender, EventArgs e) - { - SetEnabled(true); - } - - private void Muxer_ConfigurationChanged(object sender, EndPointEventArgs e) - { - Log("Configuration changed: " + e.EndPoint); - } - - private void Muxer_ErrorMessage(object sender, RedisErrorEventArgs e) - { - Log(e.EndPoint + ": " + e.Message); - } - - private void Muxer_ConnectionRestored(object sender, ConnectionFailedEventArgs e) - { - Log("Endpoint restored: " + e.EndPoint); - } - private void Log(string message) - { - if(InvokeRequired) - { - BeginInvoke((MethodInvoker)delegate - { - if (enableLog.Checked) - console.Text = message + Environment.NewLine + console.Text; - }); - } else - { - if(enableLog.Checked) - console.Text = message + Environment.NewLine + console.Text; - } - } - - class EndPointPair - { - public EndPointPair(IServer server) - { - this.server = server; - } - private readonly IServer server; - public EndPoint EndPoint { get { return server == null ? null : server.EndPoint; } } - private string state; - - public override string ToString() - { - try - { - string spacer; - switch (((uint)Thread.VolatileRead(ref loop)) % 4) - { - case 0: spacer = @" - "; break; - case 1: spacer = @" \ "; break; - case 2: spacer = @" | "; break; - case 3: spacer = @" / "; break; - default: spacer = " ! "; break; - } - return (server.IsSlave ? "S " : "M ") + EndPointCollection.ToString(EndPoint) + spacer + OpCount + ": " + state; - } - catch (Exception ex) - { - return ex.Message; - } - - } - public long OpCount { get;set; } - int loop; - internal void SetState(string msg) - { - state = msg; - Interlocked.Increment(ref loop); - Interlocked.Exchange(ref concern, 0); - } - int concern; - internal bool Worried() - { - return Interlocked.Increment(ref concern) >= 5; - } - } - private void Muxer_ConnectionFailed(object sender, ConnectionFailedEventArgs e) - { - Log("Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message))); - } - - private void ticker_Tick(object sender, EventArgs e) - { - RefreshListBox(); - if (muxer == null) return; - if(endpoints.SelectedIndices.Count == 1) - { - var ep = ((EndPointPair)endpoints.SelectedItem).EndPoint; - var server = muxer.GetServer(ep); - Text = server.ServerType + " " + server.Version + " " + (server.IsSlave ? "slave" : "master") + "; " + server.GetCounters().ToString(); - } - foreach (var pair in endpoints.Items.OfType()) - { - - if(pair.Worried()) - { - Log("No response from " + pair.EndPoint); - } - var server = muxer.GetServer(pair.EndPoint, pair); - - var q = server.GetCounters(); - pair.OpCount = q.Interactive.OperationCount; - if (q.TotalOutstanding > 5) - { - Log(q.ToString()); -//#if DEBUG -// if(q.Interactive.PendingUnsentItems != 0 || q.Subscription.PendingUnsentItems != 0) -// { -// Log(((IRedisServerDebug)server).ListPending(100)); -// } -//#endif - } - var ping = server.PingAsync().ContinueWith(UpdateEndPoint); - } - - - string s = Guid.NewGuid().ToString(); - redisKey.Text = s; - RedisKey key = s; - var db = muxer.GetDatabase(asyncState: Stopwatch.StartNew()); - db.IdentifyEndpointAsync(key, CommandFlags.DemandMaster).ContinueWith(DemandMaster); - db.IdentifyEndpointAsync(key, CommandFlags.PreferMaster).ContinueWith(PreferMaster); - db.IdentifyEndpointAsync(key, CommandFlags.PreferSlave).ContinueWith(PreferSlave); - db.IdentifyEndpointAsync(key, CommandFlags.DemandSlave).ContinueWith(DemandSlave); - - // ThreadPool.QueueUserWorkItem(AccessSync); - - } - private void AccessSync(object state) - { - var ep = muxer.GetEndPoints(); - for (int i = 0; i < ep.Length; i++) - { - try - { muxer.GetServer(ep[i]).Ping(); } - catch (Exception ex) - { - Log(ep[i] + ":" + ex.Message); - } - } - } - - private void UpdateEndPoint(Task task) - { - - string msg = ExtractMessage(task); - var pair = (EndPointPair)task.AsyncState; - if (pair != null) - { - BeginInvoke((MethodInvoker)delegate - { - pair.SetState(msg); - RefreshListBox(); - }); - } - - } - - void RefreshListBox() - { - if (InvokeRequired) - { - BeginInvoke((MethodInvoker)RefreshListBox); - } - else - { - // hacky "redraw your damned text", via http://stackoverflow.com/a/4631419/23354 - // unfortunately, while this works, it breaks the selected items - bool[] selected = new bool[endpoints.Items.Count]; - for (int i = 0; i < selected.Length; i++) - { - selected[i] = endpoints.GetSelected(i); - } - typeof(ListBox).InvokeMember("RefreshItems", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, endpoints, new object[] { }); - for (int i = 0; i < selected.Length; i++) - { - endpoints.SetSelected(i, selected[i]); - } - } - } - - static string ExtractMessage(Task task) - { - if (task == null) return ""; - try - { - var status = task.Status; - switch (status) - { - case TaskStatus.RanToCompletion: - object result = task.Result; - if(result is TimeSpan) - { - return ((TimeSpan)result).TotalMilliseconds.ToString("###,##0.00ms"); - } - if(result is EndPoint) - { - return EndPointCollection.ToString((EndPoint)result); - } - return Convert.ToString(result); - case TaskStatus.Faulted: - return string.Join(", ", task.Exception.InnerExceptions.Select(x => x.Message)); - default: - task.ContinueWith(x => - { - try - { // mark observed - GC.KeepAlive(x.Exception); - } - catch - { } - }, continuationOptions: TaskContinuationOptions.OnlyOnFaulted); - return status.ToString(); - } - } - catch (Exception ex) - { - return ex.Message; - } - - } - - private void DemandMaster(Task task) - { - Write(demandMaster, task); - } - private void DemandSlave(Task task) - { - Write(demandSlave, task); - } - private void PreferMaster(Task task) - { - Write(preferMaster, task); - } - private void PreferSlave(Task task) - { - Write(preferSlave, task); - } - - private void Write(Label output, Task task) - { - var watch = (Stopwatch)task.AsyncState; - var elapsed = watch.Elapsed; - output.BeginInvoke((MethodInvoker)delegate - { - string msg = ExtractMessage(task); - output.Text = elapsed.TotalMilliseconds.ToString("###,##0.00ms") + ": " + msg; - }); - } - - ConnectionMultiplexer muxer; - - private void breakSocket_Click(object sender, EventArgs e) - { -#if DEBUG - foreach (var pair in endpoints.SelectedItems.OfType()) - { - try - { - muxer.GetServer(pair.EndPoint).SimulateConnectionFailure(); - } catch(Exception ex) - { - Log(ex.Message); - } - } -#endif - } - - private void allowConnect_CheckedChanged(object sender, EventArgs e) - { -#if DEBUG - muxer.AllowConnect = allowConnect.Checked; -#endif - } - - private void clearLog_Click(object sender, EventArgs e) - { - console.Text = ""; - } - - - - private void deslave_Click(object sender, EventArgs e) - { - foreach (var pair in endpoints.SelectedItems.OfType()) - { - var sw = new StringWriter(); - try - { - muxer.GetServer(pair.EndPoint).MakeMaster(ReplicationChangeOptions.None, sw); - } catch(Exception ex) - { - Log(ex.Message); - } - Log(sw.ToString()); - } - } - - private void shutdown_Click(object sender, EventArgs e) - { - foreach (var pair in endpoints.SelectedItems.OfType()) - { - try - { - muxer.GetServer(pair.EndPoint).Shutdown(); - } catch(Exception ex) - { - Log(ex.Message); - } - } - } - private void flush_Click(object sender, EventArgs e) - { - foreach (var pair in endpoints.SelectedItems.OfType()) - { - try - { - muxer.GetServer(pair.EndPoint).FlushDatabase(); - } - catch (Exception ex) - { - Log(ex.Message); - } - } - } - private void clearStormLog_Click(object sender, EventArgs e) - { - try - { - muxer.ResetStormLog(); - } - catch (Exception ex) - { - Log(ex.Message); - } - } - - private void deify_Click(object sender, EventArgs e) - { - var items = endpoints.SelectedItems.OfType().ToList(); - if (items.Count != 1) return; - - var sw = new StringWriter(); - try - { - muxer.GetServer(items[0].EndPoint).MakeMaster(ReplicationChangeOptions.SetTiebreaker | ReplicationChangeOptions.Broadcast | ReplicationChangeOptions.EnslaveSubordinates, sw); - } catch(Exception ex) - { - Log(ex.Message); - } - Log(sw.ToString()); - } - - private void export_Click(object sender, EventArgs e) - { - try - { - using (var dlg = new SaveFileDialog()) - { - dlg.Filter = "Zip Files | *.zip"; - dlg.DefaultExt = "zip"; - if (dlg.ShowDialog(this) == DialogResult.OK) - { - string path = dlg.FileName; - if(!string.IsNullOrEmpty(path)) - { - using(var file = File.Create(path)) - { - muxer.ExportConfiguration(file); - } - } - } - } - } - catch (Exception ex) - { - Log(ex.Message); - } - - } - - private void reconfigure_Click(object sender, EventArgs e) - { - using(var writer = new StringWriter()) - { - try - { - muxer.Configure(writer); - } catch(Exception ex) - { - Log(ex.Message); - } - Log(writer.ToString()); - } - } - - private void bulkSync_Click(object sender, EventArgs e) - { - RunConcurrent(0.1M, (db, count, key) => { - while(count-- > 0) db.StringIncrement(key()); - return null; - }, "Bulk sync"); - } - - private void bulkFF_Click(object sender, EventArgs e) - { - RunConcurrent(1, (db, count, key) => { - while (count-- > 0) db.StringIncrement(key(), flags: CommandFlags.FireAndForget); - return null; - }, "Bulk F+F"); - } - private void bulkAsync_Click(object sender, EventArgs e) - { - RunConcurrent(1, (db, count, key) => { - while (count-- > 1) db.StringIncrementAsync(key(), flags: CommandFlags.FireAndForget); - return db.StringIncrementAsync(key()); - }, "Bulk async"); - } - - private void bulkBatch_Click(object sender, EventArgs e) - { - RunConcurrent(1, (db, count, key) => - { - var batch = db.CreateBatch(); - while (count-- > 1) batch.StringIncrementAsync(key(), flags: CommandFlags.FireAndForget); - Task last = db.StringIncrementAsync(key()); - batch.Execute(); - return last; - }, "Bulk batch"); - } - - private void RunConcurrent(decimal factor, Func, Task> work, [CallerMemberName] string caller = null, Action> whenDone = null, int timeout = 10000) - { - int threads = (int)bulkThreads.Value; - int perThread = (int)(bulkPerThread.Value * factor); - ThreadPool.QueueUserWorkItem(delegate - { - Func keyFunc; - if(sameKey.Checked) - { - RedisKey key = Guid.NewGuid().ToString(); - keyFunc = () => key; - } else - { - keyFunc = () => Guid.NewGuid().ToString(); - } - - Task last = null; - var db = muxer.GetDatabase(); - db.KeyDelete(keyFunc(), CommandFlags.FireAndForget); - try - { - if (work == null) return; - if (threads < 1) return; - Stopwatch watch = null; - ManualResetEvent allDone = new ManualResetEvent(false); - object token = new object(); - int active = 0; - ThreadStart callback = delegate - { - lock (token) - { - int nowActive = Interlocked.Increment(ref active); - if (nowActive == threads) - { - watch = Stopwatch.StartNew(); - Monitor.PulseAll(token); - } - else - { - Monitor.Wait(token); - } - } - var result = work(db, perThread, keyFunc); - if (result != null) Interlocked.Exchange(ref last, result); - if (Interlocked.Decrement(ref active) == 0) - { - allDone.Set(); - } - }; - - Thread[] threadArr = new Thread[threads]; - for (int i = 0; i < threads; i++) - { - var thd = new Thread(callback); - thd.Name = caller; - threadArr[i] = thd; - thd.Start(); - } - if (allDone.WaitOne(timeout)) - { - if (whenDone != null) whenDone(keyFunc); - var result = db.StringGet(keyFunc()); - watch.Stop(); - var finalTask = Interlocked.Exchange(ref last, null); - if (finalTask != null) Log("Last task is: " + finalTask.Status.ToString()); - Log(string.Format("{0}, {1} per-thread on {2} threads: {3:###,###,##0.##}ms, {4:###,###,##0}ops/s (result: {5})", - caller, perThread, threads, - watch.Elapsed.TotalMilliseconds, - (int)((perThread * threads) / watch.Elapsed.TotalSeconds), - result)); - } - else - { - for (int i = 0; i < threads; i++) - { - var thd = threadArr[i]; - if (thd.IsAlive) thd.Abort(); - } - Log(string.Format("{0} timed out", caller)); - } - } - catch (Exception ex) - { - Log(string.Format("{0} failed: {1}", caller, ex.Message)); - } - finally - { - db.KeyDelete(keyFunc(), CommandFlags.FireAndForget); - } - }); - } - - - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Form1.resx b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Form1.resx deleted file mode 100644 index 70a64f6..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Form1.resx +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - False - - - False - - - False - - - False - - - False - - - 17, 17 - - \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Program.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Program.cs deleted file mode 100644 index 28a1355..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Program.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Windows.Forms; - -namespace ConnectionWatcher -{ - static class Program - { - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Form1()); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/AssemblyInfo.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/AssemblyInfo.cs deleted file mode 100644 index 6f83a46..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ConnectionWatcher")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ConnectionWatcher")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f494c35a-e665-4f46-9906-dbb873e00b51")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Resources.Designer.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Resources.Designer.cs deleted file mode 100644 index 0981f11..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Resources.Designer.cs +++ /dev/null @@ -1,71 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.34011 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ConnectionWatcher.Properties -{ - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ConnectionWatcher.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { - return resourceCulture; - } - set - { - resourceCulture = value; - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Resources.resx b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Resources.resx deleted file mode 100644 index af7dbeb..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Settings.Designer.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Settings.Designer.cs deleted file mode 100644 index 9c34a24..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Settings.Designer.cs +++ /dev/null @@ -1,30 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.34011 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ConnectionWatcher.Properties -{ - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { - return defaultInstance; - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Settings.settings b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Settings.settings deleted file mode 100644 index 3964565..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/ConnectionWatcher/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Directory.build.props b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Directory.build.props deleted file mode 100644 index 2742ab6..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Directory.build.props +++ /dev/null @@ -1,44 +0,0 @@ - - - 1.2.6 - - 2017 Stack Exchange, Inc. - true - true - ../StackExchange.Redis.snk - $(AssemblyName) - Stack Exchange, Inc.; marc.gravell - true - - https://stackexchange.github.io/StackExchange.Redis/ReleaseNotes - https://github.com/StackExchange/StackExchange.Redis/ - https://raw.github.com/StackExchange/StackExchange.Redis/master/LICENSE - - git - https://github.com/StackExchange/StackExchange.Redis/ - - true - embedded - en-US - false - - net45;net46;netstandard1.5 - 4.3.0 - - - - - true - false - - - - - - - - - - - - \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/LICENSE b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/LICENSE deleted file mode 100644 index e32afb8..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/LICENSE +++ /dev/null @@ -1,47 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Stack Exchange - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -=============================================== - -Third Party Licenses: - -The Redis project (http://redis.io/) is independent of this client library, and -is licensed separately under the three clause BSD license. The full license -information can be viewed here: http://redis.io/topics/license - -This tool makes use of the "redis-doc" library from http://redis.io/documentation -in the intellisense comments, which is licensed under the -Creative Commons Attribution-ShareAlike 4.0 International license; full -details are available here: -https://github.com/antirez/redis-doc/blob/master/COPYRIGHT - -The development solution uses the Redis-64 package from nuget -(https://www.nuget.org/packages/Redis-64) by Microsoft Open Technologies, inc. -This is licensed under the BSD license; full details are available here: -https://github.com/MSOpenTech/redis/blob/2.6/license.txt -This tool is not used in the release binaries. - -The development solution uses the BookSleeve package from nuget -(https://code.google.com/p/booksleeve/) by Marc Gravell. This is licensed -under the Apache 2.0 license; full details are available here: -http://www.apache.org/licenses/LICENSE-2.0 -This tool is not used in the release binaries. \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Microsoft.Threading.Tasks.Extensions.Desktop.dll b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Microsoft.Threading.Tasks.Extensions.Desktop.dll new file mode 100644 index 0000000000000000000000000000000000000000..1288a177051fd60c5aa7ef8f9266efb7775a754d GIT binary patch literal 47424 zcmeFa2Ut``+dn+pVS$BR5G;V8s93;Vs$H>TSFmH0vLXsB?t+S_0W8tP-lDMtTcU}* zB=&BME%vA}8heX98oPeKd(PQqDdv6N@BcpEbG_g7C)xYV-DmEZxo6ItvupcaQ<;o0 zCdcQ)2gWwzN`Fl_{AZ90wx;4%4cq8=%zv|_-7){z0Vx*046`ZO9G~Ww7@wYQ%JfSx z`kAxR{Zi8XnsrT+`BB1$CuoteZ~cPbPxw%cX|_;AFa zF|NBAbH-)>v{g?mzY*ptf4!~R6DFLz6hw!9u=&pI>a z$f<>(lOJQbh3H31G230L*6-f5Lb&X^y)Vj|2KOryKcafKUuJLmY=4jB@4EMvpLjGo zsNCIm-7F(?eBrWsPgD zEYO`Xb&!);g0NaVP#!)CMR}0cEW;wmystFSADkNXq*56*RT+p$ zqO4&hTdyI~91Iq@sS?SWr8#K1JO@KuE*3HE<)+HSgiUw7lF@L-u+dt&!kk(u9Z4EW z`AD)N%>hU5rQ{}+@0Hysi~&$a8S_U7X&_{3)?gL%GBy;p;6Q7^tmd}Ju~KHK0+o?u zO6f6@DxidZEa_Jz2B+{kDs!l8szx3-L8jz2Fa?5g*`umJ6s0PI_P)F*P#s7OMloZo z8T07QJkV2;!dRh)ON|xsjogG#@K`}eo`X4ncJm?vEH~BUmJ4HrCTT6b#P*RGVntS@ zIVwQJiV(D~H?^-8lu?eOG7Y~#w9hV92({MIL$pPX5vw4GjU-cu6;*&@)systiNPtn zj>;Tfz1rk~6A&v>GwDI$vEl{=DQX18iVGNkl#Ep)>$vg=)WBVhs#2L)vT@`B$2!!k zR}4ACU2X~?yBKn=KyqLMA>ldjs4`IC3K+NQUT6n4<6m?W=YK^R15y%PFz*(;dAQ~n&MZy6E z5XnoPgDH-9@FJAtraHvL=(ffXy|1+-iR~sa#E`5=bKsw1NC?_(q;`vQwm+3YSKH>S zf@Q-dMvB&wAlf3w);UY25JRc}#W0cd>q1|k@H#4Uc=fP?AcmwXlPi?G4yO8`@sY?) z3Ubs83L;rHRR=Y#Em zj@OWRfdUnEkV>RTm4S$gl8?DxU<=byixC|KnOaU}WTXsBQcr85O=w!yP~GS!BHzWwE?bG zd}R)YU#(oLFtr6CupNM@JwR16qMG5NRe1GqS7;Sb=m2WSex;=&uI@^$(!tb;ggXOh zm8LGZ*sTOu$x6*`Sb*fF7?Q=PDhDJ7ixx%*FJcvwn_`J+8&eqBT1$#J4oC=Nifl-8 z;DN>zAs7b(X&iKgD$0YX%*PZmqg`&p%+gwtMO)++V+!ksdL)^`m?HNyrUsCHcVch~ zuc0!BSFQ(n-~{A0QZw}gg^wt1P>`Y~(1_v!y@32fZj%Q>u`pC>j~Z>HIarO+LM+a5 z6Oy*N#${;^R&2SKd=yq@VgHa$l|&X-=Mst2rSFv{qVlFIc+;^43ONZ$Lu*L|m)27< zkG3O4sYjAsw4HoW+tbJZ5|dh>@R}%vnjkx(?W9XNiS$hUK;n((77Hs(jpqVLk!rqg zpf%8%lWf@snF)TanTZ!|JY*(Lux2Fd6`2XktlWg$z{gM}AUXa3(i~p&BPOzf-55eT z*ILYC+ervxh-^r6Dgt5*5rVc`sO{ny%A|6UF(l+AECX6ghG>i2TE`HXLLA9G#c?p{ zBNwU#3a_CuhgS~i4{;=2o|j0`gfu7wlA9Fds1X!ME+CAel6lD%FT@hot+C`q8xOJM z1ZxbfSHv=qykk!ASXKj)Qx!m(!;45saua5QT`Z9#wU(h``$-6~BpcEkBy@@;A!z?F zYQGrEY$}%$OJr%SB}=qLZmqE-Q-~$Gr&taledGYOK;bo1=J3j4+9Q^v%VSB3CQN@J zmfWNuM~$FZa)FPgEL`LmlLQK>(rUwoe7&*icg+@?$B!Gu$6kv_7gj!X3ulm#`1tgac zs+Wf;kHi++#PW$V8bE3Ubi_O)4QLhhsHK7FwK4l2b&GT%B%GS)+<5|PK8cB)yMW3I z0X$4!145_(7u04EF+`!oR9*t$VOk1^a4f?GLf;VMTcNz1$}0dc@I6d!Ld8V6?}@jv zgq(*7v$v-0{_HDhPIb%|X-*9eYjRkN!yrJJ+_V}dz;wqNf+d@|(|pB<rT*nEJZDwtJ5B9eIq{s;}z zW_!bR$?z#x3BPNvrIOLkxMmG&?6*MF+Cf{XOtBYRV69sH;ua7wSl9+h^xk$m3p=R1 zlUvvYXlq=<;ug>rSlA62SlB~a;vm^e<$VAiru~2zNe6I&&`-n=g$`2rX8;e=AwYy$ z6go_dBLGma2~mnDL;hx4#g38KFU7??Or9iVT}7-{^hGH3#RWO)h zm^7Be`+WG*T5{29+Lw?91`}D4=F|qndO`@g4mnO~IR#~uk>JGj#Ea^|@AHu(7;2@p zAZK!075COkfo3@kQzOX*))}f8tux54O3N8ya0*ve=J0BtCC{9IeIKcr zeg%bZeFR6g#?dOn1!D}q*s%$+A`1T7LsP6U8h3@7FVZps!j zv|4K!E4Gsq5Hm6&%?SfU%m_hyklK}&-=K@~XH-V8)wJETiy1I2EfzdxDK}x*uyWLn@nSnj3b~2Ilw3v0RZ!gtRNbpk3~Y;%Z3x3M<}NHZ z;FhoPYVf>Aw#$?4&qdoL2iqj5h9L~+;@P-eQp8$vN6Ki=eLvgn6|;fJK*hs2dR zoW>2n4`x(pp&BL4X$E0wPIC@haM%)1X1XbajmHh9m=F1zD*7WO_#-X&BQ>lSq^IQe zl-wTNPW!0aRuGovwB|6H!#032(=BT($)_**oG$t#4frG#_#_?pBqe1IXK`cjIiqx+ zv!yv0CGgpf!}c6@;IJd0%ye65FvS->SVi(ZQ}j)m@J*`lO}g++%CtU`x{@1La^tAO ztdG{A6NIHXojL5nVGM_{fHKpaqIK}2I?NX9K$@rnsiF>~i#m`p)q&KNIb4JrM;*Q_ zy$*J{swb38cgZDkRSzIJ-2ud6H)7ti)<-zU^{4uLCDw-&P!TdB&FKn=Ttx_6&m-4= zLKo%vR4#*ZU^!c^LY`rj$krUu7Wq|j@5ohs3iG?navz!_$vV;$Rf*EnTr&B97@WfO zlsUY@4?%?`QZPM2nI|a0x~)N!pt!(e2#EKy-IylHdNw4dy%DR7`e8Swkz1ZXOpW6n zbbFB`(+f_dIlTd8rl(}emSX~_Z41PXGCK@h0aK?*g*;oEV(K^^`fhYJYJ)D-5D%n8 zyk`f#1R0M$Ug5&;4p4qgW$o0xZk)O+H55XyL_qP9o?AXTA=l#DpYd1TjK z%A2Gx0~Fxbz=NxpHcch;WCnlE_zVdP)(3~`Lk)F_qF||j0T}d^M=>@P*NGKTj>$Bq zq$gWQ!aGWMepR_^44aR#8)%hVb&W<|WGjKU2BC7(R65?^e^T7?cP}G#aMS>OT_uz@ zIT93y;8PVJbR$FeG0aJZDzZ#m(QiB-k(>%2e|%*4peguMi?vs>{cHyw;~nAfEHsqt zPxc$2MnYvDKs9S436m&Uf`lYf0M%@wWF+8fPT4M5FVV1}(w9#X;IJd0lJ!>YfX8vFAu2VS#^DClNW^5l;~YoC&~Y)!w>bR3 zp|_eSO*!n%p_#)e9Ioc@AcxmDbar~9R30$>Ah7Dz5=lvMJgfD6a-ovb`KCb+5H*7OL~m zso8K27wAalPaSEwxD$Nh9wt$OhrH)8(i*_a%f9Al3Bpvu<|>YhJ99^dZASX>V+g9>V;7p_VuO6yH_NSi51CC z4j}!}C?`l)H&!3xSi!M89O2XKP~cgjiV-%HjpP_sUr3I}ym17t3zLCY&P9-n;aDw> zDOgvIrC{zUV50}eMsQ5cdU4F?N<3%Qhhy0sbA?~BX~bMsFfB_EcpUR!NgUg!Bc3Nq z=GZxom18L!yM)C=fn8xL$If^VRuK>8$>tr7Rl=ip!Y(6eD_8)_;@DG;RYN<8ceE_= zs^bL$!s=ovRj^<-f@7VKAr-7P8^y6Cj)kyXj#WfnRIo5Mnq#3Hi)3Rt_Kah75j(Q! zgM^|$#6Ra)OO7>U6FEjtmKCfCo6NB}9Ban#jtBJiaI6)Z&arzOYs+SG%-x6dIlZ4{Mpc8&1IgM$Y=g1wHGv`fXUpxN@Y`ds8 zTM`M$*h(Zho6VLqg^xQTwolRl86+3mN8;_1^g?CF87X zzYWV|UaSW#{?NN4$;W+bq79pjyRmc|Hjnu+2iiVx$>qo(1st2k-b;R9f$Y8w+sSIM zpQ;Ix3h6;si^T<6vD3&Wk43D4^a|6n9@Pb21?gQD%I=GpLHZY77Kmcvd!$J4f|TQgH7Z+f0F!8wu{xOCs1Nh+RfG$Q*cP7{_M0cqtCD({{W=?4p3NeJ+8DL+p--U3Cd% zhu8~2kLRUBER1KAaqNV~1j!F}ydz8{@?L6k6-Stdh`G6j;(nkJ&nQB6JHmzu82j0E zH6&Zw@s6<$BJZhduHqQ$En-e?q3js@lxG{k$}zTGz}PQtmmv9>9q%}sBJ$q41uBlS z`65-z*sN$Maq-xsfZ1A4`nAAwn6w4 ztej-N0>+#@eubn1$ELCB9+#A-nUlzC=@H6KvvNEy33{hltbnn)WgJzfnZF(HEUPZ^ zjAa%n&$0*+%PkYi&N3s`K|as&lM1pML`H0*e$d*1lXQyTCT^IcDWO7BIH3d`IUCY?~eLBHJhO z_LuMHe36|Hu?yux*+q7T&rQL~MHay4<~SB#;Ri@Qw&Pu5F9nQ!Ug4ngC8iK17gq>n zmzX!7se+YDEI`1RgSWfOCEQ6D_R(cFO5_>9yUb46@%~`HiM(Fm{lV(;87|no!lDF> zjRx-uTV%((%2tTHmEc`vW%=wE^sX^K0b^&uyT&Hk@vgI(BJVwT*O?p76N26iR#w1R zH6M4E8*HW>??+3K+}w{Z)B~H4-z?bl*$Ldn`)ieeWB}?jf`ic2ZRcucItww*h6? zAK@&9{SBz#FAGbsZzZlb;Qv%v#sZ32D~(dKgiJ{a*^#qdrz>@t&}uSmZD=qLkl?$rP>aEzW%eC}+>@>=e?i^(>^waX&<3 zyU=e@o5H-XkIDZ#iqMbm?P?{=Aekfeh&v#@3t(6F=4C-fDEo7nLb{BF+EIvGlp=T} z89A$8s$@}mad`!6`VU$~xox=jST6qwpp>O>N;;sNWdkZ$9-stwRKy);SGLy`+sLCN zlqYlf>0JJU3+YlulCXbA`AJ!_{~GY)_9-_?aF6(}Li>6OT2{&y$vDYP*&YrLad?u$ z3mjhM@Ggf>IDEySL`qtY9BMf%$Du#qJ(&UUiL5SQD2w7SnnQn#`r5Z^)zBe&?y2<5lV&mq6x`7O%ME)s!*oTWJ5j|lt9<9iUwT1 zIhP+S%143TnRRz6gBH=xYnRE1t_S@d*LtR{uUsVkLEA{V z1u~(mGi#-5uG}N-u4@CBsOt!BsxB5>i!M%iNIFB8hEUKJdca_&mboy%^4K9{kwBUNNS!htBA95&iKrg6$_hwV1X zkDye=PIfM90xc@va@fzgR8~43<>f=L6XJMAER+31;I?)AU8Ioi1=geNAjcb=a)B8| z$`_9JMM{sds~w;5@>|}DCoBVgpRoM07air8eJkY75^AG|gyQgoP3PQi%f55;=G*|z zt;M;o*w(VX>M%}!#rBttQa9k`=8);BChin6xo%FG z+`H3m%jY{yic&e+u+?$?Xd7oNsXX2@+3*ugf#erE;VT!KNH`&h`-S}P{-c`-ra=6eV>_dDNrkxQvoDU{)wMcT`H&Qc~%P*2h zDn^1%@*Ywe4~t}8729bR$$~0&*LZXJ0BLJ4XXjcXH>%=DO_*Ru7E^JKrU5TE=Q4|A zQP5oh%iD0?NZH1p&0q!cVAh+d+=7{fl>v-lXI+EYAm)N{1=bVgwwybfRRiS*hts8_QJyZH&*3h>`rKwS*h%CT3b@}Ttg^#i&2C=a$Ke&u zWfJltlTh9Kc)1CO%{ZkWFXwVNno|mRc{hjqIOPg2Gby)&a~;^><;uL=gqQnqn8+!) zyj;NH5>DC8%lmlw3NK&hWhNt=ejHYok>w`5+>gUVPRZrv(Y##1%S(89H!ttwDC8%lmlw3NJGSuP291IPAw^E{6pi z?&k0chYT+dp zRTouv)pK=Yr(EZS&bOTvE+H-rUD~*Gb1}MDT)uEw;BwjJsSDH8(lpZSkRO(xl;4qu zDw--LDi$bKDR(L#DPJkmRby1^R7X`;RrggM4wW5(9r`#db9n0D>DbV*yW>zibKUNE z#__u2L&v`z6>2wiS#_|wwYrOXzWTM=$;r#9gHvCpK~BS+zHs`|slaKS(+;PzPH&ye z&SRY?IbU$T@BGZUipvR?8!rBu=9+$*R85vWPmRK4k&R;aVQB0fkE5 z>~Nh)99<>V9j`;?I_vM~C>e*(a(s?Cc9o1%_m-Sh%UN?LyiJ8qrqf)>ZKtm#20Vcp zj?Yzm&bz#l)Kw^?KWG%vx;$>IL3>kDR;sZPYoC&6Hd##lGlOFXn2qsCc;g~CHr_JG z65L`~rZL@;VoJ9JH#b@aWtuXAlTuR|F=LG8At{MQ3yaCNWE#_otFkCdc6wr`)cDN) zCUaV$9o9VE(qfoZse>^Sf)-<1LTYw;LQxZfL>zFVQ99F18HM8p38pE2!rzaXyQ5V>VH4QSRvzBI4nmv^_sh@$xb}?GA zQZqT)%#@aqY9yT)Q6wV2F;!@)C~Zt?F$9b#bFziC%t}v$Qj}2l z*74~{sm2!Z8HILPEDKJ|G?`gLQ!cbi1lpjdbka zzbK=1W@bja6b#68qq&(Woqt8&p2pB_kuJp5R@uZXge^O`nK?TnlYadmV?cIrk8pk6 zW=3;nO8=C^_)LuTVuTQ8Z@Y_eaF)@M$zAZyv{NnO45L0c#wa*s9gNAQ%oJD``!p&m za{xla9Y$G%2npIy8)`BSYGyVjkwAQ^bwF5c1>5Oj)C#jV$(Yp1Y|0cTP_qH}Ne5$U z)0A|Y<;+gO7-gXzGnxfwe8v{h?PN+#Nz7)2#@ZQ&VDJ|YU?;q=m6(!&+VPndot9xV zTTJPE?uiLW?1Y*}DtLf-Y7=oQ>2(lPsdXm5v8%C88BOjekxs11jbxlVPSu$<) zu;Vo|rCRefaQ!s>R;t9H93yhW`{%C$N(KnTYV+N;+5ulO~1j>ap z)kRIBr==mkuolBGt}=}sOzEAoFx!e)?va+t@S%iZG+QNY1e+;xT2w~BirBKB+{`uv z_=+G-c%voJoRYz_wsktkAlqBZErumxC?*@lrXea;j^M|N6_q2~%$hE&BcLS)GtxFP zvc<@3IYcx}%x07j%_;GWkiskn9aHKMqfJ%BZPFrMsL%;hri(En6_bD_4-J)~%#OUh z7BS<~dSNfp%w)E$X*8r*Yq~nu~G)h{VESbfINOUJ6wn)!J9u*}x zB7_XT)>3Sh%S^N|GqO^O+1NflGjRYjvSec>+C@uTR=U}kOsUc=tW0J$)V2!6i<2wO zm^r|d#FA)CX2fR>VEwTobcjzgG7Dc4S&}ucTlkVeUP{&wj8XfUh36@|?8*j!oKDrsFqt!1N`@_Nyz2B@HY_2V5;*!pnCEFUl5DjX z2Mb25Fi7 zfTTz(yoFh^gk4L5DJh$!i5))3n9YX7r)JqkNS7?+_%vg1H>6KYcdAeZ6R|suDVSN!jR{%F$?*yHO%!P8EXq{2y|J|~Y3GMtJg?Yx*oEx>&bFR4D83_Zl+d@Yo;8aJ zXwax`-@eV_69*WRqS8(2*=eRM3uZg=LUUuPF&R4-gV+wExfSiZKuIdB1u{V2Xp8+` zTihoZlNff%S+o!An3dVFe-~N~knXW`)ACkog+eHQ_3euJ7Ly4#EING%w)31QdVtkf zb2e5Q0S8)Wl5|^`&Dd`XB840Q7ZYQHMu~mDw2-6BVC|-#_^$X~REqLy$z%X&XQ> z5!-DxreTZTw`dJ)4P#gnKFTYqBV<6bO!Y4ry!eu&MBBZL%^|;!vIcGdzj-o$L`n!< ziMt^RTBI<9Z9z+54N8@(^AUPoWNsc7tCp>PJRl{hR*DdW5(CG8ekne_457ST{Jza* zzDV=QXesQ%b{DYdi%x~^>1r^F|w_uA8S7XU84Q*%>E{| z^bmYpLWqJrzsR&PgcpxQUDn{^(h>i}jI;*CUf)(<9+T2J_SC}Z(KOy-wC*j0l)$1b z9kNnWJDOXhWn^Ykp2F=OWjfrfx5XX`dyc*>24}_7LSRduq*0j5Xx>Fzq7tyV#hn1% ztH=biCa{tcMbk3zi;k|OVxud>F7cL>HWp^(lFa_r(N$_~ ziX`A7^(@l9kIcJ}$kL9ftm)OZkQ6z|p)?X=x5|`ch8H%cBr`&Y%zw3e2(hJDYqQCe zt(%H8yC}zA{$tHfDrG?Q7t>9VAQl-8!gMXkw@)=C`Y$BD_)tJ^7g{PZY(lUOeTmeeg~Qx1I(#V3!0nyjsi>N8G+9JJB-zynX9QfUmF-wka1=^<#fc$>vc=CAt>Pu< zLY+!EQ{)vZjm}T4!-Z-@h@mJVM|UrDfP_etM&};Ib1D+D7KNJF9nEnI_PCvd?WnF$ zsF1|v=xBwQ{91BkV~r;c?--Jc%tH5C_`L(Sf)E!!jU%I_k(06L;9L!Jy2La} z6n0RB&a4k8f+)uj;48n7z*p@9d79H9EEPI@EAteiZ?g*kGDO4pp_r8)>9?i z@|ZI_7>5ddQtYIUYF(VfTPPB3=X`d8g*1Cf>)D^po=C99%XZQu#L0%12uoNgTiq}W zYd8eblV=ZxM$v+5=4>ku|{Eiq=J^wTP`6Oj;<;phz6Dv#6nR*P@Ky}>KI;1Z-k@XB`sp5EnyM$ zE-6^b%#J|4O9)1kGOi;cOM1Zz=X6e7bYxg}TqQZeurK0`PIhSMM}!qyPb1L!(j^hU z(ista@e_`(#ar4Ub>O3?D5XT)B1#KzL@5D|6pp@2Z~8|ni13$Q^WvRljS9Z3@h=@u zMcTFzWZzaN-r%AXJe#&Hv2@a0c#JIMx}r2|LL@3bh8I_kLfm!=)|C$RZCK&+YT-oJ zf*&qOWbrJWCE|oW75~NK*9cOW36xmCL7=8H<{FQ0Kquk*%Q$_u(L|7XG?_ z26OmvcwDz~VOJ*L7aepiTCJ0tL{dgqM&iq~+A?ku1(0$;q&lB6I)4;&Rb+k)Uv-y~ zkVaQs<76x9g2b}U0J^h4r?M^xuU?QmXJ}js5nT}UIg3m|$65x%naQm_G|;gk;Am8+ zPY@IwgsaW5kD|~qm32XQ2Sn#WrX7U>v_9#7OLpasgMHjBCt7bgRx`w(aYq5ncns z9P%jXy7JaixhEnc5Vd`@@e~Ueol)c(btyuV(=-l(l{DR82fP6TnKU0>6#QoCvaNp8 zbofp_ue^h9q>sWumzyWHQ@}M$K_LfNI3SkxPgjZ>~L$5If!iUG5^huEWPsE+M)gZSFExt0hj!U17sl>2lZU zayQxVEgaur^Snowdq6kX#i~xI#?@+GU^<9{Lzm0B4q72f0*YArDBSER8W22$SlNl_ zau2!N6G;j*yjUc(giL#v(d8cFGYyJPOhKVMslgxS887Q{&+2#|=AJB+^%g^oZpAne zx;6KLZm_jqb1!HVeo~1>gLf1q8YO@>uMCwPatrXX5|igLHWN8PNpE2R?-CPbpqH`e zcOq0LUw7ZX`oiNS!DGI2UH#7G?wxl7?@#&cjciEj=yr3b`>wBl`>P9Qf8TTIt5Xr~ z{?e&V<_52FXMMW=>QJ{SKdFXxtbQj%GyR_8{*62SyO%w>^CT&*o%4)6-_H%~lThnB zV=bT8zc$S5V+y+YWYi~XT=&mzSk?P;T{B}@zqH*m!rJ#bH3M%@Nn}c06*;{*g^VMm zmUx#{0qUw~wF);0Uc-|5GPw#lNv;M^3i$~aN?uM7B!WBA7}UK%rZlGTW4gQ`ghGmo z+z&5&DNuH2O3v5FmAX6w+*T()-nzVSl*63 zTS>JG@^sf#;fxv^|d@zW-iR@2ZLm|%Medmq76S|GZstKuNi;hRaadRS!6g0BQPisdZ zRz3=@!1;Ni!dNJ@BZaYoLLMn}BG6935SIx~ellI&Bwbxy-ZXDb8C~8ixljgC(3s@F zXFqUXy#$G!%V42}JZLr^^QM78g9PhnLwpeka&s}r9Q`nsCy}%>C=1|>>!}d@hG3{c zT*M_BsQLKf&=oYmU@*4bH5m~{aM?zYttWereu&U}2cCxfW zNtS%kz!J86rQRz1`=BRDiG9G!utY)a=_>l8^^{u@9oq1`Ne*O+a5e8wUN5S^ zEIBX2lISGG&IvDzPEwqBXfzn|LM4_dgfiz#H4b9v26F*1bOHhiipyXJ7jA-kXN`4~oJ zCOM)me3+4Uj7x`F=pi8s0x!`^f~-4oICY*kf-CMjga%>{g7yh9AO;Zl2*mKQnOvqQ zGKB06(jbBsMhIrJk3y<+(D-43P6ADcIL*#jv=pN}cdP?~fUOMr&)Nhc@Vb6PpujN7oh90w#cj?iYIBy=<}5BdSCpO0W#<-^ zookh~N-f}03yMlDuu3hUT4BD>eu!d4^9A$Hih`xW@FCP$NJhCUtno!Q5)cRlApO|l zJ481#wwS) ziW^!*0qh47H%9H@w#W?jZamw@S$%D>`Pw78*#kF8(H)JRG01OUR^U6|%_V5LLFeTQ)?HQR$<@+kGm%*3a!44eBRALR*2<2gX z(V$HtXN{osmiB($3K+=EC3lCM{S*?uk3?CZk8uJ?+#(8;@z(b5p_U#Hn|_G&Clcil zZ#$|=3)}&**?V}i_i$HJ#dae|608@THc>^j!5_!YlChHn&SISLeWgUyCGEjf2W{Ska>CD=Nm#7Z1&Yh%pI2LQ`JC%9N^se}_%N91ZwML_*n?&!F+K`_3rD)% zplzOr56pFmX&!U8`sYWF)X!_bb8pL=>nkR;CY8i`aS3r@kzt0oknp;Zarnp6;_zaw z(VS*XqSvJ3{yR+wPPAm0O#}NH;`Nb{VId)L)?od&jASGwP;37`{Chj8(3$UKl>G{E z`;ztFezT|Hmn|_8o2RDYeNyoo6GkKd+6GB|r~+GVMdkl5_Wz#JFzr# z>0|x=*K+=E(Gj0a3VDMt;jcL^5?GDLX=O{CPNw3lG8$);{c(m#e*s)87F;?NwG=rK zXZRJ;S{%Yo548U9RNuq zJkuF2ozW649u@}S6O5=2gAF>zwTPC8D)<-#jtM^KFAU#fE388|Xqasp#5X`okB@;x zusXa<^)^6OgU*!^coj-^E8#Y2&B?*NehS1^4$rMjk4BA4VxN+t4wM*0SNFFT5>-ccsOH|iHlbD7@X zPEYP(T>7eMhxNa{OslhV*YFpiS#>SPjuzyX$=B!0_v!Ox-xtWF5~&ow8pv4a&1&P8 zXxh}sdwO@6G7^>(i3oY_4wMF7Bo<3hv$v(mo1(W4VTrnUdYH7Yi!VX_P zT+X%P>~8se&o>P@HvFOS^q-Z(So*3*$Ay7#EP@|0%zh4B}fRIFDi>Y8I! zX~EH(ReqV6Jo=B8FUPju_gjD8gO*YCHxBXoW?4Z&X4mC6`<0DKsB_TR@_V^w|8DnQ zeRHJg@jkIhwewycufts323;K;JgHIZ`_bLn-2W=&*%4Q_H>$8U38|7v=?DGB9F9Ag zIM;V_pZl)MJX?P^=(2xpDMqwpNxsAp5mD%U5K=sn@WjtG^{CM3!GR~r89NOPBQ~yd z>J#!fkB=dr%JQ;$&s>knVJ|OqX_=vZ(B#dKHydiM-50*WRUb?G73J;qZS~OwtqNL< zYc>F1I<8l{cA_~oIL-D|`b1M&?TkSwM6Hc`Q2Nr6rM9gbX%lX%6tk(vMrt)VouCtH_=8YO6_^gZ*&9gv4;cz5R#l z6J_@vjjFR{%ZRV*cNx9(b>%u|WSa-}+;s1XX}s*2sq?^D^|Hp^@%~+Ppu>U+%YO-I zC^G8@{2FOd{uqkizYr@@+J>yEgSW8p4X47FZ8Z7EwO$`-|#m- zO>1!Uk!EggBjvO@?!%qi?F_xR>%pq1pGH&&7~%fA`fc0K{S-cq6QwU16p z^9|86=Pc;lde|zTUz_}ZG{(`4{U<(Y?R^>+sC+Nmmp0R|&4MdO_KW8s8uG zt_j$v>9qZ__l&scZ?ZT2aPgN{899NHF`H{tKfY^)LUHwq>)`h9R>f5wUH#942ip96 zr`nj)qkd}UG>a+LbuU`Cad7&NOfDu<+q0e+=yXWA<_B{Ov;qES$P%zSF)>7f*cBe(S8dZ(Ocio%gIy zfNOT!b^X-&`H8F9<2VBUZMj)AYF zUp~^xwkCI3wdd{z%QvSIkF~kh=*C|i-hEhfWt-H!ejmTfT^lc1J++CUPFCP2@)a%9 zZap8K-DF3_V|QAdU45-jqvu%%Z}m^?cl7L6V?M)!n-`D5P9*xQYnt3f({@)q&7&V? z)%&*2jVjX}z8T*i+cw2^1zrpETAxjbupPT{p`N8?ME+yW;_LtBg zZJxF~9@(JI!i_`YmU%6lbVNI)TZ26-9s9~oTQk@v$Y8znu9O+vC6W(vgUG^$9 zlhCf%$5k%Jjl(#-PU$G#mz0sn72Ghkzc!kbc5LrX8akY=`uVJ@bNba^ZZLh*VEg$X zeL0(uhg9zDtHzmN7EU3Wv8W=sOtUh-Uz2XtzPwq*{cVk_>X=zQZ!Fb!5^`CzzLma3 zL9>FWagG1=TxJ{ZW(@5_?80~!i?wDgWUh;v_b>HRq7*W{y>KE(MPTRd?`we{JF-I_1%eC*ZTB|W-bnkQ}1 zymsGbzpXx#ACmrd=`8mff2Q1CvAEXGpKH2ljFabHe7^X#uBxN4&devnE4JBo@@ls` zCx*=~8+Rz&v+t!DKGBndcCHF*?)}iMOnKJlQh0CwU*;Tid^lD!v16LXy+gwh)mzUu zpZqKJ@Sgh_OS(_*K62)yf(or=y`SXs+O{E#*|ry zCY_(>zuF~k{^P}~#|;?mJTPe6kU`96_Nu3zIe&YO4%jmO_`v0@47I=d{rcdB=h&!( zRwsWMe`s^r*BbMrJxdy{kv19lA!Xj|Yi`TkHb!=G_;p`HeZEqK{Qbz9zdZ-gc|D%7 z{U`FbJ`#^7k+H)=^|TocF>n;O+CcwvxBLH9_WpWN>bgHJww_*N#Gv4ES9e^yeqe6r z%AHpIa;a>G0M~~nzdhM*Ri@rg`={z`?5r};Gb=QmzIslazUpsm(4Cwe_a~@aUufiW z9#1%0@knUEXA7P_OZKkyHs|(upL@4EELpUta?IgLuUi~#6-aax(zX7Q^r-)dWVIOcyn=0VqC?W`kWC|GS4LZmlfOo2t*7lsoaB&|7)`TzjW)4Si61s`Mx+=^N34#H?A6b@t5q*?Ir7iGY9uhb9Vp! zmz_CNHV2>4EuNT`u(`YRNC!XnPIE5}Z*r~swlzJz^1kXL8MkuVu%};~xL;rL@Y>EP zYQ@i!T3>q{Q|3~~@2B6mJ!#G$I%L~=DjO}GR zESNkx6gIkbGjp@zO`74siE9jvwO zc(V;RU)>+M>H5;;ncXCt##&nNN&5THChMs?RBr)qi-(HU2wRbX-8hQOr`eW z5dU5C^7mAW{bAj}h7%SIiQkyM$o-pL-?e(IGrjvfBz67!KRW+BvGSq*I~MqSrc07G z3|iB3%H|vXH#e<4oVamVtl~^maHo|s*Df3O{f2_sS>-QG|I9tBQtgoC4(SEGCsx^2 z@Mz3o|6l*~?Re;`htXGFNQ|ZlP9uL#`T17*y>Gw##Zdi&=0NYb^X)4vI{&)%!p6Z} zJqI0fU-Hh7Up+#fUp)k8y?RWy|J=ERaQa*P*rf3AxghT^+OCO*)Q&RzLZ#hdG|qPm zF(-pYZ_h15n?b9h+DjQOMNy*-vCgC`IBtdBl#x}6PYL*8h8UT#4` zZog6@OVc2a#(t@HTI&l=DD^X!bY+-J+G-T2d?!;RKo*V|+s`>j{x_^6+& zH|?L4>ZYEa|8=nR(>C)LZx0K*H>=ao#kU8(iQhkCPub%;zKk%4@8={h60NXeUgDZc!fVZ{` zbwk2JBYTw?z<%$N_By@}9{BRg^y%$ywhg=8BEZvrtl(sp#)|3H{Gf-g*Y;~S^^4d0 zUQX-vYRdPUhmPDZz+vc(&UODbe17F#_w*B)Go3yy=yXML)I9smrFkoF-a4{nz_Cdu zj~x5)q1sb-vqrlbFS<_5yBKj-J@fnDFK+A6al{?>hZm+d-SAi3)Dt!5>==4=@xd-8 z!?@JsvokBS>viPEp1!~OE%SUPnSST`%-Ku2MQ<8f`B>k0V;}D^Y309qwg1qsj>nx} zt%)l?{YdnNfT-U;Y-xEt{@ZB}+I@03=e2y|(t{Jm9+7>kQ@rY=yZd}Ymo98A{w*iZ zAAfzmaedbDf_1OH&iN~#rgx)jEkPH|*23HDUzj3W4MwwiS>86h>RK^1@ zI$8SY122B|VW%tib5GvC_1cUb#&JJAKez9j$0r6zqk~U9Y&1sd@~D^m@6#~_`7YD3 z6L-T-{H5K=arvR!GB>DBdT!=h^78h*>Vztd`nR0U2I{L~%Y_GE6$_7Dik}?&;keBp zJ_p0FG~hkEFatk6#&L@k{a$Q0H)hpfg4f-U^JJ4r>^NFxOE}VZI z{zzN-i`}pOZ1b${Z?y-z{i)qhD{@K3opD}`9@S`hV)DT)t=Xc;CkKDNead%Gn;K7l zYUh*j^@x1~noe%;Ag_Fv>y1KYHXK#<$-EnF1&T&n=I8 zm(QtP@r#h18zyh6f8oW4zxr-)AK^Zu`{sgA!sm=$6c+aMfc)z%?^}8~Py6GMYuCT; zAFX>R-ngjx!=2j53O}Yd?Rw~F_{lCCWEu14ge|NdvBIldU#DHx?fa+LzUK&M9aZST zmG#6yCbNzFb`BD|!*|XfzqC$Iy4gu_I{!Pb$jC~Y(v~02lFs`0 zv$Rqlb(u0O{Basax9y;phI3y6LHfubeI0%T6K@Rwj$pd#W6(13*&2>utY_69cVK;- z_75&Hu`{urbV>1Mncd@U%x+mew&YrKKc}ZFtNtKY^#8q1k8@{If2;gmzo4kV&4U`x zG=FH6(An72%h1`W@fk-=oruxZZx5Rjo3_+*PjK_yKX)!@bgEN}vA6ba&ra{%JM60G z8AIIzm3#iEy4`NwgpRoh2fG(Uk6O5|?Cwe}@2pL`<@ZzdiVk0mNjsdY8NFkN=jBg# zI{bAkH+$OYm%ra>*6#2AQr*C3xs%%}Po|A`?tL=P`@ysI+5=N-$IhG7PZi*wmlk$p z`hv;dHF0mc(y#HAzuk`SN=osjtdv)O0v{o|p z{)j_~=Ptb%JG{rc-k;s?zh}hX8`Osd`3sk1b0;L4Td+MQ`PyziC@n>vKA z9<*-P`CfsmS|2VGv-yjSwI<%%ztsK4m*qNFed1Sf)Y5&|S0Buo@G5c956hKtO)tGn z8v00SSXS|_w(pUp1!V>-DElNZXSn-nb4$Nnl}0+W^E;)VZE%@=rrNWXE&2sbJ9_T% z*4XTp?HB6rT=c7{|G`{lUDUTTuPmNfMfLV&_JgW>ANOxKW%T>k*JnnBE*RQ!N0pV* zrQf%{_gPx+COfJ=dS2G6uJ_wRmoD7jd3vcLDR=X^ZNoSD|Kw0PCvW}yi4Ef3I9-dm zw&(6v*S?+f`KsYKVNbB0&S<8d;!A<7*kIA;jsLf-1vo($)`IGVYr)5l;0sp;15R@4 zgy_TT3gEGqMwGZ3+^oJh) zUpK8#W6<4Roxa9bKY z`vs(~Sr|S4?to8D{V^|Qy}H)EH5XRYTs_=z&AHh<5BDptxZ8ioosce7b+vDQ@6hS^ zhUP!^Iln(xmi7IBzmBB+RWELl=d+euuhdCenVu9r?3;o_*Pzo)X1u(9S>ePbVTF*Olo8}*0WnbO&q)%hE z&Ual^uJV{8&$i0OO?uJy@rf?GCeHk9`)>ctDt*fa{&2KfV4W&+>b8kEK4RVU)!voA zUD5x3e8quR1EUx89e=G#pVR(r8+F;gse9u9+2fPLd)Gc&`Fchl*Ul}6Zg|PAZeJ@yF)V!j>l$F7!h4?NoI-TmU|N%z}F z>%aYe@*nqmf4%1IrM3O9?fEh<=fSTJ+TMYP(oejPv2cAWJ9>)~B}$rGuGkkwIk~* zBj%ubQp40{TRapUuHO6hpy6cY31RwPBv4U~l}O*QpnXBxanb+!QwB_5%v(GN!1FTO zV%Jw6+BYPGFLs|;7dI?+UG$yw9jrJOyQUwzBNg6Ev95IgU_Voz_cc}CPoDRsK5wQz zZ<_6#FIa|cqQ0@!omAo(`cLj?@lG-&TJSPV3Vxst@xG@$<2J z9k?%E1~%b!QhFIX8?T*P@H#C0GzPt9D*U)bu%Az{gvwXn z^PFaDuO?2P+jREGQ`yc__Za&I*J|`~pZR3k==VDt-%%f~zpK@XC4Z${{C}#u?x-fx zy-ny<+7*!Ao0Lh|&_M`1&$x|v z7u69lM|*zUbf3_qk(0`p*5E1p`5vENqRRMNr#4*;{{WFi_MoD8^yS#44smil>BeZ5 znu42Dj2R@?HCMSLy!0VycWXmO0lKrECsLCqFE2I3E$ST{-cakQgU@=3-JT*yka~s| z_Yu-0Q&NrhX)r9%M!gVdf^m({HOoG+&Aw}>Lf=B)*mCRkROPFI{gLKKYh{?X1b0Zq zlEliejH=+-)JmHuS5L3v2k0g(D(WJLw4^5P5WBGpL&F{8<*~RBUa$Q@$YS3qEotZc zCcC4j!<+aV6;r}T`WIIgIC9e^#<~hqdOp}WYERhGWJYLG`%yoouJ94~$0HQ#-rQgd z59Ol~?bdygABLUfXHtI2J(=7`_99oW&So*Ckj}_}B`s8-hfJ!uBBSsS(vKhB@+>be zCm=w0%^*pjY+YX@bUAya-u;15%J_R9f9{!gN@DZ@ignWiD`YPm2j>0nwJ> zYfB$$;J$e&hgj#~;nsHaB0E!nSr-(?AqL<$gm%4zq`w-t_AG_pk%V64*CDPW%6I-F&!mTm{M>~EV@15e%~_uoNaK`K-e$?BYe9bng7C2>1J+g zOv38l#X0jXsq8+>CKe#TfKg&te?>pqEA@0}a2sMsE2fTUILo=nLn{9z7V>AG*HpzXqKB#!gA50Wu3L~Crw*rdt4c8)M9HV+Zwa9 zyEl#*UM6|B zsJBtDv#9S_+zD4|&usew+=a>l%EBx}g@wouoqYxJgWG^N0;%sF9 zsUZ7Y9Q$Da$FBE9+EGw|jtD#G|FXlr{Ny{12)hV)NPrwd@mog(2hpHr`23`?fTjoz zA_F>2k|1u1f)CxNp~GzGDIj1t=UY34Qc!VQkmy6$;xL=8pMyVne>qBtQrkQ%q5AI8 zK2D_GYXfp>3#C$dze}_l^I|Lv26tqzSpfIR{A{@R` zsD*{?FvOF)OC&OJ?Ct+NTWbB)prcjN(4>Vm4+Rp8_kf4MLX!CF<@janqzlK2p zHWh#_^Snc3n57QmOXG*iw096gH_BgJ1gyky`ADXocgyS@V6(tJ+()7@|eiQ2J_akZHZ~S?G ze4Ey#{#stQx_D{OsjdJ*6r{W1-?dTO(57p5iX#(3Wh!j^+3uMJ@6`A|rMJ()9@=PV z{Gv`EMvtdi!S%!yk7NHVCiCa%?ekxbcf`HPJ9*mmsYYVF?aL?WTtEH0fxs{HbH~R4 zWC2B4n8Gf#{SO2J|6pv8*5Y?*?M_w+n*?GXfQ|cx*a+Uc1x8_@{U+&2*$W(|F5h>LIK*g+^9>u8`NA_eGt{&_~@=<2Sd~ ztUL|?cN&{r+T2E#U(fm1wU%UyO{~_E+%2tW51Qk2+19Hpu68atutocJYH4X_44&lN zKDl~|6P_x1+z363V0lca4`~TmPzpM6h<73F(&6hz$q35KoXhf;u+Fb;-gBR9eez3t z0GXE&perh@-c6z?OpddWs=dESId(n=c35Kb7(ssP{?s*vn$z~_16EpZ=bxmx#9!TZ zI~_9Ae3;?7__)fT4lE$!_ufMIO(_GFSOFl=~8wS_Fj>dT4V` zS8>m5(B-)?HE+5RJ9MfrEvo-VGk&kS`7yGQ*HD^*8>%0j_5I(hlo*tK9KH~Ya`*DP ziR~z+D_5zRY3b<0-M!GoxAgD|ggH_rEpkYQMj)BW*(ega4LIj(8 zw+D6AQ_Q?y=00maHgR^?iuiOGXxQwWHeP3{w=;d4#eYCqzP8(%N^X`3ZwBw5rIX-& zekT~tPg~uuIM8b!H;j%nWCH=GAFMPqepP9Zc`4YLXcDLZX%w|wb|4C;z4y8Uf$rGar!GXFvqc!lnbF9 z(;CD=?8>$vLhMur<5Yv~FG8*GatplEu&QwD(XALCvMN*C>G^r4%}zQzw@W8Afw!vL zMbOABFx6{FwKRLyREFSYlX0Pl6EpZR(*d@fTfIojw5_Vpw{reT4KZ{;tS9!jEU$pUW;nUuX222+mLxPH(coAj{SmreC6-?7#D&BYwb{oh znS+bf51hO1>VT?>CCbl;)ML0PAaN{&K8u?9hwbU(&{%y2!%WB9(*07UL)EV7*tMw= zoo6}gB^Y+|A5>u;`5sR=;yX~U4eKT(28(M)c{kCoaO~o4aOeQq!!~?4t4Kn2kyMWH zMt48Ndy-eMkhN;{ii%A%O~O#LAv(Rz@1{27a&Z*CpqYDWSG7;%{*47fo)|r--G2=Y zQ0ynGRI=HgmQp#lby1~ECu~MB%uV$K9@_|D>kF{80JiGCLcPE12l;K|p^2r%ZsQ>W zfGNr9DC#N8LUomup$7q}J<2ZpEoB$nTM1Rr7+m@gY+KX;7b0^18ganH0y!1g3zA

!oCb34bXoY0QB>Bv?4f_phw!L4KBC6 zvme@+cg`w)buBp*EPj8<3+*abJUu|Wb3FyeghTG*G#TK#uwn9no>th(O}s;!By#Djh!AB3)wZwK!XH7D_hn9hpT<{w}0Bm)yqM|(oHciM%X^|TPmng z2BstGf{X{uhHZKyxZQ76-5A8q#kpSPTCwjEK_&{lMLNa9tCe#|IVch689AB`eicvm zTOIz!xuo9P^He&C{CU>Igd^i!8U8v$7TY3n9T`^BsK_M8+0w(}#XJG67i{Luw6iRg zvvqvB{Rd;o-tbeuQqbQHc$dFqQg_Ed>gRXsE9EF(TE<&P#s<+~_GTG;^X7Noyc>V5 z4%~Cgeuvh4>z2U)?k{!+7$jr*#?S!1cfU$aH02KdoZ}}V>cN|nR4JNt4gS>PG2K*4 zSalvUAa5AJj(;@(IT##!24K4ZY$pKD=Jt=@dw0QnD;O;+2>xHZSztJB%<~kfMLDIE zF`1#=J+O5GnMs=Z`pE||XD3^vp51b)H~a@n86|^sn`qLb#(P;dwn=qblkElDQ{o3& zOfRU`w3lZXu~6kZPfB>ty9Bkbs0H^H%Rarvp%crRjT#zJVV2xn-iF1UNBCgwcWP$J zjLv2Xk5+iLrM@+FhxcSX2PeKVI9VoOZa!1PQs<1fK3q!iv#kV82b91y6mNa0+BE^T zh-H{JTN&!9OgNXEH+qW&h6!ci_z~M4$85KHO=s+6*hpX|dR5Wj(fUhg)7yG&kEa(>|A4d_~reX ZH&}yh-!nT9!?h@L7<;!Y`^-Vo{C~shP~iXo literal 0 HcmV?d00001 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Microsoft.Threading.Tasks.Extensions.dll b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Microsoft.Threading.Tasks.Extensions.dll new file mode 100644 index 0000000000000000000000000000000000000000..4d862e1730a34a6a5cfa39d04840bd039cf9de29 GIT binary patch literal 31520 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 literal 0 HcmV?d00001 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Microsoft.Threading.Tasks.dll b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Microsoft.Threading.Tasks.dll new file mode 100644 index 0000000000000000000000000000000000000000..8438577c2042e5d6899425d500bf8074aae650a1 GIT binary patch literal 37104 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 literal 0 HcmV?d00001 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/App.config b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/App.config deleted file mode 100644 index 8e15646..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Batches.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Batches.cs deleted file mode 100644 index 93a8104..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Batches.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using NUnit.Framework; - -namespace Tests -{ - [TestFixture] - public class Batches - { - [Test] - public void TestBatchNotSent() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(0); - conn.KeyDeleteAsync("batch"); - conn.StringSetAsync("batch", "batch-not-sent"); - var tasks = new List(); - var batch = conn.CreateBatch(); - - tasks.Add(batch.KeyDeleteAsync("batch")); - tasks.Add(batch.SetAddAsync("batch", "a")); - tasks.Add(batch.SetAddAsync("batch", "b")); - tasks.Add(batch.SetAddAsync("batch", "c")); - - Assert.AreEqual("batch-not-sent", (string)conn.StringGet("batch")); - } - } - - [Test] - public void TestBatchSent() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(0); - conn.KeyDeleteAsync("batch"); - conn.StringSetAsync("batch", "batch-sent"); - var tasks = new List(); - var batch = conn.CreateBatch(); - tasks.Add(batch.KeyDeleteAsync("batch")); - tasks.Add(batch.SetAddAsync("batch", "a")); - tasks.Add(batch.SetAddAsync("batch", "b")); - tasks.Add(batch.SetAddAsync("batch", "c")); - batch.Execute(); - - var result = conn.SetMembersAsync("batch"); - tasks.Add(result); - Task.WhenAll(tasks.ToArray()); - - var arr = result.Result; - Array.Sort(arr, (x, y) => string.Compare(x, y)); - Assert.AreEqual(3, arr.Length); - Assert.AreEqual("a", (string)arr[0]); - Assert.AreEqual("b", (string)arr[1]); - Assert.AreEqual("c", (string)arr[2]); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Config.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Config.cs deleted file mode 100644 index ca0cdee..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Config.cs +++ /dev/null @@ -1,289 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Security.Authentication; -using System.Threading.Tasks; -using NUnit.Framework; -using StackExchange.Redis; - -namespace Tests -{ - [TestFixture(Description = "Validates that the test environment is configured and responding")] - public class Config - { - public static string CreateUniqueName() - { - return Guid.NewGuid().ToString("N"); - } - - internal static IServer GetServer(ConnectionMultiplexer conn) - { - return conn.GetServer(conn.GetEndPoints()[0]); - } - - static readonly SocketManager socketManager = new SocketManager(); - static Config() - { - TaskScheduler.UnobservedTaskException += (sender, args) => - { - Trace.WriteLine(args.Exception, "UnobservedTaskException"); - args.SetObserved(); - }; - } - - public const string LocalHost = "127.0.0.1"; //"192.168.0.10"; //"127.0.0.1"; - public const string RemoteHost = "ubuntu"; - - const int unsecuredPort = 6379, securedPort = 6381, - clusterPort0 = 7000, clusterPort1 = 7001, clusterPort2 = 7002; - - -#if CLUSTER - internal static RedisCluster GetCluster(TextWriter log = null) - { - string clusterConfiguration = - RemoteHost + ":" + clusterPort0 + "," + - RemoteHost + ":" + clusterPort1 + "," + - RemoteHost + ":" + clusterPort2; - return RedisCluster.Connect(clusterConfiguration, log); - } -#endif - - //const int unsecuredPort = 6380, securedPort = 6381; - - internal static ConnectionMultiplexer GetRemoteConnection(bool open = true, bool allowAdmin = false, bool waitForOpen = false, int syncTimeout = 5000, int ioTimeout = 5000) - { - return GetConnection(RemoteHost, unsecuredPort, open, allowAdmin, waitForOpen, syncTimeout, ioTimeout); - } - private static ConnectionMultiplexer GetConnection(string host, int port, bool open = true, bool allowAdmin = false, bool waitForOpen = false, int syncTimeout = 5000, int ioTimeout = 5000) - { - var options = new ConfigurationOptions - { - EndPoints = { { host, port } }, - AllowAdmin = allowAdmin, - SyncTimeout = syncTimeout, - SocketManager = socketManager - }; - var conn = ConnectionMultiplexer.Connect(options); - conn.InternalError += (s, args) => - { - Trace.WriteLine(args.Exception.Message, args.Origin); - }; - if (open) - { - if (waitForOpen) conn.GetDatabase().Ping(); - } - return conn; - } - internal static ConnectionMultiplexer GetUnsecuredConnection(bool open = true, bool allowAdmin = false, bool waitForOpen = false, int syncTimeout = 5000, int ioTimeout = 5000) - { - return GetConnection(LocalHost, unsecuredPort, open, allowAdmin, waitForOpen, syncTimeout, ioTimeout); - } - - internal static ConnectionMultiplexer GetSecuredConnection(bool open = true) - { - var options = new ConfigurationOptions - { - EndPoints = { { LocalHost, securedPort } }, - Password = "changeme", - SyncTimeout = 6000, - SocketManager = socketManager - }; - var conn = ConnectionMultiplexer.Connect(options); - conn.InternalError += (s, args) => - { - Trace.WriteLine(args.Exception.Message, args.Origin); - }; - return conn; - } - - internal static RedisFeatures GetFeatures(ConnectionMultiplexer muxer) - { - return GetServer(muxer).Features; - } - - [Test] - public void CanOpenUnsecuredConnection() - { - using (var conn = GetUnsecuredConnection(false)) - { - var server = GetServer(conn); - server.Ping(); - } - } - - [Test] - public void CanOpenSecuredConnection() - { - using (var conn = GetSecuredConnection(false)) - { - var server = GetServer(conn); - server.Ping(); - } - } - - [Test] - public void CanNotOpenNonsenseConnection_IP() - { - Assert.Throws(() => - { - var log = new StringWriter(); - try { - using (var conn = ConnectionMultiplexer.Connect(Config.LocalHost + ":6500")) { } - } - finally { - Console.WriteLine(log); - } - }); - } - - [Test] - public void CanNotOpenNonsenseConnection_DNS() - { - Assert.Throws(() => - { - var log = new StringWriter(); - try - { - using (var conn = ConnectionMultiplexer.Connect("doesnot.exist.ds.aasd981230d.com:6500", log)) { } - } - finally - { - Console.WriteLine(log); - } - }); - } - - [Test] - public void CreateDisconnectedNonsenseConnection_IP() - { - var log = new StringWriter(); - try - { - using (var conn = ConnectionMultiplexer.Connect(Config.LocalHost + ":6500,abortConnect=false")) { - Assert.IsFalse(conn.GetServer(conn.GetEndPoints().Single()).IsConnected); - Assert.IsFalse(conn.GetDatabase().IsConnected(default(RedisKey))); - } - } - finally - { - Console.WriteLine(log); - } - } - [Test] - public void CreateDisconnectedNonsenseConnection_DNS() - { - var log = new StringWriter(); - try - { - using (var conn = ConnectionMultiplexer.Connect("doesnot.exist.ds.aasd981230d.com:6500,abortConnect=false", log)) { - Assert.IsFalse(conn.GetServer(conn.GetEndPoints().Single()).IsConnected); - Assert.IsFalse(conn.GetDatabase().IsConnected(default(RedisKey))); - } - } - finally - { - Console.WriteLine(log); - } - } - - [Test] - public void SslProtocols_SingleValue() - { - var log = new StringWriter(); - var options = ConfigurationOptions.Parse("myhost,sslProtocols=Tls11"); - Assert.AreEqual(SslProtocols.Tls11, options.SslProtocols.Value); - } - - [Test] - public void SslProtocols_MultipleValues() - { - var log = new StringWriter(); - var options = ConfigurationOptions.Parse("myhost,sslProtocols=Tls11|Tls12"); - Assert.AreEqual(SslProtocols.Tls11|SslProtocols.Tls12, options.SslProtocols.Value); - } - - [Test] - public void SslProtocols_UsingIntegerValue() - { - var log = new StringWriter(); - - // The below scenario is for cases where the *targeted* - // .NET framework version (e.g. .NET 4.0) doesn't define an enum value (e.g. Tls11) - // but the OS has been patched with support - int integerValue = (int)(SslProtocols.Tls11 | SslProtocols.Tls12); - var options = ConfigurationOptions.Parse("myhost,sslProtocols=" + integerValue); - Assert.AreEqual(SslProtocols.Tls11 | SslProtocols.Tls12, options.SslProtocols.Value); - } - - [Test] - public void SslProtocols_InvalidValue() - { - var log = new StringWriter(); - Assert.Throws(() => ConfigurationOptions.Parse("myhost,sslProtocols=InvalidSslProtocol")); - } - - [Test] - public void ConfigurationOptionsDefaultForAzure() - { - var options = ConfigurationOptions.Parse("contoso.redis.cache.windows.net"); - Assert.IsTrue(options.DefaultVersion.Equals(new Version(3, 0, 0))); - Assert.IsFalse(options.AbortOnConnectFail); - } - - [Test] - public void ConfigurationOptionsForAzureWhenSpecified() - { - var options = ConfigurationOptions.Parse("contoso.redis.cache.windows.net,abortConnect=true, version=2.1.1"); - Assert.IsTrue(options.DefaultVersion.Equals(new Version(2, 1, 1))); - Assert.IsTrue(options.AbortOnConnectFail); - } - - [Test] - public void ConfigurationOptionsDefaultForAzureChina() - { - // added a few upper case chars to validate comparison - var options = ConfigurationOptions.Parse("contoso.REDIS.CACHE.chinacloudapi.cn"); - Assert.IsTrue(options.DefaultVersion.Equals(new Version(3, 0, 0))); - Assert.IsFalse(options.AbortOnConnectFail); - } - - [Test] - public void ConfigurationOptionsDefaultForAzureGermany() - { - var options = ConfigurationOptions.Parse("contoso.redis.cache.cloudapi.de"); - Assert.IsTrue(options.DefaultVersion.Equals(new Version(3, 0, 0))); - Assert.IsFalse(options.AbortOnConnectFail); - } - - [Test] - public void ConfigurationOptionsDefaultForAzureUSGov() - { - var options = ConfigurationOptions.Parse("contoso.redis.cache.usgovcloudapi.net"); - Assert.IsTrue(options.DefaultVersion.Equals(new Version(3, 0, 0))); - Assert.IsFalse(options.AbortOnConnectFail); - } - - [Test] - public void ConfigurationOptionsDefaultForNonAzure() - { - var options = ConfigurationOptions.Parse("redis.contoso.com"); - Assert.IsTrue(options.DefaultVersion.Equals(new Version(2, 0, 0))); - Assert.IsTrue(options.AbortOnConnectFail); - } - - [Test] - public void ConfigurationOptionsDefaultWhenNoEndpointsSpecifiedYet() - { - var options = new ConfigurationOptions(); - Assert.IsTrue(options.DefaultVersion.Equals(new Version(2, 0, 0))); - Assert.IsTrue(options.AbortOnConnectFail); - } - - internal static void AssertNearlyEqual(double x, double y) - { - if (Math.Abs(x - y) > 0.00001) Assert.AreEqual(x, y); - } - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Connection.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Connection.cs deleted file mode 100644 index 1d86d66..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Connection.cs +++ /dev/null @@ -1,312 +0,0 @@ -//using BookSleeve; -//using NUnit.Framework; -//using System.Linq; -//using System; -//using System.Diagnostics; -//using System.IO; -//using System.Threading; -//using System.Collections.Generic; -//using System.Threading.Tasks; - -//namespace Tests -//{ -// [TestFixture] -// public class Connections // http://redis.io/commands#connection -// { -// [Test] -// public void TestConnectWithDownedNodeMustBeFast_multipletimes() -// { -// for (int i = 0; i < 5; i++) TestConnectWithDownedNodeMustBeFast(); -// } -// [Test] -// public void TestConnectWithDownedNodeMustBeFast() -// { -// using (var good = ConnectionUtils.Connect(Config.LocalHost + ":6379")) -// using (var bad = ConnectionUtils.Connect(Config.LocalHost + ":6666")) -// { -// Assert.IsNotNull(good, "6379 should exist for this test"); -// Assert.IsNull(bad, "6666 should not exist for this test"); -// } - -// StringWriter log = new StringWriter(); -// var watch = Stopwatch.StartNew(); -// using (var selected = ConnectionUtils.Connect(Config.LocalHost +":6379," + Config.LocalHost + ":6666,name=Core(Q&A)", log)) -// {} -// watch.Stop(); -// Console.WriteLine(log); -// Assert.Less(1, 2, "I always get this wrong!"); -// Assert.Less(watch.ElapsedMilliseconds, 1200, "I always get this wrong!"); - -// } - -// [Test] -// public void TestConnectViaSentinel() -// { -// string[] endpoints; -// StringWriter sw = new StringWriter(); -// var selected = ConnectionUtils.SelectConfiguration(Config.RemoteHost+":26379,serviceName=mymaster", out endpoints, sw); -// string log = sw.ToString(); -// Console.WriteLine(log); -// Assert.IsNotNull(selected, NO_SERVER); -// Assert.AreEqual(Config.RemoteHost + ":6379", selected); -// } -// [Test] -// public void TestConnectViaSentinelInvalidServiceName() -// { -// string[] endpoints; -// StringWriter sw = new StringWriter(); -// var selected = ConnectionUtils.SelectConfiguration(Config.RemoteHost + ":26379,serviceName=garbage", out endpoints, sw); -// string log = sw.ToString(); -// Console.WriteLine(log); -// Assert.IsNull(selected); -// } - -// const string NO_SERVER = "No server available"; -// [Test] -// public void TestDirectConnect() -// { -// string[] endpoints; -// StringWriter sw = new StringWriter(); -// var selected = ConnectionUtils.SelectConfiguration(Config.RemoteHost + ":6379", out endpoints, sw); -// string log = sw.ToString(); -// Console.WriteLine(log); -// Assert.IsNotNull(selected, NO_SERVER); -// Assert.AreEqual(Config.RemoteHost + ":6379", selected); - -// } - - -// [Test] -// public void TestName() -// { -// using (var conn = Config.GetUnsecuredConnection(open: false, allowAdmin: true)) -// { -// string name = Config.CreateUniqueName(); -// conn.Name = name; -// conn.Wait(conn.Open()); -// if (!conn.Features.ClientName) Assert.Inconclusive(); -// var client = conn.Wait(conn.Server.ListClients()).SingleOrDefault(c => c.Name == name); -// Assert.IsNotNull(client, "found client"); -// } -// } - -// [Test] -// public void CheckInProgressCountersGoToZero() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.CompletionMode = ResultCompletionMode.Concurrent; -// Task counters = null; -// Task[] allTasks = new Task[5000]; -// for (int i = 0; i < 5000; i++) -// { -// var tmp = conn.Strings.Get(5, "foo" + i); -// if (i == 2500) -// { -// counters = tmp.ContinueWith(x => -// { -// return conn.GetCounters(false); -// },TaskContinuationOptions.ExecuteSynchronously); -// } -// allTasks[i] = tmp; -// } - -// var c = conn.Wait(counters); -// Console.WriteLine("in progress during: {0}", c.AsyncCallbacksInProgress); -// Assert.AreNotEqual(0, c.AsyncCallbacksInProgress, "async during"); - -// conn.WaitAll(allTasks); -// PubSub.AllowReasonableTimeToPublishAndProcess(); -// Assert.AreEqual(0, conn.GetCounters(false).AsyncCallbacksInProgress, "async @ end"); -// Assert.AreEqual(0, c.SyncCallbacksInProgress, "sync @ end"); -// } -// } - -// [Test] -// public void TestSubscriberName() -// { -// using (var conn = Config.GetUnsecuredConnection(open: false, allowAdmin: true)) -// { -// string name = Config.CreateUniqueName(); -// conn.Name = name; -// conn.Wait(conn.Open()); -// if (!conn.Features.ClientName) Assert.Inconclusive(); -// using (var subscriber = conn.GetOpenSubscriberChannel()) -// { -// var evt = new ManualResetEvent(false); -// var tmp = subscriber.Subscribe("test-subscriber-name", delegate -// { -// evt.Set(); -// }); -// subscriber.Wait(tmp); -// conn.Publish("test-subscriber-name", "foo"); -// Assert.IsTrue(evt.WaitOne(1000), "event was set"); -// var clients = conn.Wait(conn.Server.ListClients()).Where(c => c.Name == name).ToList(); -// Assert.AreEqual(2, clients.Count, "number of clients"); -// } - -// } -// } - -// [Test] -// public void TestSubscriberNameOnRemote_WithName() -// { -// TestSubscriberNameOnRemote(true); -// } -// [Test] -// public void TestSubscriberNameOnRemote_WithoutName() -// { -// TestSubscriberNameOnRemote(false); -// } -// private void TestSubscriberNameOnRemote(bool setName) -// { -// string id = Config.CreateUniqueName(); - -// using (var pub = new RedisConnection(Config.RemoteHost, allowAdmin: true)) -// using (var sub = new RedisSubscriberConnection(Config.RemoteHost)) -// { -// List errors = new List(); -// EventHandler errorHandler = (sender, args) => -// { -// lock (errors) errors.Add(args.Exception.Message); -// }; -// pub.Error += errorHandler; -// sub.Error += errorHandler; - -// if (setName) -// { -// pub.Name = "pub_" + id; -// sub.Name = "sub_" + id; -// } -// int count = 0; -// var subscribe = sub.Subscribe("foo"+id, (key,payload) => Interlocked.Increment(ref count)); - -// Task pOpen = pub.Open(), sOpen = sub.Open(); -// pub.WaitAll(pOpen, sOpen, subscribe); - -// Assert.AreEqual(0, Interlocked.CompareExchange(ref count, 0, 0), "init message count"); -// pub.Wait(pub.Publish("foo" + id, "hello")); - -// PubSub.AllowReasonableTimeToPublishAndProcess(); -// var clients = setName ? pub.Wait(pub.Server.ListClients()) : null; -// Assert.AreEqual(1, Interlocked.CompareExchange(ref count, 0, 0), "got message"); -// lock (errors) -// { -// foreach (var error in errors) -// { -// Console.WriteLine(error); -// } -// Assert.AreEqual(0, errors.Count, "zero errors"); -// } -// if (setName) -// { -// Assert.AreEqual(1, clients.Count(x => x.Name == pub.Name), "pub has name"); -// Assert.AreEqual(1, clients.Count(x => x.Name == sub.Name), "sub has name"); -// } -// } - -// } - -// [Test] -// public void TestForcedSubscriberName() -// { -// using (var conn = Config.GetUnsecuredConnection(allowAdmin: true, open: true, waitForOpen: true)) -// using (var sub = new RedisSubscriberConnection(conn.Host, conn.Port)) -// { -// var task = sub.Subscribe("foo", delegate { }); -// string name = Config.CreateUniqueName(); -// sub.Name = name; -// sub.SetServerVersion(new Version("2.6.9"), ServerType.Master); -// sub.Wait(sub.Open()); -// sub.Wait(task); -// Assert.AreEqual(1, sub.SubscriptionCount); - -// if (!conn.Features.ClientName) Assert.Inconclusive(); -// var clients = conn.Wait(conn.Server.ListClients()).Where(c => c.Name == name).ToList(); -// Assert.AreEqual(1, clients.Count, "number of clients"); -// } -// } - -// [Test] -// public void TestNameViaConnect() -// { -// string name = Config.CreateUniqueName(); -// using (var conn = ConnectionUtils.Connect(Config.RemoteHost+",allowAdmin=true,name=" + name)) -// { -// Assert.IsNotNull(conn, NO_SERVER, "connection"); -// Assert.AreEqual(name, conn.Name, "connection name"); -// if (!conn.Features.ClientName) Assert.Inconclusive(); -// var client = conn.Wait(conn.Server.ListClients()).SingleOrDefault(c => c.Name == name); -// Assert.IsNotNull(client, "find client"); -// } -// } - -// // AUTH is already tested by secured connection - -// // QUIT is implicit in dispose - -// // ECHO has little utility in an application - -// [Test] -// public void TestGetSetOnDifferentDbHasDifferentValues() -// { -// // note: we don't expose SELECT directly, but we can verify that we have different DBs in play: - -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Strings.Set(1, "select", "abc"); -// conn.Strings.Set(2, "select", "def"); -// var x = conn.Strings.GetString(1, "select"); -// var y = conn.Strings.GetString(2, "select"); -// conn.WaitAll(x, y); -// Assert.AreEqual("abc", x.Result); -// Assert.AreEqual("def", y.Result); -// } -// } -// [Test, ExpectedException(typeof(ArgumentOutOfRangeException))] -// public void TestGetOnInvalidDbThrows() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Strings.GetString(-1, "select"); -// } -// } - - -// [Test] -// public void Ping() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// var ms = conn.Wait(conn.Server.Ping()); -// Assert.GreaterOrEqual(ms, 0); -// } -// } - -// [Test] -// public void CheckCounters() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen:true)) -// { -// conn.Wait(conn.Strings.GetString(0, "CheckCounters")); -// var first = conn.GetCounters(); - -// conn.Wait(conn.Strings.GetString(0, "CheckCounters")); -// var second = conn.GetCounters(); -// // +2 = ping + one select -// Assert.AreEqual(first.MessagesSent + 2, second.MessagesSent, "MessagesSent"); -// Assert.AreEqual(first.MessagesReceived + 2, second.MessagesReceived, "MessagesReceived"); -// Assert.AreEqual(0, second.ErrorMessages, "ErrorMessages"); -// Assert.AreEqual(0, second.MessagesCancelled, "MessagesCancelled"); -// Assert.AreEqual(0, second.SentQueue, "SentQueue"); -// Assert.AreEqual(0, second.UnsentQueue, "UnsentQueue"); -// Assert.AreEqual(0, second.QueueJumpers, "QueueJumpers"); -// Assert.AreEqual(0, second.Timeouts, "Timeouts"); -// Assert.IsTrue(second.Ping >= 0, "Ping"); -// Assert.IsTrue(second.ToString().Length > 0, "ToString"); -// } -// } - - -// } -//} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Constraints.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Constraints.cs deleted file mode 100644 index 629b06f..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Constraints.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Threading.Tasks; -using NUnit.Framework; -using StackExchange.Redis; - -namespace Tests -{ - [TestFixture] - public class Constraints - { - [Test] - public void ValueEquals() - { - RedisValue x = 1, y = "1"; - Assert.IsTrue(x.Equals(y), "equals"); - Assert.IsTrue(x == y, "operator"); - - } - - [Test] - public void TestManualIncr() - { - using (var muxer = Config.GetUnsecuredConnection(syncTimeout: 120000)) // big timeout while debugging - { - var conn = muxer.GetDatabase(0); - for (int i = 0; i < 200; i++) - { - conn.KeyDelete("foo"); - Assert.AreEqual(1, conn.Wait(ManualIncr(conn, "foo"))); - Assert.AreEqual(2, conn.Wait(ManualIncr(conn, "foo"))); - Assert.AreEqual(2, (long)conn.StringGet("foo")); - } - } - - } - - public async Task ManualIncr(IDatabase connection, string key) - { - var oldVal = (long?)await connection.StringGetAsync(key).ConfigureAwait(false); - var newVal = (oldVal ?? 0) + 1; - var tran = connection.CreateTransaction(); - { // check hasn't changed - -#pragma warning disable 4014 - tran.AddCondition(Condition.StringEqual(key, oldVal)); - tran.StringSetAsync(key, newVal); -#pragma warning restore 4014 - if (!await tran.ExecuteAsync().ConfigureAwait(false)) return null; // aborted - return newVal; - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Hashes.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Hashes.cs deleted file mode 100644 index 23d365b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Hashes.cs +++ /dev/null @@ -1,507 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Linq; -using NUnit.Framework; -using StackExchange.Redis; - -namespace Tests -{ - [TestFixture] - public class Hashes // http://redis.io/commands#hash - { - [Test] - public void TestIncrBy() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(5); - conn.KeyDeleteAsync("hash-test"); - for (int i = 1; i < 1000; i++) - { - Assert.AreEqual(i, conn.HashIncrementAsync("hash-test", "a", 1).Result); - Assert.AreEqual(-i, conn.HashIncrementAsync("hash-test", "b", -1).Result); - //Assert.AreEqual(i, conn.Wait(conn.Hashes.Increment(5, "hash-test", "a", 1))); - //Assert.AreEqual(-i, conn.Wait(conn.Hashes.Increment(5, "hash-test", "b", -1))); - } - } - } - - [Test] - public void Scan() - { - using (var muxer = Config.GetUnsecuredConnection(waitForOpen: true)) - { - if (!Config.GetFeatures(muxer).Scan) Assert.Inconclusive(); - const int db = 3; - var conn = muxer.GetDatabase(db); - - const string key = "hash-scan"; - conn.KeyDeleteAsync(key); - conn.HashSetAsync(key, "abc", "def"); - conn.HashSetAsync(key, "ghi", "jkl"); - conn.HashSetAsync(key, "mno", "pqr"); - - var t1 = conn.HashScan(key); - var t2 = conn.HashScan(key, "*h*"); - var t3 = conn.HashScan(key); - var t4 = conn.HashScan(key, "*h*"); - - var v1 = t1.ToArray(); - var v2 = t2.ToArray(); - var v3 = t3.ToArray(); - var v4 = t4.ToArray(); - - Assert.AreEqual(3, v1.Length); - Assert.AreEqual(1, v2.Length); - Assert.AreEqual(3, v3.Length); - Assert.AreEqual(1, v4.Length); - Array.Sort(v1, (x, y) => string.Compare(x.Name, y.Name)); - Array.Sort(v2, (x, y) => string.Compare(x.Name, y.Name)); - Array.Sort(v3, (x, y) => string.Compare(x.Name, y.Name)); - Array.Sort(v4, (x, y) => string.Compare(x.Name, y.Name)); - - Assert.AreEqual("abc=def,ghi=jkl,mno=pqr", string.Join(",", v1.Select(pair => pair.Name + "=" + (string)pair.Value))); - Assert.AreEqual("ghi=jkl", string.Join(",", v2.Select(pair => pair.Name + "=" + (string)pair.Value))); - Assert.AreEqual("abc=def,ghi=jkl,mno=pqr", string.Join(",", v3.Select(pair => pair.Name + "=" + pair.Value))); - Assert.AreEqual("ghi=jkl", string.Join(",", v4.Select(pair => pair.Name + "=" + pair.Value))); - } - } - [Test] - public void TestIncrementOnHashThatDoesntExist() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(0); - conn.KeyDeleteAsync("keynotexist"); - var result1 = conn.Wait(conn.HashIncrementAsync("keynotexist", "fieldnotexist", 1)); - var result2 = conn.Wait(conn.HashIncrementAsync("keynotexist", "anotherfieldnotexist", 1)); - Assert.AreEqual(1, result1); - Assert.AreEqual(1, result2); - } - } - [Test] - public void TestIncrByFloat() - { - using (var muxer = Config.GetUnsecuredConnection(waitForOpen: true)) - { - var conn = muxer.GetDatabase(5); - if (!Config.GetFeatures(muxer).IncrementFloat) Assert.Inconclusive(); - { - conn.KeyDeleteAsync("hash-test"); - for (int i = 1; i < 1000; i++) - { - Assert.AreEqual((double)i, conn.HashIncrementAsync("hash-test", "a", 1.0).Result); - Assert.AreEqual((double)(-i), conn.HashIncrementAsync("hash-test", "b", -1.0).Result); - } - } - } - } - - - [Test] - public void TestGetAll() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(6); - const string key = "hash test"; - conn.KeyDeleteAsync(key); - var shouldMatch = new Dictionary(); - var random = new Random(); - - for (int i = 1; i < 1000; i++) - { - var guid = Guid.NewGuid(); - var value = random.Next(Int32.MaxValue); - - shouldMatch[guid] = value; - - var x = conn.HashIncrementAsync(key, guid.ToString(), value).Result; // Kill Async - } -#pragma warning disable 618 - var inRedis = conn.HashGetAllAsync(key).Result.ToDictionary( - x => Guid.Parse(x.Name), x => int.Parse(x.Value)); -#pragma warning restore 618 - - Assert.AreEqual(shouldMatch.Count, inRedis.Count); - - foreach (var k in shouldMatch.Keys) - { - Assert.AreEqual(shouldMatch[k], inRedis[k]); - } - } - } - - [Test] - public void TestGet() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var key = "hash test"; - var conn = muxer.GetDatabase(6); - var shouldMatch = new Dictionary(); - var random = new Random(); - - for (int i = 1; i < 1000; i++) - { - var guid = Guid.NewGuid(); - var value = random.Next(Int32.MaxValue); - - shouldMatch[guid] = value; - - var x = conn.HashIncrementAsync(key, guid.ToString(), value).Result; // Kill Async - } - - foreach (var k in shouldMatch.Keys) - { - var inRedis = conn.HashGetAsync(key, k.ToString()).Result; - var num = int.Parse((string)inRedis); - - Assert.AreEqual(shouldMatch[k], num); - } - } - } - - [Test] - public void TestSet() // http://redis.io/commands/hset - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(9); - conn.KeyDeleteAsync("hashkey"); - - var val0 = conn.HashGetAsync("hashkey", "field"); - var set0 = conn.HashSetAsync("hashkey", "field", "value1"); - var val1 = conn.HashGetAsync("hashkey", "field"); - var set1 = conn.HashSetAsync("hashkey", "field", "value2"); - var val2 = conn.HashGetAsync("hashkey", "field"); - - var set2 = conn.HashSetAsync("hashkey", "field-blob", Encoding.UTF8.GetBytes("value3")); - var val3 = conn.HashGetAsync("hashkey", "field-blob"); - - var set3 = conn.HashSetAsync("hashkey", "empty_type1", ""); - var val4 = conn.HashGetAsync("hashkey", "empty_type1"); - var set4 = conn.HashSetAsync("hashkey", "empty_type2", RedisValue.EmptyString); - var val5 = conn.HashGetAsync("hashkey", "empty_type2"); - - Assert.AreEqual(null, (string)val0.Result); - Assert.AreEqual(true, set0.Result); - Assert.AreEqual("value1", (string)val1.Result); - Assert.AreEqual(false, set1.Result); - Assert.AreEqual("value2", (string)val2.Result); - - Assert.AreEqual(true, set2.Result); - Assert.AreEqual("value3", (string)val3.Result); - - Assert.AreEqual(true, set3.Result); - Assert.AreEqual("", (string)val4.Result); - Assert.AreEqual(true, set4.Result); - Assert.AreEqual("", (string)val5.Result); - } - } - [Test] - public void TestSetNotExists() // http://redis.io/commands/hsetnx - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(9); - conn.KeyDeleteAsync("hashkey"); - - var val0 = conn.HashGetAsync("hashkey", "field"); - var set0 = conn.HashSetAsync("hashkey", "field", "value1", When.NotExists); - var val1 = conn.HashGetAsync("hashkey", "field"); - var set1 = conn.HashSetAsync("hashkey", "field", "value2", When.NotExists); - var val2 = conn.HashGetAsync("hashkey", "field"); - - var set2 = conn.HashSetAsync("hashkey", "field-blob", Encoding.UTF8.GetBytes("value3"), When.NotExists); - var val3 = conn.HashGetAsync("hashkey", "field-blob"); - var set3 = conn.HashSetAsync("hashkey", "field-blob", Encoding.UTF8.GetBytes("value3"), When.NotExists); - - Assert.AreEqual(null, (string)val0.Result); - Assert.AreEqual(true, set0.Result); - Assert.AreEqual("value1", (string)val1.Result); - Assert.AreEqual(false, set1.Result); - Assert.AreEqual("value1", (string)val2.Result); - - Assert.AreEqual(true, set2.Result); - Assert.AreEqual("value3", (string)val3.Result); - Assert.AreEqual(false, set3.Result); - - } - } - [Test] - public void TestDelSingle() // http://redis.io/commands/hdel - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(9); - conn.KeyDeleteAsync("hashkey"); - var del0 = conn.HashDeleteAsync("hashkey", "field"); - - conn.HashSetAsync("hashkey", "field", "value"); - - var del1 = conn.HashDeleteAsync("hashkey", "field"); - var del2 = conn.HashDeleteAsync("hashkey", "field"); - - Assert.AreEqual(false, del0.Result); - Assert.AreEqual(true, del1.Result); - Assert.AreEqual(false, del2.Result); - - } - } - [Test] - public void TestDelMulti() // http://redis.io/commands/hdel - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(3); - conn.HashSetAsync("TestDelMulti", "key1", "val1"); - conn.HashSetAsync("TestDelMulti", "key2", "val2"); - conn.HashSetAsync("TestDelMulti", "key3", "val3"); - - var s1 = conn.HashExistsAsync("TestDelMulti", "key1"); - var s2 = conn.HashExistsAsync("TestDelMulti", "key2"); - var s3 = conn.HashExistsAsync("TestDelMulti", "key3"); - - var removed = conn.HashDeleteAsync("TestDelMulti", new RedisValue[] { "key1", "key3" }); - - var d1 = conn.HashExistsAsync("TestDelMulti", "key1"); - var d2 = conn.HashExistsAsync("TestDelMulti", "key2"); - var d3 = conn.HashExistsAsync("TestDelMulti", "key3"); - - Assert.IsTrue(conn.Wait(s1)); - Assert.IsTrue(conn.Wait(s2)); - Assert.IsTrue(conn.Wait(s3)); - - Assert.AreEqual(2, conn.Wait(removed)); - - Assert.IsFalse(conn.Wait(d1)); - Assert.IsTrue(conn.Wait(d2)); - Assert.IsFalse(conn.Wait(d3)); - - var removeFinal = conn.HashDeleteAsync("TestDelMulti", new RedisValue[] { "key2" }); - - Assert.AreEqual(0, conn.Wait(conn.HashLengthAsync("TestDelMulti"))); - Assert.AreEqual(1, conn.Wait(removeFinal)); - } - } - - [Test] - public void TestDelMultiInsideTransaction() // http://redis.io/commands/hdel - { - using (var outer = Config.GetUnsecuredConnection()) - { - - var conn = outer.GetDatabase(3).CreateTransaction(); - { - conn.HashSetAsync("TestDelMulti", "key1", "val1"); - conn.HashSetAsync("TestDelMulti", "key2", "val2"); - conn.HashSetAsync("TestDelMulti", "key3", "val3"); - - var s1 = conn.HashExistsAsync("TestDelMulti", "key1"); - var s2 = conn.HashExistsAsync("TestDelMulti", "key2"); - var s3 = conn.HashExistsAsync("TestDelMulti", "key3"); - - var removed = conn.HashDeleteAsync("TestDelMulti", new RedisValue[] { "key1", "key3" }); - - var d1 = conn.HashExistsAsync("TestDelMulti", "key1"); - var d2 = conn.HashExistsAsync("TestDelMulti", "key2"); - var d3 = conn.HashExistsAsync("TestDelMulti", "key3"); - - conn.Execute(); - - Assert.IsTrue(conn.Wait(s1)); - Assert.IsTrue(conn.Wait(s2)); - Assert.IsTrue(conn.Wait(s3)); - - Assert.AreEqual(2, conn.Wait(removed)); - - Assert.IsFalse(conn.Wait(d1)); - Assert.IsTrue(conn.Wait(d2)); - Assert.IsFalse(conn.Wait(d3)); - } - - } - } - [Test] - public void TestExists() // http://redis.io/commands/hexists - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(9); - conn.KeyDeleteAsync("hashkey"); - var ex0 = conn.HashExistsAsync("hashkey", "field"); - conn.HashSetAsync("hashkey", "field", "value"); - var ex1 = conn.HashExistsAsync("hashkey", "field"); - conn.HashDeleteAsync("hashkey", "field"); - var ex2 = conn.HashExistsAsync("hashkey", "field"); - - Assert.AreEqual(false, ex0.Result); - Assert.AreEqual(true, ex1.Result); - Assert.AreEqual(false, ex0.Result); - - } - } - - [Test] - public void TestHashKeys() // http://redis.io/commands/hkeys - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(9); - conn.KeyDeleteAsync("hashkey"); - - var keys0 = conn.HashKeysAsync("hashkey"); - - conn.HashSetAsync("hashkey", "foo", "abc"); - conn.HashSetAsync("hashkey", "bar", "def"); - - var keys1 = conn.HashKeysAsync("hashkey"); - - Assert.AreEqual(0, keys0.Result.Length); - - var arr = keys1.Result; - Assert.AreEqual(2, arr.Length); - Assert.AreEqual("foo", (string)arr[0]); - Assert.AreEqual("bar", (string)arr[1]); - - } - } - - [Test] - public void TestHashValues() // http://redis.io/commands/hvals - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(9); - conn.KeyDeleteAsync("hashkey"); - - var keys0 = conn.HashValuesAsync("hashkey"); - - conn.HashSetAsync("hashkey", "foo", "abc"); - conn.HashSetAsync("hashkey", "bar", "def"); - - var keys1 = conn.HashValuesAsync("hashkey"); - - Assert.AreEqual(0, keys0.Result.Length); - - var arr = keys1.Result; - Assert.AreEqual(2, arr.Length); - Assert.AreEqual("abc", Encoding.UTF8.GetString(arr[0])); - Assert.AreEqual("def", Encoding.UTF8.GetString(arr[1])); - - } - } - - [Test] - public void TestHashLength() // http://redis.io/commands/hlen - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(9); - conn.KeyDeleteAsync("hashkey"); - - var len0 = conn.HashLengthAsync("hashkey"); - - conn.HashSetAsync("hashkey", "foo", "abc"); - conn.HashSetAsync("hashkey", "bar", "def"); - - var len1 = conn.HashLengthAsync("hashkey"); - - Assert.AreEqual(0, len0.Result); - Assert.AreEqual(2, len1.Result); - - } - } - - [Test] - public void TestGetMulti() // http://redis.io/commands/hmget - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(9); - conn.KeyDeleteAsync("hashkey"); - - RedisValue[] fields = { "foo", "bar", "blop" }; - var result0 = conn.HashGetAsync("hashkey", fields); - - conn.HashSetAsync("hashkey", "foo", "abc"); - conn.HashSetAsync("hashkey", "bar", "def"); - - var result1 = conn.HashGetAsync("hashkey", fields); - - var result2 = conn.HashGetAsync("hashkey", fields); - - var arr0 = result0.Result; - var arr1 = result1.Result; - var arr2 = result2.Result; - - Assert.AreEqual(3, arr0.Length); - Assert.IsNull((string)arr0[0]); - Assert.IsNull((string)arr0[1]); - Assert.IsNull((string)arr0[2]); - - Assert.AreEqual(3, arr1.Length); - Assert.AreEqual("abc", (string)arr1[0]); - Assert.AreEqual("def", (string)arr1[1]); - Assert.IsNull((string)arr1[2]); - - Assert.AreEqual(3, arr2.Length); - Assert.AreEqual("abc", (string)arr2[0]); - Assert.AreEqual("def", (string)arr2[1]); - Assert.IsNull((string)arr2[2]); - } - } - - [Test] - public void TestGetPairs() // http://redis.io/commands/hgetall - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(9); - conn.KeyDeleteAsync("hashkey"); - - var result0 = conn.HashGetAllAsync("hashkey"); - - conn.HashSetAsync("hashkey", "foo", "abc"); - conn.HashSetAsync("hashkey", "bar", "def"); - - var result1 = conn.HashGetAllAsync("hashkey"); - - Assert.AreEqual(0, result0.Result.Length); - var result = result1.Result.ToStringDictionary(); - Assert.AreEqual(2, result.Count); - Assert.AreEqual("abc", result["foo"]); - Assert.AreEqual("def", result["bar"]); - } - } - - [Test] - public void TestSetPairs() // http://redis.io/commands/hmset - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(9); - conn.KeyDeleteAsync("hashkey"); - - var result0 = conn.HashGetAllAsync("hashkey"); - - var data = new HashEntry[] { - new HashEntry("foo", Encoding.UTF8.GetBytes("abc")), - new HashEntry("bar", Encoding.UTF8.GetBytes("def")) - }; - conn.HashSetAsync("hashkey", data); - - var result1 = conn.HashGetAllAsync("hashkey"); - - Assert.AreEqual(0, result0.Result.Length); - var result = result1.Result.ToStringDictionary(); - Assert.AreEqual(2, result.Count); - Assert.AreEqual("abc", result["foo"]); - Assert.AreEqual("def", result["bar"]); - } - } - - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/Issue10.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/Issue10.cs deleted file mode 100644 index 01afcd9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/Issue10.cs +++ /dev/null @@ -1,30 +0,0 @@ -using NUnit.Framework; - -namespace Tests.Issues -{ - [TestFixture] - public class Issue10 - { - [Test] - public void Execute() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - const int DB = 5; - const string Key = "issue-10-list"; - var conn = muxer.GetDatabase(DB); - conn.KeyDeleteAsync(Key); // contents: nil - conn.ListLeftPushAsync(Key, "abc"); // "abc" - conn.ListLeftPushAsync(Key, "def"); // "def", "abc" - conn.ListLeftPushAsync(Key, "ghi"); // "ghi", "def", "abc", - conn.ListSetByIndexAsync(Key, 1, "jkl"); // "ghi", "jkl", "abc" - - var contents = conn.Wait(conn.ListRangeAsync(Key, 0, -1)); - Assert.AreEqual(3, contents.Length); - Assert.AreEqual("ghi", (string)contents[0]); - Assert.AreEqual("jkl", (string)contents[1]); - Assert.AreEqual("abc", (string)contents[2]); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/Massive Delete.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/Massive Delete.cs deleted file mode 100644 index de8f9d6..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/Massive Delete.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Diagnostics; -using System.Threading; -using System.Threading.Tasks; -using NUnit.Framework; - -namespace Tests.Issues -{ - [TestFixture] - public class Massive_Delete - { - [OneTimeSetUpAttribute] - public void Init() - { - using (var muxer = Config.GetUnsecuredConnection(allowAdmin: true)) - { - Config.GetServer(muxer).FlushDatabase(db); - Task last = null; - var conn = muxer.GetDatabase(db); - for (int i = 0; i < 100000; i++) - { - string key = "key" + i; - conn.StringSetAsync(key, key); - last = conn.SetAddAsync(todoKey, key); - } - conn.Wait(last); - } - } - - const int db = 4; - const string todoKey = "todo"; - - [Test] - public void ExecuteMassiveDelete() - { - var watch = Stopwatch.StartNew(); - using (var muxer = Config.GetUnsecuredConnection()) - using (var throttle = new SemaphoreSlim(1)) - { - var conn = muxer.GetDatabase(db); - var originallyTask = conn.SetLengthAsync(todoKey); - int keepChecking = 1; - Task last = null; - while (Volatile.Read(ref keepChecking) == 1) - { - throttle.Wait(); // acquire - conn.SetPopAsync(todoKey).ContinueWith(task => - { - throttle.Release(); - if (task.IsCompleted) - { - if ((string)task.Result == null) - { - Volatile.Write(ref keepChecking, 0); - } - else - { - last = conn.KeyDeleteAsync((string)task.Result); - } - } - }); - } - if (last != null) - { - conn.Wait(last); - } - watch.Stop(); - long originally = conn.Wait(originallyTask), - remaining = conn.SetLength(todoKey); - Console.WriteLine("From {0} to {1}; {2}ms", originally, remaining, - watch.ElapsedMilliseconds); - - var counters = Config.GetServer(muxer).GetCounters(); - Console.WriteLine("Completions: {0} sync, {1} async", counters.Interactive.CompletedSynchronously, counters.Interactive.CompletedAsynchronously); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/SO10504853.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/SO10504853.cs deleted file mode 100644 index 54fa8fc..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/SO10504853.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Diagnostics; -using NUnit.Framework; -using StackExchange.Redis; - -namespace Tests.Issues -{ - [TestFixture] - public class SO10504853 - { - [Test] - public void LoopLotsOfTrivialStuff() - { - Trace.WriteLine("### init"); - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(0); - conn.KeyDelete("lots-trivial"); - } - const int COUNT = 2; - for (int i = 0; i < COUNT; i++) - { - Trace.WriteLine("### incr:" + i); - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(0); - Assert.AreEqual(i + 1, conn.StringIncrement("lots-trivial")); - } - } - Trace.WriteLine("### close"); - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(0); - Assert.AreEqual(COUNT, (long)conn.StringGet("lots-trivial")); - } - } - [Test] - public void ExecuteWithEmptyStartingPoint() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(0); - var task = new { priority = 3 }; - conn.KeyDeleteAsync("item:1"); - conn.HashSetAsync("item:1", "something else", "abc"); - conn.HashSetAsync("item:1", "priority", task.priority.ToString()); - - var taskResult = conn.HashGetAsync("item:1", "priority"); - - conn.Wait(taskResult); - - var priority = Int32.Parse(taskResult.Result); - - Assert.AreEqual(3, priority); - } - } - - [Test] - public void ExecuteWithNonHashStartingPoint() - { - Assert.Throws(() => - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(0); - var task = new { priority = 3 }; - conn.KeyDeleteAsync("item:1"); - conn.StringSetAsync("item:1", "not a hash"); - conn.HashSetAsync("item:1", "priority", task.priority.ToString()); - - var taskResult = conn.HashGetAsync("item:1", "priority"); - - try - { - conn.Wait(taskResult); - Assert.Fail(); - } - catch (AggregateException ex) - { - throw ex.InnerExceptions[0]; - } - } - }, - message: "WRONGTYPE Operation against a key holding the wrong kind of value"); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/SO10825542.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/SO10825542.cs deleted file mode 100644 index 1163665..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/SO10825542.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Text; -using NUnit.Framework; -using StackExchange.Redis; - -namespace Tests.Issues -{ - [TestFixture] - public class SO10825542 - { - [Test] - public void Execute() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var key = "somekey1"; - - var con = muxer.GetDatabase(1); - // set the field value and expiration - con.HashSetAsync(key, "field1", Encoding.UTF8.GetBytes("hello world")); - con.KeyExpireAsync(key, TimeSpan.FromSeconds(7200)); - con.HashSetAsync(key, "field2", "fooobar"); - var task = con.HashGetAllAsync(key); - con.Wait(task); - - Assert.AreEqual(2, task.Result.Length); - var dict = task.Result.ToStringDictionary(); - Assert.AreEqual("hello world", dict["field1"]); - Assert.AreEqual("fooobar", dict["field2"]); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/SO11766033.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/SO11766033.cs deleted file mode 100644 index f3fa1cc..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Issues/SO11766033.cs +++ /dev/null @@ -1,41 +0,0 @@ -using NUnit.Framework; - -namespace Tests.Issues -{ - [TestFixture] - public class SO11766033 - { - [Test] - public void TestNullString() - { - const int db = 3; - using (var muxer = Config.GetUnsecuredConnection(true)) - { - var redis = muxer.GetDatabase(db); - string expectedTestValue = null; - var uid = Config.CreateUniqueName(); - redis.StringSetAsync(uid, "abc"); - redis.StringSetAsync(uid, expectedTestValue); - string testValue = redis.StringGet(uid); - Assert.IsNull(testValue); - } - } - - [Test] - public void TestEmptyString() - { - const int db = 3; - using (var muxer = Config.GetUnsecuredConnection(true)) - { - var redis = muxer.GetDatabase(db); - string expectedTestValue = ""; - var uid = Config.CreateUniqueName(); - - redis.StringSetAsync(uid, expectedTestValue); - string testValue = redis.StringGet(uid); - - Assert.AreEqual(expectedTestValue, testValue); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Keys.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Keys.cs deleted file mode 100644 index aa678b4..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Keys.cs +++ /dev/null @@ -1,511 +0,0 @@ -//using System.Threading; -//using BookSleeve; -//using NUnit.Framework; -//using System.Text.RegularExpressions; -//using System.Linq; -//using System; -//namespace Tests -//{ -// [TestFixture] -// public class Keys // http://redis.io/commands#generic -// { -// // note we don't expose EXPIREAT as it raises all sorts of problems with -// // time synchronisation, UTC vs local, DST, etc; easier for the caller -// // to use EXPIRE - -// [Test] -// public void TestDeleteValidKey() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Strings.Set(0, "del", "abcdef"); -// var x = conn.Strings.GetString(0, "del"); -// var del = conn.Keys.Remove(0, "del"); -// var y = conn.Strings.GetString(0, "del"); -// conn.WaitAll(x, del, y); -// Assert.AreEqual("abcdef", x.Result); -// Assert.IsTrue(del.Result); -// Assert.AreEqual(null, y.Result); -// } -// } - -// [Test] -// public void TestLargeIntegers() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// const long expected = 20L * int.MaxValue; -// conn.Strings.Set(0, "large-int", expected); -// var result = conn.Strings.GetInt64(0, "large-int"); -// Assert.AreEqual(expected, conn.Wait(result)); -// } -// } - -// [Test] -// public void TestDeleteInvalidKey() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Strings.Set(0, "exists", "abcdef"); -// var x = conn.Keys.Remove(0, "exists"); -// var y = conn.Keys.Remove(0, "exists"); -// conn.WaitAll(x, y); -// Assert.IsTrue(x.Result); -// Assert.IsFalse(y.Result); -// } -// } - -// [Test] -// public void TestDeleteMultiple() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Strings.Set(0, "del", "abcdef"); -// var x = conn.Keys.Remove(0, "del"); -// var y = conn.Keys.Remove(0, "del"); -// conn.WaitAll(x, y); -// Assert.IsTrue(x.Result); -// Assert.IsFalse(y.Result); -// } -// } - -// [Test] -// public void Scan() -// { -// using (var conn = Config.GetUnsecuredConnection(allowAdmin: true, waitForOpen: true)) -// { -// if (!conn.Features.Scan) Assert.Inconclusive(); - -// const int DB = 3; -// conn.Wait(conn.Server.FlushDb(DB)); -// conn.Strings.Set(DB, "foo", "foo"); -// conn.Strings.Set(DB, "bar", "bar"); -// conn.Strings.Set(DB, "blap", "blap"); - -// var keys = conn.Keys.Scan(DB).ToArray(); -// Array.Sort(keys); -// Assert.AreEqual(3, keys.Length); -// Assert.AreEqual("bar", keys[0]); -// Assert.AreEqual("blap", keys[1]); -// Assert.AreEqual("foo", keys[2]); - -// keys = conn.Keys.Scan(DB, "b*").ToArray(); -// Array.Sort(keys); -// Assert.AreEqual(2, keys.Length); -// Assert.AreEqual("bar", keys[0]); -// Assert.AreEqual("blap", keys[1]); - - -// } -// } - -// [Test] -// public void TestExpireAgainstInvalidKey() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Strings.Set(0, "delA", "abcdef"); -// conn.Keys.Remove(0, "delB"); -// conn.Strings.Set(0, "delC", "abcdef"); - -// var del = conn.Keys.Remove(0, new[] {"delA", "delB", "delC"}); -// Assert.AreEqual(2, conn.Wait(del)); -// } -// } - -// [Test] -// public void TestExists() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Strings.Set(0, "exists", "abcdef"); -// var x = conn.Keys.Exists(0, "exists"); -// conn.Keys.Remove(0, "exists"); -// var y = conn.Keys.Exists(0, "exists"); -// conn.WaitAll(x, y); -// Assert.IsTrue(x.Result); -// Assert.IsFalse (y.Result); -// } -// } - -// [Test] -// public void TestExpireAgainstValidKey() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Strings.Set(0, "expire", "abcdef"); -// var x = conn.Keys.TimeToLive(0, "expire"); -// var exp1 = conn.Keys.Expire(0, "expire", 100); -// var y = conn.Keys.TimeToLive(0, "expire"); -// var exp2 = conn.Keys.Expire(0, "expire", 150); -// var z = conn.Keys.TimeToLive(0, "expire"); - -// conn.WaitAll(x, exp1, y, exp2, z); - -// Assert.AreEqual(-1, x.Result); -// Assert.IsTrue(exp1.Result); -// Assert.GreaterOrEqual(y.Result, 90); -// Assert.LessOrEqual(y.Result, 100); - -// if (conn.Features.ExpireOverwrite) -// { -// Assert.IsTrue(exp2.Result); -// Assert.GreaterOrEqual(z.Result, 140); -// Assert.LessOrEqual(z.Result, 150); -// } -// else -// { -// Assert.IsFalse(exp2.Result); -// Assert.GreaterOrEqual(z.Result, 90); -// Assert.LessOrEqual(z.Result, 100); -// } -// } -// } - -// [Test] -// public void TestSuccessfulMove() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Strings.Set(1, "move", "move-value"); -// conn.Keys.Remove(2, "move"); - -// var succ = conn.Keys.Move(1, "move", 2); -// var in1 = conn.Strings.GetString(1, "move"); -// var in2 = conn.Strings.GetString(2, "move"); - -// Assert.IsTrue(conn.Wait(succ)); -// Assert.IsNull(conn.Wait(in1)); -// Assert.AreEqual("move-value", conn.Wait(in2)); -// } -// } - -// [Test] -// public void TestFailedMoveWhenNotExistsInSource() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "move"); -// conn.Strings.Set(2, "move", "move-value"); - -// var succ = conn.Keys.Move(1, "move", 2); -// var in1 = conn.Strings.GetString(1, "move"); -// var in2 = conn.Strings.GetString(2, "move"); - -// Assert.IsFalse(conn.Wait(succ)); -// Assert.IsNull(conn.Wait(in1)); -// Assert.AreEqual("move-value", conn.Wait(in2)); -// } -// } - -// [Test] -// public void TestFailedMoveWhenNotExistsInTarget() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Strings.Set(1, "move", "move-valueA"); -// conn.Strings.Set(2, "move", "move-valueB"); - -// var succ = conn.Keys.Move(1, "move", 2); -// var in1 = conn.Strings.GetString(1, "move"); -// var in2 = conn.Strings.GetString(2, "move"); - -// Assert.IsFalse(conn.Wait(succ)); -// Assert.AreEqual("move-valueA", conn.Wait(in1)); -// Assert.AreEqual("move-valueB", conn.Wait(in2)); -// } -// } - -// [Test] -// public void RemoveExpiry() -// { -// int errors = 0, expectedErrors; -// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// conn.Error += delegate -// { -// Interlocked.Increment(ref errors); -// }; -// conn.Keys.Remove(1, "persist"); -// conn.Strings.Set(1, "persist", "persist"); -// var persist1 = conn.Keys.Persist(1, "persist"); -// conn.Keys.Expire(1, "persist", 100); -// var before = conn.Keys.TimeToLive(1, "persist"); -// var persist2 = conn.Keys.Persist(1, "persist"); -// var after = conn.Keys.TimeToLive(1, "persist"); - -// Assert.GreaterOrEqual(conn.Wait(before), 90); -// if (conn.Features.Persist) -// { -// Assert.IsFalse(conn.Wait(persist1)); -// Assert.IsTrue(conn.Wait(persist2)); -// Assert.AreEqual(-1, conn.Wait(after)); -// expectedErrors = 0; -// } -// else -// { -// try{ -// conn.Wait(persist1); -// Assert.Fail(); -// } -// catch (RedisException){} -// try -// { -// conn.Wait(persist2); -// Assert.Fail(); -// } -// catch (RedisException) { } -// Assert.GreaterOrEqual(conn.Wait(after), 90); -// expectedErrors = 2; -// } -// } - -// Assert.AreEqual(expectedErrors, Interlocked.CompareExchange(ref errors,0,0)); -// } - - -// [Test] -// public void RandomKeys() -// { -// using (var conn = Config.GetUnsecuredConnection(allowAdmin: true, waitForOpen: true)) -// { -// conn.Server.FlushDb(6); -// var key1 = conn.Keys.Random(6); -// conn.Strings.Set(6, "random1", "random1"); -// var key2 = conn.Keys.Random(6); -// for (int i = 2; i < 100; i++) -// { -// string key = "random" + i; -// conn.Strings.Set(6, key, key); -// } -// var key3 = conn.Keys.Random(6); - -// Assert.IsNull(conn.Wait(key1)); -// Assert.AreEqual("random1", conn.Wait(key2)); -// string s = conn.Wait(key3); - -// Assert.IsTrue(s.StartsWith("random")); -// s = s.Substring(6); -// int result = int.Parse(s); -// Assert.GreaterOrEqual(result, 1); -// Assert.Less(result, 100); -// } - -// } - -// [Test] -// public void Sort() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "sort"); -// conn.Lists.AddLast(1, "sort", "10"); -// conn.Lists.AddLast(1, "sort", "3"); -// conn.Lists.AddLast(1, "sort", "1.1"); -// conn.Lists.AddLast(1, "sort", "2"); -// var a = conn.Keys.SortString(1, "sort"); -// var b = conn.Keys.SortString(1, "sort", ascending: false, offset: 1, count: 2); -// var c = conn.Keys.SortString(1, "sort", alpha: true); -// var d = conn.Keys.SortAndStore(1, "sort-store", "sort"); -// var e = conn.Lists.RangeString(1, "sort-store", 0, -1); -// var f = conn.Lists.RangeString(1, "sort", 0, -1); - -// Assert.AreEqual("1.1;2;3;10",string.Join(";", conn.Wait(a))); -// Assert.AreEqual("3;2",string.Join(";", conn.Wait(b))); -// Assert.AreEqual("10;1.1;2;3", string.Join(";", conn.Wait(c))); -// Assert.AreEqual(4, conn.Wait(d)); -// Assert.AreEqual("1.1;2;3;10", string.Join(";", conn.Wait(e))); -// Assert.AreEqual("10;3;1.1;2", string.Join(";", conn.Wait(f))); - -// } - -// } - -// [Test] -// public void ItemType() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(4, new[]{"type-none", "type-list", "type-string", -// "type-set", "type-zset", "type-hash"}); -// conn.Strings.Set(4, "type-string", "blah"); -// conn.Lists.AddLast(4, "type-list", "blah"); -// conn.Sets.Add(4, "type-set", "blah"); -// conn.SortedSets.Add(4, "type-zset", "blah", 123); -// conn.Hashes.Set(4, "type-hash", "foo", "blah"); - -// var x0 = conn.Keys.Type(4, "type-none"); -// var x1 = conn.Keys.Type(4, "type-list"); -// var x2 = conn.Keys.Type(4, "type-string"); -// var x3 = conn.Keys.Type(4, "type-set"); -// var x4 = conn.Keys.Type(4, "type-zset"); -// var x5 = conn.Keys.Type(4, "type-hash"); - -// Assert.AreEqual(RedisConnection.ItemTypes.None, conn.Wait(x0)); -// Assert.AreEqual(RedisConnection.ItemTypes.List, conn.Wait(x1)); -// Assert.AreEqual(RedisConnection.ItemTypes.String, conn.Wait(x2)); -// Assert.AreEqual(RedisConnection.ItemTypes.Set, conn.Wait(x3)); -// Assert.AreEqual(RedisConnection.ItemTypes.SortedSet, conn.Wait(x4)); -// Assert.AreEqual(RedisConnection.ItemTypes.Hash, conn.Wait(x5)); -// } -// } -// [Test] -// public void RenameKeyWithOverwrite() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "foo"); -// conn.Keys.Remove(1, "bar"); - -// var check1 = conn.Keys.Rename(1, "foo", "bar"); // neither -// var after1_foo = conn.Strings.GetString(1, "foo"); -// var after1_bar = conn.Strings.GetString(1, "bar"); - -// conn.Strings.Set(1, "foo", "foo-value"); - -// var check2 = conn.Keys.Rename(1, "foo", "bar"); // source only -// var after2_foo = conn.Strings.GetString(1, "foo"); -// var after2_bar = conn.Strings.GetString(1, "bar"); - -// var check3 = conn.Keys.Rename(1, "foo", "bar"); // dest only -// var after3_foo = conn.Strings.GetString(1, "foo"); -// var after3_bar = conn.Strings.GetString(1, "bar"); - -// conn.Strings.Set(1, "foo", "new-value"); -// var check4 = conn.Keys.Rename(1, "foo", "bar"); // both -// var after4_foo = conn.Strings.GetString(1, "foo"); -// var after4_bar = conn.Strings.GetString(1, "bar"); - -// try -// { -// conn.Wait(check1); -// Assert.Fail(); -// } -// catch (RedisException) { } -// Assert.IsNull(conn.Wait(after1_foo)); -// Assert.IsNull(conn.Wait(after1_bar)); - -// conn.Wait(check2); -// Assert.IsNull(conn.Wait(after2_foo)); -// Assert.AreEqual("foo-value", conn.Wait(after2_bar)); - -// try -// { -// conn.Wait(check3); -// Assert.Fail(); -// } -// catch (RedisException) { } -// Assert.IsNull(conn.Wait(after3_foo)); -// Assert.AreEqual("foo-value", conn.Wait(after3_bar)); - -// conn.Wait(check4); -// Assert.IsNull(conn.Wait(after4_foo)); -// Assert.AreEqual("new-value", conn.Wait(after4_bar)); - -// } -// } - -// [Test] -// public void RenameKeyWithoutOverwrite() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "foo"); -// conn.Keys.Remove(1, "bar"); - -// var check1 = conn.Keys.RenameIfNotExists(1, "foo", "bar"); // neither -// var after1_foo = conn.Strings.GetString(1, "foo"); -// var after1_bar = conn.Strings.GetString(1, "bar"); - -// conn.Strings.Set(1, "foo", "foo-value"); - -// var check2 = conn.Keys.RenameIfNotExists(1, "foo", "bar"); // source only -// var after2_foo = conn.Strings.GetString(1, "foo"); -// var after2_bar = conn.Strings.GetString(1, "bar"); - -// var check3 = conn.Keys.RenameIfNotExists(1, "foo", "bar"); // dest only -// var after3_foo = conn.Strings.GetString(1, "foo"); -// var after3_bar = conn.Strings.GetString(1, "bar"); - -// conn.Strings.Set(1, "foo", "new-value"); -// var check4 = conn.Keys.RenameIfNotExists(1, "foo", "bar"); // both -// var after4_foo = conn.Strings.GetString(1, "foo"); -// var after4_bar = conn.Strings.GetString(1, "bar"); - -// try -// { -// conn.Wait(check1); -// Assert.Fail(); -// } -// catch (RedisException) { } -// Assert.IsNull(conn.Wait(after1_foo)); -// Assert.IsNull(conn.Wait(after1_bar)); - -// Assert.IsTrue(conn.Wait(check2)); -// Assert.IsNull(conn.Wait(after2_foo)); -// Assert.AreEqual("foo-value", conn.Wait(after2_bar)); - -// try -// { -// conn.Wait(check3); -// Assert.Fail(); -// } -// catch (RedisException) { } -// Assert.IsNull(conn.Wait(after3_foo)); -// Assert.AreEqual("foo-value", conn.Wait(after3_bar)); - -// Assert.IsFalse(conn.Wait(check4)); -// Assert.AreEqual("new-value", conn.Wait(after4_foo)); -// Assert.AreEqual("foo-value", conn.Wait(after4_bar)); - -// } -// } - -// [Test] -// public void TestFind() -// { -// using(var conn = Config.GetUnsecuredConnection(allowAdmin:true)) -// { -// conn.Server.FlushDb(5); -// conn.Strings.Set(5, "abc", "def"); -// conn.Strings.Set(5, "abd", "ghi"); -// conn.Strings.Set(5, "aef", "jkl"); -// var arr = conn.Wait(conn.Keys.Find(5, "ab*")); -// Assert.AreEqual(2, arr.Length); -// Assert.Contains("abc", arr); -// Assert.Contains("abd", arr); -// } -// } - -// [Test] -// public void TestDBSize() -// { -// using(var conn = Config.GetUnsecuredConnection(allowAdmin:true)) -// { -// conn.Server.FlushDb(5); -// var empty = conn.Keys.GetLength(5); -// for (int i = 0; i < 10; i++ ) -// conn.Strings.Set(5, "abc" + i, "def" + i); -// var withData = conn.Keys.GetLength(5); - -// Assert.AreEqual(0, conn.Wait(empty)); -// Assert.AreEqual(10, conn.Wait(withData)); -// } -// } - -// [Test] -// public void TestDebugObject() -// { -// using (var conn = Config.GetUnsecuredConnection(allowAdmin: true)) -// { -// conn.Strings.Set(3, "test-debug", "some value"); -// var s = conn.Wait(conn.Keys.DebugObject(3, "test-debug")); -// Assert.IsTrue(Regex.IsMatch(s, @"\bserializedlength:([0-9]+)\b")); -// } -// } -// } -//} - - - - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Lists.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Lists.cs deleted file mode 100644 index 8e1de87..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Lists.cs +++ /dev/null @@ -1,713 +0,0 @@ -//using System.Text; -//using NUnit.Framework; -//using System.Linq; -//using System; -//using System.Threading; -//namespace Tests -//{ -// [TestFixture] -// public class Lists // http://redis.io/commands#list -// { -// [Test] -// public void CheckLengthWhenEmpty() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(4, "mylist"); -// var len = conn.Lists.GetLength(4, "mylist"); - -// Assert.AreEqual(0, conn.Wait(len)); -// } -// } - -// [Test] -// public void CheckLengthWithContents() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(4, "mylist"); -// for (int i = 0; i < 100; i++) -// conn.Lists.AddLast(4, "mylist", new[] { (byte)i }); -// var len = conn.Lists.GetLength(4, "mylist"); - -// Assert.AreEqual(100, conn.Wait(len)); -// } -// } - -// static byte[] Encode(string value) { return Encoding.UTF8.GetBytes(value); } -// static string Decode(byte[] value) { return Encoding.UTF8.GetString(value); } -// [Test] -// public void CheckRightPush() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// conn.Keys.Remove(4, "mylist"); -// var lenNil = conn.Features.PushIfNotExists ? conn.Lists.AddLast(4, "mylist", Encode("value1"), createIfMissing: false) : null; -// var len1 = conn.Lists.AddLast(4, "mylist", Encode("value1")); -// var len2 = conn.Lists.AddLast(4, "mylist", Encode("value2")); -// var items = conn.Lists.Range(4, "mylist", 0, -1); - -// if (lenNil != null) Assert.AreEqual(0, conn.Wait(lenNil)); -// Assert.AreEqual(1, conn.Wait(len1)); -// Assert.AreEqual(2, conn.Wait(len2)); -// var arr = conn.Wait(items); -// Assert.AreEqual(2, arr.Length); -// Assert.AreEqual("value1", Decode(arr[0])); -// Assert.AreEqual("value2", Decode(arr[1])); -// } -// } -// [Test] -// public void CheckLeftPush() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// conn.Keys.Remove(4, "mylist"); -// var lenNil = conn.Features.PushIfNotExists ? conn.Lists.AddLast(4, "mylist", Encode("value1"), createIfMissing: false) : null; -// var len1 = conn.Lists.AddFirst(4, "mylist", Encode("value1")); -// var len2 = conn.Lists.AddFirst(4, "mylist", Encode("value2")); -// var items = conn.Lists.Range(4, "mylist", 0, -1); - -// if(lenNil != null) Assert.AreEqual(0, conn.Wait(lenNil)); -// Assert.AreEqual(1, conn.Wait(len1)); -// Assert.AreEqual(2, conn.Wait(len2)); -// var arr = conn.Wait(items); -// Assert.AreEqual(2, arr.Length); -// Assert.AreEqual("value2", Decode(arr[0])); -// Assert.AreEqual("value1", Decode(arr[1])); -// } -// } -// [Test] -// public void CheckLeftPop() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(4, "mylist"); -// conn.Lists.AddLast(4, "mylist", Encode("value1")); -// conn.Lists.AddLast(4, "mylist", Encode("value2")); - -// var first = conn.Lists.RemoveFirst(4, "mylist"); -// var second = conn.Lists.RemoveFirstString(4, "mylist"); -// var third = conn.Lists.RemoveFirst(4, "mylist"); -// var len = conn.Lists.GetLength(4, "mylist"); - -// Assert.AreEqual("value1", Decode(conn.Wait(first))); -// Assert.AreEqual("value2", conn.Wait(second)); -// Assert.IsNull(conn.Wait(third)); -// Assert.AreEqual(0, conn.Wait(len)); -// } -// } -// [Test] -// public void CheckRightPop() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(4, "mylist"); -// conn.Lists.AddLast(4, "mylist", Encode("value1")); -// conn.Lists.AddLast(4, "mylist", Encode("value2")); - -// var first = conn.Lists.RemoveLast(4, "mylist"); -// var second = conn.Lists.RemoveLastString(4, "mylist"); -// var third = conn.Lists.RemoveLast(4, "mylist"); -// var len = conn.Lists.GetLength(4, "mylist"); - -// Assert.AreEqual("value2", Decode(conn.Wait(first))); -// Assert.AreEqual("value1", conn.Wait(second)); -// Assert.IsNull(conn.Wait(third)); -// Assert.AreEqual(0, conn.Wait(len)); -// } -// } - - -// [Test] -// public void CheckPushPop() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(4, "source"); -// conn.Keys.Remove(4, "dest"); - -// var empty0 = conn.Lists.RemoveLastAndAddFirst(4, "source", "dest"); -// var empty1 = conn.Lists.RemoveLastAndAddFirstString(4, "source", "dest"); -// conn.Lists.AddLast(4, "source", "abc"); -// conn.Lists.AddLast(4, "source", "def"); - -// var s = conn.Lists.RemoveLastAndAddFirstString(4, "source", "dest"); -// var b = conn.Lists.RemoveLastAndAddFirst(4, "source", "dest"); -// var l0 = conn.Lists.GetLength(4, "source"); -// var l1 = conn.Lists.GetLength(4, "dest"); -// var final = conn.Lists.RangeString(4, "dest", 0, 3); - -// Assert.IsNull(conn.Wait(empty0)); -// Assert.IsNull(conn.Wait(empty1)); -// Assert.AreEqual("def", conn.Wait(s)); -// Assert.AreEqual("abc", Decode(conn.Wait(b))); -// Assert.AreEqual(0, conn.Wait(l0)); -// Assert.AreEqual(2, conn.Wait(l1)); - -// var arr = conn.Wait(final); -// Assert.AreEqual(2, arr.Length); -// Assert.AreEqual("abc", arr[0]); -// Assert.AreEqual("def", arr[1]); - - -// } -// } - - - -// [Test] -// public void GetStringFromList() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(4, "mylist"); -// var missing = conn.Lists.GetString(4, "mylist", 0); - -// conn.Lists.AddLast(4, "mylist", "abc"); -// conn.Lists.AddLast(4, "mylist", "def"); -// conn.Lists.AddLast(4, "mylist", "ghi"); - -// var x0 = conn.Lists.GetString(4, "mylist", 0); -// var x1 = conn.Lists.GetString(4, "mylist", 1); -// var x2 = conn.Lists.GetString(4, "mylist", 2); -// var x3 = conn.Lists.GetString(4, "mylist", 3); - -// var m1 = conn.Lists.GetString(4, "mylist", -1); -// var m2 = conn.Lists.GetString(4, "mylist", -2); -// var m3 = conn.Lists.GetString(4, "mylist", -3); -// var m4 = conn.Lists.GetString(4, "mylist", -4); - -// Assert.IsNull(conn.Wait(missing)); - -// Assert.AreEqual("abc", conn.Wait(x0)); -// Assert.AreEqual("def", conn.Wait(x1)); -// Assert.AreEqual("ghi", conn.Wait(x2)); -// Assert.IsNull(conn.Wait(x3)); - -// Assert.AreEqual("ghi", conn.Wait(m1)); -// Assert.AreEqual("def", conn.Wait(m2)); -// Assert.AreEqual("abc", conn.Wait(m3)); -// Assert.IsNull(conn.Wait(m4)); - -// } -// } - -// [Test] -// public void GetBytesFromList() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(4, "mylist"); -// var missing = conn.Lists.GetString(4, "mylist", 0); - -// conn.Lists.AddLast(4, "mylist", Encode("abc")); -// conn.Lists.AddLast(4, "mylist", Encode("def")); -// conn.Lists.AddLast(4, "mylist", Encode("ghi")); - -// var x0 = conn.Lists.Get(4, "mylist", 0); -// var x1 = conn.Lists.Get(4, "mylist", 1); -// var x2 = conn.Lists.Get(4, "mylist", 2); -// var x3 = conn.Lists.Get(4, "mylist", 3); - -// var m1 = conn.Lists.Get(4, "mylist", -1); -// var m2 = conn.Lists.Get(4, "mylist", -2); -// var m3 = conn.Lists.Get(4, "mylist", -3); -// var m4 = conn.Lists.Get(4, "mylist", -4); - -// Assert.IsNull(conn.Wait(missing)); - -// Assert.AreEqual("abc", Decode(conn.Wait(x0))); -// Assert.AreEqual("def", Decode(conn.Wait(x1))); -// Assert.AreEqual("ghi", Decode(conn.Wait(x2))); -// Assert.IsNull(conn.Wait(x3)); - -// Assert.AreEqual("ghi", Decode(conn.Wait(m1))); -// Assert.AreEqual("def", Decode(conn.Wait(m2))); -// Assert.AreEqual("abc", Decode(conn.Wait(m3))); -// Assert.IsNull(conn.Wait(m4)); - -// } -// } - -// [Test] -// public void TestListInsertString() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen:true)) -// { -// if (conn.Features.ListInsert) -// { -// conn.Keys.Remove(2, "ins"); -// conn.Lists.AddFirst(2, "ins", "x"); -// var missingB = conn.Lists.InsertBefore(2, "ins", "abc", "AAA"); -// var missingA = conn.Lists.InsertAfter(2, "ins", "abc", "BBB"); - -// conn.Lists.AddFirst(2, "ins", "abc"); -// conn.Lists.AddFirst(2, "ins", "y"); -// var existB = conn.Lists.InsertBefore(2, "ins", "abc", "CCC"); -// var existA = conn.Lists.InsertAfter(2, "ins", "abc", "DDD"); -// var all = conn.Lists.RangeString(2, "ins", 0, -1); -// Assert.AreEqual(-1, conn.Wait(missingB)); -// Assert.AreEqual(-1, conn.Wait(missingA)); - -// Assert.AreEqual(4, conn.Wait(existB)); -// Assert.AreEqual(5, conn.Wait(existA)); - -// string seq = string.Join(" ", conn.Wait(all)); -// Assert.AreEqual("y CCC abc DDD x", seq); -// } -// } -// } -// [Test] -// public void TestListInsertBlob() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen:true)) -// { -// if (conn.Features.ListInsert) -// { -// conn.Keys.Remove(2, "ins"); -// conn.Lists.AddFirst(2, "ins", Encode("x")); -// var missingB = conn.Lists.InsertBefore(2, "ins", Encode("abc"), Encode("AAA")); -// var missingA = conn.Lists.InsertAfter(2, "ins", Encode("abc"), Encode("BBB")); - -// conn.Lists.AddFirst(2, "ins", Encode("abc")); -// conn.Lists.AddFirst(2, "ins", Encode("y")); -// var existB = conn.Lists.InsertBefore(2, "ins", Encode("abc"), Encode("CCC")); -// var existA = conn.Lists.InsertAfter(2, "ins", Encode("abc"), Encode("DDD")); -// var all = conn.Lists.Range(2, "ins", 0, -1); -// Assert.AreEqual(-1, conn.Wait(missingB)); -// Assert.AreEqual(-1, conn.Wait(missingA)); - -// Assert.AreEqual(4, conn.Wait(existB)); -// Assert.AreEqual(5, conn.Wait(existA)); -// string seq = string.Join(" ", conn.Wait(all).Select(Decode)); -// Assert.AreEqual("y CCC abc DDD x", seq); -// } -// } -// } -// [Test] -// public void TestListByIndexString() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(2, "byindex"); -// var notExists = conn.Lists.GetString(2, "byindex", 1); -// conn.Lists.AddLast(2, "byindex", "a"); -// conn.Lists.AddLast(2, "byindex", "b"); -// conn.Lists.AddLast(2, "byindex", "c"); - -// var item = conn.Lists.GetString(2, "byindex", 1); -// var outOfRange = conn.Lists.GetString(3, "byindex", 1); -// Assert.IsNull(conn.Wait(notExists)); -// Assert.AreEqual("b", conn.Wait(item)); -// Assert.IsNull(conn.Wait(outOfRange)); -// } -// } -// [Test] -// public void TestListByIndexBlob() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(2, "byindex"); -// var notExists = conn.Lists.Get(2, "byindex", 1); -// conn.Lists.AddLast(2, "byindex", Encode("a")); -// conn.Lists.AddLast(2, "byindex", Encode("b")); -// conn.Lists.AddLast(2, "byindex", Encode("c")); - -// var item = conn.Lists.Get(2, "byindex", 1); -// var outOfRange = conn.Lists.Get(3, "byindex", 1); -// Assert.IsNull(conn.Wait(notExists)); -// Assert.AreEqual("b", Decode(conn.Wait(item))); -// Assert.IsNull(conn.Wait(outOfRange)); -// } -// } -// [Test] -// public void TestTrim() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(2, "trim"); - -// conn.Lists.Trim(2, "trim", 1); -// var ne = conn.Lists.GetLength(2, "trim"); - -// conn.Lists.AddLast(2, "trim", Encode("a")); -// conn.Lists.AddLast(2, "trim", Encode("b")); -// conn.Lists.AddLast(2, "trim", Encode("c")); - - -// conn.Lists.Trim(2, "trim", 1); -// var e = conn.Lists.GetLength(2, "trim"); - -// Assert.AreEqual(0, conn.Wait(ne)); -// Assert.AreEqual(1, conn.Wait(e)); -// } -// } -// [Test] -// public void TestSetByIndexString() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(2, "setbyindex"); - -// conn.Lists.AddLast(2, "setbyindex", "a"); -// conn.Lists.AddLast(2, "setbyindex", "b"); -// conn.Lists.AddLast(2, "setbyindex", "c"); - -// conn.Lists.Set(2, "setbyindex", 1, "d"); -// var item = conn.Lists.GetString(2, "setbyindex", 1); - -// Assert.AreEqual("d", conn.Wait(item)); -// } -// } -// [Test] -// public void TestSetByIndexBlob() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(2, "setbyindex"); - -// conn.Lists.AddLast(2, "setbyindex", Encode("a")); -// conn.Lists.AddLast(2, "setbyindex", Encode("b")); -// conn.Lists.AddLast(2, "setbyindex", Encode("c")); - -// conn.Lists.Set(2, "setbyindex", 1, Encode("d")); -// var item = conn.Lists.Get(2, "setbyindex", 1); - -// Assert.AreEqual("d", Decode(conn.Wait(item))); -// } -// } -// [Test] -// public void TestRemoveString() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(2, "remove"); -// var ne = conn.Lists.Remove(2, "remove", "b"); - -// conn.Lists.AddLast(2, "remove", "b"); -// conn.Lists.AddLast(2, "remove", "a"); -// conn.Lists.AddLast(2, "remove", "b"); -// conn.Lists.AddLast(2, "remove", "c"); -// conn.Lists.AddLast(2, "remove", "b"); - -// var e = conn.Lists.Remove(2, "remove", "b", count: 2); -// var count = conn.Lists.GetLength(2, "remove"); -// Assert.AreEqual(0, conn.Wait(ne)); -// Assert.AreEqual(2, conn.Wait(e)); -// Assert.AreEqual(3, conn.Wait(count)); -// } -// } -// [Test] -// public void TestRemoveBlob() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(2, "remove"); -// var ne = conn.Lists.Remove(2, "remove", Encode("b")); - -// conn.Lists.AddLast(2, "remove", Encode("b")); -// conn.Lists.AddLast(2, "remove", Encode("a")); -// conn.Lists.AddLast(2, "remove", Encode("b")); -// conn.Lists.AddLast(2, "remove", Encode("c")); -// conn.Lists.AddLast(2, "remove", Encode("b")); - -// var e = conn.Lists.Remove(2, "remove", Encode("b"), count: 2); -// var count = conn.Lists.GetLength(2, "remove"); -// Assert.AreEqual(0, conn.Wait(ne)); -// Assert.AreEqual(2, conn.Wait(e)); -// Assert.AreEqual(3, conn.Wait(count)); -// } -// } - -// [Test, ExpectedException(typeof(ArgumentOutOfRangeException))] -// public void TestTrimNeg() -// { -// using(var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "trim"); -// conn.Lists.AddLast(1, "trim", "x"); -// conn.Lists.AddLast(1, "trim", "x"); -// conn.Lists.Trim(1, "trim", -1); -// } -// } -// [Test] -// public void TestTrimZero() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "trim"); -// conn.Lists.AddLast(1, "trim", "x"); -// conn.Lists.AddLast(1, "trim", "x"); -// conn.Lists.Trim(1, "trim", 0); -// Assert.IsFalse(conn.Wait(conn.Keys.Exists(1, "trim"))); -// Assert.AreEqual(0, conn.Wait(conn.Lists.GetLength(1, "trim"))); -// } -// } -// [Test] -// public void TestTrimOne() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "trim"); -// conn.Lists.AddLast(1, "trim", "x"); -// conn.Lists.AddLast(1, "trim", "x"); -// conn.Lists.Trim(1, "trim", 1); -// Assert.IsTrue(conn.Wait(conn.Keys.Exists(1, "trim"))); -// Assert.AreEqual(1, conn.Wait(conn.Lists.GetLength(1, "trim"))); -// } -// } - -// [Test, ExpectedException(typeof(TimeoutException), ExpectedMessage = "The operation has timed out; possibly blocked by: 1: BLPOP \"blocking\" 5")] -// public void TestBlockingTimeout() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "blocking"); -// conn.Lists.BlockingRemoveFirst(1, new[]{"blocking"}, 5); -// var next = conn.Strings.Get(1, "foofoo"); -// conn.Wait(next); -// } -// } - -// [Test] -// public void TestLeftBlockingPop() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// using (var conn2 = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "blocking"); -// conn.Keys.Remove(1, "blocking-A"); -// conn.Keys.Remove(1, "blocking-B"); -// // empty, no data -// Assert.IsNull(conn.Lists.BlockingRemoveFirstString(1, new[] { "blocking" }, 1).Result); - -// // empty, successful blocking getting data from another client -// var found = conn.Lists.BlockingRemoveFirstString(1, new[] { "blocking" }, 1); -// var len = conn2.Lists.AddLast(1, "blocking", "another client"); -// Assert.AreEqual("blocking", conn.Wait(found).Item1); -// Assert.AreEqual("another client", conn.Wait(found).Item2); -// Assert.AreEqual(1, conn2.Wait(len)); - -// // empty, successful blocking getting data from another client, multiple keys -// found = conn.Lists.BlockingRemoveFirstString(1, new[] { "blocking-A", "blocking", "blocking-B" }, 1); -// len = conn2.Lists.AddLast(1, "blocking", "another client"); -// Assert.AreEqual("blocking", conn.Wait(found).Item1); -// Assert.AreEqual("another client", conn.Wait(found).Item2); -// Assert.AreEqual(1, conn2.Wait(len)); - -// // data, no need to block -// conn.Lists.AddLast(1, "blocking", "abc"); -// len = conn.Lists.AddLast(1, "blocking", "def"); -// var found0 = conn.Lists.BlockingRemoveFirstString(1, new[] { "blocking" }, 1); -// var found1 = conn.Lists.BlockingRemoveFirstString(1, new[] { "blocking" }, 1); -// var found2 = conn.Lists.BlockingRemoveFirstString(1, new[] { "blocking" }, 1); -// Assert.AreEqual(2, conn.Wait(len)); -// Assert.AreEqual("blocking", conn.Wait(found0).Item1); -// Assert.AreEqual("abc", conn.Wait(found0).Item2); -// Assert.AreEqual("blocking", conn.Wait(found1).Item1); -// Assert.AreEqual("def", conn.Wait(found1).Item2); -// Assert.IsNull(found2.Result); -// } -// } - -// [Test] -// public void TestRightBlockingPop() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// using (var conn2 = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "blocking"); -// conn.Keys.Remove(1, "blocking-A"); -// conn.Keys.Remove(1, "blocking-B"); -// // empty, no data -// Assert.IsNull(conn.Lists.BlockingRemoveLastString(1, new[] { "blocking" }, 1).Result); - -// // empty, successful blocking getting data from another client -// var found = conn.Lists.BlockingRemoveLastString(1, new[] { "blocking" }, 1); -// var len = conn2.Lists.AddLast(1, "blocking", "another client"); -// Assert.AreEqual("blocking", conn.Wait(found).Item1); -// Assert.AreEqual("another client", conn.Wait(found).Item2); -// Assert.AreEqual(1, conn2.Wait(len)); - -// // empty, successful blocking getting data from another client, multiple keys -// found = conn.Lists.BlockingRemoveLastString(1, new[] { "blocking-A", "blocking", "blocking-B" }, 1); -// len = conn2.Lists.AddLast(1, "blocking", "another client"); -// Assert.AreEqual("blocking", conn.Wait(found).Item1); -// Assert.AreEqual("another client", conn.Wait(found).Item2); -// Assert.AreEqual(1, conn2.Wait(len)); - -// // data, no need to block -// conn.Lists.AddLast(1, "blocking", "abc"); -// len = conn.Lists.AddLast(1, "blocking", "def"); -// var found0 = conn.Lists.BlockingRemoveLastString(1, new[] { "blocking" }, 1); -// var found1 = conn.Lists.BlockingRemoveLastString(1, new[] { "blocking" }, 1); -// var found2 = conn.Lists.BlockingRemoveLastString(1, new[] { "blocking" }, 1); -// Assert.AreEqual(2, conn.Wait(len)); -// Assert.AreEqual("blocking", conn.Wait(found0).Item1); -// Assert.AreEqual("def", conn.Wait(found0).Item2); -// Assert.AreEqual("blocking", conn.Wait(found1).Item1); -// Assert.AreEqual("abc", conn.Wait(found1).Item2); -// Assert.IsNull(found2.Result); -// } -// } - -// [Test] -// public void TestLeftBlockingPopBytes() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// using (var conn2 = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "blocking"); -// conn.Keys.Remove(1, "blocking-A"); -// conn.Keys.Remove(1, "blocking-B"); -// // empty, no data -// Assert.IsNull(conn.Lists.BlockingRemoveFirst(1, new[] { "blocking" }, 1).Result); - -// // empty, successful blocking getting data from another client -// var found = conn.Lists.BlockingRemoveFirst(1, new[] { "blocking" }, 1); -// var len = conn2.Lists.AddLast(1, "blocking", "another client"); -// Assert.AreEqual("blocking", conn.Wait(found).Item1); -// Assert.AreEqual("another client", Encoding.UTF8.GetString(conn.Wait(found).Item2)); -// Assert.AreEqual(1, conn2.Wait(len)); - -// // empty, successful blocking getting data from another client, multiple keys -// found = conn.Lists.BlockingRemoveFirst(1, new[] { "blocking-A", "blocking", "blocking-B" }, 1); -// len = conn2.Lists.AddLast(1, "blocking", "another client"); -// Assert.AreEqual("blocking", conn.Wait(found).Item1); -// Assert.AreEqual("another client", Encoding.UTF8.GetString(conn.Wait(found).Item2)); -// Assert.AreEqual(1, conn2.Wait(len)); - -// // data, no need to block -// conn.Lists.AddLast(1, "blocking", "abc"); -// len = conn.Lists.AddLast(1, "blocking", "def"); -// var found0 = conn.Lists.BlockingRemoveFirst(1, new[] { "blocking" }, 1); -// var found1 = conn.Lists.BlockingRemoveFirst(1, new[] { "blocking" }, 1); -// var found2 = conn.Lists.BlockingRemoveFirst(1, new[] { "blocking" }, 1); -// Assert.AreEqual(2, conn.Wait(len)); -// Assert.AreEqual("blocking", conn.Wait(found0).Item1); -// Assert.AreEqual("abc", Encoding.UTF8.GetString(conn.Wait(found0).Item2)); -// Assert.AreEqual("blocking", conn.Wait(found1).Item1); -// Assert.AreEqual("def", Encoding.UTF8.GetString(conn.Wait(found1).Item2)); -// Assert.IsNull(found2.Result); -// } -// } - -// [Test] -// public void TestRightBlockingPopBytes() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// using (var conn2 = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "blocking"); -// conn.Keys.Remove(1, "blocking-A"); -// conn.Keys.Remove(1, "blocking-B"); -// // empty, no data -// Assert.IsNull(conn.Lists.BlockingRemoveLast(1, new[] { "blocking" }, 1).Result); - -// // empty, successful blocking getting data from another client -// var found = conn.Lists.BlockingRemoveLast(1, new[] { "blocking" }, 1); -// var len = conn2.Lists.AddLast(1, "blocking", "another client"); -// Assert.AreEqual("blocking", conn.Wait(found).Item1); -// Assert.AreEqual("another client", Encoding.UTF8.GetString(conn.Wait(found).Item2)); -// Assert.AreEqual(1, conn2.Wait(len)); - -// // empty, successful blocking getting data from another client, multiple keys -// found = conn.Lists.BlockingRemoveLast(1, new[] { "blocking-A", "blocking", "blocking-B" }, 1); -// len = conn2.Lists.AddLast(1, "blocking", "another client"); -// Assert.AreEqual("blocking", conn.Wait(found).Item1); -// Assert.AreEqual("another client", Encoding.UTF8.GetString(conn.Wait(found).Item2)); -// Assert.AreEqual(1, conn2.Wait(len)); - -// // data, no need to block -// conn.Lists.AddLast(1, "blocking", "abc"); -// len = conn.Lists.AddLast(1, "blocking", "def"); -// var found0 = conn.Lists.BlockingRemoveLast(1, new[] { "blocking" }, 1); -// var found1 = conn.Lists.BlockingRemoveLast(1, new[] { "blocking" }, 1); -// var found2 = conn.Lists.BlockingRemoveLast(1, new[] { "blocking" }, 1); -// Assert.AreEqual(2, conn.Wait(len)); -// Assert.AreEqual("blocking", conn.Wait(found0).Item1); -// Assert.AreEqual("def", Encoding.UTF8.GetString(conn.Wait(found0).Item2)); -// Assert.AreEqual("blocking", conn.Wait(found1).Item1); -// Assert.AreEqual("abc", Encoding.UTF8.GetString(conn.Wait(found1).Item2)); -// Assert.IsNull(found2.Result); -// } -// } - -// [Test] -// public void TestBlockingPopPush() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// using (var conn2 = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "source"); -// conn.Keys.Remove(1, "target"); - -// // empty -// var found = conn.Lists.BlockingRemoveLastAndAddFirstString(1, "source", "target", 1); -// Assert.IsNull(found.Result); - -// // already data -// conn.Lists.AddLast(1, "source", "abc"); -// conn.Lists.AddLast(1, "source", "def"); -// var found0 = conn.Lists.BlockingRemoveLastAndAddFirstString(1, "source", "target", 1); -// var found1 = conn.Lists.BlockingRemoveLastAndAddFirstString(1, "source", "target", 1); -// var found2 = conn.Lists.BlockingRemoveLastAndAddFirstString(1, "source", "target", 1); -// Assert.AreEqual("def", found0.Result); -// Assert.AreEqual("abc", found1.Result); -// Assert.IsNull(found2.Result); - -// // add data from another client -// conn.Lists.AddFirst(1, "source", "abc"); -// found0 = conn.Lists.BlockingRemoveLastAndAddFirstString(1, "source", "target", 1); -// found1 = conn.Lists.BlockingRemoveLastAndAddFirstString(1, "source", "target", 1); -// found2 = conn.Lists.BlockingRemoveLastAndAddFirstString(1, "source", "target", 1); -// var found3 = conn.Lists.BlockingRemoveLastAndAddFirstString(1, "source", "target", 1); -// conn2.Lists.AddFirst(1, "source", "def"); -// conn2.Lists.AddFirst(1, "source", "ghi"); -// Assert.AreEqual("abc", found0.Result); -// Assert.AreEqual("def", found1.Result); -// Assert.AreEqual("ghi", found2.Result); -// Assert.IsNull(found3.Result); -// } -// } -// [Test] -// public void TestBlockingPopPushBytes() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// using (var conn2 = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "source"); -// conn.Keys.Remove(1, "target"); - -// // empty -// var found = conn.Lists.BlockingRemoveLastAndAddFirst(1, "source", "target", 1); -// Assert.IsNull(found.Result); - -// // already data -// conn.Lists.AddLast(1, "source", "abc"); -// conn.Lists.AddLast(1, "source", "def"); -// var found0 = conn.Lists.BlockingRemoveLastAndAddFirst(1, "source", "target", 1); -// var found1 = conn.Lists.BlockingRemoveLastAndAddFirst(1, "source", "target", 1); -// var found2 = conn.Lists.BlockingRemoveLastAndAddFirst(1, "source", "target", 1); -// Assert.AreEqual("def", Encoding.UTF8.GetString(found0.Result)); -// Assert.AreEqual("abc", Encoding.UTF8.GetString(found1.Result)); -// Assert.IsNull(found2.Result); - -// // add data from another client -// conn.Lists.AddFirst(1, "source", "abc"); -// found0 = conn.Lists.BlockingRemoveLastAndAddFirst(1, "source", "target", 1); -// found1 = conn.Lists.BlockingRemoveLastAndAddFirst(1, "source", "target", 1); -// found2 = conn.Lists.BlockingRemoveLastAndAddFirst(1, "source", "target", 1); -// var found3 = conn.Lists.BlockingRemoveLastAndAddFirst(1, "source", "target", 1); -// Thread.Sleep(100); // make sure those commands at least get queued before conn2 starts monkeying - -// conn2.Lists.AddFirst(1, "source", "def"); -// conn2.Lists.AddFirst(1, "source", "ghi"); -// Assert.AreEqual("abc", Encoding.UTF8.GetString(found0.Result)); -// Assert.AreEqual("def", Encoding.UTF8.GetString(found1.Result)); -// Assert.AreEqual("ghi", Encoding.UTF8.GetString(found2.Result)); -// Assert.IsNull(found3.Result); -// } -// } -// } -//} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Locking.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Locking.cs deleted file mode 100644 index 21b178e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Locking.cs +++ /dev/null @@ -1,241 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using NUnit.Framework; -using StackExchange.Redis; - -namespace Tests -{ - [TestFixture] - public class Locking - { - [Test] - public void AggressiveParallel() - { - int count = 2; - int errorCount = 0; - ManualResetEvent evt = new ManualResetEvent(false); - using (var c1 = Config.GetUnsecuredConnection(waitForOpen: true)) - using (var c2 = Config.GetUnsecuredConnection(waitForOpen: true)) - { - WaitCallback cb = obj => - { - var conn = (ConnectionMultiplexer)obj; - conn.InternalError += delegate { Interlocked.Increment(ref errorCount); }; - conn.ErrorMessage += delegate { Interlocked.Increment(ref errorCount); }; - var db = conn.GetDatabase(2); - for (int i = 0; i < 1000; i++) - { - db.LockTake("abc", "def", TimeSpan.FromSeconds(5)); - } - db.Ping(); - conn.Close(false); - if (Interlocked.Decrement(ref count) == 0) evt.Set(); - }; - ThreadPool.QueueUserWorkItem(cb, c1); - ThreadPool.QueueUserWorkItem(cb, c2); - evt.WaitOne(8000); - } - Assert.AreEqual(0, Interlocked.CompareExchange(ref errorCount, 0, 0)); - } - - [Test] - public void TestOpCountByVersionLocal_UpLevel() - { - using (var conn = Config.GetUnsecuredConnection(open: false)) - { - TestLockOpCountByVersion(conn, 1, false); - TestLockOpCountByVersion(conn, 1, true); - //TestManualLockOpCountByVersion(conn, 5, false); - //TestManualLockOpCountByVersion(conn, 3, true); - } - } - //[Test] - //public void TestOpCountByVersionLocal_DownLevel() - //{ - // var config = new ConfigurationOptions - // { - // EndPoints = { { Config.LocalHost } }, - // DefaultVersion = new Version(2, 6, 0), - // CommandMap = CommandMap.Create( - // new HashSet { "info" }, false) - // }; - // using (var conn = ConnectionMultiplexer.Connect(config)) - // { - // TestLockOpCountByVersion(conn, 5, false); - // TestLockOpCountByVersion(conn, 3, true); - // //TestManualLockOpCountByVersion(conn, 5, false); - // //TestManualLockOpCountByVersion(conn, 3, true); - // } - //} - - //[Test] - //public void TestOpCountByVersionRemote() - //{ - // using (var conn = Config.GetRemoteConnection(open: false)) - // { - // TestLockOpCountByVersion(conn, 1, false); - // TestLockOpCountByVersion(conn, 1, true); - // //TestManualLockOpCountByVersion(conn, 1, false); - // //TestManualLockOpCountByVersion(conn, 1, true); - // } - //} - public void TestLockOpCountByVersion(ConnectionMultiplexer conn, int expected, bool existFirst) - { - const int DB = 0, LockDuration = 30; - const string Key = "TestOpCountByVersion"; - - var db = conn.GetDatabase(DB); - db.KeyDelete(Key); - var newVal = "us:" + Config.CreateUniqueName(); - string expectedVal = newVal; - if (existFirst) - { - expectedVal = "other:" + Config.CreateUniqueName(); - db.StringSet(Key, expectedVal, TimeSpan.FromSeconds(LockDuration)); - } - long countBefore = conn.GetCounters().Interactive.OperationCount; - var taken = db.LockTake(Key, newVal, TimeSpan.FromSeconds(LockDuration)); - long countAfter = conn.GetCounters().Interactive.OperationCount; - string valAfter = db.StringGet(Key); - Assert.AreEqual(!existFirst, taken, "lock taken"); - Assert.AreEqual(expectedVal, valAfter, "taker"); - Console.WriteLine("{0} ops before, {1} ops after", countBefore, countAfter); - Assert.AreEqual(expected, (countAfter - countBefore), "expected ops (including ping)"); - // note we get a ping from GetCounters - } - - [Test] - public void TakeLockAndExtend() - { - using (var conn = Config.GetUnsecuredConnection()) - { - string right = Guid.NewGuid().ToString(), - wrong = Guid.NewGuid().ToString(); - - const int DB = 7; - const string Key = "lock-key"; - - //conn.SuspendFlush(); - var db = conn.GetDatabase(DB); - - db.KeyDelete(Key); - var t1 = db.LockTakeAsync(Key, right, TimeSpan.FromSeconds(20)); - var t1b = db.LockTakeAsync(Key, wrong, TimeSpan.FromSeconds(10)); - var t2 = db.StringGetAsync(Key); - var t3 = db.LockReleaseAsync(Key, wrong); - var t4 = db.StringGetAsync(Key); - var t5 = db.LockExtendAsync(Key, wrong, TimeSpan.FromSeconds(60)); - var t6 = db.StringGetAsync(Key); - var t7 = db.KeyTimeToLiveAsync(Key); - var t8 = db.LockExtendAsync(Key, right, TimeSpan.FromSeconds(60)); - var t9 = db.StringGetAsync(Key); - var t10 = db.KeyTimeToLiveAsync(Key); - var t11 = db.LockReleaseAsync(Key, right); - var t12 = db.StringGetAsync(Key); - var t13 = db.LockTakeAsync(Key, wrong, TimeSpan.FromSeconds(10)); - - Assert.IsNotNull(right); - Assert.IsNotNull(wrong); - Assert.AreNotEqual(right, (string)wrong); - Assert.IsTrue(conn.Wait(t1), "1"); - Assert.IsFalse(conn.Wait(t1b), "1b"); - Assert.AreEqual(right, (string)conn.Wait(t2), "2"); - Assert.IsFalse(conn.Wait(t3), "3"); - Assert.AreEqual(right, (string)conn.Wait(t4), "4"); - Assert.IsFalse(conn.Wait(t5), "5"); - Assert.AreEqual(right, (string)conn.Wait(t6), "6"); - var ttl = conn.Wait(t7).Value.TotalSeconds; - Assert.IsTrue(ttl > 0 && ttl <= 20, "7"); - Assert.IsTrue(conn.Wait(t8), "8"); - Assert.AreEqual(right, (string)conn.Wait(t9), "9"); - ttl = conn.Wait(t10).Value.TotalSeconds; - Assert.IsTrue(ttl > 50 && ttl <= 60, "10"); - Assert.IsTrue(conn.Wait(t11), "11"); - Assert.IsNull((string)conn.Wait(t12), "12"); - Assert.IsTrue(conn.Wait(t13), "13"); - } - } - - - ////public void TestManualLockOpCountByVersion(RedisConnection conn, int expected, bool existFirst) - ////{ - //// const int DB = 0, LockDuration = 30; - //// const string Key = "TestManualLockOpCountByVersion"; - //// conn.Wait(conn.Open()); - //// conn.Keys.Remove(DB, Key); - //// var newVal = "us:" + Config.CreateUniqueName(); - //// string expectedVal = newVal; - //// if (existFirst) - //// { - //// expectedVal = "other:" + Config.CreateUniqueName(); - //// conn.Strings.Set(DB, Key, expectedVal, LockDuration); - //// } - //// int countBefore = conn.GetCounters().MessagesSent; - - //// var tran = conn.CreateTransaction(); - //// tran.AddCondition(Condition.KeyNotExists(DB, Key)); - //// tran.Strings.Set(DB, Key, newVal, LockDuration); - //// var taken = conn.Wait(tran.Execute()); - - //// int countAfter = conn.GetCounters().MessagesSent; - //// var valAfter = conn.Wait(conn.Strings.GetString(DB, Key)); - //// Assert.AreEqual(!existFirst, taken, "lock taken (manual)"); - //// Assert.AreEqual(expectedVal, valAfter, "taker (manual)"); - //// Assert.AreEqual(expected, (countAfter - countBefore) - 1, "expected ops (including ping) (manual)"); - //// // note we get a ping from GetCounters - ////} - - - - [Test] - public void TestBasicLockNotTaken() - { - using (var conn = Config.GetUnsecuredConnection()) - { - int errorCount = 0; - - conn.InternalError += delegate { Interlocked.Increment(ref errorCount); }; - - var db = conn.GetDatabase(0); - Task taken = null; - Task newValue = null; - Task ttl = null; - - const int LOOP = 50; - for (int i = 0; i < LOOP; i++) - { - db.KeyDeleteAsync("lock-not-exists"); - taken = db.LockTakeAsync("lock-not-exists", "new-value", TimeSpan.FromSeconds(10)); - newValue = db.StringGetAsync("lock-not-exists"); - ttl = db.KeyTimeToLiveAsync("lock-not-exists"); - } - Assert.IsTrue(conn.Wait(taken), "taken"); - Assert.AreEqual("new-value", (string)conn.Wait(newValue)); - var ttlValue = conn.Wait(ttl).Value.TotalSeconds; - Assert.IsTrue(ttlValue >= 8 && ttlValue <= 10, "ttl"); - - Assert.AreEqual(0, errorCount); - } - } - - [Test] - public void TestBasicLockTaken() - { - using (var conn = Config.GetUnsecuredConnection()) - { - var db = conn.GetDatabase(0); - db.KeyDelete("lock-exists"); - db.StringSet("lock-exists", "old-value", TimeSpan.FromSeconds(20)); - var taken = db.LockTakeAsync("lock-exists", "new-value", TimeSpan.FromSeconds(10)); - var newValue = db.StringGetAsync("lock-exists"); - var ttl = db.KeyTimeToLiveAsync("lock-exists"); - - Assert.IsFalse(conn.Wait(taken), "taken"); - Assert.AreEqual("old-value", (string)conn.Wait(newValue)); - var ttlValue = conn.Wait(ttl).Value.TotalSeconds; - Assert.IsTrue(ttlValue >= 18 && ttlValue <= 20, "ttl"); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/MigratedBookSleeveTestSuite.csproj b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/MigratedBookSleeveTestSuite.csproj deleted file mode 100644 index c020212..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/MigratedBookSleeveTestSuite.csproj +++ /dev/null @@ -1,56 +0,0 @@ - - - - MigratedBookSleeveTestSuite - net45;netcoreapp1.0 - MigratedBookSleeveTestSuite - MigratedBookSleeveTestSuite - false - true - $(PackageTargetFallback);portable-net45+win8 - 1.0.4 - false - false - false - false - false - false - false - false - - - - - - - - - - - - - - - - - - - - - - $(DefineConstants);PLAT_SAFE_CONTINUATIONS;CORE_CLR - - - - - - - - - - - - - - - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Performance.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Performance.cs deleted file mode 100644 index 0b17549..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Performance.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Diagnostics; -using System.Text; -using System.Threading.Tasks; -using NUnit.Framework; -using StackExchange.Redis; - -namespace Tests -{ - [TestFixture] - public class Performance - { - [Test] - public void VerifyPerformanceImprovement() - { - int asyncTimer, sync, op = 0, asyncFaF, syncFaF; - using (var muxer= Config.GetUnsecuredConnection()) - { - // do these outside the timings, just to ensure the core methods are JITted etc - for (int db = 0; db < 5; db++) - { - muxer.GetDatabase(db).KeyDeleteAsync("perftest"); - } - - var timer = Stopwatch.StartNew(); - for (int i = 0; i < 100; i++) - { - // want to test multiplex scenario; test each db, but to make it fair we'll - // do in batches of 10 on each - for (int db = 0; db < 5; db++) - { - var conn = muxer.GetDatabase(db); - for (int j = 0; j < 10; j++) - conn.StringIncrementAsync("perftest"); - } - } - asyncFaF = (int)timer.ElapsedMilliseconds; - Task[] final = new Task[5]; - for (int db = 0; db < 5; db++) - final[db] = muxer.GetDatabase(db).StringGetAsync("perftest"); - muxer.WaitAll(final); - timer.Stop(); - asyncTimer = (int)timer.ElapsedMilliseconds; - Console.WriteLine("async to completion (local): {0}ms", timer.ElapsedMilliseconds); - for (int db = 0; db < 5; db++) - Assert.AreEqual(1000, (long)final[db].Result, "async, db:" + db); - } - - using (var conn = new Redis(Config.LocalHost, 6379)) - { - // do these outside the timings, just to ensure the core methods are JITted etc - for (int db = 0; db < 5; db++) - { - conn.Db = db; - conn.Remove("perftest"); - } - - var timer = Stopwatch.StartNew(); - for (int i = 0; i < 100; i++) - { - // want to test multiplex scenario; test each db, but to make it fair we'll - // do in batches of 10 on each - for (int db = 0; db < 5; db++) - { - conn.Db = db; - op++; - for (int j = 0; j < 10; j++) - { - conn.Increment("perftest"); - op++; - } - } - } - syncFaF = (int)timer.ElapsedMilliseconds; - string[] final = new string[5]; - for (int db = 0; db < 5; db++) - { - conn.Db = db; - final[db] = Encoding.ASCII.GetString(conn.Get("perftest")); - } - timer.Stop(); - sync = (int)timer.ElapsedMilliseconds; - Console.WriteLine("sync to completion (local): {0}ms", timer.ElapsedMilliseconds); - for (int db = 0; db < 5; db++) - Assert.AreEqual("1000", final[db], "async, db:" + db); - } - int effectiveAsync = ((10 * asyncTimer) + 3) / 10; - int effectiveSync = ((10 * sync) + (op * 3)) / 10; - Console.WriteLine("async to completion with assumed 0.3ms LAN latency: " + effectiveAsync); - Console.WriteLine("sync to completion with assumed 0.3ms LAN latency: " + effectiveSync); - Console.WriteLine("fire-and-forget: {0}ms sync vs {1}ms async ", syncFaF, asyncFaF); - Assert.Less(effectiveAsync, effectiveSync, "Everything"); - Assert.Less(asyncFaF, syncFaF, "Fire and Forget"); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Program.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Program.cs deleted file mode 100644 index 0d204d2..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Program.cs +++ /dev/null @@ -1,178 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; -using NUnit.Framework; - -namespace Tests -{ - class Program - { - // static void Main() - // { - // try - // { - // Main2(); - // } - // catch (Exception ex) - // { - // Console.WriteLine(); - // Console.WriteLine("CRAZY ERRORS: " + ex); - // } - // finally - // { - // Console.WriteLine("Press any key to exit"); - // Console.ReadKey(); - // } - // } - static void Main2() - { -#if !CORE_CLR - // why is this here? because some dumbass forgot to install a decent test-runner before going to the airport - var epicFail = new List(); - var testTypes = from type in typeof(Program).Assembly.GetTypes() - where Attribute.IsDefined(type, typeof(TestFixtureAttribute)) - && !Attribute.IsDefined(type, typeof(IgnoreAttribute)) - let methods = type.GetMethods() - select new - { - Type = type, - Methods = methods, - ActiveMethods = methods.Where(x => Attribute.IsDefined(x, typeof(ActiveTestAttribute))).ToArray(), - Setup = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(OneTimeSetUpAttribute))), - TearDown = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(OneTimeTearDownAttribute))) - }; - int pass = 0, fail = 0; - - bool activeOnly = testTypes.SelectMany(x => x.ActiveMethods).Any(); - - TaskScheduler.UnobservedTaskException += (sender, args) => - { - args.SetObserved(); - //if (args.Exception is AggregateException) - //{ - // foreach (var ex in ((AggregateException)args.Exception).InnerExceptions) - // { - // Console.WriteLine(ex.Message); - // } - //} - //else - //{ - // Console.WriteLine(args.Exception.Message); - //} - }; - - foreach (var type in testTypes) - { - var tests = (from method in (activeOnly ? type.ActiveMethods : type.Methods) - where Attribute.IsDefined(method, typeof(TestAttribute)) - && !Attribute.IsDefined(method, typeof(IgnoreAttribute)) - select method).ToArray(); - - if (tests.Length == 0) continue; - - Console.WriteLine(type.Type.FullName); - object obj; - try - { - obj = Activator.CreateInstance(type.Type); - if (obj == null) throw new InvalidOperationException("the world has gone mad"); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - continue; - } - using (obj as IDisposable) - { - if (type.Setup != null) - { - try - { type.Setup.Invoke(obj, null); } - catch (Exception ex) - { - Console.WriteLine("Test fixture startup failed: " + ex.Message); - fail++; - epicFail.Add(type.Setup.DeclaringType.FullName + "." + type.Setup.Name); - continue; - } - } - - foreach (var test in tests) - { - Console.Write(test.Name + ": "); - Exception err = null; - - try - { - int count = 1; - if (activeOnly) - { - var ata = test.GetCustomAttribute(typeof(ActiveTestAttribute)) as ActiveTestAttribute; - if (ata != null) count = ata.Count; - } - while (count-- > 0) - { - test.Invoke(obj, null); - } - } - catch (TargetInvocationException ex) - { - err = ex.InnerException; - } - catch (Exception ex) - { - err = ex; - } - - if (err is AggregateException && ((AggregateException)err).InnerExceptions.Count == 1) - { - err = ((AggregateException)err).InnerExceptions[0]; - } - - if (err == null) - { - Console.WriteLine("pass"); - pass++; - } - else - { - Console.WriteLine(err.Message); - fail++; - epicFail.Add(test.DeclaringType.FullName + "." + test.Name); - } - } - if (type.TearDown != null) - { - try - { type.TearDown.Invoke(obj, null); } - catch (Exception ex) - { - Console.WriteLine("Test fixture teardown failed: " + ex.Message); - fail++; - epicFail.Add(type.TearDown.DeclaringType.FullName + "." + type.TearDown.Name); - } - } - } - } - Console.WriteLine("Passed: {0}; Failed: {1}", pass, fail); - foreach (var msg in epicFail) Console.WriteLine(msg); -//#if DEBUG -// Console.WriteLine(); -// Console.WriteLine("Callbacks: {0:###,###,##0} sync, {1:###,###,##0} async", -// BookSleeve.RedisConnectionBase.AllSyncCallbacks, BookSleeve.RedisConnectionBase.AllAsyncCallbacks); -//#endif - -#endif - } - } -} - -[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ActiveTestAttribute : Attribute -{ - public int Count { get; } - public ActiveTestAttribute() : this(1) { } - public ActiveTestAttribute(int count) { this.Count = count; } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Properties/AssemblyInfo.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Properties/AssemblyInfo.cs deleted file mode 100644 index 9dc391d..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("MigratedBookSleeveTestSuite")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("MigratedBookSleeveTestSuite")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("350d3b30-78dd-4b74-a76d-bb593a05e8d1")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/PubSub.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/PubSub.cs deleted file mode 100644 index c6af2cb..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/PubSub.cs +++ /dev/null @@ -1,269 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using NUnit.Framework; -using StackExchange.Redis; - -namespace Tests -{ - [TestFixture] - public class PubSub // http://redis.io/commands#pubsub - { - [Test] - public void TestPublishWithNoSubscribers() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetSubscriber(); - Assert.AreEqual(0, conn.Publish("channel", "message")); - } - } - - [Test] - public void TestMassivePublishWithWithoutFlush_Local() - { - using (var muxer = Config.GetUnsecuredConnection(waitForOpen: true)) - { - var conn = muxer.GetSubscriber(); - TestMassivePublish(conn, "local"); - } - } - [Test] - public void TestMassivePublishWithWithoutFlush_Remote() - { - using (var muxer = Config.GetRemoteConnection(waitForOpen: true)) - { - var conn = muxer.GetSubscriber(); - TestMassivePublish(conn, "remote"); - } - } - - private void TestMassivePublish(ISubscriber conn, string caption) - { - const int loop = 100000; - - GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); - GC.WaitForPendingFinalizers(); - - var tasks = new Task[loop]; - - var withFAF = Stopwatch.StartNew(); - for (int i = 0; i < loop; i++) - conn.Publish("foo", "bar", CommandFlags.FireAndForget); - withFAF.Stop(); - - GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); - GC.WaitForPendingFinalizers(); - - var withAsync = Stopwatch.StartNew(); - for (int i = 0; i < loop; i++) - tasks[i] = conn.PublishAsync("foo", "bar"); - conn.WaitAll(tasks); - withAsync.Stop(); - - Assert.Less(1, 2, "sanity check"); - Assert.Less(withFAF.ElapsedMilliseconds, withAsync.ElapsedMilliseconds, caption); - Console.WriteLine("{2}: {0}ms (F+F) vs {1}ms (async)", - withFAF.ElapsedMilliseconds, withAsync.ElapsedMilliseconds, caption); - } - - - [Test] - public void PubSubOrder() - { - using (var muxer = Config.GetRemoteConnection(waitForOpen: true)) - { - var sub = muxer.GetSubscriber(); - string channel = "PubSubOrder"; - const int count = 500000; - object syncLock = new object(); - - List data = new List(count); - muxer.PreserveAsyncOrder = true; - sub.SubscribeAsync(channel, (key, val) => - { - bool pulse; - lock (data) - { - data.Add(int.Parse(Encoding.UTF8.GetString(val))); - pulse = data.Count == count; - if ((data.Count % 10) == 99) Console.WriteLine(data.Count); - } - if (pulse) - lock (syncLock) - Monitor.PulseAll(syncLock); - }).Wait(); - - lock (syncLock) - { - for (int i = 0; i < count; i++) - { - sub.Publish(channel, i.ToString(), CommandFlags.FireAndForget); - } - sub.Ping(); - if (!Monitor.Wait(syncLock, 10000)) - { - throw new TimeoutException("Items: " + data.Count); - } - for (int i = 0; i < count; i++) - Assert.AreEqual(i, data[i]); - } - } - - } - - [Test] - public void TestPublishWithSubscribers() - { - using (var muxerA = Config.GetUnsecuredConnection()) - using (var muxerB = Config.GetUnsecuredConnection()) - using (var conn = Config.GetUnsecuredConnection()) - { - var listenA = muxerA.GetSubscriber(); - var listenB = muxerB.GetSubscriber(); - var t1 = listenA.SubscribeAsync("channel", delegate { }); - var t2 = listenB.SubscribeAsync("channel", delegate { }); - - listenA.Wait(t1); - listenB.Wait(t2); - - var pub = conn.GetSubscriber().PublishAsync("channel", "message"); - Assert.AreEqual(2, conn.Wait(pub), "delivery count"); - } - } - - [Test] - public void TestMultipleSubscribersGetMessage() - { - using (var muxerA = Config.GetUnsecuredConnection()) - using (var muxerB = Config.GetUnsecuredConnection()) - using (var conn = Config.GetUnsecuredConnection()) - { - var listenA = muxerA.GetSubscriber(); - var listenB = muxerB.GetSubscriber(); - conn.GetDatabase().Ping(); - var pub = conn.GetSubscriber(); - int gotA = 0, gotB = 0; - var tA = listenA.SubscribeAsync("channel", (s, msg) => { if (msg == "message") Interlocked.Increment(ref gotA); }); - var tB = listenB.SubscribeAsync("channel", (s, msg) => { if (msg == "message") Interlocked.Increment(ref gotB); }); - listenA.Wait(tA); - listenB.Wait(tB); - Assert.AreEqual(2, pub.Publish("channel", "message")); - AllowReasonableTimeToPublishAndProcess(); - Assert.AreEqual(1, Interlocked.CompareExchange(ref gotA, 0, 0)); - Assert.AreEqual(1, Interlocked.CompareExchange(ref gotB, 0, 0)); - - // and unsubscibe... - tA = listenA.UnsubscribeAsync("channel"); - listenA.Wait(tA); - Assert.AreEqual(1, pub.Publish("channel", "message")); - AllowReasonableTimeToPublishAndProcess(); - Assert.AreEqual(1, Interlocked.CompareExchange(ref gotA, 0, 0)); - Assert.AreEqual(2, Interlocked.CompareExchange(ref gotB, 0, 0)); - } - } - - [Test] - public void Issue38() - { // https://code.google.com/p/booksleeve/issues/detail?id=38 - - using (var pub = Config.GetUnsecuredConnection(waitForOpen: true)) - { - var sub = pub.GetSubscriber(); - int count = 0; - Action handler = (channel, payload) => Interlocked.Increment(ref count); - var a0 = sub.SubscribeAsync("foo", handler); - var a1 = sub.SubscribeAsync("bar", handler); - var b0 = sub.SubscribeAsync("f*o", handler); - var b1 = sub.SubscribeAsync("b*r", handler); - sub.WaitAll(a0, a1, b0, b1); - - var c = sub.PublishAsync("foo", "foo"); - var d = sub.PublishAsync("f@o", "f@o"); - var e = sub.PublishAsync("bar", "bar"); - var f = sub.PublishAsync("b@r", "b@r"); - - pub.WaitAll(c, d, e, f); - long total = c.Result + d.Result + e.Result + f.Result; - - AllowReasonableTimeToPublishAndProcess(); - - Assert.AreEqual(6, total, "sent"); - Assert.AreEqual(6, Interlocked.CompareExchange(ref count, 0, 0), "received"); - - - } - } - - internal static void AllowReasonableTimeToPublishAndProcess() - { - Thread.Sleep(50); - } - - [Test] - public void TestPartialSubscriberGetMessage() - { - using (var muxerA = Config.GetUnsecuredConnection()) - using (var muxerB = Config.GetUnsecuredConnection()) - using (var conn = Config.GetUnsecuredConnection()) - { - int gotA = 0, gotB = 0; - var listenA = muxerA.GetSubscriber(); - var listenB = muxerB.GetSubscriber(); - var pub = conn.GetSubscriber(); - var tA = listenA.SubscribeAsync("channel", (s, msg) => { if (s == "channel" && msg == "message") Interlocked.Increment(ref gotA); }); - var tB = listenB.SubscribeAsync("chann*", (s, msg) => { if (s == "channel" && msg == "message") Interlocked.Increment(ref gotB); }); - listenA.Wait(tA); - listenB.Wait(tB); - Assert.AreEqual(2, pub.Publish("channel", "message")); - AllowReasonableTimeToPublishAndProcess(); - Assert.AreEqual(1, Interlocked.CompareExchange(ref gotA, 0, 0)); - Assert.AreEqual(1, Interlocked.CompareExchange(ref gotB, 0, 0)); - - // and unsubscibe... - tB = listenB.UnsubscribeAsync("chann*", null); - listenB.Wait(tB); - Assert.AreEqual(1, pub.Publish("channel", "message")); - AllowReasonableTimeToPublishAndProcess(); - Assert.AreEqual(2, Interlocked.CompareExchange(ref gotA, 0, 0)); - Assert.AreEqual(1, Interlocked.CompareExchange(ref gotB, 0, 0)); - } - } - - [Test] - public void TestSubscribeUnsubscribeAndSubscribeAgain() - { - using (var pubMuxer = Config.GetUnsecuredConnection()) - using (var subMuxer = Config.GetUnsecuredConnection()) - { - var pub = pubMuxer.GetSubscriber(); - var sub = subMuxer.GetSubscriber(); - int x = 0, y = 0; - var t1 = sub.SubscribeAsync("abc", delegate { Interlocked.Increment(ref x); }); - var t2 = sub.SubscribeAsync("ab*", delegate { Interlocked.Increment(ref y); }); - sub.WaitAll(t1, t2); - pub.Publish("abc", ""); - AllowReasonableTimeToPublishAndProcess(); - Assert.AreEqual(1, Volatile.Read(ref x)); - Assert.AreEqual(1, Volatile.Read(ref y)); - t1 = sub.UnsubscribeAsync("abc", null); - t2 = sub.UnsubscribeAsync("ab*", null); - sub.WaitAll(t1, t2); - pub.Publish("abc", ""); - Assert.AreEqual(1, Volatile.Read(ref x)); - Assert.AreEqual(1, Volatile.Read(ref y)); - t1 = sub.SubscribeAsync("abc", delegate { Interlocked.Increment(ref x); }); - t2 = sub.SubscribeAsync("ab*", delegate { Interlocked.Increment(ref y); }); - sub.WaitAll(t1, t2); - pub.Publish("abc", ""); - AllowReasonableTimeToPublishAndProcess(); - Assert.AreEqual(2, Volatile.Read(ref x)); - Assert.AreEqual(2, Volatile.Read(ref y)); - - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Scripting.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Scripting.cs deleted file mode 100644 index dff281b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Scripting.cs +++ /dev/null @@ -1,369 +0,0 @@ -using System; -using System.Diagnostics; -using System.Linq; -using System.Text; -using NUnit.Framework; -using StackExchange.Redis; - -namespace Tests -{ - [TestFixture] - public class Scripting - { - static ConnectionMultiplexer GetScriptConn(bool allowAdmin = false) - { - int syncTimeout = 5000; - if (Debugger.IsAttached) syncTimeout = 500000; - var muxer = Config.GetUnsecuredConnection(waitForOpen: true, allowAdmin: allowAdmin, syncTimeout: syncTimeout); - if (!Config.GetFeatures(muxer).Scripting) - { - Assert.Inconclusive("The server does not support scripting"); - } - return muxer; - - } - [Test] - public void ClientScripting() - { - using (var conn = GetScriptConn()) - { - var result = conn.GetDatabase().ScriptEvaluate("return redis.call('info','server')", null, null); - } - } - - [Test] - public void BasicScripting() - { - using (var muxer = GetScriptConn()) - { - var conn = muxer.GetDatabase(); - var noCache = conn.ScriptEvaluateAsync("return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}", - new RedisKey[] { "key1", "key2" }, new RedisValue[] { "first", "second" }); - var cache = conn.ScriptEvaluateAsync("return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}", - new RedisKey[] { "key1", "key2" }, new RedisValue[] { "first", "second" }); - var results = (string[])conn.Wait(noCache); - Assert.AreEqual(4, results.Length); - Assert.AreEqual("key1", results[0]); - Assert.AreEqual("key2", results[1]); - Assert.AreEqual("first", results[2]); - Assert.AreEqual("second", results[3]); - - results = (string[])conn.Wait(cache); - Assert.AreEqual(4, results.Length); - Assert.AreEqual("key1", results[0]); - Assert.AreEqual("key2", results[1]); - Assert.AreEqual("first", results[2]); - Assert.AreEqual("second", results[3]); - } - } - [Test] - public void KeysScripting() - { - using (var muxer = GetScriptConn()) - { - var conn = muxer.GetDatabase(); - conn.StringSet("foo", "bar"); - var result = (string)conn.ScriptEvaluate("return redis.call('get', KEYS[1])", new RedisKey[] { "foo" }, null); - Assert.AreEqual("bar", result); - } - } - - [Test] - public void TestRandomThingFromForum() - { - const string script = @"local currentVal = tonumber(redis.call('GET', KEYS[1])); - if (currentVal <= 0 ) then return 1 elseif (currentVal - (tonumber(ARGV[1])) < 0 ) then return 0 end; - return redis.call('INCRBY', KEYS[1], -tonumber(ARGV[1]));"; - - using (var muxer = GetScriptConn()) - { - var conn = muxer.GetDatabase(); - conn.StringSetAsync("A", "0"); - conn.StringSetAsync("B", "5"); - conn.StringSetAsync("C", "10"); - - var a = conn.ScriptEvaluateAsync(script, new RedisKey[] { "A" }, new RedisValue[] { 6 }); - var b = conn.ScriptEvaluateAsync(script, new RedisKey[] { "B" }, new RedisValue[] { 6 }); - var c = conn.ScriptEvaluateAsync(script, new RedisKey[] { "C" }, new RedisValue[] { 6 }); - - var vals = conn.StringGetAsync(new RedisKey[] { "A", "B", "C" }); - - Assert.AreEqual(1, (long)conn.Wait(a)); // exit code when current val is non-positive - Assert.AreEqual(0, (long)conn.Wait(b)); // exit code when result would be negative - Assert.AreEqual(4, (long)conn.Wait(c)); // 10 - 6 = 4 - Assert.AreEqual("0", (string)conn.Wait(vals)[0]); - Assert.AreEqual("5", (string)conn.Wait(vals)[1]); - Assert.AreEqual("4", (string)conn.Wait(vals)[2]); - } - } - - [Test] - public void HackyGetPerf() - { - using (var muxer = GetScriptConn()) - { - var conn = muxer.GetDatabase(); - conn.StringSetAsync("foo", "bar"); - var key = Config.CreateUniqueName(); - var result = (long)conn.ScriptEvaluate(@" -redis.call('psetex', KEYS[1], 60000, 'timing') -for i = 1,100000 do - redis.call('set', 'ignore','abc') -end -local timeTaken = 60000 - redis.call('pttl', KEYS[1]) -redis.call('del', KEYS[1]) -return timeTaken -", new RedisKey[] { key }, null); - Console.WriteLine(result); - Assert.IsTrue(result > 0); - } - } - - [Test] - public void MultiIncrWithoutReplies() - { - using (var muxer = GetScriptConn()) - { - const int DB = 0; // any database number - var conn = muxer.GetDatabase(DB); - // prime some initial values - conn.KeyDeleteAsync(new RedisKey[] { "a", "b", "c" }); - conn.StringIncrementAsync("b"); - conn.StringIncrementAsync("c"); - conn.StringIncrementAsync("c"); - - // run the script, passing "a", "b", "c", "c" to - // increment a & b by 1, c twice - var result = conn.ScriptEvaluateAsync( - @"for i,key in ipairs(KEYS) do redis.call('incr', key) end", - new RedisKey[] { "a", "b", "c", "c" }, // <== aka "KEYS" in the script - null); // <== aka "ARGV" in the script - - // check the incremented values - var a = conn.StringGetAsync("a"); - var b = conn.StringGetAsync("b"); - var c = conn.StringGetAsync("c"); - - Assert.IsTrue(conn.Wait(result).IsNull, "result"); - Assert.AreEqual(1, (long)conn.Wait(a), "a"); - Assert.AreEqual(2, (long)conn.Wait(b), "b"); - Assert.AreEqual(4, (long)conn.Wait(c), "c"); - } - } - - [Test] - public void MultiIncrByWithoutReplies() - { - using (var muxer = GetScriptConn()) - { - const int DB = 0; // any database number - var conn = muxer.GetDatabase(DB); - // prime some initial values - conn.KeyDeleteAsync(new RedisKey[] { "a", "b", "c" }); - conn.StringIncrementAsync("b"); - conn.StringIncrementAsync("c"); - conn.StringIncrementAsync("c"); - - //run the script, passing "a", "b", "c" and 1,2,3 - // increment a &b by 1, c twice - var result = conn.ScriptEvaluateAsync( - @"for i,key in ipairs(KEYS) do redis.call('incrby', key, ARGV[i]) end", - new RedisKey[] { "a", "b", "c" }, // <== aka "KEYS" in the script - new RedisValue[] { 1, 1, 2 }); // <== aka "ARGV" in the script - - // check the incremented values - var a = conn.StringGetAsync("a"); - var b = conn.StringGetAsync("b"); - var c = conn.StringGetAsync("c"); - - Assert.IsTrue(conn.Wait(result).IsNull, "result"); - Assert.AreEqual(1, (long)conn.Wait(a), "a"); - Assert.AreEqual(2, (long)conn.Wait(b), "b"); - Assert.AreEqual(4, (long)conn.Wait(c), "c"); - } - } - - [Test] - public void DisableStringInference() - { - using (var muxer = GetScriptConn()) - { - var conn = muxer.GetDatabase(0); - conn.StringSet("foo", "bar"); - var result = (byte[])conn.ScriptEvaluate("return redis.call('get', KEYS[1])", new RedisKey[] { "foo" }); - Assert.AreEqual("bar", Encoding.UTF8.GetString(result)); - } - } - - [Test] - public void FlushDetection() - { // we don't expect this to handle everything; we just expect it to be predictable - using (var muxer = GetScriptConn(allowAdmin: true)) - { - var conn = muxer.GetDatabase(0); - conn.StringSet("foo", "bar"); - var result = (string)conn.ScriptEvaluate("return redis.call('get', KEYS[1])", new RedisKey[] { "foo" }, null); - Assert.AreEqual("bar", result); - - // now cause all kinds of problems - Config.GetServer(muxer).ScriptFlush(); - - //expect this one to fail just work fine (self-fix) - conn.ScriptEvaluate("return redis.call('get', KEYS[1])", new RedisKey[] { "foo" }, null); - - result = (string)conn.ScriptEvaluate("return redis.call('get', KEYS[1])", new RedisKey[] { "foo" }, null); - Assert.AreEqual("bar", result); - } - } - - [Test] - public void PrepareScript() - { - string[] scripts = { "return redis.call('get', KEYS[1])", "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" }; - using (var muxer = GetScriptConn(allowAdmin: true)) - { - var server = Config.GetServer(muxer); - server.ScriptFlush(); - - // when vanilla - server.ScriptLoad(scripts[0]); - server.ScriptLoad(scripts[1]); - - //when known to exist - server.ScriptLoad(scripts[0]); - server.ScriptLoad(scripts[1]); - } - using (var muxer = GetScriptConn()) - { - var server = Config.GetServer(muxer); - - //when vanilla - server.ScriptLoad(scripts[0]); - server.ScriptLoad(scripts[1]); - - //when known to exist - server.ScriptLoad(scripts[0]); - server.ScriptLoad(scripts[1]); - - //when known to exist - server.ScriptLoad(scripts[0]); - server.ScriptLoad(scripts[1]); - } - } - [Test] - public void NonAsciiScripts() - { - using (var muxer = GetScriptConn()) - { - const string evil = "return '僕'"; - var conn = muxer.GetDatabase(0); - Config.GetServer(muxer).ScriptLoad(evil); - - var result = (string)conn.ScriptEvaluate(evil, null, null); - Assert.AreEqual("僕", result); - } - } - - [Test] - public void ScriptThrowsError() - { - Assert.Throws(() => - { - using (var muxer = GetScriptConn()) - { - var conn = muxer.GetDatabase(0); - var result = conn.ScriptEvaluateAsync("return redis.error_reply('oops')", null, null); - try - { - conn.Wait(result); - } - catch (AggregateException ex) - { - throw ex.InnerExceptions[0]; - } - } - }, - message: "oops"); - } - - [Test] - public void ScriptThrowsErrorInsideTransaction() - { - using (var muxer = GetScriptConn()) - { - const int db = 0; - const string key = "ScriptThrowsErrorInsideTransaction"; - var conn = muxer.GetDatabase(db); - conn.KeyDeleteAsync(key); - var beforeTran = (string)conn.StringGet(key); - Assert.IsNull(beforeTran); - var tran = conn.CreateTransaction(); - { - var a = tran.StringIncrementAsync(key); - var b = tran.ScriptEvaluateAsync("return redis.error_reply('oops')", null, null); - var c = tran.StringIncrementAsync(key); - var complete = tran.ExecuteAsync(); - - Assert.IsTrue(tran.Wait(complete)); - Assert.IsTrue(a.IsCompleted); - Assert.IsTrue(c.IsCompleted); - Assert.AreEqual(1L, a.Result); - Assert.AreEqual(2L, c.Result); - - Assert.IsTrue(b.IsFaulted); - Assert.AreEqual(1, b.Exception.InnerExceptions.Count); - var ex = b.Exception.InnerExceptions.Single(); - Assert.IsInstanceOf(ex); - Assert.AreEqual("oops", ex.Message); - - } - var afterTran = conn.StringGetAsync(key); - Assert.AreEqual(2L, (long)conn.Wait(afterTran)); - } - } - - - - [Test] - public void ChangeDbInScript() - { - using (var muxer = GetScriptConn()) - { - muxer.GetDatabase(1).StringSet("foo", "db 1"); - muxer.GetDatabase(2).StringSet("foo", "db 2"); - - var conn = muxer.GetDatabase(2); - var evalResult = conn.ScriptEvaluateAsync(@"redis.call('select', 1) - return redis.call('get','foo')", null, null); - var getResult = conn.StringGetAsync("foo"); - - Assert.AreEqual("db 1", (string)conn.Wait(evalResult)); - // now, our connection thought it was in db 2, but the script changed to db 1 - Assert.AreEqual("db 2", (string)conn.Wait(getResult)); - - } - } - - [Test] - public void ChangeDbInTranScript() - { - using (var muxer = GetScriptConn()) - { - muxer.GetDatabase(1).StringSet("foo", "db 1"); - muxer.GetDatabase(2).StringSet("foo", "db 2"); - - var conn = muxer.GetDatabase(2); - var tran = conn.CreateTransaction(); - var evalResult = tran.ScriptEvaluateAsync(@"redis.call('select', 1) - return redis.call('get','foo')", null, null); - var getResult = tran.StringGetAsync("foo"); - Assert.IsTrue(tran.Execute()); - - Assert.AreEqual("db 1", (string)conn.Wait(evalResult)); - // now, our connection thought it was in db 2, but the script changed to db 1 - Assert.AreEqual("db 2", (string)conn.Wait(getResult)); - - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Server.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Server.cs deleted file mode 100644 index 9cc139c..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Server.cs +++ /dev/null @@ -1,446 +0,0 @@ -//using System.Linq; -//using BookSleeve; -//using NUnit.Framework; -//using System.Threading; -//using System; -//using System.Threading.Tasks; -//using System.Collections.Generic; -//using System.Diagnostics; - -//namespace Tests -//{ -// [TestFixture] -// public class Server // http://redis.io/commands#server -// { -// [Test] -// public void TestGetConfigAll() -// { -// using (var db = Config.GetUnsecuredConnection()) -// { -// var pairs = db.Wait(db.Server.GetConfig("*")); -// Assert.Greater(1, 0); // I always get double-check which arg is which -// Assert.Greater(pairs.Count, 0); -// } -// } - -// [Test] -// public void BGSaveAndLastSave() -// { -// using(var db = Config.GetUnsecuredConnection(allowAdmin: true)) -// { -// var oldWhen = db.Server.GetLastSaveTime(); -// db.Wait(db.Server.SaveDatabase(foreground: false)); - -// bool saved = false; -// for(int i = 0; i < 50; i++) -// { -// var newWhen = db.Server.GetLastSaveTime(); -// db.Wait(newWhen); -// if(newWhen.Result > oldWhen.Result) -// { -// saved = true; -// break; -// } -// Console.WriteLine("waiting..."); -// Thread.Sleep(200); -// } -// Assert.IsTrue(saved); -// } -// } - -// [Test] -// [TestCase(true)] -// [TestCase(false)] -// public void Slowlog(bool remote) -// { -// using(var db = remote ? Config.GetRemoteConnection(allowAdmin: true) : Config.GetUnsecuredConnection(allowAdmin: true)) -// { -// var oldWhen = db.Wait(db.Server.Time()); -// db.Server.FlushAll(); -// db.Server.ResetSlowCommands(); -// for (int i = 0; i < 100000; i++) -// { -// db.Strings.Set(1, Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); -// } -// var settings = db.Wait(db.Server.GetConfig("slowlog-*")); -// var count = int.Parse(settings["slowlog-max-len"]); -// var threshold = int.Parse(settings["slowlog-log-slower-than"]); - -// var ping = db.Server.Ping(); -// Assert.IsTrue(ping.Wait(10000)); // wait until inserted -// db.Server.SaveDatabase(foreground: true); -// var keys = db.Wait(db.Keys.Find(1, "*")); -// var slow = db.Wait(db.Server.GetSlowCommands()); -// var slow2 = db.Wait(db.Server.GetSlowCommands(slow.Length)); // different command syntax -// Assert.AreEqual(slow.Length, slow2.Length); - - - -// foreach(var cmd in slow) -// { -// Console.WriteLine(cmd.UniqueId + ": " + cmd.Duration.Milliseconds + "ms; " + -// string.Join(", ", cmd.Arguments), cmd.GetHelpUrl()); -// Assert.IsTrue(cmd.Time > oldWhen && cmd.Time < oldWhen.AddMinutes(1)); -// } - -// Assert.AreEqual(2, slow.Length); - -// Assert.AreEqual(2, slow[0].Arguments.Length); -// Assert.AreEqual("KEYS", slow[0].Arguments[0]); -// Assert.AreEqual("*", slow[0].Arguments[1]); -// Assert.AreEqual("http://redis.io/commands/keys", slow[0].GetHelpUrl()); - -// Assert.AreEqual(1, slow[1].Arguments.Length); -// Assert.AreEqual("SAVE", slow[1].Arguments[0]); -// Assert.AreEqual("http://redis.io/commands/save", slow[1].GetHelpUrl()); -// } -// } - -// [Test] -// public void TestTime() -// { -// using (var db = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// Assert.IsNotNull(db.Features); // we waited, after all -// if (db.Features.Time) -// { -// var local = DateTime.UtcNow; -// var server = db.Wait(db.Server.Time()); - -// Assert.True(Math.Abs((local - server).TotalMilliseconds) < 10); - -// } -// } -// } - -// [Test] -// public void TestTimeWithExplicitVersion() -// { -// using (var db = Config.GetUnsecuredConnection(open: false)) -// { -// db.SetServerVersion(new Version("2.6.9"), ServerType.Master); -// db.SetKeepAlive(10); -// Assert.IsNotNull(db.Features, "Features"); // we waited, after all -// Assert.IsTrue(db.Features.ClientName, "ClientName"); -// Assert.IsTrue(db.Features.Time, "Time"); -// db.Name = "FooFoo"; -// db.Wait(db.Open()); - -// var local = DateTime.UtcNow; -// var server = db.Wait(db.Server.Time()); - -// Assert.True(Math.Abs((local - server).TotalMilliseconds) < 10, "Latency"); -// } -// } - -// [Test, ExpectedException(typeof(TimeoutException), ExpectedMessage = "The operation has timed out; the connection is not open")] -// public void TimeoutMessageNotOpened() -// { -// using (var conn = Config.GetUnsecuredConnection(open: false)) -// { -// conn.Wait(conn.Strings.Get(0, "abc")); -// } -// } - -// [Test, ExpectedException(typeof(TimeoutException), ExpectedMessage = "The operation has timed out.")] -// public void TimeoutMessageNoDetail() -// { -// using (var conn = Config.GetUnsecuredConnection(open: true)) -// { -// conn.IncludeDetailInTimeouts = false; -// conn.Keys.Remove(0, "noexist"); -// conn.Lists.BlockingRemoveFirst(0, new[] { "noexist" }, 5); -// conn.Wait(conn.Strings.Get(0, "abc")); -// } -// } - -// [Test, ExpectedException(typeof(TimeoutException), ExpectedMessage = "The operation has timed out; possibly blocked by: 0: BLPOP \"noexist\" 5")] -// public void TimeoutMessageWithDetail() -// { -// using (var conn = Config.GetUnsecuredConnection(open: true, waitForOpen: true)) -// { -// conn.IncludeDetailInTimeouts = true; -// conn.Keys.Remove(0, "noexist"); -// conn.Lists.BlockingRemoveFirst(0, new[] { "noexist" }, 5); -// conn.Wait(conn.Strings.Get(0, "abc")); -// } -// } - -// [Test] -// public void ClientList() -// { -// using (var killMe = Config.GetUnsecuredConnection()) -// using (var conn = Config.GetUnsecuredConnection(allowAdmin: true)) -// { -// killMe.Wait(killMe.Strings.GetString(7, "kill me quick")); -// var clients = conn.Wait(conn.Server.ListClients()); -// var target = clients.Single(x => x.Database == 7); -// conn.Wait(conn.Server.KillClient(target.Address)); -// Assert.IsTrue(clients.Length > 0); - -// try -// { -// killMe.Wait(killMe.Strings.GetString(7, "kill me quick")); -// Assert.Fail("Should have been dead"); -// } -// catch (Exception) { } -// } -// } - -// [Test] -// public void HappilyMurderedClientDoesntGetError() -// { -// using (var victim = Config.GetUnsecuredConnection(waitForOpen: true)) -// using (var murderer = Config.GetUnsecuredConnection(allowAdmin: true)) -// { -// const int VictimDB = 4; -// victim.Wait(victim.Strings.GetString(VictimDB, "kill me quick")); -// victim.CompletionMode = ResultCompletionMode.PreserveOrder; -// var clients = murderer.Wait(murderer.Server.ListClients()); -// var target = clients.Single(x => x.Database == VictimDB); - -// int i = 0; -// victim.Closed += (s, a) => -// { -// Interlocked.Increment(ref i); -// }; -// var errors = new List(); -// victim.Shutdown += (s, a) => -// { -// if (a.Exception != null) -// { -// lock (errors) -// { -// errors.Add(a.Exception); -// } -// } -// }; -// victim.Error += (s, a) => -// { -// lock (errors) -// { -// errors.Add(a.Exception); -// } -// }; -// victim.Wait(victim.Server.Ping()); -// murderer.Wait(murderer.Server.KillClient(target.Address)); - -// PubSub.AllowReasonableTimeToPublishAndProcess(); - -// Assert.AreEqual(1, Interlocked.CompareExchange(ref i, 0, 0)); -// lock(errors) -// { -// foreach (var err in errors) Console.WriteLine(err.Message); -// Assert.AreEqual(0, errors.Count); -// } -// Assert.AreEqual(ShutdownType.ServerClosed, victim.ShutdownType); - - -// } -// } -// [Test] -// public void MurderedClientKnowsAboutIt() -// { -// using (var victim = Config.GetUnsecuredConnection(waitForOpen: true)) -// using (var murderer = Config.GetUnsecuredConnection(allowAdmin: true)) -// { -// const int VictimDB = 3; -// victim.Wait(victim.Strings.GetString(VictimDB, "kill me quick")); -// victim.CompletionMode = ResultCompletionMode.PreserveOrder; -// var clients = murderer.Wait(murderer.Server.ListClients()); -// var target = clients.Single(x => x.Database == VictimDB); - -// object sync = new object(); -// ErrorEventArgs args = null; -// Exception ex = null; -// ManualResetEvent shutdownGate = new ManualResetEvent(false), -// exGate = new ManualResetEvent(false); -// victim.Shutdown += (s,a) => -// { -// Console.WriteLine("shutdown"); -// Interlocked.Exchange(ref args, a); -// shutdownGate.Set(); -// }; -// lock (sync) -// { -// ThreadPool.QueueUserWorkItem(x => -// { -// try -// { - -// for (int i = 0; i < 50000; i++) -// { -// if (i == 5) lock (sync) { Monitor.PulseAll(sync); } -// victim.Wait(victim.Strings.Set(VictimDB, "foo", "foo")); -// } -// } -// catch(Exception ex2) -// { -// Console.WriteLine("ex"); -// Interlocked.Exchange(ref ex, ex2); -// exGate.Set(); -// } -// }, null); -// // want the other thread to be running -// Monitor.Wait(sync); -// Console.WriteLine("got pulse; victim is ready"); -// } - -// Console.WriteLine("killing " + target.Address); -// murderer.Wait(murderer.Server.KillClient(target.Address)); - -// Console.WriteLine("waiting on gates..."); -// Assert.IsTrue(shutdownGate.WaitOne(10000), "shutdown gate"); -// Assert.IsTrue(exGate.WaitOne(10000), "exception gate"); -// Console.WriteLine("gates passed"); - -// Assert.AreEqual(ShutdownType.ServerClosed, victim.ShutdownType); -// var args_final = Interlocked.Exchange(ref args, null); -// var ex_final = Interlocked.Exchange(ref ex, null); -// Assert.IsNotNull(ex_final, "ex"); -// Assert.IsNotNull(args_final, "args"); -// } -// } - -// [Test] -// public void CleanCloseKnowsReason() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// conn.Wait(conn.Server.Ping()); -// conn.Close(false); -// Assert.AreEqual(ShutdownType.ClientClosed, conn.ShutdownType); -// } -// } -// [Test] -// public void DisposeKnowsReason() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// conn.Wait(conn.Server.Ping()); -// conn.Dispose(); -// Assert.AreEqual(ShutdownType.ClientDisposed, conn.ShutdownType); -// } -// } - -// [Test] -// public void TestLastSentCounter() -// { -// using (var db = Config.GetUnsecuredConnection(open: false)) -// { -// db.SetServerVersion(new Version("2.6.0"), ServerType.Master); -// db.SetKeepAlive(0); // turn off keep-alives so we don't get unexpected pings - -// db.Wait(db.Open()); -// db.Wait(db.Server.Ping()); -// var first = db.GetCounters(false); -// Assert.LessOrEqual(0, 1, "0 <= 1"); -// Assert.LessOrEqual(first.LastSentMillisecondsAgo, 100, "first"); - -// Thread.Sleep(2000); -// var second = db.GetCounters(false); -// Assert.GreaterOrEqual(1, 0, "1 >= 0"); -// Assert.GreaterOrEqual(second.LastSentMillisecondsAgo, 1900, "second"); -// Assert.LessOrEqual(second.LastSentMillisecondsAgo, 2100, "second"); - -// db.Wait(db.Server.Ping()); -// var third = db.GetCounters(false); -// Assert.LessOrEqual(0, 1, "0 <= 1"); -// Assert.LessOrEqual(third.LastSentMillisecondsAgo, 100, "third"); -// } -// } - -// [Test] -// public void TestKeepAlive() -// { -// string oldValue = null; -// try -// { -// using (var db = Config.GetUnsecuredConnection(allowAdmin: true)) -// { -// oldValue = db.Wait(db.Server.GetConfig("timeout")).Single().Value; -// db.Server.SetConfig("timeout", "20"); -// } -// using (var db = Config.GetUnsecuredConnection(allowAdmin: false, waitForOpen:true)) -// { -// var before = db.GetCounters(false); -// Assert.AreEqual(4, before.KeepAliveSeconds, "keep-alive"); -// Thread.Sleep(13 * 1000); -// var after = db.GetCounters(false); -// // 3 here is 2 * keep-alive, and one PING in GetCounters() -// int sent = after.MessagesSent - before.MessagesSent; -// Assert.GreaterOrEqual(1, 0); -// Assert.GreaterOrEqual(sent, 3); -// Assert.LessOrEqual(0, 4); -// Assert.LessOrEqual(sent, 4); -// } -// } -// finally -// { -// if (oldValue != null) -// { -// Task t; -// using (var db = Config.GetUnsecuredConnection(allowAdmin: true)) -// { -// t = db.Server.SetConfig("timeout", oldValue); -// } -// Assert.IsTrue(t.Wait(5000)); -// if (t.Exception != null) throw t.Exception; -// } -// } -// } - -// [Test, ActiveTest] -// public void SetValueWhileDisposing() -// { -// const int LOOP = 10; -// for (int i = 0; i < LOOP; i++) -// { -// var guid = Config.CreateUniqueName(); -// Task t1, t3; -// Task t2; -// string key = "SetValueWhileDisposing:" + i; -// using (var db = Config.GetUnsecuredConnection(open: true)) -// { -// t1 = db.Strings.Set(0, key, guid); -// } -// Assert.IsTrue(t1.Wait(500)); -// using (var db = Config.GetUnsecuredConnection()) -// { -// t2 = db.Strings.GetString(0, key); -// t3 = db.Keys.Remove(0, key); -// } -// Assert.IsTrue(t2.Wait(500)); -// Assert.AreEqual(guid, t2.Result); -// Assert.IsTrue(t3.Wait(500)); -// } -// } - -// [Test] -// public void TestMasterSlaveSetup() -// { -// using (var unsec = Config.GetUnsecuredConnection(true, true, true)) -// using (var sec = Config.GetUnsecuredConnection(true, true, true)) -// { -// try -// { -// var makeSlave = sec.Server.MakeSlave(unsec.Host, unsec.Port); -// var info = sec.Wait(sec.Server.GetInfo()); -// sec.Wait(makeSlave); -// Assert.AreEqual("slave", info["role"], "slave"); -// Assert.AreEqual(unsec.Host, info["master_host"], "host"); -// Assert.AreEqual(unsec.Port.ToString(), info["master_port"], "port"); -// var makeMaster = sec.Server.MakeMaster(); -// info = sec.Wait(sec.Server.GetInfo()); -// sec.Wait(makeMaster); -// Assert.AreEqual("master", info["role"], "master"); -// } -// finally -// { -// sec.Server.MakeMaster(); -// } - -// } -// } -// } -//} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Sets.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Sets.cs deleted file mode 100644 index 37fc64b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Sets.cs +++ /dev/null @@ -1,513 +0,0 @@ -//using System; -//using NUnit.Framework; -//using System.Text; -//using System.Linq; -//namespace Tests -//{ -// [TestFixture] -// public class Sets // http://redis.io/commands#set -// { -// [Test] -// public void AddSingle() -// { -// using(var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "set"); -// var r0 = conn.Sets.Add(3, "set", "abc"); -// var r1 = conn.Sets.Add(3, "set", "abc"); -// var len = conn.Sets.GetLength(3, "set"); - -// Assert.AreEqual(true, r0.Result); -// Assert.AreEqual(false, r1.Result); -// Assert.AreEqual(1, len.Result); -// } -// } -// [Test] -// public void Scan() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// if (!conn.Features.Scan) Assert.Inconclusive(); - -// const int db = 3; -// const string key = "set-scan"; -// conn.Keys.Remove(db, key); -// conn.Sets.Add(db, key, "abc"); -// conn.Sets.Add(db, key, "def"); -// conn.Sets.Add(db, key, "ghi"); - -// var t1 = conn.Sets.Scan(db, key); -// var t3 = conn.Sets.ScanString(db, key); -// var t4 = conn.Sets.ScanString(db, key, "*h*"); - -// var v1 = t1.ToArray(); -// var v3 = t3.ToArray(); -// var v4 = t4.ToArray(); - -// Assert.AreEqual(3, v1.Length); -// Assert.AreEqual(3, v3.Length); -// Assert.AreEqual(1, v4.Length); -// Array.Sort(v1, (x, y) => string.Compare(Encoding.UTF8.GetString(x), Encoding.UTF8.GetString(y))); -// Array.Sort(v3); -// Array.Sort(v4); - -// Assert.AreEqual("abc,def,ghi", string.Join(",", v1.Select(x => Encoding.UTF8.GetString(x)))); -// Assert.AreEqual("abc,def,ghi", string.Join(",", v3)); -// Assert.AreEqual("ghi", string.Join(",", v4)); -// } -// } -// [Test] -// public void AddSingleBinary() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "set"); -// var r0 = conn.Sets.Add(3, "set", Encode("abc")); -// var r1 = conn.Sets.Add(3, "set", Encode("abc")); -// var len = conn.Sets.GetLength(3, "set"); - -// Assert.AreEqual(true, r0.Result); -// Assert.AreEqual(false, r1.Result); -// Assert.AreEqual(1, len.Result); -// } -// } -// static byte[] Encode(string value) { return Encoding.UTF8.GetBytes(value); } -// static string Decode(byte[] value) { return Encoding.UTF8.GetString(value); } -// [Test] -// public void RemoveSingle() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "set"); -// conn.Sets.Add(3, "set", "abc"); -// conn.Sets.Add(3, "set", "def"); - -// var r0 = conn.Sets.Remove(3, "set", "abc"); -// var r1 = conn.Sets.Remove(3, "set", "abc"); -// var len = conn.Sets.GetLength(3, "set"); - -// Assert.AreEqual(true, r0.Result); -// Assert.AreEqual(false, r1.Result); -// Assert.AreEqual(1, len.Result); -// } -// } - -// [Test] -// public void RemoveSingleBinary() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "set"); -// conn.Sets.Add(3, "set", Encode("abc")); -// conn.Sets.Add(3, "set", Encode("def")); - -// var r0 = conn.Sets.Remove(3, "set", Encode("abc")); -// var r1 = conn.Sets.Remove(3, "set", Encode("abc")); -// var len = conn.Sets.GetLength(3, "set"); - -// Assert.AreEqual(true, r0.Result); -// Assert.AreEqual(false, r1.Result); -// Assert.AreEqual(1, len.Result); -// } -// } - -// [Test] -// public void AddMulti() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// conn.Keys.Remove(3, "set"); -// var r0 = conn.Sets.Add(3, "set", "abc"); -// var r1 = conn.Sets.Add(3, "set", new[] {"abc", "def"}); -// var len = conn.Sets.GetLength(3, "set"); - -// Assert.AreEqual(true, r0.Result); -// Assert.AreEqual(1, r1.Result); -// Assert.AreEqual(2, len.Result); -// } -// } - -// [Test] -// public void RemoveMulti() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// conn.Keys.Remove(3, "set"); -// conn.Sets.Add(3, "set", "abc"); -// conn.Sets.Add(3, "set", "ghi"); - -// var r0 = conn.Sets.Remove(3, "set", new[] {"abc", "def"}); -// var len = conn.Sets.GetLength(3, "set"); - -// Assert.AreEqual(1, r0.Result); -// Assert.AreEqual(1, len.Result); -// } -// } - -// [Test] -// public void AddMultiBinary() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen:true)) -// { -// conn.Keys.Remove(3, "set"); -// var r0 = conn.Sets.Add(3, "set", Encode("abc")); -// var r1 = conn.Sets.Add(3, "set", new[] { Encode("abc"), Encode("def") }); -// var len = conn.Sets.GetLength(3, "set"); - -// Assert.AreEqual(true, r0.Result); -// Assert.AreEqual(1, r1.Result); -// Assert.AreEqual(2, len.Result); -// } -// } - -// [Test] -// public void RemoveMultiBinary() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// conn.Keys.Remove(3, "set"); -// conn.Sets.Add(3, "set", Encode("abc")); -// conn.Sets.Add(3, "set", Encode("ghi")); - -// var r0 = conn.Sets.Remove(3, "set", new[] { Encode("abc"), Encode("def") }); -// var len = conn.Sets.GetLength(3, "set"); - -// Assert.AreEqual(1, r0.Result); -// Assert.AreEqual(1, len.Result); -// } -// } - -// [Test] -// public void Exists() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "set"); -// var r0 = conn.Sets.Contains(3, "set", "def"); - -// conn.Sets.Add(3, "set", "abc"); -// var r1 = conn.Sets.Contains(3, "set", "def"); - -// conn.Sets.Add(3, "set", "def"); -// var r2 = conn.Sets.Contains(3, "set", "def"); - -// conn.Sets.Remove(3, "set", "def"); -// var r3 = conn.Sets.Contains(3, "set", "def"); - -// Assert.AreEqual(false, r0.Result); -// Assert.AreEqual(false, r1.Result); -// Assert.AreEqual(true, r2.Result); -// Assert.AreEqual(false, r3.Result); -// } -// } - - -// [Test] -// public void ExistsBinary() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "set"); -// var r0 = conn.Sets.Contains(3, "set", Encode("def")); - -// conn.Sets.Add(3, "set", "abc"); -// var r1 = conn.Sets.Contains(3, "set", Encode("def")); - -// conn.Sets.Add(3, "set", "def"); -// var r2 = conn.Sets.Contains(3, "set", Encode("def")); - -// conn.Sets.Remove(3, "set", "def"); -// var r3 = conn.Sets.Contains(3, "set", Encode("def")); - -// Assert.AreEqual(false, r0.Result); -// Assert.AreEqual(false, r1.Result); -// Assert.AreEqual(true, r2.Result); -// Assert.AreEqual(false, r3.Result); -// } -// } - -// [Test] -// public void GetRandom() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "set"); - -// Assert.IsNull(conn.Sets.GetRandomString(3, "set").Result); -// Assert.IsNull(conn.Sets.GetRandom(3, "set").Result); - -// conn.Sets.Add(3, "set", "abc"); -// Assert.AreEqual("abc", conn.Sets.GetRandomString(3, "set").Result); -// Assert.AreEqual("abc", Decode(conn.Sets.GetRandom(3, "set").Result)); - -// conn.Sets.Add(3, "set", Encode("def")); -// var result = conn.Sets.GetRandomString(3, "set").Result; -// Assert.IsTrue(result == "abc" || result == "def"); -// result = Decode(conn.Sets.GetRandom(3, "set").Result); -// Assert.IsTrue(result == "abc" || result == "def"); -// } -// } - -// [Test] -// public void GetRandomMulti() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// if (conn.Features.MultipleRandom) -// { -// conn.Keys.Remove(3, "set"); - -// Assert.AreEqual(0, conn.Sets.GetRandomString(3, "set", 2).Result.Length); -// Assert.AreEqual(0, conn.Sets.GetRandom(3, "set", 2).Result.Length); - -// conn.Sets.Add(3, "set", "abc"); -// var a1 = conn.Sets.GetRandomString(3, "set", 2).Result; -// var a2 = conn.Sets.GetRandom(3, "set", 2).Result; -// Assert.AreEqual(1, a1.Length); -// Assert.AreEqual(1, a2.Length); -// Assert.AreEqual("abc", a1[0]); -// Assert.AreEqual("abc", Decode(a2[0])); - -// conn.Sets.Add(3, "set", Encode("def")); -// var a3 = conn.Sets.GetRandomString(3, "set", 3).Result; -// var a4 = Array.ConvertAll(conn.Sets.GetRandom(3, "set", 3).Result, Decode); - -// Assert.AreEqual(2, a3.Length); -// Assert.AreEqual(2, a4.Length); -// Assert.Contains("abc", a3); -// Assert.Contains("def", a3); -// Assert.Contains("abc", a4); -// Assert.Contains("def", a4); - -// var a5 = conn.Sets.GetRandomString(3, "set", -3).Result; -// var a6 = Array.ConvertAll(conn.Sets.GetRandom(3, "set", -3).Result, Decode); -// Assert.AreEqual(3, a5.Length); -// Assert.AreEqual(3, a6.Length); -// Assert.IsTrue(a5.All(x => x == "abc" || x == "def")); -// Assert.IsTrue(a6.All(x => x == "abc" || x == "def")); -// } -// } -// } - -// [Test] -// public void RemoveRandom() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "set"); - -// Assert.IsNull(conn.Sets.RemoveRandomString(3, "set").Result); -// Assert.IsNull(conn.Sets.RemoveRandom(3, "set").Result); - -// conn.Sets.Add(3, "set", "abc"); -// Assert.AreEqual("abc", conn.Sets.RemoveRandomString(3, "set").Result); -// Assert.AreEqual(0, conn.Sets.GetLength(3, "set").Result); - -// conn.Sets.Add(3, "set", "abc"); -// Assert.AreEqual("abc", Decode(conn.Sets.RemoveRandom(3, "set").Result)); -// Assert.AreEqual(0, conn.Sets.GetLength(3, "set").Result); - -// conn.Sets.Add(3, "set", "abc"); -// conn.Sets.Add(3, "set", Encode("def")); -// var result1 = conn.Sets.RemoveRandomString(3, "set").Result; -// var result2 = Decode(conn.Sets.RemoveRandom(3, "set").Result); -// Assert.AreEqual(0, conn.Sets.GetLength(3, "set").Result); - -// Assert.AreNotEqual(result1, result2); -// Assert.IsTrue(result1 == "abc" || result1 == "def"); -// Assert.IsTrue(result2 == "abc" || result2 == "def"); -// } -// } - -// [Test] -// public void GetAll() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "set"); - -// var b0 = conn.Sets.GetAll(3, "set"); -// var s0 = conn.Sets.GetAllString(3, "set"); -// conn.Sets.Add(3, "set", "abc"); -// conn.Sets.Add(3, "set", "def"); -// var b1 = conn.Sets.GetAll(3, "set"); -// var s1 = conn.Sets.GetAllString(3, "set"); - -// Assert.AreEqual(0, conn.Wait(b0).Length); -// Assert.AreEqual(0, conn.Wait(s0).Length); -// // check strings -// var s = conn.Wait(s1); -// Assert.AreEqual(2, s.Length); -// Array.Sort(s); -// Assert.AreEqual("abc", s[0]); -// Assert.AreEqual("def", s[1]); -// // check binary -// s = Array.ConvertAll(conn.Wait(b1), Decode); -// Assert.AreEqual(2, s.Length); -// Array.Sort(s); -// Assert.AreEqual("abc", s[0]); -// Assert.AreEqual("def", s[1]); -// } -// } - -// [Test] -// public void Move() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "from"); -// conn.Keys.Remove(3, "to"); -// conn.Sets.Add(3, "from", "abc"); -// conn.Sets.Add(3, "from", "def"); - -// Assert.AreEqual(2, conn.Sets.GetLength(3, "from").Result); -// Assert.AreEqual(0, conn.Sets.GetLength(3, "to").Result); - -// Assert.IsFalse(conn.Sets.Move(3, "from", "to", "nix").Result); -// Assert.IsFalse(conn.Sets.Move(3, "from", "to", Encode("nix")).Result); - -// Assert.IsTrue(conn.Sets.Move(3, "from", "to", "abc").Result); -// Assert.IsTrue(conn.Sets.Move(3, "from", "to", Encode("def")).Result); - -// Assert.AreEqual(0, conn.Sets.GetLength(3, "from").Result); -// Assert.AreEqual(2, conn.Sets.GetLength(3, "to").Result); -// } -// } - -// [Test] -// public void Diff() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "key1"); -// conn.Keys.Remove(3, "key2"); -// conn.Keys.Remove(3, "key3"); -// conn.Keys.Remove(3, "to"); -// conn.Sets.Add(3, "key1", "a"); -// conn.Sets.Add(3, "key1", "b"); -// conn.Sets.Add(3, "key1", "c"); -// conn.Sets.Add(3, "key1", "d"); -// conn.Sets.Add(3, "key2", "c"); -// conn.Sets.Add(3, "key3", "a"); -// conn.Sets.Add(3, "key3", "c"); -// conn.Sets.Add(3, "key3", "e"); - -// var diff1 = conn.Sets.Difference(3, new[] {"key1", "key2", "key3"}); -// var diff2 = conn.Sets.DifferenceString(3, new[] { "key1", "key2", "key3" }); -// var len = conn.Sets.DifferenceAndStore(3, "to", new[] { "key1", "key2", "key3" }); -// var diff3 = conn.Sets.GetAllString(3, "to"); - -// var s = Array.ConvertAll(conn.Wait(diff1), Decode); -// Assert.AreEqual(2, s.Length); -// Array.Sort(s); -// Assert.AreEqual("b", s[0]); -// Assert.AreEqual("d", s[1]); - -// s = conn.Wait(diff2); -// Assert.AreEqual(2, s.Length); -// Array.Sort(s); -// Assert.AreEqual("b", s[0]); -// Assert.AreEqual("d", s[1]); - -// Assert.AreEqual(2, conn.Wait(len)); -// s = conn.Wait(diff3); -// Assert.AreEqual(2, s.Length); -// Array.Sort(s); -// Assert.AreEqual("b", s[0]); -// Assert.AreEqual("d", s[1]); -// } -// } - - -// [Test] -// public void Intersect() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "key1"); -// conn.Keys.Remove(3, "key2"); -// conn.Keys.Remove(3, "key3"); -// conn.Keys.Remove(3, "to"); -// conn.Sets.Add(3, "key1", "a"); -// conn.Sets.Add(3, "key1", "b"); -// conn.Sets.Add(3, "key1", "c"); -// conn.Sets.Add(3, "key1", "d"); -// conn.Sets.Add(3, "key2", "c"); -// conn.Sets.Add(3, "key3", "a"); -// conn.Sets.Add(3, "key3", "c"); -// conn.Sets.Add(3, "key3", "e"); - -// var diff1 = conn.Sets.Intersect(3, new[] { "key1", "key2", "key3" }); -// var diff2 = conn.Sets.IntersectString(3, new[] { "key1", "key2", "key3" }); -// var len = conn.Sets.IntersectAndStore(3, "to", new[] { "key1", "key2", "key3" }); -// var diff3 = conn.Sets.GetAllString(3, "to"); - -// var s = Array.ConvertAll(conn.Wait(diff1), Decode); -// Assert.AreEqual(1, s.Length); -// Assert.AreEqual("c", s[0]); - -// s = conn.Wait(diff2); -// Assert.AreEqual(1, s.Length); -// Assert.AreEqual("c", s[0]); - -// Assert.AreEqual(1, conn.Wait(len)); -// s = conn.Wait(diff3); -// Assert.AreEqual(1, s.Length); -// Assert.AreEqual("c", s[0]); -// } -// } - -// [Test] -// public void Union() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "key1"); -// conn.Keys.Remove(3, "key2"); -// conn.Keys.Remove(3, "key3"); -// conn.Keys.Remove(3, "to"); -// conn.Sets.Add(3, "key1", "a"); -// conn.Sets.Add(3, "key1", "b"); -// conn.Sets.Add(3, "key1", "c"); -// conn.Sets.Add(3, "key1", "d"); -// conn.Sets.Add(3, "key2", "c"); -// conn.Sets.Add(3, "key3", "a"); -// conn.Sets.Add(3, "key3", "c"); -// conn.Sets.Add(3, "key3", "e"); - -// var diff1 = conn.Sets.Union(3, new[] { "key1", "key2", "key3" }); -// var diff2 = conn.Sets.UnionString(3, new[] { "key1", "key2", "key3" }); -// var len = conn.Sets.UnionAndStore(3, "to", new[] { "key1", "key2", "key3" }); -// var diff3 = conn.Sets.GetAllString(3, "to"); - -// var s = Array.ConvertAll(conn.Wait(diff1), Decode); -// Assert.AreEqual(5, s.Length); -// Array.Sort(s); -// Assert.AreEqual("a", s[0]); -// Assert.AreEqual("b", s[1]); -// Assert.AreEqual("c", s[2]); -// Assert.AreEqual("d", s[3]); -// Assert.AreEqual("e", s[4]); - -// s = conn.Wait(diff2); -// Assert.AreEqual(5, s.Length); -// Array.Sort(s); -// Assert.AreEqual("a", s[0]); -// Assert.AreEqual("b", s[1]); -// Assert.AreEqual("c", s[2]); -// Assert.AreEqual("d", s[3]); -// Assert.AreEqual("e", s[4]); - -// Assert.AreEqual(5, conn.Wait(len)); -// s = conn.Wait(diff3); -// Assert.AreEqual(5, s.Length); -// Array.Sort(s); -// Assert.AreEqual("a", s[0]); -// Assert.AreEqual("b", s[1]); -// Assert.AreEqual("c", s[2]); -// Assert.AreEqual("d", s[3]); -// Assert.AreEqual("e", s[4]); -// } -// } -// } -//} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/SortedSets.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/SortedSets.cs deleted file mode 100644 index 55d40a9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/SortedSets.cs +++ /dev/null @@ -1,376 +0,0 @@ -//using System.Linq; -//using NUnit.Framework; -//using System; -//using System.Text; -//using BookSleeve; -//using System.Collections.Generic; -//using System.Threading.Tasks; - -//namespace Tests -//{ -// [TestFixture] -// public class SortedSets // http://redis.io/commands#sorted_set -// { -// [Test] -// public void SortedTrim() -// { -// using(var conn = Config.GetUnsecuredConnection()) -// { -// const int db = 0; -// const string key = "sorted-trim"; -// for(int i = 0; i < 200; i++) -// { -// conn.SortedSets.Add(db, key, i.ToString(), i); -// } -// conn.SortedSets.RemoveRange(db, key, 0, -21); -// var count = conn.SortedSets.GetLength(db, key); -// Assert.AreEqual(20, conn.Wait(count)); -// } -// } - -// [Test] -// public void Scan() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen:true)) -// { -// if (!conn.Features.Scan) Assert.Inconclusive(); - -// const int db = 3; -// const string key = "sorted-set-scan"; -// conn.Keys.Remove(db, key); -// conn.SortedSets.Add(db, key, "abc", 1); -// conn.SortedSets.Add(db, key, "def", 2); -// conn.SortedSets.Add(db, key, "ghi", 3); - -// var t1 = conn.SortedSets.Scan(db, key); -// var t3 = conn.SortedSets.ScanString(db, key); -// var t4 = conn.SortedSets.ScanString(db, key, "*h*"); - -// var v1 = t1.ToArray(); -// var v3 = t3.ToArray(); -// var v4 = t4.ToArray(); - -// Assert.AreEqual(3, v1.Length); -// Assert.AreEqual(3, v3.Length); -// Assert.AreEqual(1, v4.Length); -// Array.Sort(v1, (x, y) => string.Compare(Encoding.UTF8.GetString(x.Key), Encoding.UTF8.GetString(y.Key))); -// Array.Sort(v3, (x, y) => string.Compare(x.Key, y.Key)); -// Array.Sort(v4, (x, y) => string.Compare(x.Key, y.Key)); - -// Assert.AreEqual("abc=1,def=2,ghi=3", string.Join(",", v1.Select(pair => Encoding.UTF8.GetString(pair.Key) + "=" + pair.Value))); -// Assert.AreEqual("abc=1,def=2,ghi=3", string.Join(",", v3.Select(pair => pair.Key + "=" + pair.Value))); -// Assert.AreEqual("ghi=3", string.Join(",", v4.Select(pair => pair.Key + "=" + pair.Value))); -// } -// } -// [Test] -// public void Range() // http://code.google.com/p/booksleeve/issues/detail?id=12 -// { -// using(var conn = Config.GetUnsecuredConnection()) -// { -// const double value = 634614442154715; -// conn.SortedSets.Add(3, "zset", "abc", value); -// var range = conn.SortedSets.Range(3, "zset", 0, -1); - -// Assert.AreEqual(value, conn.Wait(range).Single().Value); -// } -// } -// [Test] -// public void RangeString() // http://code.google.com/p/booksleeve/issues/detail?id=18 -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// const double value = 634614442154715; -// conn.SortedSets.Add(3, "zset", "abc", value); -// var range = conn.SortedSets.RangeString(3, "zset", 0, -1); - -// Assert.AreEqual(value, conn.Wait(range).Single().Value); -// } -// } - -// [Test] -// public void Score() // http://code.google.com/p/booksleeve/issues/detail?id=23 -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(0, "abc"); -// conn.SortedSets.Add(0, "abc", "def", 1.0); -// var s1 = conn.SortedSets.Score(0, "abc", "def"); -// var s2 = conn.SortedSets.Score(0, "abc", "ghi"); - -// Assert.AreEqual(1.0, conn.Wait(s1)); -// Assert.IsNull(conn.Wait(s2)); -// } -// } - -// [Test] -// public void Rank() // http://code.google.com/p/booksleeve/issues/detail?id=23 -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(0, "abc"); -// conn.SortedSets.Add(0, "abc", "def", 1.0); -// conn.SortedSets.Add(0, "abc", "jkl", 2.0); -// var a1 = conn.SortedSets.Rank(0, "abc", "def", ascending: true); -// var a2 = conn.SortedSets.Rank(0, "abc", "ghi", ascending: true); -// var a3 = conn.SortedSets.Rank(0, "abc", "jkl", ascending: true); - -// var d1 = conn.SortedSets.Rank(0, "abc", "def", ascending: false); -// var d2 = conn.SortedSets.Rank(0, "abc", "ghi", ascending: false); -// var d3 = conn.SortedSets.Rank(0, "abc", "jkl", ascending: false); - -// Assert.AreEqual(0, conn.Wait(a1)); -// Assert.IsNull(conn.Wait(a2)); -// Assert.AreEqual(1, conn.Wait(a3)); - -// Assert.AreEqual(1, conn.Wait(d1)); -// Assert.IsNull(conn.Wait(d2)); -// Assert.AreEqual(0, conn.Wait(d3)); -// } -// } - -// static string SeedRange(RedisConnection connection, out double min, out double max) -// { -// var rand = new Random(123456); -// const string key = "somerange"; -// connection.Keys.Remove(0, key); -// min = max = 0; -// for (int i = 0; i < 50; i++) -// { -// double value = rand.NextDouble(); -// if (i == 0) -// { -// min = max = value; -// } -// else -// { -// if (value < min) min = value; -// if (value > max) max= value; -// } -// connection.SortedSets.Add(0, key, "item " + i, value); -// } -// return key; -// } -// [Test] -// public void GetAll() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// double minActual, maxActual; -// string key = SeedRange(conn, out minActual, out maxActual); - -// var all = conn.Wait(conn.SortedSets.Range(0, key, 0.0, 1.0)); -// Assert.AreEqual(50, all.Length, "all between 0.0 and 1.0"); - -// var subset = conn.Wait(conn.SortedSets.Range(0, key, 0.0, 1.0, offset: 2, count: 46)); -// Assert.AreEqual(46, subset.Length); - -// var subVals = new HashSet(subset.Select(x => x.Value)); - -// Assert.IsFalse(subVals.Contains(all[0].Value)); -// Assert.IsFalse(subVals.Contains(all[1].Value)); -// Assert.IsFalse(subVals.Contains(all[48].Value)); -// Assert.IsFalse(subVals.Contains(all[49].Value)); -// for (int i = 2; i < 48; i++) -// { -// Assert.IsTrue(subVals.Contains(all[i].Value)); -// } -// } -// } - -// [Test] -// public void FindMinMax() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// double minActual, maxActual; -// string key = SeedRange(conn, out minActual, out maxActual); - -// var min = conn.SortedSets.Range(0, key, ascending: true, count: 1); -// var max = conn.SortedSets.Range(0, key, ascending: false, count: 1); - -// var minScore = conn.Wait(min).Single().Value; -// var maxScore = conn.Wait(max).Single().Value; - -// Assert.Less(1, 2); // I *always* get these args the wrong way around -// Assert.Less(Math.Abs(minActual - minScore), 0.0000001, "min"); -// Assert.Less(Math.Abs(maxActual - maxScore), 0.0000001, "max"); -// } -// } - -// [Test] -// public void CheckInfinity() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(0, "infs"); -// conn.SortedSets.Add(0, "infs", "neg", double.NegativeInfinity); -// conn.SortedSets.Add(0, "infs", "pos", double.PositiveInfinity); -// conn.SortedSets.Add(0, "infs", "zero", 0.0); -// var pairs = conn.Wait(conn.SortedSets.RangeString(0, "infs", 0, -1)); -// Assert.AreEqual(3, pairs.Length); -// Assert.AreEqual("neg", pairs[0].Key); -// Assert.AreEqual("zero", pairs[1].Key); -// Assert.AreEqual("pos", pairs[2].Key); -// Assert.IsTrue(double.IsNegativeInfinity(pairs[0].Value), "-inf"); -// Assert.AreEqual(0.0, pairs[1].Value); -// Assert.IsTrue(double.IsPositiveInfinity(pairs[2].Value), "+inf"); -// } -// } - -// [Test] -// public void UnionAndStore() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "key1"); -// conn.Keys.Remove(3, "key2"); -// conn.Keys.Remove(3, "to"); - -// conn.SortedSets.Add(3, "key1", "a", 1); -// conn.SortedSets.Add(3, "key1", "b", 2); -// conn.SortedSets.Add(3, "key1", "c", 3); - -// conn.SortedSets.Add(3, "key2", "a", 1); -// conn.SortedSets.Add(3, "key2", "b", 2); -// conn.SortedSets.Add(3, "key2", "c", 3); - -// var numberOfElementsT = conn.SortedSets.UnionAndStore(3, "to", new string[] { "key1", "key2" }, BookSleeve.RedisAggregate.Sum); -// var resultSetT = conn.SortedSets.RangeString(3, "to", 0, -1); - -// var numberOfElements = conn.Wait(numberOfElementsT); -// Assert.AreEqual(3, numberOfElements); - -// var s = conn.Wait(resultSetT); - -// Assert.AreEqual("a", s[0].Key); -// Assert.AreEqual("b", s[1].Key); -// Assert.AreEqual("c", s[2].Key); - -// Assert.AreEqual(2, s[0].Value); -// Assert.AreEqual(4, s[1].Value); -// Assert.AreEqual(6, s[2].Value); -// } -// } - -// [Test] -// public void UnionAndStoreMax() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "key1"); -// conn.Keys.Remove(3, "key2"); -// conn.Keys.Remove(3, "to"); - -// conn.SortedSets.Add(3, "key1", "a", 1); -// conn.SortedSets.Add(3, "key1", "b", 2); -// conn.SortedSets.Add(3, "key1", "c", 3); - -// conn.SortedSets.Add(3, "key2", "a", 4); -// conn.SortedSets.Add(3, "key2", "b", 5); -// conn.SortedSets.Add(3, "key2", "c", 6); - -// var numberOfElementsT = conn.SortedSets.UnionAndStore(3, "to", new string[] { "key1", "key2" }, BookSleeve.RedisAggregate.Max); -// var resultSetT = conn.SortedSets.RangeString(3, "to", 0, -1); - -// var numberOfElements = conn.Wait(numberOfElementsT); -// Assert.AreEqual(3, numberOfElements); - -// var s = conn.Wait(resultSetT); - -// Assert.AreEqual("a", s[0].Key); -// Assert.AreEqual("b", s[1].Key); -// Assert.AreEqual("c", s[2].Key); - -// Assert.AreEqual(4, s[0].Value); -// Assert.AreEqual(5, s[1].Value); -// Assert.AreEqual(6, s[2].Value); -// } -// } - -// [Test] -// public void UnionAndStoreMin() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(3, "key1"); -// conn.Keys.Remove(3, "key2"); -// conn.Keys.Remove(3, "to"); - -// conn.SortedSets.Add(3, "key1", "a", 1); -// conn.SortedSets.Add(3, "key1", "b", 2); -// conn.SortedSets.Add(3, "key1", "c", 3); - -// conn.SortedSets.Add(3, "key2", "a", 4); -// conn.SortedSets.Add(3, "key2", "b", 5); -// conn.SortedSets.Add(3, "key2", "c", 6); - -// var numberOfElementsT = conn.SortedSets.UnionAndStore(3, "to", new string[] { "key1", "key2" }, BookSleeve.RedisAggregate.Min); -// var resultSetT = conn.SortedSets.RangeString(3, "to", 0, -1); - -// var numberOfElements = conn.Wait(numberOfElementsT); -// Assert.AreEqual(3, numberOfElements); - -// var s = conn.Wait(resultSetT); - -// Assert.AreEqual("a", s[0].Key); -// Assert.AreEqual("b", s[1].Key); -// Assert.AreEqual("c", s[2].Key); - -// Assert.AreEqual(1, s[0].Value); -// Assert.AreEqual(2, s[1].Value); -// Assert.AreEqual(3, s[2].Value); -// } -// } - -// [Test] -// public void TestZUNIONSTORElimit() -// { -// const int SIZE = 10000; -// using (var conn = Config.GetUnsecuredConnection()) -// { -// for (int i = 0; i < SIZE; i++) -// { -// string key = "z_" + i; -// conn.Keys.Remove(0, key); -// for (int j = 0; j < 5; j++) -// conn.SortedSets.Add(0, key, "s" + j.ToString(), j); -// } -// conn.Wait(conn.Server.Ping()); - -// List results = new List(SIZE); -// for (int i = 0; i < SIZE; i+=100) -// { -// string[] keys = Enumerable.Range(0,i+1).Select(x => "z_" + x).ToArray(); -// results.Add(conn.SortedSets.UnionAndStore(0, "zu_" + i, keys, RedisAggregate.Max)); -// } -// foreach (var task in results) -// conn.WaitAll(task); -// } -// } - -// [Test] -// public void SO14991819() -// { -// const int _db = 0; -// const string _thisChannel = "SO14991819"; -// string thisChannel = string.Format("urn:{0}", _thisChannel); -// const string message = "hi"; -// using (var _connection = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// _connection.Keys.Remove(_db, thisChannel); // start from known state - -// TimeSpan span = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)); -// double val = span.TotalSeconds; - -// _connection.SortedSets.Add(_db, thisChannel, message, val, false); - -// var subset = _connection.Wait(_connection.SortedSets.RangeString( -// _db, thisChannel, span.TotalSeconds - 10000, span.TotalSeconds, offset: 0, count: 50)); - -// Assert.AreEqual(1, subset.Length); -// Config.AssertNearlyEqual(val, subset[0].Value); -// Assert.AreEqual(message, subset[0].Key); -// } -// } -// } -//} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Strings.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Strings.cs deleted file mode 100644 index 0674f2a..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Strings.cs +++ /dev/null @@ -1,253 +0,0 @@ -using System.Linq; -using System.Text; -using NUnit.Framework; -using StackExchange.Redis; - -namespace Tests -{ - [TestFixture] - public class Strings // http://redis.io/commands#string - { - [Test] - public void Append() - { - using (var muxer = Config.GetUnsecuredConnection(waitForOpen: true)) - { - var conn = muxer.GetDatabase(2); - var server = Config.GetServer(muxer); - conn.KeyDelete("append"); - var l0 = server.Features.StringLength ? conn.StringLengthAsync("append") : null; - - var s0 = conn.StringGetAsync("append"); - - conn.StringSetAsync("append", "abc"); - var s1 = conn.StringGetAsync("append"); - var l1 = server.Features.StringLength ? conn.StringLengthAsync("append") : null; - - var result = conn.StringAppendAsync("append", Encode("defgh")); - var s3 = conn.StringGetAsync("append"); - var l2 = server.Features.StringLength ? conn.StringLengthAsync("append") : null; - - Assert.AreEqual(null, (string)conn.Wait(s0)); - Assert.AreEqual("abc", (string)conn.Wait(s1)); - Assert.AreEqual(8, conn.Wait(result)); - Assert.AreEqual("abcdefgh", (string)conn.Wait(s3)); - - if (server.Features.StringLength) - { - Assert.AreEqual(0, conn.Wait(l0)); - Assert.AreEqual(3, conn.Wait(l1)); - Assert.AreEqual(8, conn.Wait(l2)); - } - } - } - [Test] - public void Set() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(2); - conn.KeyDeleteAsync("set"); - - conn.StringSetAsync("set", "abc"); - var v1 = conn.StringGetAsync("set"); - - conn.StringSetAsync("set", Encode("def")); - var v2 = conn.StringGetAsync("set"); - - Assert.AreEqual("abc", (string)conn.Wait(v1)); - Assert.AreEqual("def", (string)Decode(conn.Wait(v2))); - } - } - - [Test] - public void SetNotExists() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(2); - conn.KeyDeleteAsync("set"); - conn.KeyDeleteAsync("set2"); - conn.KeyDeleteAsync("set3"); - conn.StringSetAsync("set", "abc"); - - var x0 = conn.StringSetAsync("set", "def", when: When.NotExists); - var x1 = conn.StringSetAsync("set", Encode("def"), when: When.NotExists); - var x2 = conn.StringSetAsync("set2", "def", when: When.NotExists); - var x3 = conn.StringSetAsync("set3", Encode("def"), when: When.NotExists); - - var s0 = conn.StringGetAsync("set"); - var s2 = conn.StringGetAsync("set2"); - var s3 = conn.StringGetAsync("set3"); - - Assert.IsFalse(conn.Wait(x0)); - Assert.IsFalse(conn.Wait(x1)); - Assert.IsTrue(conn.Wait(x2)); - Assert.IsTrue(conn.Wait(x3)); - Assert.AreEqual("abc", (string)conn.Wait(s0)); - Assert.AreEqual("def", (string)conn.Wait(s2)); - Assert.AreEqual("def", (string)conn.Wait(s3)); - } - } - - [Test] - public void Ranges() - { - using (var muxer = Config.GetUnsecuredConnection(waitForOpen: true)) - { - if (!Config.GetFeatures(muxer).StringSetRange) Assert.Inconclusive(); - var conn = muxer.GetDatabase(2); - - conn.KeyDeleteAsync("range"); - - conn.StringSetAsync("range", "abcdefghi"); - conn.StringSetRangeAsync("range", 2, "xy"); - conn.StringSetRangeAsync("range", 4, Encode("z")); - - var val = conn.StringGetAsync("range"); - - Assert.AreEqual("abxyzfghi", (string)conn.Wait(val)); - } - } - - [Test] - public void IncrDecr() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(2); - conn.KeyDeleteAsync("incr"); - - conn.StringSetAsync("incr", "2"); - var v1 = conn.StringIncrementAsync("incr"); - var v2 = conn.StringIncrementAsync("incr", 5); - var v3 = conn.StringIncrementAsync("incr", -2); - var v4 = conn.StringDecrementAsync("incr"); - var v5 = conn.StringDecrementAsync("incr", 5); - var v6 = conn.StringDecrementAsync("incr", -2); - var s = conn.StringGetAsync("incr"); - - Assert.AreEqual(3, conn.Wait(v1)); - Assert.AreEqual(8, conn.Wait(v2)); - Assert.AreEqual(6, conn.Wait(v3)); - Assert.AreEqual(5, conn.Wait(v4)); - Assert.AreEqual(0, conn.Wait(v5)); - Assert.AreEqual(2, conn.Wait(v6)); - Assert.AreEqual("2", (string)conn.Wait(s)); - } - } - [Test] - public void IncrDecrFloat() - { - using (var muxer = Config.GetUnsecuredConnection(waitForOpen: true)) - { - if (!Config.GetFeatures(muxer).IncrementFloat) Assert.Inconclusive(); - var conn = muxer.GetDatabase(2); - conn.KeyDelete("incr"); - - conn.StringSetAsync("incr", "2"); - var v1 = conn.StringIncrementAsync("incr", 1.1); - var v2 = conn.StringIncrementAsync("incr", 5.0); - var v3 = conn.StringIncrementAsync("incr", -2.0); - var v4 = conn.StringIncrementAsync("incr", -1.0); - var v5 = conn.StringIncrementAsync("incr", -5.0); - var v6 = conn.StringIncrementAsync("incr", 2.0); - - var s = conn.StringGetAsync("incr"); - - Config.AssertNearlyEqual(3.1, conn.Wait(v1)); - Config.AssertNearlyEqual(8.1, conn.Wait(v2)); - Config.AssertNearlyEqual(6.1, conn.Wait(v3)); - Config.AssertNearlyEqual(5.1, conn.Wait(v4)); - Config.AssertNearlyEqual(0.1, conn.Wait(v5)); - Config.AssertNearlyEqual(2.1, conn.Wait(v6)); - Assert.AreEqual("2.1", (string)conn.Wait(s)); - } - } - - [Test] - public void GetRange() - { - using (var muxer = Config.GetUnsecuredConnection(waitForOpen: true)) - { - var conn = muxer.GetDatabase(2); - conn.KeyDeleteAsync("range"); - - conn.StringSetAsync("range", "abcdefghi"); - var s = conn.StringGetRangeAsync("range", 2, 4); - var b = conn.StringGetRangeAsync("range", 2, 4); - - Assert.AreEqual("cde", (string)conn.Wait(s)); - Assert.AreEqual("cde", Decode(conn.Wait(b))); - } - } - - [Test] - public void BitCount() - { - using (var muxer = Config.GetUnsecuredConnection(waitForOpen: true)) - { - if (!Config.GetFeatures(muxer).BitwiseOperations) Assert.Inconclusive(); - - var conn = muxer.GetDatabase(0); - conn.StringSetAsync("mykey", "foobar"); - var r1 = conn.StringBitCountAsync("mykey"); - var r2 = conn.StringBitCountAsync("mykey", 0, 0); - var r3 = conn.StringBitCountAsync("mykey", 1, 1); - - Assert.AreEqual(26, conn.Wait(r1)); - Assert.AreEqual(4, conn.Wait(r2)); - Assert.AreEqual(6, conn.Wait(r3)); - } - } - - [Test] - public void BitOp() - { - using (var muxer = Config.GetUnsecuredConnection(waitForOpen: true)) - { - if (!Config.GetFeatures(muxer).BitwiseOperations) Assert.Inconclusive(); - var conn = muxer.GetDatabase(0); - conn.StringSetAsync("key1", new byte[] { 3 }); - conn.StringSetAsync("key2", new byte[] { 6 }); - conn.StringSetAsync("key3", new byte[] { 12 }); - - var len_and = conn.StringBitOperationAsync(Bitwise.And, "and", new RedisKey[] { "key1", "key2", "key3" }); - var len_or = conn.StringBitOperationAsync(Bitwise.Or, "or", new RedisKey[] { "key1", "key2", "key3" }); - var len_xor = conn.StringBitOperationAsync(Bitwise.Xor, "xor", new RedisKey[] { "key1", "key2", "key3" }); - var len_not = conn.StringBitOperationAsync(Bitwise.Not, "not", "key1"); - - Assert.AreEqual(1, conn.Wait(len_and)); - Assert.AreEqual(1, conn.Wait(len_or)); - Assert.AreEqual(1, conn.Wait(len_xor)); - Assert.AreEqual(1, conn.Wait(len_not)); - - var r_and = ((byte[])conn.Wait(conn.StringGetAsync("and"))).Single(); - var r_or = ((byte[])conn.Wait(conn.StringGetAsync("or"))).Single(); - var r_xor = ((byte[])conn.Wait(conn.StringGetAsync("xor"))).Single(); - var r_not = ((byte[])conn.Wait(conn.StringGetAsync("not"))).Single(); - - Assert.AreEqual((byte)(3 & 6 & 12), r_and); - Assert.AreEqual((byte)(3 | 6 | 12), r_or); - Assert.AreEqual((byte)(3 ^ 6 ^ 12), r_xor); - Assert.AreEqual(unchecked((byte)(~3)), r_not); - - } - - } - - [Test] - public void RangeString() - { - using (var muxer = Config.GetUnsecuredConnection()) - { - var conn = muxer.GetDatabase(0); - conn.StringSetAsync("my key", "hello world"); - var result = conn.StringGetRangeAsync("my key", 2, 6); - Assert.AreEqual("llo w", (string)conn.Wait(result)); - } - } - static byte[] Encode(string value) { return Encoding.UTF8.GetBytes(value); } - static string Decode(byte[] value) { return Encoding.UTF8.GetString(value); } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Transactions.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Transactions.cs deleted file mode 100644 index 9192201..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/Transactions.cs +++ /dev/null @@ -1,296 +0,0 @@ -//using System.Threading.Tasks; -//using NUnit.Framework; -//using System.Collections.Generic; -//using System; -//using System.Linq; -//using BookSleeve; -//using System.Text; -//using System.Threading; - -//namespace Tests -//{ -// [TestFixture] -// public class Transactions // http://redis.io/commands#transactions -// { - - -// [Test] -// public void TestBasicMultiExec() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(1, "tran"); -// conn.Keys.Remove(2, "tran"); - -// using (var tran = conn.CreateTransaction()) -// { -// var s1 = tran.Strings.Set(1, "tran", "abc"); -// var s2 = tran.Strings.Set(2, "tran", "def"); -// var g1 = tran.Strings.GetString(1, "tran"); -// var g2 = tran.Strings.GetString(2, "tran"); - -// var outsideTran = conn.Strings.GetString(1, "tran"); - -// var exec = tran.Execute(); - -// Assert.IsNull(conn.Wait(outsideTran)); -// Assert.AreEqual("abc", conn.Wait(g1)); -// Assert.AreEqual("def", conn.Wait(g2)); -// conn.Wait(s1); -// conn.Wait(s2); -// conn.Wait(exec); -// } - -// } -// } - -// [Test] -// public void TestRollback() -// { -// using (var conn = Config.GetUnsecuredConnection()) -// using (var tran = conn.CreateTransaction()) -// { -// var task = tran.Strings.Set(4, "abc", "def"); -// tran.Discard(); - -// Assert.IsTrue(task.IsCanceled, "should be cancelled"); -// try -// { -// conn.Wait(task); -// } -// catch (TaskCanceledException) -// { }// ok, else boom! - -// } -// } - -// [Test] -// public void TestDispose() -// { -// Task task; -// using (var conn = Config.GetUnsecuredConnection()) -// { -// using (var tran = conn.CreateTransaction()) -// { -// task = tran.Strings.Set(4, "abc", "def"); -// } -// Assert.IsTrue(task.IsCanceled, "should be cancelled"); -// try -// { -// conn.Wait(task); -// } -// catch (TaskCanceledException) -// { }// ok, else boom! -// } -// } - -// [Test] -// public void BlogDemo() -// { -// int db = 8; -// using (var conn = Config.GetUnsecuredConnection()) -// { -// conn.Keys.Remove(db, "foo"); // just to reset -// using (var tran = conn.CreateTransaction()) -// { // deliberately ignoring INCRBY here -// tran.AddCondition(Condition.KeyNotExists(db, "foo")); -// var t1 = tran.Strings.Increment(db, "foo"); -// var t2 = tran.Strings.Increment(db, "foo"); -// var val = tran.Strings.GetString(db, "foo"); - -// var t3 = tran.Execute(); // this *still* returns a Task - -// Assert.AreEqual(true, conn.Wait(t3)); -// Assert.AreEqual(1, conn.Wait(t1)); -// Assert.AreEqual(2, conn.Wait(t2)); -// Assert.AreEqual("2", conn.Wait(val)); -// } -// } -// } - -// [Test] -// public void AbortWorks() -// { -// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) -// { -// conn.CompletionMode = ResultCompletionMode.PreserveOrder; -// conn.Keys.Remove(0, "AbortWorks"); -// using (var tran = conn.CreateTransaction()) -// { -// var condition = tran.AddCondition(Condition.KeyExists(0, "AbortWorks")); -// var rename = tran.Strings.Increment(0, "key"); -// var success = conn.Wait(tran.Execute()); - -// Assert.IsFalse(success, "success"); -// Assert.IsFalse(conn.Wait(condition), "condition"); -// Assert.AreEqual(TaskStatus.Canceled, rename.Status, "rename"); -// } -// } -// } -// [Test] -// public void SignalRSend() -// { -// const int db = 3; -// const string idKey = "newid"; -// const string channel = "SignalRSend"; -// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) -// using (var sub = conn.GetOpenSubscriberChannel()) -// { -// conn.CompletionMode = ResultCompletionMode.ConcurrentIfContinuation; -// sub.CompletionMode = ResultCompletionMode.PreserveOrder; -// var received = new List(); -// sub.Subscribe(channel, (chan, payload) => -// { -// lock (received) { received.Add(Encoding.UTF8.GetString(payload)); } -// }); -// conn.Keys.Remove(db, idKey); - -// int totalAttempts = 0; -// var evt = new ManualResetEvent(false); -// const int threadCount = 2; -// const int perThread = 5; -// int unreadyThreads = threadCount; -// ParameterizedThreadStart work = state => -// { -// string thread = (string)state; -// if (Interlocked.Decrement(ref unreadyThreads) == 0) -// { -// // all threads ready; unleash the hounds! -// evt.Set(); -// } -// else -// { -// evt.WaitOne(); -// } - -// for (int i = 0; i < perThread; i++) -// { -// int attempts = Send(conn, idKey, db, channel, thread + ":" + i).Result; -// Interlocked.Add(ref totalAttempts, attempts); -// } - -// }; -// var threads = new Thread[unreadyThreads]; -// for (int i = 0; i < threads.Length; i++) threads[i] = new Thread(work); -// for (int i = 0; i < threads.Length; i++) threads[i].Start(i.ToString()); -// for (int i = 0; i < threads.Length; i++) threads[i].Join(); - -// const int expected = perThread * threadCount; -// // it doesn't matter that this number is big; we are testing the pathological worst-case -// // scenario here; multiple threads aggressively causing conflicts -// Console.WriteLine("total messages: {0} (vs {1} theoretical)", totalAttempts, expected); - -// // check we got everything we expected, and nothing more; the messages should -// // all be increasing; we should have every thread/loop combination -// Assert.AreEqual(expected, received.Count, "total messages"); -// for (int i = 0; i < expected; i++) -// { -// string want = (i + 1) + ":"; -// Assert.IsTrue(received[i].StartsWith(want), want); -// } -// for (int i = 0; i < threadCount; i++) -// { -// for (int j = 0; j < perThread; j++) -// { -// string want = ":" + i + ":" + j; -// bool found = received.Any(x => x.EndsWith(want)); -// Assert.IsTrue(found, want); -// } -// } -// } -// } -// static async Task Send(RedisConnection conn, string idKey, int db, string channel, string data) -// { -// int attempts = 0; -// bool success; -// do -// { -// var oldId = await conn.Strings.GetInt64(db, idKey).SafeAwaitable().ConfigureAwait(false); // important: let this be nullable; -// // means "doesn't exist" -// var newId = (oldId ?? 0) + 1; -// var payload = Pack(newId, data); - -// using (var tran = conn.CreateTransaction()) -// { -// var x0 = tran.AddCondition(Condition.KeyEquals(db, idKey, oldId)).SafeAwaitable(); -// var x1 = tran.Strings.Increment(db, idKey).SafeAwaitable(); -// var x2 = tran.Publish(channel, payload).SafeAwaitable(); -// success = await tran.Execute().SafeAwaitable().ConfigureAwait(false); - -// if (success) -// { -// // still expect all of these to get answers -// await Task.WhenAll(x0, x1, x2); - -// Assert.IsTrue(x0.Result, "condition passed"); -// Assert.AreEqual(newId, x1.Result); -// } -// else -// { -// // can't say much about x0; could have got past that -// Assert.IsTrue(await IsCancelled(x1)); -// Assert.IsTrue(await IsCancelled(x2)); -// } - -// attempts++; -// } -// } while (!success); -// return attempts; -// } - -// [Test] -// public void Issue43() -// { -// using(var conn = Config.GetRemoteConnection()) -// { -// conn.Keys.Remove(0, "anExistingKey1"); -// conn.Keys.Remove(0, "anExistingKey2"); -// conn.Keys.Remove(0, "anExistingKey3"); -// conn.Strings.Set(0, "anExistingKey1", "anExistingKey1"); -// conn.Strings.Set(0, "anExistingKey2", "anExistingKey2"); -// conn.Strings.Set(0, "anExistingKey3", "anExistingKey3"); -// for(int i = 0; i < 10000; i++) -// { -// using(var tx = conn.CreateTransaction()) -// { -// var cond1 = tx.AddCondition(Condition.KeyExists(0, "anExistingKey1")); -// var cond2 = tx.AddCondition(Condition.KeyExists(0, "anExistingKey2")); -// var cond3 = tx.AddCondition(Condition.KeyExists(0, "anExistingKey3")); - -// tx.Strings.Increment(0, "foo", 1); -// tx.Strings.Increment(0, "foo", 1); -// tx.Strings.Increment(0, "foo", 1); - -// var txRes = tx.Execute(); - -// Assert.IsTrue(tx.Wait(cond1), "cond1" + i); //--> ok -// Assert.IsTrue(tx.Wait(cond2), "cond2" + i); //--> ok -// Assert.IsTrue(tx.Wait(cond3), "cond3" + i); //--> ok -// Assert.IsTrue(tx.Wait(txRes), "txRes" + i); //--> not ok: false -// } -// } -// } -// } - -// static async Task IsCancelled(Task task) -// { -// try -// { -// await task; -// return false; -// } -// catch -// { -// return task.IsCanceled; -// } -// } - -// static byte[] Pack(long id, string data) -// { -// return Encoding.UTF8.GetBytes(id + ":" + data); -// } - - -// } -//} - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/redis-sharp.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/redis-sharp.cs deleted file mode 100644 index d9d9b30..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/MigratedBookSleeveTestSuite/redis-sharp.cs +++ /dev/null @@ -1,877 +0,0 @@ -// preamble: original source: https://github.com/migueldeicaza/redis-sharp/blob/master/redis-sharp.cs -// included here for performance test purposes only; this is a separate and parallel implementation - - -// -// redis-sharp.cs: ECMA CLI Binding to the Redis key-value storage system -// -// Authors: -// Miguel de Icaza (miguel@gnome.org) -// -// Copyright 2010 Novell, Inc. -// -// Licensed under the same terms of reddis: new BSD license. -// - - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net.Sockets; -using System.Text; - -public class Redis : IDisposable -{ - Socket socket; - BufferedStream bstream; - - public enum KeyType - { - None, String, List, Set - } - - public class ResponseException : Exception - { - public ResponseException(string code) - : base("Response error") - { - Code = code; - } - - public string Code { get; private set; } - } - - public Redis(string host, int port) - { - if (host == null) - throw new ArgumentNullException(nameof(host)); - - Host = host; - Port = port; - SendTimeout = -1; - } - - public Redis(string host) - : this(host, 6379) - { - } - - public Redis() - : this("localhost", 6379) - { - } - - public string Host { get; private set; } - public int Port { get; private set; } - public int RetryTimeout { get; set; } - public int RetryCount { get; set; } - public int SendTimeout { get; set; } - public string Password { get; set; } - - int db; - public int Db - { - get - { - return db; - } - - set - { - db = value; - SendExpectSuccess("SELECT {0}\r\n", db); - } - } - - public string this[string key] - { - get { return GetString(key); } - set { Set(key, value); } - } - - public void Set(string key, string value) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - if (value == null) - throw new ArgumentNullException(nameof(value)); - - Set(key, Encoding.UTF8.GetBytes(value)); - } - - public void Set(string key, byte[] value) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - if (value == null) - throw new ArgumentNullException(nameof(value)); - - if (value.Length > 1073741824) - throw new ArgumentException("value exceeds 1G", nameof(value)); - - if (!SendDataCommand(value, "SET {0} {1}\r\n", key, value.Length)) - throw new Exception("Unable to connect"); - ExpectSuccess(); - } - - public bool SetNX(string key, string value) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - if (value == null) - throw new ArgumentNullException(nameof(value)); - - return SetNX(key, Encoding.UTF8.GetBytes(value)); - } - - public bool SetNX(string key, byte[] value) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - if (value == null) - throw new ArgumentNullException(nameof(value)); - - if (value.Length > 1073741824) - throw new ArgumentException("value exceeds 1G", nameof(value)); - - return SendDataExpectInt(value, "SETNX {0} {1}\r\n", key, value.Length) > 0 ? true : false; - } - - public void Set(IDictionary dict) - { - Set(dict.ToDictionary(k => k.Key, v => Encoding.UTF8.GetBytes(v.Value))); - } - - public void Set(IDictionary dict) - { - if (dict == null) - throw new ArgumentNullException(nameof(dict)); - - var nl = Encoding.UTF8.GetBytes("\r\n"); - - var ms = new MemoryStream(); - foreach (var key in dict.Keys) - { - var val = dict[key]; - - var kLength = Encoding.UTF8.GetBytes("$" + key.Length + "\r\n"); - var k = Encoding.UTF8.GetBytes(key + "\r\n"); - var vLength = Encoding.UTF8.GetBytes("$" + val.Length + "\r\n"); - ms.Write(kLength, 0, kLength.Length); - ms.Write(k, 0, k.Length); - ms.Write(vLength, 0, vLength.Length); - ms.Write(val, 0, val.Length); - ms.Write(nl, 0, nl.Length); - } - - SendDataCommand(ms.ToArray(), "*" + (dict.Count * 2 + 1) + "\r\n$4\r\nMSET\r\n"); - ExpectSuccess(); - } - - public byte[] Get(string key) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - return SendExpectData(null, "GET " + key + "\r\n"); - } - - public string GetString(string key) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - return Encoding.UTF8.GetString(Get(key)); - } - - public byte[][] Sort(SortOptions options) - { - return SendDataCommandExpectMultiBulkReply(null, options.ToCommand() + "\r\n"); - } - - public byte[] GetSet(string key, byte[] value) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - if (value == null) - throw new ArgumentNullException(nameof(value)); - - if (value.Length > 1073741824) - throw new ArgumentException("value exceeds 1G", nameof(value)); - - if (!SendDataCommand(value, "GETSET {0} {1}\r\n", key, value.Length)) - throw new Exception("Unable to connect"); - - return ReadData(); - } - - public string GetSet(string key, string value) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - if (value == null) - throw new ArgumentNullException(nameof(value)); - return Encoding.UTF8.GetString(GetSet(key, Encoding.UTF8.GetBytes(value))); - } - - string ReadLine() - { - var sb = new StringBuilder(); - int c; - - while ((c = bstream.ReadByte()) != -1) - { - if (c == '\r') - continue; - if (c == '\n') - break; - sb.Append((char)c); - } - return sb.ToString(); - } - - void Connect() - { - socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - socket.NoDelay = true; - socket.SendTimeout = SendTimeout; - socket.Connect(Host, Port); - if (!socket.Connected) - { - socket.Dispose(); - socket = null; - return; - } - bstream = new BufferedStream(new NetworkStream(socket), 16 * 1024); - - if (Password != null) - SendExpectSuccess("AUTH {0}\r\n", Password); - } - - byte[] end_data = new byte[] { (byte)'\r', (byte)'\n' }; - - bool SendDataCommand(byte[] data, string cmd, params object[] args) - { - if (socket == null) - Connect(); - if (socket == null) - return false; - - var s = args.Length > 0 ? String.Format(cmd, args) : cmd; - byte[] r = Encoding.UTF8.GetBytes(s); - try - { - Log("S: " + String.Format(cmd, args)); - socket.Send(r); - if (data != null) - { - socket.Send(data); - socket.Send(end_data); - } - } - catch (SocketException) - { - // timeout; - socket.Dispose(); - socket = null; - - return false; - } - return true; - } - - bool SendCommand(string cmd, params object[] args) - { - if (socket == null) - Connect(); - if (socket == null) - return false; - - var s = args != null && args.Length > 0 ? String.Format(cmd, args) : cmd; - byte[] r = Encoding.UTF8.GetBytes(s); - try - { - Log("S: " + String.Format(cmd, args)); - socket.Send(r); - } - catch (SocketException) - { - // timeout; - socket.Dispose(); - socket = null; - - return false; - } - return true; - } - - [Conditional("DEBUG")] - void Log(string fmt, params object[] args) - { - Console.WriteLine("{0}", String.Format(fmt, args).Trim()); - } - - void ExpectSuccess() - { - int c = bstream.ReadByte(); - if (c == -1) - throw new ResponseException("No more data"); - - var s = ReadLine(); - Log((char)c + s); - if (c == '-') - throw new ResponseException(s.StartsWith("ERR") ? s.Substring(4) : s); - } - - void SendExpectSuccess(string cmd, params object[] args) - { - if (!SendCommand(cmd, args)) - throw new Exception("Unable to connect"); - - ExpectSuccess(); - } - - int SendDataExpectInt(byte[] data, string cmd, params object[] args) - { - if (!SendDataCommand(data, cmd, args)) - throw new Exception("Unable to connect"); - - int c = bstream.ReadByte(); - if (c == -1) - throw new ResponseException("No more data"); - - var s = ReadLine(); - Log("R: " + s); - if (c == '-') - throw new ResponseException(s.StartsWith("ERR") ? s.Substring(4) : s); - if (c == ':') - { - int i; - if (int.TryParse(s, out i)) - return i; - } - throw new ResponseException("Unknown reply on integer request: " + c + s); - } - - int SendExpectInt(string cmd, params object[] args) - { - if (!SendCommand(cmd, args)) - throw new Exception("Unable to connect"); - - int c = bstream.ReadByte(); - if (c == -1) - throw new ResponseException("No more data"); - - var s = ReadLine(); - Log("R: " + s); - if (c == '-') - throw new ResponseException(s.StartsWith("ERR") ? s.Substring(4) : s); - if (c == ':') - { - int i; - if (int.TryParse(s, out i)) - return i; - } - throw new ResponseException("Unknown reply on integer request: " + c + s); - } - - string SendExpectString(string cmd, params object[] args) - { - if (!SendCommand(cmd, args)) - throw new Exception("Unable to connect"); - - int c = bstream.ReadByte(); - if (c == -1) - throw new ResponseException("No more data"); - - var s = ReadLine(); - Log("R: " + s); - if (c == '-') - throw new ResponseException(s.StartsWith("ERR") ? s.Substring(4) : s); - if (c == '+') - return s; - - throw new ResponseException("Unknown reply on integer request: " + c + s); - } - - // - // This one does not throw errors - // - string SendGetString(string cmd, params object[] args) - { - if (!SendCommand(cmd, args)) - throw new Exception("Unable to connect"); - - return ReadLine(); - } - - byte[] SendExpectData(byte[] data, string cmd, params object[] args) - { - if (!SendDataCommand(data, cmd, args)) - throw new Exception("Unable to connect"); - - return ReadData(); - } - - byte[] ReadData() - { - string r = ReadLine(); - Log("R: {0}", r); - if (r.Length == 0) - throw new ResponseException("Zero length respose"); - - char c = r[0]; - if (c == '-') - throw new ResponseException(r.StartsWith("-ERR") ? r.Substring(5) : r.Substring(1)); - - if (c == '$') - { - if (r == "$-1") - return null; - int n; - - if (Int32.TryParse(r.Substring(1), out n)) - { - byte[] retbuf = new byte[n]; - - int bytesRead = 0; - do - { - int read = bstream.Read(retbuf, bytesRead, n - bytesRead); - if (read < 1) - throw new ResponseException("Invalid termination mid stream"); - bytesRead += read; - } - while (bytesRead < n); - if (bstream.ReadByte() != '\r' || bstream.ReadByte() != '\n') - throw new ResponseException("Invalid termination"); - return retbuf; - } - throw new ResponseException("Invalid length"); - } - - //returns the number of matches - if (c == '*') - { - int n; - if (Int32.TryParse(r.Substring(1), out n)) - return n <= 0 ? new byte[0] : ReadData(); - - throw new ResponseException("Unexpected length parameter" + r); - } - - throw new ResponseException("Unexpected reply: " + r); - } - - public bool ContainsKey(string key) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - return SendExpectInt("EXISTS " + key + "\r\n") == 1; - } - - public bool Remove(string key) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - return SendExpectInt("DEL " + key + "\r\n", key) == 1; - } - - public int Remove(params string[] args) - { - if (args == null) - throw new ArgumentNullException(nameof(args)); - return SendExpectInt("DEL " + string.Join(" ", args) + "\r\n"); - } - - public int Increment(string key) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - return SendExpectInt("INCR " + key + "\r\n"); - } - - public int Increment(string key, int count) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - return SendExpectInt("INCRBY {0} {1}\r\n", key, count); - } - - public int Decrement(string key) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - return SendExpectInt("DECR " + key + "\r\n"); - } - - public int Decrement(string key, int count) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - return SendExpectInt("DECRBY {0} {1}\r\n", key, count); - } - - public KeyType TypeOf(string key) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - switch (SendExpectString("TYPE {0}\r\n", key)) - { - case "none": - return KeyType.None; - case "string": - return KeyType.String; - case "set": - return KeyType.Set; - case "list": - return KeyType.List; - } - throw new ResponseException("Invalid value"); - } - - public string RandomKey() - { - return SendExpectString("RANDOMKEY\r\n"); - } - - public bool Rename(string oldKeyname, string newKeyname) - { - if (oldKeyname == null) - throw new ArgumentNullException(nameof(oldKeyname)); - if (newKeyname == null) - throw new ArgumentNullException(nameof(newKeyname)); - return SendGetString("RENAME {0} {1}\r\n", oldKeyname, newKeyname)[0] == '+'; - } - - public bool Expire(string key, int seconds) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - return SendExpectInt("EXPIRE {0} {1}\r\n", key, seconds) == 1; - } - - public bool ExpireAt(string key, int time) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - return SendExpectInt("EXPIREAT {0} {1}\r\n", key, time) == 1; - } - - public int TimeToLive(string key) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - return SendExpectInt("TTL {0}\r\n", key); - } - - public int DbSize - { - get - { - return SendExpectInt("DBSIZE\r\n"); - } - } - - public string Save() - { - return SendGetString("SAVE\r\n"); - } - - public void BackgroundSave() - { - SendGetString("BGSAVE\r\n"); - } - - public void Shutdown() - { - SendGetString("SHUTDOWN\r\n"); - } - - public void FlushAll() - { - SendGetString("FLUSHALL\r\n"); - } - - public void FlushDb() - { - SendGetString("FLUSHDB\r\n"); - } - - const long UnixEpoch = 621355968000000000L; - - public DateTime LastSave - { - get - { - int t = SendExpectInt("LASTSAVE\r\n"); - - return new DateTime(UnixEpoch) + TimeSpan.FromSeconds(t); - } - } - - public Dictionary GetInfo() - { - byte[] r = SendExpectData(null, "INFO\r\n"); - var dict = new Dictionary(); - - foreach (var line in Encoding.UTF8.GetString(r).Split('\n')) - { - int p = line.IndexOf(':'); - if (p == -1) - continue; - dict.Add(line.Substring(0, p), line.Substring(p + 1)); - } - return dict; - } - - public string[] Keys - { - get - { - string commandResponse = Encoding.UTF8.GetString(SendExpectData(null, "KEYS *\r\n")); - if (commandResponse.Length < 1) - return new string[0]; - else - return commandResponse.Split(' '); - } - } - - public string[] GetKeys(string pattern) - { - if (pattern == null) - throw new ArgumentNullException("key"); - var keys = SendExpectData(null, "KEYS {0}\r\n", pattern); - if (keys.Length == 0) - return new string[0]; - return Encoding.UTF8.GetString(keys).Split(' '); - } - - public byte[][] GetKeys(params string[] keys) - { - if (keys == null) - throw new ArgumentNullException("key1"); - if (keys.Length == 0) - throw new ArgumentException("keys"); - - return SendDataCommandExpectMultiBulkReply(null, "MGET {0}\r\n", string.Join(" ", keys)); - } - - - public byte[][] SendDataCommandExpectMultiBulkReply(byte[] data, string command, params object[] args) - { - if (!SendDataCommand(data, command, args)) - throw new Exception("Unable to connect"); - int c = bstream.ReadByte(); - if (c == -1) - throw new ResponseException("No more data"); - - var s = ReadLine(); - Log("R: " + s); - if (c == '-') - throw new ResponseException(s.StartsWith("ERR") ? s.Substring(4) : s); - if (c == '*') - { - int count; - if (int.TryParse(s, out count)) - { - var result = new byte[count][]; - - for (int i = 0; i < count; i++) - result[i] = ReadData(); - - return result; - } - } - throw new ResponseException("Unknown reply on multi-request: " + c + s); - } - - #region List commands - public byte[][] ListRange(string key, int start, int end) - { - return SendDataCommandExpectMultiBulkReply(null, "LRANGE {0} {1} {2}\r\n", key, start, end); - } - - public void RightPush(string key, string value) - { - SendExpectSuccess("RPUSH {0} {1}\r\n{2}\r\n", key, value.Length, value); - } - - public int ListLength(string key) - { - return SendExpectInt("LLEN {0}\r\n", key); - } - - public byte[] ListIndex(string key, int index) - { - SendCommand("LINDEX {0} {1}\r\n", key, index); - return ReadData(); - } - - public byte[] LeftPop(string key) - { - SendCommand("LPOP {0}\r\n", key); - return ReadData(); - } - #endregion - - #region Set commands - public bool AddToSet(string key, byte[] member) - { - return SendDataExpectInt(member, "SADD {0} {1}\r\n", key, member.Length) > 0; - } - - public bool AddToSet(string key, string member) - { - return AddToSet(key, Encoding.UTF8.GetBytes(member)); - } - - public int CardinalityOfSet(string key) - { - return SendDataExpectInt(null, "SCARD {0}\r\n", key); - } - - public bool IsMemberOfSet(string key, byte[] member) - { - return SendDataExpectInt(member, "SISMEMBER {0} {1}\r\n", key, member.Length) > 0; - } - - public bool IsMemberOfSet(string key, string member) - { - return IsMemberOfSet(key, Encoding.UTF8.GetBytes(member)); - } - - public byte[][] GetMembersOfSet(string key) - { - return SendDataCommandExpectMultiBulkReply(null, "SMEMBERS {0}\r\n", key); - } - - public byte[] GetRandomMemberOfSet(string key) - { - return SendExpectData(null, "SRANDMEMBER {0}\r\n", key); - } - - public byte[] PopRandomMemberOfSet(string key) - { - return SendExpectData(null, "SPOP {0}\r\n", key); - } - - public bool RemoveFromSet(string key, byte[] member) - { - return SendDataExpectInt(member, "SREM {0} {1}\r\n", key, member.Length) > 0; - } - - public bool RemoveFromSet(string key, string member) - { - return RemoveFromSet(key, Encoding.UTF8.GetBytes(member)); - } - - public byte[][] GetUnionOfSets(params string[] keys) - { - if (keys == null) - throw new ArgumentNullException(); - - return SendDataCommandExpectMultiBulkReply(null, "SUNION " + string.Join(" ", keys) + "\r\n"); - - } - - void StoreSetCommands(string cmd, string destKey, params string[] keys) - { - if (String.IsNullOrEmpty(cmd)) - throw new ArgumentNullException(nameof(cmd)); - - if (String.IsNullOrEmpty(destKey)) - throw new ArgumentNullException(nameof(destKey)); - - if (keys == null) - throw new ArgumentNullException(nameof(keys)); - - SendExpectSuccess("{0} {1} {2}\r\n", cmd, destKey, String.Join(" ", keys)); - } - - public void StoreUnionOfSets(string destKey, params string[] keys) - { - StoreSetCommands("SUNIONSTORE", destKey, keys); - } - - public byte[][] GetIntersectionOfSets(params string[] keys) - { - if (keys == null) - throw new ArgumentNullException(); - - return SendDataCommandExpectMultiBulkReply(null, "SINTER " + string.Join(" ", keys) + "\r\n"); - } - - public void StoreIntersectionOfSets(string destKey, params string[] keys) - { - StoreSetCommands("SINTERSTORE", destKey, keys); - } - - public byte[][] GetDifferenceOfSets(params string[] keys) - { - if (keys == null) - throw new ArgumentNullException(); - - return SendDataCommandExpectMultiBulkReply(null, "SDIFF " + string.Join(" ", keys) + "\r\n"); - } - - public void StoreDifferenceOfSets(string destKey, params string[] keys) - { - StoreSetCommands("SDIFFSTORE", destKey, keys); - } - - public bool MoveMemberToSet(string srcKey, string destKey, byte[] member) - { - return SendDataExpectInt(member, "SMOVE {0} {1} {2}\r\n", srcKey, destKey, member.Length) > 0; - } - #endregion - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - ~Redis() - { - Dispose(false); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - SendCommand("QUIT\r\n"); - socket.Dispose(); - socket = null; - } - } -} - -public class SortOptions -{ - public string Key { get; set; } - public bool Descending { get; set; } - public bool Lexographically { get; set; } - public Int32 LowerLimit { get; set; } - public Int32 UpperLimit { get; set; } - public string By { get; set; } - public string StoreInKey { get; set; } - public string Get { get; set; } - - public string ToCommand() - { - var command = "SORT " + this.Key; - if (LowerLimit != 0 || UpperLimit != 0) - command += " LIMIT " + LowerLimit + " " + UpperLimit; - if (Lexographically) - command += " ALPHA"; - if (!string.IsNullOrEmpty(By)) - command += " BY " + By; - if (!string.IsNullOrEmpty(Get)) - command += " GET " + Get; - if (!string.IsNullOrEmpty(StoreInKey)) - command += " STORE " + StoreInKey; - return command; - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch.Test/ExampleUsage.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch.Test/ExampleUsage.cs deleted file mode 100644 index 3d54288..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch.Test/ExampleUsage.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using Xunit; -using StackExchange.Redis; -using NRediSearch; -using System.Collections.Generic; -using System.Linq; - -namespace NRediSearch.Test -{ - public class ExampleUsage : IDisposable - { - ConnectionMultiplexer conn; - IDatabase db; - public ExampleUsage() - { - conn = ConnectionMultiplexer.Connect("127.0.0.1:6379"); - db = conn.GetDatabase(); - } - public void Dispose() - { - conn?.Dispose(); - conn = null; - db = null; - } - [Fact] - public void BasicUsage() - { - var client = new Client("testung", db); - - try { client.DropIndex(); } catch { } // reset DB - - // Defining a schema for an index and creating it: - var sc = new Schema() - .AddTextField("title", 5.0) - .AddTextField("body", 1.0) - .AddNumericField("price"); - - Assert.True(client.CreateIndex(sc, Client.IndexOptions.Default)); - - // note: using java API equivalent here; it would be nice to - // use meta-programming / reflection instead in .NET - - // Adding documents to the index: - var fields = new Dictionary(); - fields.Add("title", "hello world"); - fields.Add("body", "lorem ipsum"); - fields.Add("price", 1337); - - Assert.True(client.AddDocument("doc1", fields)); - - // Creating a complex query - var q = new Query("hello world") - .AddFilter(new Query.NumericFilter("price", 1300, 1350)) - .Limit(0, 5); - - // actual search - var res = client.Search(q); - - Assert.Equal(1, res.TotalResults); - var item = res.Documents.Single(); - Assert.Equal("doc1", item.Id); - - Assert.True(item.HasProperty("title")); - Assert.True(item.HasProperty("body")); - Assert.True(item.HasProperty("price")); - Assert.False(item.HasProperty("blap")); - - Assert.Equal("hello world", (string)item["title"]); - Assert.Equal("lorem ipsum", (string)item["body"]); - Assert.Equal(1337, (int)item["price"]); - - - - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch.Test/NRediSearch.Test.csproj b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch.Test/NRediSearch.Test.csproj deleted file mode 100644 index c6ff738..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch.Test/NRediSearch.Test.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - netcoreapp1.1 - false - - - - - - - - - - - - - - - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Client.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Client.cs deleted file mode 100644 index 2d66114..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Client.cs +++ /dev/null @@ -1,420 +0,0 @@ -// .NET port of https://github.com/RedisLabs/JRediSearch/ - -using StackExchange.Redis; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace NRediSearch -{ - public sealed class Client - { - [Flags] - public enum IndexOptions - { - ///

- /// All options disabled - /// - None = 0, - /// - /// Set this to tell the index not to save term offset vectors. This reduces memory consumption but does not - /// allow performing exact matches, and reduces overall relevance of multi-term queries - /// - UseTermOffsets = 1, - /// - /// If set (default), we keep flags per index record telling us what fields the term appeared on, - /// and allowing us to filter results by field - /// - KeepFieldFlags = 2, - /// - /// If set, we keep an index of the top entries per term, allowing extremely fast single word queries - /// regardless of index size, at the cost of more memory - /// - UseScoreIndexes = 4, - /// - /// The default indexing options - use term offsets and keep fields flags - /// - Default = UseTermOffsets | KeepFieldFlags - } - private static void SerializeRedisArgs(IndexOptions flags, List args) - { - if ((flags & IndexOptions.UseTermOffsets) == 0) - { - args.Add("NOOFFSETS".Literal()); - } - if ((flags & IndexOptions.KeepFieldFlags) == 0) - { - args.Add("NOFIELDS".Literal()); - } - if ((flags & IndexOptions.UseScoreIndexes) == 0) - { - args.Add("NOSCOREIDX".Literal()); - } - } - private readonly IDatabaseAsync _db; - private IDatabase DbSync - => (_db as IDatabase) ?? throw new InvalidOperationException("Synchronous operations are not available on this database instance"); - - private readonly object _boxedIndexName; - public RedisKey IndexName => (RedisKey)_boxedIndexName; - public Client(RedisKey indexName, IDatabaseAsync db) - { - _db = db ?? throw new ArgumentNullException(nameof(db)); - _boxedIndexName = indexName; // only box once, not per-command - } - public Client(RedisKey indexName, IDatabase db) : this(indexName, (IDatabaseAsync)db) { } - - /// - /// Create the index definition in redis - /// - /// a schema definition - /// index option flags - /// true if successful - public bool CreateIndex(Schema schema, IndexOptions options) - { - var args = new List(); - - args.Add(_boxedIndexName); - SerializeRedisArgs(options, args); - args.Add("SCHEMA".Literal()); - - foreach (var f in schema.Fields) - { - f.SerializeRedisArgs(args); - } - - return (string)DbSync.Execute("FT.CREATE", args) == "OK"; - } - - /// - /// Create the index definition in redis - /// - /// a schema definition - /// index option flags - /// true if successful - public async Task CreateIndexAsync(Schema schema, IndexOptions options) - { - var args = new List(); - - args.Add(_boxedIndexName); - SerializeRedisArgs(options, args); - args.Add("SCHEMA".Literal()); - - foreach (var f in schema.Fields) - { - f.SerializeRedisArgs(args); - } - - return (string)await _db.ExecuteAsync("FT.CREATE", args).ConfigureAwait(false) == "OK"; - } - - /// - /// Search the index - /// - /// a object with the query string and optional parameters - /// a object with the results - public SearchResult Search(Query q) - { - var args = new List(); - args.Add(_boxedIndexName); - q.SerializeRedisArgs(args); - - var resp = (RedisResult[])DbSync.Execute("FT.SEARCH", args); - return new SearchResult(resp, !q.NoContent, q.WithScores, q.WithPayloads); - } - - /// - /// Search the index - /// - /// a object with the query string and optional parameters - /// a object with the results - public async Task SearchAsync(Query q) - { - var args = new List(); - args.Add(_boxedIndexName); - q.SerializeRedisArgs(args); - - var resp = (RedisResult[])await _db.ExecuteAsync("FT.SEARCH", args).ConfigureAwait(false); - return new SearchResult(resp, !q.NoContent, q.WithScores, q.WithPayloads); - } - - /// - /// Add a single document to the query - /// - /// the id of the document. It cannot belong to a document already in the index unless replace is set - /// the document's score, floating point number between 0 and 1 - /// a map of the document's fields - /// if set, we only index the document and do not save its contents. This allows fetching just doc ids - /// if set, and the document already exists, we reindex and update it - /// if set, we can save a payload in the index to be retrieved or evaluated by scoring functions on the server - public bool AddDocument(string docId, Dictionary fields, double score = 1.0, bool noSave = false, bool replace = false, byte[] payload = null) - { - var args = BuildAddDocumentArgs(docId, fields, score, noSave, replace, payload); - return (string)DbSync.Execute("FT.ADD", args) == "OK"; - } - - /// - /// Add a single document to the query - /// - /// the id of the document. It cannot belong to a document already in the index unless replace is set - /// the document's score, floating point number between 0 and 1 - /// a map of the document's fields - /// if set, we only index the document and do not save its contents. This allows fetching just doc ids - /// if set, and the document already exists, we reindex and update it - /// if set, we can save a payload in the index to be retrieved or evaluated by scoring functions on the server - public async Task AddDocumentAsync(string docId, Dictionary fields, double score = 1.0, bool noSave = false, bool replace = false, byte[] payload = null) - { - var args = BuildAddDocumentArgs(docId, fields, score, noSave, replace, payload); - return (string)await _db.ExecuteAsync("FT.ADD", args).ConfigureAwait(false) == "OK"; - } - - private List BuildAddDocumentArgs(string docId, Dictionary fields, double score, bool noSave, bool replace, byte[] payload) - { - var args = new List { _boxedIndexName, docId, score }; - if (noSave) - { - args.Add("NOSAVE".Literal()); - } - if (replace) - { - args.Add("REPLACE".Literal()); - } - if (payload != null) - { - args.Add("PAYLOAD".Literal()); - // TODO: Fix this - args.Add(payload); - } - - args.Add("FIELDS".Literal()); - foreach (var ent in fields) - { - args.Add(ent.Key); - args.Add(ent.Value); - } - return args; - } - - /// - /// replaceDocument is a convenience for calling addDocument with replace=true - /// - public bool ReplaceDocument(string docId, Dictionary fields, double score = 1.0, byte[] payload = null) - => AddDocument(docId, fields, score, false, true, payload); - - /// - /// replaceDocument is a convenience for calling addDocument with replace=true - /// - public Task ReplaceDocumentAsync(string docId, Dictionary fields, double score = 1.0, byte[] payload = null) - => AddDocumentAsync(docId, fields, score, false, true, payload); - - /// - /// Index a document already in redis as a HASH key. - /// - /// the id of the document in redis. This must match an existing, unindexed HASH key - /// the document's index score, between 0 and 1 - /// if set, and the document already exists, we reindex and update it - /// true on success - public bool AddHash(string docId, double score, bool replace) - { - var args = new List { _boxedIndexName, docId, score }; - if (replace) - { - args.Add("REPLACE".Literal()); - } - return (string)DbSync.Execute("FT.ADDHASH", args) == "OK"; - } - /// - /// Index a document already in redis as a HASH key. - /// - /// the id of the document in redis. This must match an existing, unindexed HASH key - /// the document's index score, between 0 and 1 - /// if set, and the document already exists, we reindex and update it - /// true on success - public async Task AddHashAsync(string docId, double score, bool replace) - { - var args = new List { _boxedIndexName, docId, score }; - if (replace) - { - args.Add("REPLACE".Literal()); - } - return (string)await _db.ExecuteAsync("FT.ADDHASH", args).ConfigureAwait(false) == "OK"; - } - - /// - /// Get the index info, including memory consumption and other statistics. - /// - /// TODO: Make a class for easier access to the index properties - /// a map of key/value pairs - public Dictionary GetInfo() - { - return ParseGetInfo(DbSync.Execute("FT.INFO", _boxedIndexName)); - } - /// - /// Get the index info, including memory consumption and other statistics. - /// - /// TODO: Make a class for easier access to the index properties - /// a map of key/value pairs - public async Task> GetInfoAsync() - { - return ParseGetInfo(await _db.ExecuteAsync("FT.INFO", _boxedIndexName).ConfigureAwait(false)); - } - static Dictionary ParseGetInfo(RedisResult value) - { - var res = (RedisValue[])value; - var info = new Dictionary(); - for (int i = 0; i < res.Length; i += 2) - { - var key = (string)res[i]; - var val = res[i + 1]; - info.Add(key, val); - } - return info; - } - - /// - /// Delete a document from the index. - /// - /// the document's id - /// true if it has been deleted, false if it did not exist - public bool DeleteDocument(string docId) - { - return (long)DbSync.Execute("FT.DEL", _boxedIndexName, docId) == 1; - } - - /// - /// Delete a document from the index. - /// - /// the document's id - /// true if it has been deleted, false if it did not exist - public async Task DeleteDocumentAsync(string docId) - { - return (long)await _db.ExecuteAsync("FT.DEL", _boxedIndexName, docId).ConfigureAwait(false) == 1; - } - - /// - /// Drop the index and all associated keys, including documents - /// - /// true on success - public bool DropIndex() - { - return (string)DbSync.Execute("FT.DROP", _boxedIndexName) == "OK"; - } - /// - /// Drop the index and all associated keys, including documents - /// - /// true on success - public async Task DropIndexAsync() - { - return (string) await _db.ExecuteAsync("FT.DROP", _boxedIndexName).ConfigureAwait(false) == "OK"; - } - - /// - /// Optimize memory consumption of the index by removing extra saved capacity. This does not affect speed - /// - public long OptimizeIndex() - { - return (long)DbSync.Execute("FT.OPTIMIZE", _boxedIndexName); - } - - /// - /// Optimize memory consumption of the index by removing extra saved capacity. This does not affect speed - /// - public async Task OptimizeIndexAsync() - { - return (long) await _db.ExecuteAsync("FT.OPTIMIZE", _boxedIndexName).ConfigureAwait(false); - } - - /// - /// Get the size of an autoc-complete suggestion dictionary - /// - public long CountSuggestions() - => (long)DbSync.Execute("FT.SUGLEN", _boxedIndexName); - - /// - /// Get the size of an autoc-complete suggestion dictionary - /// - public async Task CountSuggestionsAsync() - => (long)await _db.ExecuteAsync("FT.SUGLEN", _boxedIndexName).ConfigureAwait(false); - - /// - /// Add a suggestion string to an auto-complete suggestion dictionary. This is disconnected from the index definitions, and leaves creating and updating suggestino dictionaries to the user. - /// - /// the suggestion string we index - /// a floating point number of the suggestion string's weight - /// if set, we increment the existing entry of the suggestion by the given score, instead of replacing the score. This is useful for updating the dictionary based on user queries in real time - /// the current size of the suggestion dictionary. - public long AddSuggestion(string value, double score, bool increment = false) - { - object args = increment - ? new object[] { _boxedIndexName, value, score, "INCR".Literal() } - : new object[] { _boxedIndexName, value, score }; - return (long)DbSync.Execute("FT.SUGADD", args); - } - - /// - /// Add a suggestion string to an auto-complete suggestion dictionary. This is disconnected from the index definitions, and leaves creating and updating suggestino dictionaries to the user. - /// - /// the suggestion string we index - /// a floating point number of the suggestion string's weight - /// if set, we increment the existing entry of the suggestion by the given score, instead of replacing the score. This is useful for updating the dictionary based on user queries in real time - /// the current size of the suggestion dictionary. - public async Task AddSuggestionAsync(string value, double score, bool increment = false) - { - object args = increment - ? new object[] { _boxedIndexName, value, score, "INCR".Literal() } - : new object[] { _boxedIndexName, value, score }; - return (long)await _db.ExecuteAsync("FT.SUGADD", args).ConfigureAwait(false); - } - - /// - /// Delete a string from a suggestion index. - /// - /// the string to delete - public bool DeleteSuggestion(string value) - => (long)DbSync.Execute("FT.SUGDEL", _boxedIndexName, value) == 1; - - /// - /// Delete a string from a suggestion index. - /// - /// the string to delete - public async Task DeleteSuggestionAsync(string value) - => (long)await _db.ExecuteAsync("FT.SUGDEL", _boxedIndexName, value).ConfigureAwait(false) == 1; - - /// - /// Get completion suggestions for a prefix - /// - /// the prefix to complete on - /// if set,we do a fuzzy prefix search, including prefixes at levenshtein distance of 1 from the prefix sent - /// If set, we limit the results to a maximum of num. (Note: The default is 5, and the number cannot be greater than 10). - /// a list of the top suggestions matching the prefix - public string[] GetSuggestions(string prefix, bool fuzzy = false, int max = 5) - { - var args = new List { _boxedIndexName, prefix}; - if (fuzzy) args.Add("FUZZY".Literal()); - if (max != 5) - { - args.Add("MAX".Literal()); - args.Add(max); - } - return (string[])DbSync.Execute("FT.SUGGET", args); - } - /// - /// Get completion suggestions for a prefix - /// - /// the prefix to complete on - /// if set,we do a fuzzy prefix search, including prefixes at levenshtein distance of 1 from the prefix sent - /// If set, we limit the results to a maximum of num. (Note: The default is 5, and the number cannot be greater than 10). - /// a list of the top suggestions matching the prefix - public async Task GetSuggestionsAsync(string prefix, bool fuzzy = false, int max = 5) - { - var args = new List { _boxedIndexName, prefix }; - if (fuzzy) args.Add("FUZZY".Literal()); - if (max != 5) - { - args.Add("MAX".Literal()); - args.Add(max); - } - return (string[])await _db.ExecuteAsync("FT.SUGGET", args).ConfigureAwait(false); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Document.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Document.cs deleted file mode 100644 index 90a81e8..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Document.cs +++ /dev/null @@ -1,51 +0,0 @@ -// .NET port of https://github.com/RedisLabs/JRediSearch/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using StackExchange.Redis; - -namespace NRediSearch -{ - /// - /// Document represents a single indexed document or entity in the engine - /// - public class Document - { - - public string Id { get; } - public double Score { get; } - public byte[] Payload { get; } - private Dictionary properties = new Dictionary(); - - public Document(string id, double score, byte[] payload) - { - Id = id; - Score = score; - Payload = payload; - } - - public static Document Load(string id, double score, byte[] payload, RedisValue[] fields) - { - Document ret = new Document(id, score, payload); - if (fields != null) - { - for (int i = 0; i < fields.Length; i += 2) - { - ret[(string)fields[i]] = fields[i + 1]; - } - } - return ret; - } - - public RedisValue this[string key] - { - get { return properties.TryGetValue(key, out var val) ? val : default(RedisValue); } - internal set { properties[key] = value; } - } - - public bool HasProperty(string key) => properties.ContainsKey(key); - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Literals.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Literals.cs deleted file mode 100644 index 2310f5e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Literals.cs +++ /dev/null @@ -1,36 +0,0 @@ -using StackExchange.Redis; -using System.Collections; -namespace NRediSearch -{ - /// - /// Cache to ensure we encode and box literals once only - /// - internal static class Literals - { - private static Hashtable _boxed = new Hashtable(); - private static object _null = RedisValue.Null; - /// - /// Obtain a lazily-cached pre-encoded and boxed representation of a string - /// - /// This shoul donly be used for fixed values, not user data (the cache is never reclaimed, so it will be a memory leak) - public static object Literal(this string value) - { - if (value == null) return _null; - - object boxed = _boxed[value]; - if (boxed == null) - { - lock (_boxed) - { - boxed = _boxed[value]; - if (boxed == null) - { - boxed = (RedisValue)value; - _boxed.Add(value, boxed); - } - } - } - return boxed; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/NRediSearch.csproj b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/NRediSearch.csproj deleted file mode 100644 index 673bb28..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/NRediSearch.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - $(LibraryTargetFrameworks) - 0.1 - false - Redis;Search;Modules;RediSearch - - - - - \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Query.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Query.cs deleted file mode 100644 index 79b4879..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Query.cs +++ /dev/null @@ -1,294 +0,0 @@ -// .NET port of https://github.com/RedisLabs/JRediSearch/ - -using StackExchange.Redis; -using System; -using System.Collections.Generic; -using System.Globalization; - -namespace NRediSearch -{ - /// - /// Query represents query parameters and filters to load results from the engine - /// - public class Query - { - /// - /// Filter represents a filtering rules in a query - /// - public abstract class Filter - { - - public string Property { get; } - - internal abstract void SerializeRedisArgs(List args); - - internal Filter(string property) - { - Property = property; - } - - } - - /// - /// NumericFilter wraps a range filter on a numeric field. It can be inclusive or exclusive - /// - public class NumericFilter : Filter - { - - private readonly double min, max; - private readonly bool exclusiveMin, exclusiveMax; - - public NumericFilter(string property, double min, bool exclusiveMin, double max, bool exclusiveMax) : base(property) - { - this.min = min; - this.max = max; - this.exclusiveMax = exclusiveMax; - this.exclusiveMin = exclusiveMin; - } - - public NumericFilter(string property, double min, double max) : this(property, min, false, max, false) { } - - - internal override void SerializeRedisArgs(List args) - { - RedisValue FormatNum(double num, bool exclude) - { - if (!exclude || double.IsInfinity(num)) - { - return (RedisValue)num; // can use directly - } - // need to add leading bracket - return "(" + num.ToString("G17", NumberFormatInfo.InvariantInfo); - } - args.Add("FILTER".Literal()); - args.Add(Property); - args.Add(FormatNum(min, exclusiveMin)); - args.Add(FormatNum(max, exclusiveMax)); - } - } - - /// - /// GeoFilter encapsulates a radius filter on a geographical indexed fields - /// - public class GeoFilter : Filter - { - - private readonly double lon, lat, radius; - private GeoUnit unit; - - public GeoFilter(string property, double lon, double lat, double radius, GeoUnit unit) : base(property) - { - this.lon = lon; - this.lat = lat; - this.radius = radius; - this.unit = unit; - } - - internal override void SerializeRedisArgs(List args) - { - args.Add("GEOFILTER".Literal()); - args.Add(Property); - args.Add(lon); - args.Add(lat); - args.Add(radius); - - switch (unit) - { - case GeoUnit.Feet: args.Add("ft".Literal()); break; - case GeoUnit.Kilometers: args.Add("km".Literal()); break; - case GeoUnit.Meters: args.Add("m".Literal()); break; - case GeoUnit.Miles: args.Add("mi".Literal()); break; - default: throw new InvalidOperationException($"Unknown unit: {unit}"); - } - } - } - - private struct Paging - { - public int Offset { get; } - public int Count { get; } - - public Paging(int offset, int count) - { - Offset = offset; - Count = count; - } - } - - /// - /// The query's filter list. We only support AND operation on all those filters - /// - List _filters = new List(); - - /// - /// The textual part of the query - /// - public string QueryString { get; } - - /// - /// The sorting parameters - /// - Paging _paging = new Paging(0, 10); - - /// - /// Set the query to verbatim mode, disabling stemming and query expansion - /// - public bool Verbatim { get; set; } - /// - /// Set the query not to return the contents of documents, and rather just return the ids - /// - public bool NoContent { get; set; } - /// - /// Set the query not to filter for stopwords. In general this should not be used - /// - public bool NoStopwords { get; set; } - /// - /// Set the query to return a factored score for each results. This is useful to merge results from multiple queries. - /// - public bool WithScores { get; set; } - /// - /// Set the query to return object payloads, if any were given - /// - public bool WithPayloads { get; set; } - - /// - /// Set the query language, for stemming purposes; see http://redisearch.io for documentation on languages and stemming - /// - public string Language { get; set; } - protected String[] _fields = null; - /// - /// Set the query payload to be evaluated by the scoring function - /// - public byte[] Payload { get; set; } - - /// - /// Set the query parameter to sort by - /// - public string SortBy { get; set; } - - /// - /// Set the query parameter to sort by ASC by default - /// - public bool SortAscending {get; set;} = true; - - /// - /// Create a new index - /// - public Query(String queryString) - { - QueryString = queryString; - } - - internal void SerializeRedisArgs(List args) - { - args.Add(QueryString); - - if (Verbatim) - { - args.Add("VERBATIM".Literal()); - } - if (NoContent) - { - args.Add("NOCONTENT".Literal()); - } - if (NoStopwords) - { - args.Add("NOSTOPWORDS".Literal()); - } - if (WithScores) - { - args.Add("WITHSCORES".Literal()); - } - if (WithPayloads) - { - args.Add("WITHPAYLOADS".Literal()); - } - if (Language != null) - { - args.Add("LANGUAGE".Literal()); - args.Add(Language); - } - if (_fields != null && _fields.Length > 0) - { - args.Add("INFIELDS".Literal()); - args.Add(_fields.Length); - args.AddRange(_fields); - } - - if(SortBy != null) - { - args.Add("SORTBY".Literal()); - args.Add(SortBy); - args.Add((SortAscending ? "ASC" : "DESC").Literal()); - } - - if (Payload != null) - { - args.Add("PAYLOAD".Literal()); - args.Add(Payload); - } - - if (_paging.Offset != 0 || _paging.Count != 10) - { - args.Add("LIMIT".Literal()); - args.Add(_paging.Offset); - args.Add(_paging.Count); - } - - if (_filters != null && _filters.Count > 0) - { - foreach (var f in _filters) - { - f.SerializeRedisArgs(args); - } - } - } - - /// - /// Limit the results to a certain offset and limit - /// - /// the first result to show, zero based indexing - /// how many results we want to show - /// the query itself, for builder-style syntax - public Query Limit(int offset, int count) - { - _paging = new Paging(offset, count); - return this; - } - - /// - /// Add a filter to the query's filter list - /// - /// either a numeric or geo filter object - /// the query itself - public Query AddFilter(Filter f) - { - _filters.Add(f); - return this; - } - - /// - /// Limit the query to results that are limited to a specific set of fields - /// - /// a list of TEXT fields in the schemas - /// the query object itself - public Query LimitFields(params string[] fields) - { - this._fields = fields; - return this; - } - - /// - /// Set the query to be sorted by a sortable field defined in the schema - /// - /// the sorting field's name - /// if set to true, the sorting order is ascending, else descending - /// the query object itself - public Query SetSortBy(string field, bool ascending = true) - { - SortBy = field; - SortAscending = ascending; - return this; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Schema.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Schema.cs deleted file mode 100644 index bb729fb..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/Schema.cs +++ /dev/null @@ -1,133 +0,0 @@ -// .NET port of https://github.com/RedisLabs/JRediSearch/ - -using System; -using System.Collections.Generic; - -namespace NRediSearch -{ - /// - /// Schema abstracts the schema definition when creating an index. - /// Documents can contain fields not mentioned in the schema, but the index will only index pre-defined fields - /// - public sealed class Schema - { - public enum FieldType - { - FullText, - Geo, - Numeric - } - - public class Field - { - public String Name { get; } - public FieldType Type { get; } - public bool Sortable {get;} - - internal Field(string name, FieldType type, bool sortable) - { - Name = name; - Type = type; - Sortable = sortable; - } - - internal virtual void SerializeRedisArgs(List args) - { - object GetForRedis(FieldType type) - { - switch (type) - { - case FieldType.FullText: return "TEXT".Literal(); - case FieldType.Geo: return "GEO".Literal(); - case FieldType.Numeric: return "NUMERIC".Literal(); - default: throw new ArgumentOutOfRangeException(nameof(type)); - } - } - args.Add(Name); - args.Add(GetForRedis(Type)); - if(Sortable){args.Add("SORTABLE");} - } - } - public class TextField : Field - { - public double Weight { get; } - internal TextField(string name, double weight = 1.0) : base(name, FieldType.FullText, false) - { - Weight = weight; - } - internal TextField(string name, bool sortable, double weight = 1.0) : base(name, FieldType.FullText, sortable) - { - Weight = weight; - } - internal override void SerializeRedisArgs(List args) - { - base.SerializeRedisArgs(args); - if (Weight != 1.0) - { - args.Add("WEIGHT".Literal()); - args.Add(Weight); - } - } - } - - public List Fields { get; } = new List(); - - /// - /// Add a text field to the schema with a given weight - /// - /// the field's name - /// its weight, a positive floating point number - /// the schema object - public Schema AddTextField(string name, double weight = 1.0) - { - Fields.Add(new TextField(name, weight)); - return this; - } - - /// - /// Add a text field that can be sorted on - /// - /// the field's name - /// its weight, a positive floating point number - /// the schema object - public Schema AddSortableTextField(string name, double weight = 1.0) - { - Fields.Add(new TextField(name, true, weight)); - return this; - } - - /// - /// Add a numeric field to the schema - /// - /// the field's name - /// the schema object - public Schema AddGeoField(string name) - { - Fields.Add(new Field(name, FieldType.Geo, false)); - return this; - } - - /// - /// Add a numeric field to the schema - /// - /// the field's name - /// the schema object - public Schema AddNumericField(string name) - { - Fields.Add(new Field(name, FieldType.Numeric, false)); - return this; - } - - /// - /// Add a numeric field that can be sorted on - /// - /// the field's name - /// the schema object - public Schema AddSortableNumericField(string name) - { - Fields.Add(new Field(name, FieldType.Numeric, true)); - return this; - } - - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/SearchResult.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/SearchResult.cs deleted file mode 100644 index d974ad2..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NRediSearch/SearchResult.cs +++ /dev/null @@ -1,75 +0,0 @@ -// .NET port of https://github.com/RedisLabs/JRediSearch/ - -using StackExchange.Redis; -using System.Collections.Generic; - -namespace NRediSearch -{ - /// - /// SearchResult encapsulates the returned result from a search query. - /// It contains publically accessible fields for the total number of results, and an array of - /// objects conatining the actual returned documents. - /// - public class SearchResult - { - public long TotalResults { get; } - public List Documents { get; } - - - internal SearchResult(RedisResult[] resp, bool hasContent, bool hasScores, bool hasPayloads) - { - // Calculate the step distance to walk over the results. - // The order of results is id, score (if withScore), payLoad (if hasPayloads), fields - int step = 1; - int scoreOffset = 0; - int contentOffset = 1; - int payloadOffset = 0; - if (hasScores) - { - step += 1; - scoreOffset = 1; - contentOffset += 1; - } - if (hasContent) - { - step += 1; - if (hasPayloads) - { - payloadOffset = scoreOffset + 1; - step += 1; - contentOffset += 1; - } - } - - // the first element is always the number of results - TotalResults = (long)resp[0]; - var docs = new List((resp.Length - 1) / step); - Documents = docs; - for (int i = 1; i < resp.Length; i += step) - { - - var id = (string)resp[i]; - double score = 1.0; - byte[] payload = null; - RedisValue[] fields = null; - if (hasScores) - { - score = (double)resp[i + scoreOffset]; - } - if (hasPayloads) - { - payload = (byte[])resp[i + payloadOffset]; - } - - if (hasContent) - { - fields = (RedisValue[])resp[i + contentOffset]; - } - - docs.Add(Document.Load(id, score, payload, fields)); - } - - - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NuGet.Config b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NuGet.Config deleted file mode 100644 index d80bb29..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/NuGet.Config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/README.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/README.md deleted file mode 100644 index 3bed651..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/README.md +++ /dev/null @@ -1,4 +0,0 @@ -StackExchange.Redis -=================== - -For all documentation, [see here](http://stackexchange.github.io/StackExchange.Redis/) \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7000/nodes.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7000/nodes.conf deleted file mode 100644 index e72c20b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7000/nodes.conf +++ /dev/null @@ -1,7 +0,0 @@ -ea828c6074663c8bd4e705d3e3024d9d1721ef3b 127.0.0.1:7001 master - 0 1467584830754 2 connected 5461-10922 -5ffbeb7f7872923ee0ed0913aedfe806265f5090 127.0.0.1:7003 slave 780813af558af81518e58e495d63b6e248e80adf 0 1467584830349 4 connected -780813af558af81518e58e495d63b6e248e80adf 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460 -eaf2fc952dad107ffa28c0f436f73c3d52112276 127.0.0.1:7004 slave ea828c6074663c8bd4e705d3e3024d9d1721ef3b 0 1467584830854 5 connected -b1dc6b4fd60ffcff552d669b3294f6991ccb2b68 127.0.0.1:7005 slave 17f2a81c7fc22283ef93bf118cedb193a1122399 0 1467584829346 6 connected -17f2a81c7fc22283ef93bf118cedb193a1122399 127.0.0.1:7002 master - 0 1467584830754 3 connected 10923-16383 -vars currentEpoch 6 lastVoteEpoch 0 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7000/redis.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7000/redis.conf deleted file mode 100644 index 5e62bb5..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7000/redis.conf +++ /dev/null @@ -1,4 +0,0 @@ -cluster-enabled yes -cluster-config-file nodes.conf -cluster-node-timeout 5000 -appendonly yes \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7001/nodes.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7001/nodes.conf deleted file mode 100644 index b5c1041..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7001/nodes.conf +++ /dev/null @@ -1,7 +0,0 @@ -eaf2fc952dad107ffa28c0f436f73c3d52112276 127.0.0.1:7004 slave ea828c6074663c8bd4e705d3e3024d9d1721ef3b 0 1467584830397 5 connected -b1dc6b4fd60ffcff552d669b3294f6991ccb2b68 127.0.0.1:7005 slave 17f2a81c7fc22283ef93bf118cedb193a1122399 0 1467584829393 6 connected -17f2a81c7fc22283ef93bf118cedb193a1122399 127.0.0.1:7002 master - 0 1467584829092 3 connected 10923-16383 -780813af558af81518e58e495d63b6e248e80adf 127.0.0.1:7000 master - 0 1467584829895 1 connected 0-5460 -5ffbeb7f7872923ee0ed0913aedfe806265f5090 127.0.0.1:7003 slave 780813af558af81518e58e495d63b6e248e80adf 0 1467584831402 4 connected -ea828c6074663c8bd4e705d3e3024d9d1721ef3b 127.0.0.1:7001 myself,master - 0 0 2 connected 5461-10922 -vars currentEpoch 6 lastVoteEpoch 0 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7001/redis.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7001/redis.conf deleted file mode 100644 index 5e62bb5..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7001/redis.conf +++ /dev/null @@ -1,4 +0,0 @@ -cluster-enabled yes -cluster-config-file nodes.conf -cluster-node-timeout 5000 -appendonly yes \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7002/nodes.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7002/nodes.conf deleted file mode 100644 index 36ce107..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7002/nodes.conf +++ /dev/null @@ -1,7 +0,0 @@ -ea828c6074663c8bd4e705d3e3024d9d1721ef3b 127.0.0.1:7001 master - 0 1467584829405 2 connected 5461-10922 -5ffbeb7f7872923ee0ed0913aedfe806265f5090 127.0.0.1:7003 slave 780813af558af81518e58e495d63b6e248e80adf 0 1467584831415 4 connected -b1dc6b4fd60ffcff552d669b3294f6991ccb2b68 127.0.0.1:7005 slave 17f2a81c7fc22283ef93bf118cedb193a1122399 0 1467584831615 6 connected -eaf2fc952dad107ffa28c0f436f73c3d52112276 127.0.0.1:7004 slave ea828c6074663c8bd4e705d3e3024d9d1721ef3b 0 1467584830408 5 connected -780813af558af81518e58e495d63b6e248e80adf 127.0.0.1:7000 master - 0 1467584830914 1 connected 0-5460 -17f2a81c7fc22283ef93bf118cedb193a1122399 127.0.0.1:7002 myself,master - 0 0 3 connected 10923-16383 -vars currentEpoch 6 lastVoteEpoch 0 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7002/redis.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7002/redis.conf deleted file mode 100644 index 5e62bb5..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7002/redis.conf +++ /dev/null @@ -1,4 +0,0 @@ -cluster-enabled yes -cluster-config-file nodes.conf -cluster-node-timeout 5000 -appendonly yes \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7003/nodes.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7003/nodes.conf deleted file mode 100644 index edefab1..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7003/nodes.conf +++ /dev/null @@ -1,7 +0,0 @@ -ea828c6074663c8bd4e705d3e3024d9d1721ef3b 127.0.0.1:7001 master - 0 1467584829099 2 connected 5461-10922 -b1dc6b4fd60ffcff552d669b3294f6991ccb2b68 127.0.0.1:7005 slave 17f2a81c7fc22283ef93bf118cedb193a1122399 0 1467584829099 6 connected -eaf2fc952dad107ffa28c0f436f73c3d52112276 127.0.0.1:7004 slave ea828c6074663c8bd4e705d3e3024d9d1721ef3b 0 1467584830405 5 connected -17f2a81c7fc22283ef93bf118cedb193a1122399 127.0.0.1:7002 master - 0 1467584829399 3 connected 10923-16383 -5ffbeb7f7872923ee0ed0913aedfe806265f5090 127.0.0.1:7003 myself,slave 780813af558af81518e58e495d63b6e248e80adf 0 0 4 connected -780813af558af81518e58e495d63b6e248e80adf 127.0.0.1:7000 master - 0 1467584831436 1 connected 0-5460 -vars currentEpoch 6 lastVoteEpoch 0 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7003/redis.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7003/redis.conf deleted file mode 100644 index 5e62bb5..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7003/redis.conf +++ /dev/null @@ -1,4 +0,0 @@ -cluster-enabled yes -cluster-config-file nodes.conf -cluster-node-timeout 5000 -appendonly yes \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7004/nodes.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7004/nodes.conf deleted file mode 100644 index 201f97d..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7004/nodes.conf +++ /dev/null @@ -1,7 +0,0 @@ -17f2a81c7fc22283ef93bf118cedb193a1122399 127.0.0.1:7002 master - 0 1467584828911 3 connected 10923-16383 -5ffbeb7f7872923ee0ed0913aedfe806265f5090 127.0.0.1:7003 slave 780813af558af81518e58e495d63b6e248e80adf 0 1467584829103 4 connected -780813af558af81518e58e495d63b6e248e80adf 127.0.0.1:7000 master - 0 1467584829407 1 connected 0-5460 -ea828c6074663c8bd4e705d3e3024d9d1721ef3b 127.0.0.1:7001 master - 0 1467584830411 2 connected 5461-10922 -b1dc6b4fd60ffcff552d669b3294f6991ccb2b68 127.0.0.1:7005 slave 17f2a81c7fc22283ef93bf118cedb193a1122399 0 1467584829207 6 connected -eaf2fc952dad107ffa28c0f436f73c3d52112276 127.0.0.1:7004 myself,slave ea828c6074663c8bd4e705d3e3024d9d1721ef3b 0 0 5 connected -vars currentEpoch 6 lastVoteEpoch 0 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7004/redis.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7004/redis.conf deleted file mode 100644 index 5e62bb5..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7004/redis.conf +++ /dev/null @@ -1,4 +0,0 @@ -cluster-enabled yes -cluster-config-file nodes.conf -cluster-node-timeout 5000 -appendonly yes \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7005/nodes.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7005/nodes.conf deleted file mode 100644 index f695cba..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7005/nodes.conf +++ /dev/null @@ -1,7 +0,0 @@ -eaf2fc952dad107ffa28c0f436f73c3d52112276 127.0.0.1:7004 slave ea828c6074663c8bd4e705d3e3024d9d1721ef3b 0 1467584831428 5 connected -5ffbeb7f7872923ee0ed0913aedfe806265f5090 127.0.0.1:7003 slave 780813af558af81518e58e495d63b6e248e80adf 0 1467584831528 4 connected -780813af558af81518e58e495d63b6e248e80adf 127.0.0.1:7000 master - 0 1467584830927 1 connected 0-5460 -ea828c6074663c8bd4e705d3e3024d9d1721ef3b 127.0.0.1:7001 master - 0 1467584830407 2 connected 5461-10922 -b1dc6b4fd60ffcff552d669b3294f6991ccb2b68 127.0.0.1:7005 myself,slave 17f2a81c7fc22283ef93bf118cedb193a1122399 0 0 6 connected -17f2a81c7fc22283ef93bf118cedb193a1122399 127.0.0.1:7002 master - 0 1467584829400 3 connected 10923-16383 -vars currentEpoch 6 lastVoteEpoch 0 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7005/redis.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7005/redis.conf deleted file mode 100644 index 5e62bb5..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/Cluster/7005/redis.conf +++ /dev/null @@ -1,4 +0,0 @@ -cluster-enabled yes -cluster-config-file nodes.conf -cluster-node-timeout 5000 -appendonly yes \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/master.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/master.conf deleted file mode 100644 index 6e7bd43..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/master.conf +++ /dev/null @@ -1,5 +0,0 @@ -port 6379 -dbfilename master.rdb -databases 2000 -maxmemory 6gb -save "" \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7000.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7000.cmd deleted file mode 100644 index dbbaab9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7000.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\packages\Redis-64.3.0.503\redis-cli.exe -h 127.0.0.1 -p 7000 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7001.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7001.cmd deleted file mode 100644 index 22488be..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7001.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\packages\Redis-64.3.0.503\redis-cli.exe -h 127.0.0.1 -p 7001 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7002.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7002.cmd deleted file mode 100644 index cd7c9d0..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7002.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\packages\Redis-64.3.0.503\redis-cli.exe -h 127.0.0.1 -p 7002 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7003.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7003.cmd deleted file mode 100644 index 16c0f6c..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7003.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\packages\Redis-64.3.0.503\redis-cli.exe -h 127.0.0.1 -p 7003 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7004.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7004.cmd deleted file mode 100644 index 574a98d..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7004.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\packages\Redis-64.3.0.503\redis-cli.exe -h 127.0.0.1 -p 7004 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7005.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7005.cmd deleted file mode 100644 index 5a702e0..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli 7005.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\packages\Redis-64.3.0.503\redis-cli.exe -h 127.0.0.1 -p 7005 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli master.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli master.cmd deleted file mode 100644 index 1bc7266..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli master.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\packages\Redis-64.3.0.503\redis-cli.exe -p 6379 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli secure.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli secure.cmd deleted file mode 100644 index 84546d7..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli secure.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\packages\Redis-64.3.0.503\redis-cli.exe -p 6381 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli slave.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli slave.cmd deleted file mode 100644 index 91e215b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-cli slave.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\packages\Redis-64.3.0.503\redis-cli.exe -p 6380 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server all local.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server all local.cmd deleted file mode 100644 index 6644b6a..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server all local.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@start ..\packages\Redis-64.3.0.503\redis-server.exe master.conf -@start ..\packages\Redis-64.3.0.503\redis-server.exe slave.conf -@start ..\packages\Redis-64.3.0.503\redis-server.exe secure.conf diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server cluster.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server cluster.cmd deleted file mode 100644 index 8faec24..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server cluster.cmd +++ /dev/null @@ -1,19 +0,0 @@ -@echo off -pushd Cluster\7000 -@start /min ..\..\..\packages\Redis-64.3.0.503\redis-server.exe redis.conf --port 7000 -popd -pushd Cluster\7001 -@start /min ..\..\..\packages\Redis-64.3.0.503\redis-server.exe redis.conf --port 7001 -popd -pushd Cluster\7002 -@start /min ..\..\..\packages\Redis-64.3.0.503\redis-server.exe redis.conf --port 7002 -popd -pushd Cluster\7003 -@start /min ..\..\..\packages\Redis-64.3.0.503\redis-server.exe redis.conf --port 7003 -popd -pushd Cluster\7004 -@start /min ..\..\..\packages\Redis-64.3.0.503\redis-server.exe redis.conf --port 7004 -popd -pushd Cluster\7005 -@start /min ..\..\..\packages\Redis-64.3.0.503\redis-server.exe redis.conf --port 7005 -popd \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server master.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server master.cmd deleted file mode 100644 index 9432c3e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server master.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\packages\Redis-64.3.0.503\redis-server.exe master.conf diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server secure.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server secure.cmd deleted file mode 100644 index 2fcb360..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server secure.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\packages\Redis-64.3.0.503\redis-server.exe secure.conf diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server slave.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server slave.cmd deleted file mode 100644 index 9f75faa..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-server slave.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\packages\Redis-64.3.0.503\redis-server.exe slave.conf diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-trib.rb b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-trib.rb deleted file mode 100644 index 1c3d7ed..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/redis-trib.rb +++ /dev/null @@ -1,1699 +0,0 @@ -#!/usr/bin/env ruby - -# redis-trib from the main redis repo at: -# https://github.com/antirez/redis/blob/unstable/src/redis-trib.rb - -# TODO (temporary here, we'll move this into the Github issues once -# redis-trib initial implementation is completed). -# -# - Make sure that if the rehashing fails in the middle redis-trib will try -# to recover. -# - When redis-trib performs a cluster check, if it detects a slot move in -# progress it should prompt the user to continue the move from where it -# stopped. -# - Gracefully handle Ctrl+C in move_slot to prompt the user if really stop -# while rehashing, and performing the best cleanup possible if the user -# forces the quit. -# - When doing "fix" set a global Fix to true, and prompt the user to -# fix the problem if automatically fixable every time there is something -# to fix. For instance: -# 1) If there is a node that pretend to receive a slot, or to migrate a -# slot, but has no entries in that slot, fix it. -# 2) If there is a node having keys in slots that are not owned by it -# fix this condition moving the entries in the same node. -# 3) Perform more possibly slow tests about the state of the cluster. -# 4) When aborted slot migration is detected, fix it. - -require 'rubygems' -require 'redis' - -ClusterHashSlots = 16384 -MigrateDefaultTimeout = 60000 -MigrateDefaultPipeline = 10 -RebalanceDefaultThreshold = 2 - -$verbose = false - -def xputs(s) - case s[0..2] - when ">>>" - color="29;1" - when "[ER" - color="31;1" - when "[WA" - color="31;1" - when "[OK" - color="32" - when "[FA","***" - color="33" - else - color=nil - end - - color = nil if ENV['TERM'] != "xterm" - print "\033[#{color}m" if color - print s - print "\033[0m" if color - print "\n" -end - -class ClusterNode - def initialize(addr) - s = addr.split("@")[0].split(":") - if s.length < 2 - puts "Invalid IP or Port (given as #{addr}) - use IP:Port format" - exit 1 - end - port = s.pop # removes port from split array - ip = s.join(":") # if s.length > 1 here, it's IPv6, so restore address - @r = nil - @info = {} - @info[:host] = ip - @info[:port] = port - @info[:slots] = {} - @info[:migrating] = {} - @info[:importing] = {} - @info[:replicate] = false - @dirty = false # True if we need to flush slots info into node. - @friends = [] - end - - def friends - @friends - end - - def slots - @info[:slots] - end - - def has_flag?(flag) - @info[:flags].index(flag) - end - - def to_s - "#{@info[:host]}:#{@info[:port]}" - end - - def connect(o={}) - return if @r - print "Connecting to node #{self}: " if $verbose - STDOUT.flush - begin - @r = Redis.new(:host => @info[:host], :port => @info[:port], :timeout => 60) - @r.ping - rescue - xputs "[ERR] Sorry, can't connect to node #{self}" - exit 1 if o[:abort] - @r = nil - end - xputs "OK" if $verbose - end - - def assert_cluster - info = @r.info - if !info["cluster_enabled"] || info["cluster_enabled"].to_i == 0 - xputs "[ERR] Node #{self} is not configured as a cluster node." - exit 1 - end - end - - def assert_empty - if !(@r.cluster("info").split("\r\n").index("cluster_known_nodes:1")) || - (@r.info['db0']) - xputs "[ERR] Node #{self} is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0." - exit 1 - end - end - - def load_info(o={}) - self.connect - nodes = @r.cluster("nodes").split("\n") - nodes.each{|n| - # name addr flags role ping_sent ping_recv link_status slots - split = n.split - name,addr,flags,master_id,ping_sent,ping_recv,config_epoch,link_status = split[0..6] - slots = split[8..-1] - info = { - :name => name, - :addr => addr, - :flags => flags.split(","), - :replicate => master_id, - :ping_sent => ping_sent.to_i, - :ping_recv => ping_recv.to_i, - :link_status => link_status - } - info[:replicate] = false if master_id == "-" - - if info[:flags].index("myself") - @info = @info.merge(info) - @info[:slots] = {} - slots.each{|s| - if s[0..0] == '[' - if s.index("->-") # Migrating - slot,dst = s[1..-1].split("->-") - @info[:migrating][slot.to_i] = dst - elsif s.index("-<-") # Importing - slot,src = s[1..-1].split("-<-") - @info[:importing][slot.to_i] = src - end - elsif s.index("-") - start,stop = s.split("-") - self.add_slots((start.to_i)..(stop.to_i)) - else - self.add_slots((s.to_i)..(s.to_i)) - end - } if slots - @dirty = false - @r.cluster("info").split("\n").each{|e| - k,v=e.split(":") - k = k.to_sym - v.chop! - if k != :cluster_state - @info[k] = v.to_i - else - @info[k] = v - end - } - elsif o[:getfriends] - @friends << info - end - } - end - - def add_slots(slots) - slots.each{|s| - @info[:slots][s] = :new - } - @dirty = true - end - - def set_as_replica(node_id) - @info[:replicate] = node_id - @dirty = true - end - - def flush_node_config - return if !@dirty - if @info[:replicate] - begin - @r.cluster("replicate",@info[:replicate]) - rescue - # If the cluster did not already joined it is possible that - # the slave does not know the master node yet. So on errors - # we return ASAP leaving the dirty flag set, to flush the - # config later. - return - end - else - new = [] - @info[:slots].each{|s,val| - if val == :new - new << s - @info[:slots][s] = true - end - } - @r.cluster("addslots",*new) - end - @dirty = false - end - - def info_string - # We want to display the hash slots assigned to this node - # as ranges, like in: "1-5,8-9,20-25,30" - # - # Note: this could be easily written without side effects, - # we use 'slots' just to split the computation into steps. - - # First step: we want an increasing array of integers - # for instance: [1,2,3,4,5,8,9,20,21,22,23,24,25,30] - slots = @info[:slots].keys.sort - - # As we want to aggregate adjacent slots we convert all the - # slot integers into ranges (with just one element) - # So we have something like [1..1,2..2, ... and so forth. - slots.map!{|x| x..x} - - # Finally we group ranges with adjacent elements. - slots = slots.reduce([]) {|a,b| - if !a.empty? && b.first == (a[-1].last)+1 - a[0..-2] + [(a[-1].first)..(b.last)] - else - a + [b] - end - } - - # Now our task is easy, we just convert ranges with just one - # element into a number, and a real range into a start-end format. - # Finally we join the array using the comma as separator. - slots = slots.map{|x| - x.count == 1 ? x.first.to_s : "#{x.first}-#{x.last}" - }.join(",") - - role = self.has_flag?("master") ? "M" : "S" - - if self.info[:replicate] and @dirty - is = "S: #{self.info[:name]} #{self.to_s}" - else - is = "#{role}: #{self.info[:name]} #{self.to_s}\n"+ - " slots:#{slots} (#{self.slots.length} slots) "+ - "#{(self.info[:flags]-["myself"]).join(",")}" - end - if self.info[:replicate] - is += "\n replicates #{info[:replicate]}" - elsif self.has_flag?("master") && self.info[:replicas] - is += "\n #{info[:replicas].length} additional replica(s)" - end - is - end - - # Return a single string representing nodes and associated slots. - # TODO: remove slaves from config when slaves will be handled - # by Redis Cluster. - def get_config_signature - config = [] - @r.cluster("nodes").each_line{|l| - s = l.split - slots = s[8..-1].select {|x| x[0..0] != "["} - next if slots.length == 0 - config << s[0]+":"+(slots.sort.join(",")) - } - config.sort.join("|") - end - - def info - @info - end - - def is_dirty? - @dirty - end - - def r - @r - end -end - -class RedisTrib - def initialize - @nodes = [] - @fix = false - @errors = [] - @timeout = MigrateDefaultTimeout - end - - def check_arity(req_args, num_args) - if ((req_args > 0 and num_args != req_args) || - (req_args < 0 and num_args < req_args.abs)) - xputs "[ERR] Wrong number of arguments for specified sub command" - exit 1 - end - end - - def add_node(node) - @nodes << node - end - - def reset_nodes - @nodes = [] - end - - def cluster_error(msg) - @errors << msg - xputs msg - end - - # Return the node with the specified ID or Nil. - def get_node_by_name(name) - @nodes.each{|n| - return n if n.info[:name] == name.downcase - } - return nil - end - - # Like get_node_by_name but the specified name can be just the first - # part of the node ID as long as the prefix in unique across the - # cluster. - def get_node_by_abbreviated_name(name) - l = name.length - candidates = [] - @nodes.each{|n| - if n.info[:name][0...l] == name.downcase - candidates << n - end - } - return nil if candidates.length != 1 - candidates[0] - end - - # This function returns the master that has the least number of replicas - # in the cluster. If there are multiple masters with the same smaller - # number of replicas, one at random is returned. - def get_master_with_least_replicas - masters = @nodes.select{|n| n.has_flag? "master"} - sorted = masters.sort{|a,b| - a.info[:replicas].length <=> b.info[:replicas].length - } - sorted[0] - end - - def check_cluster(opt={}) - xputs ">>> Performing Cluster Check (using node #{@nodes[0]})" - show_nodes if !opt[:quiet] - check_config_consistency - check_open_slots - check_slots_coverage - end - - def show_cluster_info - masters = 0 - keys = 0 - @nodes.each{|n| - if n.has_flag?("master") - puts "#{n} (#{n.info[:name][0...8]}...) -> #{n.r.dbsize} keys | #{n.slots.length} slots | "+ - "#{n.info[:replicas].length} slaves." - masters += 1 - keys += n.r.dbsize - end - } - xputs "[OK] #{keys} keys in #{masters} masters." - keys_per_slot = sprintf("%.2f",keys/16384.0) - puts "#{keys_per_slot} keys per slot on average." - end - - # Merge slots of every known node. If the resulting slots are equal - # to ClusterHashSlots, then all slots are served. - def covered_slots - slots = {} - @nodes.each{|n| - slots = slots.merge(n.slots) - } - slots - end - - def check_slots_coverage - xputs ">>> Check slots coverage..." - slots = covered_slots - if slots.length == ClusterHashSlots - xputs "[OK] All #{ClusterHashSlots} slots covered." - else - cluster_error \ - "[ERR] Not all #{ClusterHashSlots} slots are covered by nodes." - fix_slots_coverage if @fix - end - end - - def check_open_slots - xputs ">>> Check for open slots..." - open_slots = [] - @nodes.each{|n| - if n.info[:migrating].size > 0 - cluster_error \ - "[WARNING] Node #{n} has slots in migrating state (#{n.info[:migrating].keys.join(",")})." - open_slots += n.info[:migrating].keys - end - if n.info[:importing].size > 0 - cluster_error \ - "[WARNING] Node #{n} has slots in importing state (#{n.info[:importing].keys.join(",")})." - open_slots += n.info[:importing].keys - end - } - open_slots.uniq! - if open_slots.length > 0 - xputs "[WARNING] The following slots are open: #{open_slots.join(",")}" - end - if @fix - open_slots.each{|slot| fix_open_slot slot} - end - end - - def nodes_with_keys_in_slot(slot) - nodes = [] - @nodes.each{|n| - next if n.has_flag?("slave") - nodes << n if n.r.cluster("getkeysinslot",slot,1).length > 0 - } - nodes - end - - def fix_slots_coverage - not_covered = (0...ClusterHashSlots).to_a - covered_slots.keys - xputs ">>> Fixing slots coverage..." - xputs "List of not covered slots: " + not_covered.join(",") - - # For every slot, take action depending on the actual condition: - # 1) No node has keys for this slot. - # 2) A single node has keys for this slot. - # 3) Multiple nodes have keys for this slot. - slots = {} - not_covered.each{|slot| - nodes = nodes_with_keys_in_slot(slot) - slots[slot] = nodes - xputs "Slot #{slot} has keys in #{nodes.length} nodes: #{nodes.join(", ")}" - } - - none = slots.select {|k,v| v.length == 0} - single = slots.select {|k,v| v.length == 1} - multi = slots.select {|k,v| v.length > 1} - - # Handle case "1": keys in no node. - if none.length > 0 - xputs "The folowing uncovered slots have no keys across the cluster:" - xputs none.keys.join(",") - yes_or_die "Fix these slots by covering with a random node?" - none.each{|slot,nodes| - node = @nodes.sample - xputs ">>> Covering slot #{slot} with #{node}" - node.r.cluster("addslots",slot) - } - end - - # Handle case "2": keys only in one node. - if single.length > 0 - xputs "The folowing uncovered slots have keys in just one node:" - puts single.keys.join(",") - yes_or_die "Fix these slots by covering with those nodes?" - single.each{|slot,nodes| - xputs ">>> Covering slot #{slot} with #{nodes[0]}" - nodes[0].r.cluster("addslots",slot) - } - end - - # Handle case "3": keys in multiple nodes. - if multi.length > 0 - xputs "The folowing uncovered slots have keys in multiple nodes:" - xputs multi.keys.join(",") - yes_or_die "Fix these slots by moving keys into a single node?" - multi.each{|slot,nodes| - target = get_node_with_most_keys_in_slot(nodes,slot) - xputs ">>> Covering slot #{slot} moving keys to #{target}" - - target.r.cluster('addslots',slot) - target.r.cluster('setslot',slot,'stable') - nodes.each{|src| - next if src == target - # Set the source node in 'importing' state (even if we will - # actually migrate keys away) in order to avoid receiving - # redirections for MIGRATE. - src.r.cluster('setslot',slot,'importing',target.info[:name]) - move_slot(src,target,slot,:dots=>true,:fix=>true,:cold=>true) - src.r.cluster('setslot',slot,'stable') - } - } - end - end - - # Return the owner of the specified slot - def get_slot_owners(slot) - owners = [] - @nodes.each{|n| - next if n.has_flag?("slave") - n.slots.each{|s,_| - owners << n if s == slot - } - } - owners - end - - # Return the node, among 'nodes' with the greatest number of keys - # in the specified slot. - def get_node_with_most_keys_in_slot(nodes,slot) - best = nil - best_numkeys = 0 - @nodes.each{|n| - next if n.has_flag?("slave") - numkeys = n.r.cluster("countkeysinslot",slot) - if numkeys > best_numkeys || best == nil - best = n - best_numkeys = numkeys - end - } - return best - end - - # Slot 'slot' was found to be in importing or migrating state in one or - # more nodes. This function fixes this condition by migrating keys where - # it seems more sensible. - def fix_open_slot(slot) - puts ">>> Fixing open slot #{slot}" - - # Try to obtain the current slot owner, according to the current - # nodes configuration. - owners = get_slot_owners(slot) - owner = owners[0] if owners.length == 1 - - migrating = [] - importing = [] - @nodes.each{|n| - next if n.has_flag? "slave" - if n.info[:migrating][slot] - migrating << n - elsif n.info[:importing][slot] - importing << n - elsif n.r.cluster("countkeysinslot",slot) > 0 && n != owner - xputs "*** Found keys about slot #{slot} in node #{n}!" - importing << n - end - } - puts "Set as migrating in: #{migrating.join(",")}" - puts "Set as importing in: #{importing.join(",")}" - - # If there is no slot owner, set as owner the slot with the biggest - # number of keys, among the set of migrating / importing nodes. - if !owner - xputs ">>> Nobody claims ownership, selecting an owner..." - owner = get_node_with_most_keys_in_slot(@nodes,slot) - - # If we still don't have an owner, we can't fix it. - if !owner - xputs "[ERR] Can't select a slot owner. Impossible to fix." - exit 1 - end - - # Use ADDSLOTS to assign the slot. - puts "*** Configuring #{owner} as the slot owner" - owner.r.cluster("setslot",slot,"stable") - owner.r.cluster("addslots",slot) - # Make sure this information will propagate. Not strictly needed - # since there is no past owner, so all the other nodes will accept - # whatever epoch this node will claim the slot with. - owner.r.cluster("bumpepoch") - - # Remove the owner from the list of migrating/importing - # nodes. - migrating.delete(owner) - importing.delete(owner) - end - - # If there are multiple owners of the slot, we need to fix it - # so that a single node is the owner and all the other nodes - # are in importing state. Later the fix can be handled by one - # of the base cases above. - # - # Note that this case also covers multiple nodes having the slot - # in migrating state, since migrating is a valid state only for - # slot owners. - if owners.length > 1 - owner = get_node_with_most_keys_in_slot(owners,slot) - owners.each{|n| - next if n == owner - n.r.cluster('delslots',slot) - n.r.cluster('setslot',slot,'importing',owner.info[:name]) - importing.delete(n) # Avoid duplciates - importing << n - } - owner.r.cluster('bumpepoch') - end - - # Case 1: The slot is in migrating state in one slot, and in - # importing state in 1 slot. That's trivial to address. - if migrating.length == 1 && importing.length == 1 - move_slot(migrating[0],importing[0],slot,:dots=>true,:fix=>true) - # Case 2: There are multiple nodes that claim the slot as importing, - # they probably got keys about the slot after a restart so opened - # the slot. In this case we just move all the keys to the owner - # according to the configuration. - elsif migrating.length == 0 && importing.length > 0 - xputs ">>> Moving all the #{slot} slot keys to its owner #{owner}" - importing.each {|node| - next if node == owner - move_slot(node,owner,slot,:dots=>true,:fix=>true,:cold=>true) - xputs ">>> Setting #{slot} as STABLE in #{node}" - node.r.cluster("setslot",slot,"stable") - } - # Case 3: There are no slots claiming to be in importing state, but - # there is a migrating node that actually don't have any key. We - # can just close the slot, probably a reshard interrupted in the middle. - elsif importing.length == 0 && migrating.length == 1 && - migrating[0].r.cluster("getkeysinslot",slot,10).length == 0 - migrating[0].r.cluster("setslot",slot,"stable") - else - xputs "[ERR] Sorry, Redis-trib can't fix this slot yet (work in progress). Slot is set as migrating in #{migrating.join(",")}, as importing in #{importing.join(",")}, owner is #{owner}" - end - end - - # Check if all the nodes agree about the cluster configuration - def check_config_consistency - if !is_config_consistent? - cluster_error "[ERR] Nodes don't agree about configuration!" - else - xputs "[OK] All nodes agree about slots configuration." - end - end - - def is_config_consistent? - signatures=[] - @nodes.each{|n| - signatures << n.get_config_signature - } - return signatures.uniq.length == 1 - end - - def wait_cluster_join - print "Waiting for the cluster to join" - while !is_config_consistent? - print "." - STDOUT.flush - sleep 1 - end - print "\n" - end - - def alloc_slots - nodes_count = @nodes.length - masters_count = @nodes.length / (@replicas+1) - masters = [] - - # The first step is to split instances by IP. This is useful as - # we'll try to allocate master nodes in different physical machines - # (as much as possible) and to allocate slaves of a given master in - # different physical machines as well. - # - # This code assumes just that if the IP is different, than it is more - # likely that the instance is running in a different physical host - # or at least a different virtual machine. - ips = {} - @nodes.each{|n| - ips[n.info[:host]] = [] if !ips[n.info[:host]] - ips[n.info[:host]] << n - } - - # Select master instances - puts "Using #{masters_count} masters:" - interleaved = [] - stop = false - while not stop do - # Take one node from each IP until we run out of nodes - # across every IP. - ips.each do |ip,nodes| - if nodes.empty? - # if this IP has no remaining nodes, check for termination - if interleaved.length == nodes_count - # stop when 'interleaved' has accumulated all nodes - stop = true - next - end - else - # else, move one node from this IP to 'interleaved' - interleaved.push nodes.shift - end - end - end - - masters = interleaved.slice!(0, masters_count) - nodes_count -= masters.length - - masters.each{|m| puts m} - - # Alloc slots on masters - slots_per_node = ClusterHashSlots.to_f / masters_count - first = 0 - cursor = 0.0 - masters.each_with_index{|n,masternum| - last = (cursor+slots_per_node-1).round - if last > ClusterHashSlots || masternum == masters.length-1 - last = ClusterHashSlots-1 - end - last = first if last < first # Min step is 1. - n.add_slots first..last - first = last+1 - cursor += slots_per_node - } - - # Select N replicas for every master. - # We try to split the replicas among all the IPs with spare nodes - # trying to avoid the host where the master is running, if possible. - # - # Note we loop two times. The first loop assigns the requested - # number of replicas to each master. The second loop assigns any - # remaining instances as extra replicas to masters. Some masters - # may end up with more than their requested number of replicas, but - # all nodes will be used. - assignment_verbose = false - - [:requested,:unused].each do |assign| - masters.each do |m| - assigned_replicas = 0 - while assigned_replicas < @replicas - break if nodes_count == 0 - if assignment_verbose - if assign == :requested - puts "Requesting total of #{@replicas} replicas " \ - "(#{assigned_replicas} replicas assigned " \ - "so far with #{nodes_count} total remaining)." - elsif assign == :unused - puts "Assigning extra instance to replication " \ - "role too (#{nodes_count} remaining)." - end - end - - # Return the first node not matching our current master - node = interleaved.find{|n| n.info[:host] != m.info[:host]} - - # If we found a node, use it as a best-first match. - # Otherwise, we didn't find a node on a different IP, so we - # go ahead and use a same-IP replica. - if node - slave = node - interleaved.delete node - else - slave = interleaved.shift - end - slave.set_as_replica(m.info[:name]) - nodes_count -= 1 - assigned_replicas += 1 - puts "Adding replica #{slave} to #{m}" - - # If we are in the "assign extra nodes" loop, - # we want to assign one extra replica to each - # master before repeating masters. - # This break lets us assign extra replicas to masters - # in a round-robin way. - break if assign == :unused - end - end - end - end - - def flush_nodes_config - @nodes.each{|n| - n.flush_node_config - } - end - - def show_nodes - @nodes.each{|n| - xputs n.info_string - } - end - - # Redis Cluster config epoch collision resolution code is able to eventually - # set a different epoch to each node after a new cluster is created, but - # it is slow compared to assign a progressive config epoch to each node - # before joining the cluster. However we do just a best-effort try here - # since if we fail is not a problem. - def assign_config_epoch - config_epoch = 1 - @nodes.each{|n| - begin - n.r.cluster("set-config-epoch",config_epoch) - rescue - end - config_epoch += 1 - } - end - - def join_cluster - # We use a brute force approach to make sure the node will meet - # each other, that is, sending CLUSTER MEET messages to all the nodes - # about the very same node. - # Thanks to gossip this information should propagate across all the - # cluster in a matter of seconds. - first = false - @nodes.each{|n| - if !first then first = n.info; next; end # Skip the first node - n.r.cluster("meet",first[:host],first[:port]) - } - end - - def yes_or_die(msg) - print "#{msg} (type 'yes' to accept): " - STDOUT.flush - if !(STDIN.gets.chomp.downcase == "yes") - xputs "*** Aborting..." - exit 1 - end - end - - def load_cluster_info_from_node(nodeaddr) - node = ClusterNode.new(nodeaddr) - node.connect(:abort => true) - node.assert_cluster - node.load_info(:getfriends => true) - add_node(node) - node.friends.each{|f| - next if f[:flags].index("noaddr") || - f[:flags].index("disconnected") || - f[:flags].index("fail") - fnode = ClusterNode.new(f[:addr]) - fnode.connect() - next if !fnode.r - begin - fnode.load_info() - add_node(fnode) - rescue => e - xputs "[ERR] Unable to load info for node #{fnode}" - end - } - populate_nodes_replicas_info - end - - # This function is called by load_cluster_info_from_node in order to - # add additional information to every node as a list of replicas. - def populate_nodes_replicas_info - # Start adding the new field to every node. - @nodes.each{|n| - n.info[:replicas] = [] - } - - # Populate the replicas field using the replicate field of slave - # nodes. - @nodes.each{|n| - if n.info[:replicate] - master = get_node_by_name(n.info[:replicate]) - if !master - xputs "*** WARNING: #{n} claims to be slave of unknown node ID #{n.info[:replicate]}." - else - master.info[:replicas] << n - end - end - } - end - - # Given a list of source nodes return a "resharding plan" - # with what slots to move in order to move "numslots" slots to another - # instance. - def compute_reshard_table(sources,numslots) - moved = [] - # Sort from bigger to smaller instance, for two reasons: - # 1) If we take less slots than instances it is better to start - # getting from the biggest instances. - # 2) We take one slot more from the first instance in the case of not - # perfect divisibility. Like we have 3 nodes and need to get 10 - # slots, we take 4 from the first, and 3 from the rest. So the - # biggest is always the first. - sources = sources.sort{|a,b| b.slots.length <=> a.slots.length} - source_tot_slots = sources.inject(0) {|sum,source| - sum+source.slots.length - } - sources.each_with_index{|s,i| - # Every node will provide a number of slots proportional to the - # slots it has assigned. - n = (numslots.to_f/source_tot_slots*s.slots.length) - if i == 0 - n = n.ceil - else - n = n.floor - end - s.slots.keys.sort[(0...n)].each{|slot| - if moved.length < numslots - moved << {:source => s, :slot => slot} - end - } - } - return moved - end - - def show_reshard_table(table) - table.each{|e| - puts " Moving slot #{e[:slot]} from #{e[:source].info[:name]}" - } - end - - # Move slots between source and target nodes using MIGRATE. - # - # Options: - # :verbose -- Print a dot for every moved key. - # :fix -- We are moving in the context of a fix. Use REPLACE. - # :cold -- Move keys without opening slots / reconfiguring the nodes. - # :update -- Update nodes.info[:slots] for source/target nodes. - # :quiet -- Don't print info messages. - def move_slot(source,target,slot,o={}) - o = {:pipeline => MigrateDefaultPipeline}.merge(o) - - # We start marking the slot as importing in the destination node, - # and the slot as migrating in the target host. Note that the order of - # the operations is important, as otherwise a client may be redirected - # to the target node that does not yet know it is importing this slot. - if !o[:quiet] - print "Moving slot #{slot} from #{source} to #{target}: " - STDOUT.flush - end - - if !o[:cold] - target.r.cluster("setslot",slot,"importing",source.info[:name]) - source.r.cluster("setslot",slot,"migrating",target.info[:name]) - end - # Migrate all the keys from source to target using the MIGRATE command - while true - keys = source.r.cluster("getkeysinslot",slot,o[:pipeline]) - break if keys.length == 0 - begin - source.r.client.call(["migrate",target.info[:host],target.info[:port],"",0,@timeout,:keys,*keys]) - rescue => e - if o[:fix] && e.to_s =~ /BUSYKEY/ - xputs "*** Target key exists. Replacing it for FIX." - source.r.client.call(["migrate",target.info[:host],target.info[:port],"",0,@timeout,:replace,:keys,*keys]) - else - puts "" - xputs "[ERR] Calling MIGRATE: #{e}" - exit 1 - end - end - print "."*keys.length if o[:dots] - STDOUT.flush - end - - puts if !o[:quiet] - # Set the new node as the owner of the slot in all the known nodes. - if !o[:cold] - @nodes.each{|n| - next if n.has_flag?("slave") - n.r.cluster("setslot",slot,"node",target.info[:name]) - } - end - - # Update the node logical config - if o[:update] then - source.info[:slots].delete(slot) - target.info[:slots][slot] = true - end - end - - # redis-trib subcommands implementations. - - def check_cluster_cmd(argv,opt) - load_cluster_info_from_node(argv[0]) - check_cluster - end - - def info_cluster_cmd(argv,opt) - load_cluster_info_from_node(argv[0]) - show_cluster_info - end - - def rebalance_cluster_cmd(argv,opt) - opt = { - 'pipeline' => MigrateDefaultPipeline, - 'threshold' => RebalanceDefaultThreshold - }.merge(opt) - - # Load nodes info before parsing options, otherwise we can't - # handle --weight. - load_cluster_info_from_node(argv[0]) - - # Options parsing - threshold = opt['threshold'].to_i - autoweights = opt['auto-weights'] - weights = {} - opt['weight'].each{|w| - fields = w.split("=") - node = get_node_by_abbreviated_name(fields[0]) - if !node || !node.has_flag?("master") - puts "*** No such master node #{fields[0]}" - exit 1 - end - weights[node.info[:name]] = fields[1].to_f - } if opt['weight'] - useempty = opt['use-empty-masters'] - - # Assign a weight to each node, and compute the total cluster weight. - total_weight = 0 - nodes_involved = 0 - @nodes.each{|n| - if n.has_flag?("master") - next if !useempty && n.slots.length == 0 - n.info[:w] = weights[n.info[:name]] ? weights[n.info[:name]] : 1 - total_weight += n.info[:w] - nodes_involved += 1 - end - } - - # Check cluster, only proceed if it looks sane. - check_cluster(:quiet => true) - if @errors.length != 0 - puts "*** Please fix your cluster problems before rebalancing" - exit 1 - end - - # Calculate the slots balance for each node. It's the number of - # slots the node should lose (if positive) or gain (if negative) - # in order to be balanced. - threshold = opt['threshold'].to_f - threshold_reached = false - @nodes.each{|n| - if n.has_flag?("master") - next if !n.info[:w] - expected = ((ClusterHashSlots.to_f / total_weight) * - n.info[:w]).to_i - n.info[:balance] = n.slots.length - expected - # Compute the percentage of difference between the - # expected number of slots and the real one, to see - # if it's over the threshold specified by the user. - over_threshold = false - if threshold > 0 - if n.slots.length > 0 - err_perc = (100-(100.0*expected/n.slots.length)).abs - over_threshold = true if err_perc > threshold - elsif expected > 0 - over_threshold = true - end - end - threshold_reached = true if over_threshold - end - } - if !threshold_reached - xputs "*** No rebalancing needed! All nodes are within the #{threshold}% threshold." - return - end - - # Only consider nodes we want to change - sn = @nodes.select{|n| - n.has_flag?("master") && n.info[:w] - } - - # Because of rounding, it is possible that the balance of all nodes - # summed does not give 0. Make sure that nodes that have to provide - # slots are always matched by nodes receiving slots. - total_balance = sn.map{|x| x.info[:balance]}.reduce{|a,b| a+b} - while total_balance > 0 - sn.each{|n| - if n.info[:balance] < 0 && total_balance > 0 - n.info[:balance] -= 1 - total_balance -= 1 - end - } - end - - # Sort nodes by their slots balance. - sn = sn.sort{|a,b| - a.info[:balance] <=> b.info[:balance] - } - - xputs ">>> Rebalancing across #{nodes_involved} nodes. Total weight = #{total_weight}" - - if $verbose - sn.each{|n| - puts "#{n} balance is #{n.info[:balance]} slots" - } - end - - # Now we have at the start of the 'sn' array nodes that should get - # slots, at the end nodes that must give slots. - # We take two indexes, one at the start, and one at the end, - # incrementing or decrementing the indexes accordingly til we - # find nodes that need to get/provide slots. - dst_idx = 0 - src_idx = sn.length - 1 - - while dst_idx < src_idx - dst = sn[dst_idx] - src = sn[src_idx] - numslots = [dst.info[:balance],src.info[:balance]].map{|n| - n.abs - }.min - - if numslots > 0 - puts "Moving #{numslots} slots from #{src} to #{dst}" - - # Actaully move the slots. - reshard_table = compute_reshard_table([src],numslots) - if reshard_table.length != numslots - xputs "*** Assertio failed: Reshard table != number of slots" - exit 1 - end - if opt['simulate'] - print "#"*reshard_table.length - else - reshard_table.each{|e| - move_slot(e[:source],dst,e[:slot], - :quiet=>true, - :dots=>false, - :update=>true, - :pipeline=>opt['pipeline']) - print "#" - STDOUT.flush - } - end - puts - end - - # Update nodes balance. - dst.info[:balance] += numslots - src.info[:balance] -= numslots - dst_idx += 1 if dst.info[:balance] == 0 - src_idx -= 1 if src.info[:balance] == 0 - end - end - - def fix_cluster_cmd(argv,opt) - @fix = true - @timeout = opt['timeout'].to_i if opt['timeout'] - - load_cluster_info_from_node(argv[0]) - check_cluster - end - - def reshard_cluster_cmd(argv,opt) - opt = {'pipeline' => MigrateDefaultPipeline}.merge(opt) - - load_cluster_info_from_node(argv[0]) - check_cluster - if @errors.length != 0 - puts "*** Please fix your cluster problems before resharding" - exit 1 - end - - @timeout = opt['timeout'].to_i if opt['timeout'].to_i - - # Get number of slots - if opt['slots'] - numslots = opt['slots'].to_i - else - numslots = 0 - while numslots <= 0 or numslots > ClusterHashSlots - print "How many slots do you want to move (from 1 to #{ClusterHashSlots})? " - numslots = STDIN.gets.to_i - end - end - - # Get the target instance - if opt['to'] - target = get_node_by_name(opt['to']) - if !target || target.has_flag?("slave") - xputs "*** The specified node is not known or not a master, please retry." - exit 1 - end - else - target = nil - while not target - print "What is the receiving node ID? " - target = get_node_by_name(STDIN.gets.chop) - if !target || target.has_flag?("slave") - xputs "*** The specified node is not known or not a master, please retry." - target = nil - end - end - end - - # Get the source instances - sources = [] - if opt['from'] - opt['from'].split(',').each{|node_id| - if node_id == "all" - sources = "all" - break - end - src = get_node_by_name(node_id) - if !src || src.has_flag?("slave") - xputs "*** The specified node is not known or is not a master, please retry." - exit 1 - end - sources << src - } - else - xputs "Please enter all the source node IDs." - xputs " Type 'all' to use all the nodes as source nodes for the hash slots." - xputs " Type 'done' once you entered all the source nodes IDs." - while true - print "Source node ##{sources.length+1}:" - line = STDIN.gets.chop - src = get_node_by_name(line) - if line == "done" - break - elsif line == "all" - sources = "all" - break - elsif !src || src.has_flag?("slave") - xputs "*** The specified node is not known or is not a master, please retry." - elsif src.info[:name] == target.info[:name] - xputs "*** It is not possible to use the target node as source node." - else - sources << src - end - end - end - - if sources.length == 0 - puts "*** No source nodes given, operation aborted" - exit 1 - end - - # Handle soures == all. - if sources == "all" - sources = [] - @nodes.each{|n| - next if n.info[:name] == target.info[:name] - next if n.has_flag?("slave") - sources << n - } - end - - # Check if the destination node is the same of any source nodes. - if sources.index(target) - xputs "*** Target node is also listed among the source nodes!" - exit 1 - end - - puts "\nReady to move #{numslots} slots." - puts " Source nodes:" - sources.each{|s| puts " "+s.info_string} - puts " Destination node:" - puts " #{target.info_string}" - reshard_table = compute_reshard_table(sources,numslots) - puts " Resharding plan:" - show_reshard_table(reshard_table) - if !opt['yes'] - print "Do you want to proceed with the proposed reshard plan (yes/no)? " - yesno = STDIN.gets.chop - exit(1) if (yesno != "yes") - end - reshard_table.each{|e| - move_slot(e[:source],target,e[:slot], - :dots=>true, - :pipeline=>opt['pipeline']) - } - end - - # This is an helper function for create_cluster_cmd that verifies if - # the number of nodes and the specified replicas have a valid configuration - # where there are at least three master nodes and enough replicas per node. - def check_create_parameters - masters = @nodes.length/(@replicas+1) - if masters < 3 - puts "*** ERROR: Invalid configuration for cluster creation." - puts "*** Redis Cluster requires at least 3 master nodes." - puts "*** This is not possible with #{@nodes.length} nodes and #{@replicas} replicas per node." - puts "*** At least #{3*(@replicas+1)} nodes are required." - exit 1 - end - end - - def create_cluster_cmd(argv,opt) - opt = {'replicas' => 0}.merge(opt) - @replicas = opt['replicas'].to_i - - xputs ">>> Creating cluster" - argv[0..-1].each{|n| - node = ClusterNode.new(n) - node.connect(:abort => true) - node.assert_cluster - node.load_info - node.assert_empty - add_node(node) - } - check_create_parameters - xputs ">>> Performing hash slots allocation on #{@nodes.length} nodes..." - alloc_slots - show_nodes - yes_or_die "Can I set the above configuration?" - flush_nodes_config - xputs ">>> Nodes configuration updated" - xputs ">>> Assign a different config epoch to each node" - assign_config_epoch - xputs ">>> Sending CLUSTER MEET messages to join the cluster" - join_cluster - # Give one second for the join to start, in order to avoid that - # wait_cluster_join will find all the nodes agree about the config as - # they are still empty with unassigned slots. - sleep 1 - wait_cluster_join - flush_nodes_config # Useful for the replicas - check_cluster - end - - def addnode_cluster_cmd(argv,opt) - xputs ">>> Adding node #{argv[0]} to cluster #{argv[1]}" - - # Check the existing cluster - load_cluster_info_from_node(argv[1]) - check_cluster - - # If --master-id was specified, try to resolve it now so that we - # abort before starting with the node configuration. - if opt['slave'] - if opt['master-id'] - master = get_node_by_name(opt['master-id']) - if !master - xputs "[ERR] No such master ID #{opt['master-id']}" - end - else - master = get_master_with_least_replicas - xputs "Automatically selected master #{master}" - end - end - - # Add the new node - new = ClusterNode.new(argv[0]) - new.connect(:abort => true) - new.assert_cluster - new.load_info - new.assert_empty - first = @nodes.first.info - add_node(new) - - # Send CLUSTER MEET command to the new node - xputs ">>> Send CLUSTER MEET to node #{new} to make it join the cluster." - new.r.cluster("meet",first[:host],first[:port]) - - # Additional configuration is needed if the node is added as - # a slave. - if opt['slave'] - wait_cluster_join - xputs ">>> Configure node as replica of #{master}." - new.r.cluster("replicate",master.info[:name]) - end - xputs "[OK] New node added correctly." - end - - def delnode_cluster_cmd(argv,opt) - id = argv[1].downcase - xputs ">>> Removing node #{id} from cluster #{argv[0]}" - - # Load cluster information - load_cluster_info_from_node(argv[0]) - - # Check if the node exists and is not empty - node = get_node_by_name(id) - - if !node - xputs "[ERR] No such node ID #{id}" - exit 1 - end - - if node.slots.length != 0 - xputs "[ERR] Node #{node} is not empty! Reshard data away and try again." - exit 1 - end - - # Send CLUSTER FORGET to all the nodes but the node to remove - xputs ">>> Sending CLUSTER FORGET messages to the cluster..." - @nodes.each{|n| - next if n == node - if n.info[:replicate] && n.info[:replicate].downcase == id - # Reconfigure the slave to replicate with some other node - master = get_master_with_least_replicas - xputs ">>> #{n} as replica of #{master}" - n.r.cluster("replicate",master.info[:name]) - end - n.r.cluster("forget",argv[1]) - } - - # Finally shutdown the node - xputs ">>> SHUTDOWN the node." - node.r.shutdown - end - - def set_timeout_cluster_cmd(argv,opt) - timeout = argv[1].to_i - if timeout < 100 - puts "Setting a node timeout of less than 100 milliseconds is a bad idea." - exit 1 - end - - # Load cluster information - load_cluster_info_from_node(argv[0]) - ok_count = 0 - err_count = 0 - - # Send CLUSTER FORGET to all the nodes but the node to remove - xputs ">>> Reconfiguring node timeout in every cluster node..." - @nodes.each{|n| - begin - n.r.config("set","cluster-node-timeout",timeout) - n.r.config("rewrite") - ok_count += 1 - xputs "*** New timeout set for #{n}" - rescue => e - puts "ERR setting node-timeot for #{n}: #{e}" - err_count += 1 - end - } - xputs ">>> New node timeout set. #{ok_count} OK, #{err_count} ERR." - end - - def call_cluster_cmd(argv,opt) - cmd = argv[1..-1] - cmd[0] = cmd[0].upcase - - # Load cluster information - load_cluster_info_from_node(argv[0]) - xputs ">>> Calling #{cmd.join(" ")}" - @nodes.each{|n| - begin - res = n.r.send(*cmd) - puts "#{n}: #{res}" - rescue => e - puts "#{n}: #{e}" - end - } - end - - def import_cluster_cmd(argv,opt) - source_addr = opt['from'] - xputs ">>> Importing data from #{source_addr} to cluster #{argv[1]}" - use_copy = opt['copy'] - use_replace = opt['replace'] - - # Check the existing cluster. - load_cluster_info_from_node(argv[0]) - check_cluster - - # Connect to the source node. - xputs ">>> Connecting to the source Redis instance" - src_host,src_port = source_addr.split(":") - source = Redis.new(:host =>src_host, :port =>src_port) - if source.info['cluster_enabled'].to_i == 1 - xputs "[ERR] The source node should not be a cluster node." - end - xputs "*** Importing #{source.dbsize} keys from DB 0" - - # Build a slot -> node map - slots = {} - @nodes.each{|n| - n.slots.each{|s,_| - slots[s] = n - } - } - - # Use SCAN to iterate over the keys, migrating to the - # right node as needed. - cursor = nil - while cursor != 0 - cursor,keys = source.scan(cursor, :count => 1000) - cursor = cursor.to_i - keys.each{|k| - # Migrate keys using the MIGRATE command. - slot = key_to_slot(k) - target = slots[slot] - print "Migrating #{k} to #{target}: " - STDOUT.flush - begin - cmd = ["migrate",target.info[:host],target.info[:port],k,0,@timeout] - cmd << :copy if use_copy - cmd << :replace if use_replace - source.client.call(cmd) - rescue => e - puts e - else - puts "OK" - end - } - end - end - - def help_cluster_cmd(argv,opt) - show_help - exit 0 - end - - # Parse the options for the specific command "cmd". - # Returns an hash populate with option => value pairs, and the index of - # the first non-option argument in ARGV. - def parse_options(cmd) - idx = 1 ; # Current index into ARGV - options={} - while idx < ARGV.length && ARGV[idx][0..1] == '--' - if ARGV[idx][0..1] == "--" - option = ARGV[idx][2..-1] - idx += 1 - - # --verbose is a global option - if option == "verbose" - $verbose = true - next - end - - if ALLOWED_OPTIONS[cmd] == nil || ALLOWED_OPTIONS[cmd][option] == nil - puts "Unknown option '#{option}' for command '#{cmd}'" - exit 1 - end - if ALLOWED_OPTIONS[cmd][option] != false - value = ARGV[idx] - idx += 1 - else - value = true - end - - # If the option is set to [], it's a multiple arguments - # option. We just queue every new value into an array. - if ALLOWED_OPTIONS[cmd][option] == [] - options[option] = [] if !options[option] - options[option] << value - else - options[option] = value - end - else - # Remaining arguments are not options. - break - end - end - - # Enforce mandatory options - if ALLOWED_OPTIONS[cmd] - ALLOWED_OPTIONS[cmd].each {|option,val| - if !options[option] && val == :required - puts "Option '--#{option}' is required "+ \ - "for subcommand '#{cmd}'" - exit 1 - end - } - end - return options,idx - end -end - -################################################################################# -# Libraries -# -# We try to don't depend on external libs since this is a critical part -# of Redis Cluster. -################################################################################# - -# This is the CRC16 algorithm used by Redis Cluster to hash keys. -# Implementation according to CCITT standards. -# -# This is actually the XMODEM CRC 16 algorithm, using the -# following parameters: -# -# Name : "XMODEM", also known as "ZMODEM", "CRC-16/ACORN" -# Width : 16 bit -# Poly : 1021 (That is actually x^16 + x^12 + x^5 + 1) -# Initialization : 0000 -# Reflect Input byte : False -# Reflect Output CRC : False -# Xor constant to output CRC : 0000 -# Output for "123456789" : 31C3 - -module RedisClusterCRC16 - def RedisClusterCRC16.crc16(bytes) - crc = 0 - bytes.each_byte{|b| - crc = ((crc<<8) & 0xffff) ^ XMODEMCRC16Lookup[((crc>>8)^b) & 0xff] - } - crc - end - -private - XMODEMCRC16Lookup = [ - 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, - 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, - 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, - 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, - 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, - 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, - 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, - 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, - 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, - 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, - 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, - 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, - 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, - 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, - 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, - 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, - 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, - 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, - 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, - 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, - 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, - 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, - 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, - 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, - 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, - 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, - 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, - 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, - 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, - 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, - 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, - 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 - ] -end - -# Turn a key name into the corrisponding Redis Cluster slot. -def key_to_slot(key) - # Only hash what is inside {...} if there is such a pattern in the key. - # Note that the specification requires the content that is between - # the first { and the first } after the first {. If we found {} without - # nothing in the middle, the whole key is hashed as usually. - s = key.index "{" - if s - e = key.index "}",s+1 - if e && e != s+1 - key = key[s+1..e-1] - end - end - RedisClusterCRC16.crc16(key) % 16384 -end - -################################################################################# -# Definition of commands -################################################################################# - -COMMANDS={ - "create" => ["create_cluster_cmd", -2, "host1:port1 ... hostN:portN"], - "check" => ["check_cluster_cmd", 2, "host:port"], - "info" => ["info_cluster_cmd", 2, "host:port"], - "fix" => ["fix_cluster_cmd", 2, "host:port"], - "reshard" => ["reshard_cluster_cmd", 2, "host:port"], - "rebalance" => ["rebalance_cluster_cmd", -2, "host:port"], - "add-node" => ["addnode_cluster_cmd", 3, "new_host:new_port existing_host:existing_port"], - "del-node" => ["delnode_cluster_cmd", 3, "host:port node_id"], - "set-timeout" => ["set_timeout_cluster_cmd", 3, "host:port milliseconds"], - "call" => ["call_cluster_cmd", -3, "host:port command arg arg .. arg"], - "import" => ["import_cluster_cmd", 2, "host:port"], - "help" => ["help_cluster_cmd", 1, "(show this help)"] -} - -ALLOWED_OPTIONS={ - "create" => {"replicas" => true}, - "add-node" => {"slave" => false, "master-id" => true}, - "import" => {"from" => :required, "copy" => false, "replace" => false}, - "reshard" => {"from" => true, "to" => true, "slots" => true, "yes" => false, "timeout" => true, "pipeline" => true}, - "rebalance" => {"weight" => [], "auto-weights" => false, "use-empty-masters" => false, "timeout" => true, "simulate" => false, "pipeline" => true, "threshold" => true}, - "fix" => {"timeout" => MigrateDefaultTimeout}, -} - -def show_help - puts "Usage: redis-trib \n\n" - COMMANDS.each{|k,v| - o = "" - puts " #{k.ljust(15)} #{v[2]}" - if ALLOWED_OPTIONS[k] - ALLOWED_OPTIONS[k].each{|optname,has_arg| - puts " --#{optname}" + (has_arg ? " " : "") - } - end - } - puts "\nFor check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.\n" -end - -# Sanity check -if ARGV.length == 0 - show_help - exit 1 -end - -rt = RedisTrib.new -cmd_spec = COMMANDS[ARGV[0].downcase] -if !cmd_spec - puts "Unknown redis-trib subcommand '#{ARGV[0]}'" - exit 1 -end - -# Parse options -cmd_options,first_non_option = rt.parse_options(ARGV[0].downcase) -rt.check_arity(cmd_spec[1],ARGV.length-(first_non_option-1)) - -# Dispatch -rt.send(cmd_spec[0],ARGV[first_non_option..-1],cmd_options) diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/secure.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/secure.conf deleted file mode 100644 index 766ca88..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/secure.conf +++ /dev/null @@ -1,6 +0,0 @@ -port 6381 -requirepass changeme -dbfilename secure.rdb -databases 2000 -maxmemory 512mb -save "" \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/slave.conf b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/slave.conf deleted file mode 100644 index f3c3096..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/Redis Configs/slave.conf +++ /dev/null @@ -1,6 +0,0 @@ -port 6380 -slaveof 127.0.0.1 6379 -dbfilename slave.rdb -databases 2000 -maxmemory 2gb -save "" \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Client.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Client.cs deleted file mode 100644 index 5334ae9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Client.cs +++ /dev/null @@ -1,420 +0,0 @@ -// .NET port of https://github.com/RedisLabs/JRediSearch/ - -using StackExchange.Redis; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace StackExchange.Redis.Modules.RediSearch -{ - public sealed class Client - { - [Flags] - public enum IndexOptions - { - /// - /// All options disabled - /// - None = 0, - /// - /// Set this to tell the index not to save term offset vectors. This reduces memory consumption but does not - /// allow performing exact matches, and reduces overall relevance of multi-term queries - /// - UseTermOffsets = 1, - /// - /// If set (default), we keep flags per index record telling us what fields the term appeared on, - /// and allowing us to filter results by field - /// - KeepFieldFlags = 2, - /// - /// If set, we keep an index of the top entries per term, allowing extremely fast single word queries - /// regardless of index size, at the cost of more memory - /// - UseScoreIndexes = 4, - /// - /// The default indexing options - use term offsets and keep fields flags - /// - Default = UseTermOffsets | KeepFieldFlags - } - private static void SerializeRedisArgs(IndexOptions flags, List args) - { - if ((flags & IndexOptions.UseTermOffsets) == 0) - { - args.Add("NOOFFSETS".Literal()); - } - if ((flags & IndexOptions.KeepFieldFlags) == 0) - { - args.Add("NOFIELDS".Literal()); - } - if ((flags & IndexOptions.UseScoreIndexes) == 0) - { - args.Add("NOSCOREIDX".Literal()); - } - } - private readonly IDatabaseAsync _db; - private IDatabase DbSync - => (_db as IDatabase) ?? throw new InvalidOperationException("Synchronous operations are not available on this database instance"); - - private readonly object _boxedIndexName; - public RedisKey IndexName => (RedisKey)_boxedIndexName; - public Client(RedisKey indexName, IDatabaseAsync db) - { - _db = db ?? throw new ArgumentNullException(nameof(db)); - _boxedIndexName = indexName; // only box once, not per-command - } - public Client(RedisKey indexName, IDatabase db) : this(indexName, (IDatabaseAsync)db) { } - - /// - /// Create the index definition in redis - /// - /// a schema definition - /// index option flags - /// true if successful - public bool CreateIndex(Schema schema, IndexOptions options) - { - var args = new List(); - - args.Add(_boxedIndexName); - SerializeRedisArgs(options, args); - args.Add("SCHEMA".Literal()); - - foreach (var f in schema.Fields) - { - f.SerializeRedisArgs(args); - } - - return (string)DbSync.Execute("FT.CREATE", args) == "OK"; - } - - /// - /// Create the index definition in redis - /// - /// a schema definition - /// index option flags - /// true if successful - public async Task CreateIndexAsync(Schema schema, IndexOptions options) - { - var args = new List(); - - args.Add(_boxedIndexName); - SerializeRedisArgs(options, args); - args.Add("SCHEMA".Literal()); - - foreach (var f in schema.Fields) - { - f.SerializeRedisArgs(args); - } - - return (string)await _db.ExecuteAsync("FT.CREATE", args).ConfigureAwait(false) == "OK"; - } - - /// - /// Search the index - /// - /// a object with the query string and optional parameters - /// a object with the results - public SearchResult Search(Query q) - { - var args = new List(); - args.Add(_boxedIndexName); - q.SerializeRedisArgs(args); - - var resp = (RedisResult[])DbSync.Execute("FT.SEARCH", args); - return new SearchResult(resp, !q.NoContent, q.WithScores, q.WithPayloads); - } - - /// - /// Search the index - /// - /// a object with the query string and optional parameters - /// a object with the results - public async Task SearchAsync(Query q) - { - var args = new List(); - args.Add(_boxedIndexName); - q.SerializeRedisArgs(args); - - var resp = (RedisResult[])await _db.ExecuteAsync("FT.SEARCH", args).ConfigureAwait(false); - return new SearchResult(resp, !q.NoContent, q.WithScores, q.WithPayloads); - } - - /// - /// Add a single document to the query - /// - /// the id of the document. It cannot belong to a document already in the index unless replace is set - /// the document's score, floating point number between 0 and 1 - /// a map of the document's fields - /// if set, we only index the document and do not save its contents. This allows fetching just doc ids - /// if set, and the document already exists, we reindex and update it - /// if set, we can save a payload in the index to be retrieved or evaluated by scoring functions on the server - public bool AddDocument(string docId, Dictionary fields, double score = 1.0, bool noSave = false, bool replace = false, byte[] payload = null) - { - var args = BuildAddDocumentArgs(docId, fields, score, noSave, replace, payload); - return (string)DbSync.Execute("FT.ADD", args) == "OK"; - } - - /// - /// Add a single document to the query - /// - /// the id of the document. It cannot belong to a document already in the index unless replace is set - /// the document's score, floating point number between 0 and 1 - /// a map of the document's fields - /// if set, we only index the document and do not save its contents. This allows fetching just doc ids - /// if set, and the document already exists, we reindex and update it - /// if set, we can save a payload in the index to be retrieved or evaluated by scoring functions on the server - public async Task AddDocumentAsync(string docId, Dictionary fields, double score = 1.0, bool noSave = false, bool replace = false, byte[] payload = null) - { - var args = BuildAddDocumentArgs(docId, fields, score, noSave, replace, payload); - return (string)await _db.ExecuteAsync("FT.ADD", args).ConfigureAwait(false) == "OK"; - } - - private List BuildAddDocumentArgs(string docId, Dictionary fields, double score, bool noSave, bool replace, byte[] payload) - { - var args = new List { _boxedIndexName, docId, score }; - if (noSave) - { - args.Add("NOSAVE".Literal()); - } - if (replace) - { - args.Add("REPLACE".Literal()); - } - if (payload != null) - { - args.Add("PAYLOAD".Literal()); - // TODO: Fix this - args.Add(payload); - } - - args.Add("FIELDS".Literal()); - foreach (var ent in fields) - { - args.Add(ent.Key); - args.Add(ent.Value); - } - return args; - } - - /// - /// replaceDocument is a convenience for calling addDocument with replace=true - /// - public bool ReplaceDocument(string docId, Dictionary fields, double score = 1.0, byte[] payload = null) - => AddDocument(docId, fields, score, false, true, payload); - - /// - /// replaceDocument is a convenience for calling addDocument with replace=true - /// - public Task ReplaceDocumentAsync(string docId, Dictionary fields, double score = 1.0, byte[] payload = null) - => AddDocumentAsync(docId, fields, score, false, true, payload); - - /// - /// Index a document already in redis as a HASH key. - /// - /// the id of the document in redis. This must match an existing, unindexed HASH key - /// the document's index score, between 0 and 1 - /// if set, and the document already exists, we reindex and update it - /// true on success - public bool AddHash(string docId, double score, bool replace) - { - var args = new List { _boxedIndexName, docId, score }; - if (replace) - { - args.Add("REPLACE".Literal()); - } - return (string)DbSync.Execute("FT.ADDHASH", args) == "OK"; - } - /// - /// Index a document already in redis as a HASH key. - /// - /// the id of the document in redis. This must match an existing, unindexed HASH key - /// the document's index score, between 0 and 1 - /// if set, and the document already exists, we reindex and update it - /// true on success - public async Task AddHashAsync(string docId, double score, bool replace) - { - var args = new List { _boxedIndexName, docId, score }; - if (replace) - { - args.Add("REPLACE".Literal()); - } - return (string)await _db.ExecuteAsync("FT.ADDHASH", args).ConfigureAwait(false) == "OK"; - } - - /// - /// Get the index info, including memory consumption and other statistics. - /// - /// TODO: Make a class for easier access to the index properties - /// a map of key/value pairs - public Dictionary GetInfo() - { - return ParseGetInfo(DbSync.Execute("FT.INFO", _boxedIndexName)); - } - /// - /// Get the index info, including memory consumption and other statistics. - /// - /// TODO: Make a class for easier access to the index properties - /// a map of key/value pairs - public async Task> GetInfoAsync() - { - return ParseGetInfo(await _db.ExecuteAsync("FT.INFO", _boxedIndexName).ConfigureAwait(false)); - } - static Dictionary ParseGetInfo(RedisResult value) - { - var res = (RedisValue[])value; - var info = new Dictionary(); - for (int i = 0; i < res.Length; i += 2) - { - var key = (string)res[i]; - var val = res[i + 1]; - info.Add(key, val); - } - return info; - } - - /// - /// Delete a document from the index. - /// - /// the document's id - /// true if it has been deleted, false if it did not exist - public bool DeleteDocument(string docId) - { - return (long)DbSync.Execute("FT.DEL", _boxedIndexName, docId) == 1; - } - - /// - /// Delete a document from the index. - /// - /// the document's id - /// true if it has been deleted, false if it did not exist - public async Task DeleteDocumentAsync(string docId) - { - return (long)await _db.ExecuteAsync("FT.DEL", _boxedIndexName, docId).ConfigureAwait(false) == 1; - } - - /// - /// Drop the index and all associated keys, including documents - /// - /// true on success - public bool DropIndex() - { - return (string)DbSync.Execute("FT.DROP", _boxedIndexName) == "OK"; - } - /// - /// Drop the index and all associated keys, including documents - /// - /// true on success - public async Task DropIndexAsync() - { - return (string) await _db.ExecuteAsync("FT.DROP", _boxedIndexName).ConfigureAwait(false) == "OK"; - } - - /// - /// Optimize memory consumption of the index by removing extra saved capacity. This does not affect speed - /// - public long OptimizeIndex() - { - return (long)DbSync.Execute("FT.OPTIMIZE", _boxedIndexName); - } - - /// - /// Optimize memory consumption of the index by removing extra saved capacity. This does not affect speed - /// - public async Task OptimizeIndexAsync() - { - return (long) await _db.ExecuteAsync("FT.OPTIMIZE", _boxedIndexName).ConfigureAwait(false); - } - - /// - /// Get the size of an autoc-complete suggestion dictionary - /// - public long CountSuggestions() - => (long)DbSync.Execute("FT.SUGLEN", _boxedIndexName); - - /// - /// Get the size of an autoc-complete suggestion dictionary - /// - public async Task CountSuggestionsAsync() - => (long)await _db.ExecuteAsync("FT.SUGLEN", _boxedIndexName).ConfigureAwait(false); - - /// - /// Add a suggestion string to an auto-complete suggestion dictionary. This is disconnected from the index definitions, and leaves creating and updating suggestino dictionaries to the user. - /// - /// the suggestion string we index - /// a floating point number of the suggestion string's weight - /// if set, we increment the existing entry of the suggestion by the given score, instead of replacing the score. This is useful for updating the dictionary based on user queries in real time - /// the current size of the suggestion dictionary. - public long AddSuggestion(string value, double score, bool increment = false) - { - object args = increment - ? new object[] { _boxedIndexName, value, score, "INCR".Literal() } - : new object[] { _boxedIndexName, value, score }; - return (long)DbSync.Execute("FT.SUGADD", args); - } - - /// - /// Add a suggestion string to an auto-complete suggestion dictionary. This is disconnected from the index definitions, and leaves creating and updating suggestino dictionaries to the user. - /// - /// the suggestion string we index - /// a floating point number of the suggestion string's weight - /// if set, we increment the existing entry of the suggestion by the given score, instead of replacing the score. This is useful for updating the dictionary based on user queries in real time - /// the current size of the suggestion dictionary. - public async Task AddSuggestionAsync(string value, double score, bool increment = false) - { - object args = increment - ? new object[] { _boxedIndexName, value, score, "INCR".Literal() } - : new object[] { _boxedIndexName, value, score }; - return (long)await _db.ExecuteAsync("FT.SUGADD", args).ConfigureAwait(false); - } - - /// - /// Delete a string from a suggestion index. - /// - /// the string to delete - public bool DeleteSuggestion(string value) - => (long)DbSync.Execute("FT.SUGDEL", _boxedIndexName, value) == 1; - - /// - /// Delete a string from a suggestion index. - /// - /// the string to delete - public async Task DeleteSuggestionAsync(string value) - => (long)await _db.ExecuteAsync("FT.SUGDEL", _boxedIndexName, value).ConfigureAwait(false) == 1; - - /// - /// Get completion suggestions for a prefix - /// - /// the prefix to complete on - /// if set,we do a fuzzy prefix search, including prefixes at levenshtein distance of 1 from the prefix sent - /// If set, we limit the results to a maximum of num. (Note: The default is 5, and the number cannot be greater than 10). - /// a list of the top suggestions matching the prefix - public string[] GetSuggestions(string prefix, bool fuzzy = false, int max = 5) - { - var args = new List { _boxedIndexName, prefix}; - if (fuzzy) args.Add("FUZZY".Literal()); - if (max != 5) - { - args.Add("MAX".Literal()); - args.Add(max); - } - return (string[])DbSync.Execute("FT.SUGGET", args); - } - /// - /// Get completion suggestions for a prefix - /// - /// the prefix to complete on - /// if set,we do a fuzzy prefix search, including prefixes at levenshtein distance of 1 from the prefix sent - /// If set, we limit the results to a maximum of num. (Note: The default is 5, and the number cannot be greater than 10). - /// a list of the top suggestions matching the prefix - public async Task GetSuggestionsAsync(string prefix, bool fuzzy = false, int max = 5) - { - var args = new List { _boxedIndexName, prefix }; - if (fuzzy) args.Add("FUZZY".Literal()); - if (max != 5) - { - args.Add("MAX".Literal()); - args.Add(max); - } - return (string[])await _db.ExecuteAsync("FT.SUGGET", args).ConfigureAwait(false); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Document.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Document.cs deleted file mode 100644 index 6f241aa..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Document.cs +++ /dev/null @@ -1,51 +0,0 @@ -// .NET port of https://github.com/RedisLabs/JRediSearch/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using StackExchange.Redis; - -namespace StackExchange.Redis.Modules.RediSearch -{ - /// - /// Document represents a single indexed document or entity in the engine - /// - public class Document - { - - public string Id { get; } - public double Score { get; } - public byte[] Payload { get; } - private Dictionary properties = new Dictionary(); - - public Document(string id, double score, byte[] payload) - { - Id = id; - Score = score; - Payload = payload; - } - - public static Document Load(string id, double score, byte[] payload, RedisValue[] fields) - { - Document ret = new Document(id, score, payload); - if (fields != null) - { - for (int i = 0; i < fields.Length; i += 2) - { - ret[(string)fields[i]] = fields[i + 1]; - } - } - return ret; - } - - public RedisValue this[string key] - { - get { return properties.TryGetValue(key, out var val) ? val : default(RedisValue); } - internal set { properties[key] = value; } - } - - public bool HasProperty(string key) => properties.ContainsKey(key); - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Literals.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Literals.cs deleted file mode 100644 index fb39761..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Literals.cs +++ /dev/null @@ -1,36 +0,0 @@ -using StackExchange.Redis; -using System.Collections; -namespace StackExchange.Redis.Modules.RediSearch -{ - /// - /// Cache to ensure we encode and box literals once only - /// - internal static class Literals - { - private static Hashtable _boxed = new Hashtable(); - private static object _null = RedisValue.Null; - /// - /// Obtain a lazily-cached pre-encoded and boxed representation of a string - /// - /// This shoul donly be used for fixed values, not user data (the cache is never reclaimed, so it will be a memory leak) - public static object Literal(this string value) - { - if (value == null) return _null; - - object boxed = _boxed[value]; - if (boxed == null) - { - lock (_boxed) - { - boxed = _boxed[value]; - if (boxed == null) - { - boxed = (RedisValue)value; - _boxed.Add(value, boxed); - } - } - } - return boxed; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Query.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Query.cs deleted file mode 100644 index 0cd854e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Query.cs +++ /dev/null @@ -1,264 +0,0 @@ -// .NET port of https://github.com/RedisLabs/JRediSearch/ - -using StackExchange.Redis; -using System; -using System.Collections.Generic; -using System.Globalization; - -namespace StackExchange.Redis.Modules.RediSearch -{ - /// - /// Query represents query parameters and filters to load results from the engine - /// - public class Query - { - /// - /// Filter represents a filtering rules in a query - /// - public abstract class Filter - { - - public string Property { get; } - - internal abstract void SerializeRedisArgs(List args); - - internal Filter(string property) - { - Property = property; - } - - } - - /// - /// NumericFilter wraps a range filter on a numeric field. It can be inclusive or exclusive - /// - public class NumericFilter : Filter - { - - private readonly double min, max; - private readonly bool exclusiveMin, exclusiveMax; - - public NumericFilter(string property, double min, bool exclusiveMin, double max, bool exclusiveMax) : base(property) - { - this.min = min; - this.max = max; - this.exclusiveMax = exclusiveMax; - this.exclusiveMin = exclusiveMin; - } - - public NumericFilter(string property, double min, double max) : this(property, min, false, max, false) { } - - - internal override void SerializeRedisArgs(List args) - { - RedisValue FormatNum(double num, bool exclude) - { - if (!exclude || double.IsInfinity(num)) - { - return (RedisValue)num; // can use directly - } - // need to add leading bracket - return "(" + num.ToString("G17", NumberFormatInfo.InvariantInfo); - } - args.Add("FILTER".Literal()); - args.Add(Property); - args.Add(FormatNum(min, exclusiveMin)); - args.Add(FormatNum(max, exclusiveMax)); - } - } - - /// - /// GeoFilter encapsulates a radius filter on a geographical indexed fields - /// - public class GeoFilter : Filter - { - - private readonly double lon, lat, radius; - private GeoUnit unit; - - public GeoFilter(string property, double lon, double lat, double radius, GeoUnit unit) : base(property) - { - this.lon = lon; - this.lat = lat; - this.radius = radius; - this.unit = unit; - } - - internal override void SerializeRedisArgs(List args) - { - args.Add("GEOFILTER".Literal()); - args.Add(Property); - args.Add(lon); - args.Add(lat); - args.Add(radius); - - switch (unit) - { - case GeoUnit.Feet: args.Add("ft".Literal()); break; - case GeoUnit.Kilometers: args.Add("km".Literal()); break; - case GeoUnit.Meters: args.Add("m".Literal()); break; - case GeoUnit.Miles: args.Add("mi".Literal()); break; - default: throw new InvalidOperationException($"Unknown unit: {unit}"); - } - } - } - - private struct Paging - { - public int Offset { get; } - public int Count { get; } - - public Paging(int offset, int count) - { - Offset = offset; - Count = count; - } - } - - /// - /// The query's filter list. We only support AND operation on all those filters - /// - List _filters = new List(); - - /// - /// The textual part of the query - /// - public string QueryString { get; } - - /// - /// The sorting parameters - /// - Paging _paging = new Paging(0, 10); - - /// - /// Set the query to verbatim mode, disabling stemming and query expansion - /// - public bool Verbatim { get; set; } - /// - /// Set the query not to return the contents of documents, and rather just return the ids - /// - public bool NoContent { get; set; } - /// - /// Set the query not to filter for stopwords. In general this should not be used - /// - public bool NoStopwords { get; set; } - /// - /// Set the query to return a factored score for each results. This is useful to merge results from multiple queries. - /// - public bool WithScores { get; set; } - /// - /// Set the query to return object payloads, if any were given - /// - public bool WithPayloads { get; set; } - - /// - /// Set the query language, for stemming purposes; see http://redisearch.io for documentation on languages and stemming - /// - public string Language { get; set; } - protected String[] _fields = null; - /// - /// Set the query payload to be evaluated by the scoring function - /// - public byte[] Payload { get; set; } - - /// - /// Create a new index - /// - public Query(String queryString) - { - QueryString = queryString; - } - - internal void SerializeRedisArgs(List args) - { - args.Add(QueryString); - - if (Verbatim) - { - args.Add("VERBATIM".Literal()); - } - if (NoContent) - { - args.Add("NOCONTENT".Literal()); - } - if (NoStopwords) - { - args.Add("NOSTOPWORDS".Literal()); - } - if (WithScores) - { - args.Add("WITHSCORES".Literal()); - } - if (WithPayloads) - { - args.Add("WITHPAYLOADS".Literal()); - } - if (Language != null) - { - args.Add("LANGUAGE".Literal()); - args.Add(Language); - } - if (_fields != null && _fields.Length > 0) - { - args.Add("INFIELDS".Literal()); - args.Add(_fields.Length); - args.AddRange(_fields); - } - - if (Payload != null) - { - args.Add("PAYLOAD".Literal()); - args.Add(Payload); - } - - if (_paging.Offset != 0 || _paging.Count != 10) - { - args.Add("LIMIT".Literal()); - args.Add(_paging.Offset); - args.Add(_paging.Count); - } - - if (_filters != null && _filters.Count > 0) - { - foreach (var f in _filters) - { - f.SerializeRedisArgs(args); - } - } - } - - /// - /// Limit the results to a certain offset and limit - /// - /// the first result to show, zero based indexing - /// how many results we want to show - /// the query itself, for builder-style syntax - public Query Limit(int offset, int count) - { - _paging = new Paging(offset, count); - return this; - } - - /// - /// Add a filter to the query's filter list - /// - /// either a numeric or geo filter object - /// the query itself - public Query AddFilter(Filter f) - { - _filters.Add(f); - return this; - } - - /// - /// Limit the query to results that are limited to a specific set of fields - /// - /// a list of TEXT fields in the schemas - /// the query object itself - public Query LimitFields(params string[] fields) - { - this._fields = fields; - return this; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Schema.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Schema.cs deleted file mode 100644 index de8f6de..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/Schema.cs +++ /dev/null @@ -1,103 +0,0 @@ -// .NET port of https://github.com/RedisLabs/JRediSearch/ - -using System; -using System.Collections.Generic; - -namespace StackExchange.Redis.Modules.RediSearch -{ - /// - /// Schema abstracts the schema definition when creating an index. - /// Documents can contain fields not mentioned in the schema, but the index will only index pre-defined fields - /// - public sealed class Schema - { - public enum FieldType - { - FullText, - Geo, - Numeric - } - - public class Field - { - public String Name { get; } - public FieldType Type { get; } - - internal Field(string name, FieldType type) - { - Name = name; - Type = type; - } - - internal virtual void SerializeRedisArgs(List args) - { - object GetForRedis(FieldType type) - { - switch (type) - { - case FieldType.FullText: return "TEXT".Literal(); - case FieldType.Geo: return "GEO".Literal(); - case FieldType.Numeric: return "NUMERIC".Literal(); - default: throw new ArgumentOutOfRangeException(nameof(type)); - } - } - args.Add(Name); - args.Add(GetForRedis(Type)); - } - } - public class TextField : Field - { - public double Weight { get; } - internal TextField(string name, double weight = 1.0) : base(name, FieldType.FullText) - { - Weight = weight; - } - internal override void SerializeRedisArgs(List args) - { - base.SerializeRedisArgs(args); - if (Weight != 1.0) - { - args.Add("WEIGHT".Literal()); - args.Add(Weight); - } - } - } - - public List Fields { get; } = new List(); - - /// - /// Add a text field to the schema with a given weight - /// - /// the field's name - /// its weight, a positive floating point number - /// the schema object - public Schema AddTextField(string name, double weight = 1.0) - { - Fields.Add(new TextField(name, weight)); - return this; - } - - /// - /// Add a numeric field to the schema - /// - /// the field's name - /// the schema object - public Schema AddGeoField(string name) - { - Fields.Add(new Field(name, FieldType.Geo)); - return this; - } - - /// - /// Add a numeric field to the schema - /// - /// the field's name - /// the schema object - public Schema AddNumericField(string name) - { - Fields.Add(new Field(name, FieldType.Numeric)); - return this; - } - - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/SearchResult.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/SearchResult.cs deleted file mode 100644 index fbbf667..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/RediSearch/SearchResult.cs +++ /dev/null @@ -1,75 +0,0 @@ -// .NET port of https://github.com/RedisLabs/JRediSearch/ - -using StackExchange.Redis; -using System.Collections.Generic; - -namespace StackExchange.Redis.Modules.RediSearch -{ - /// - /// SearchResult encapsulates the returned result from a search query. - /// It contains publically accessible fields for the total number of results, and an array of - /// objects conatining the actual returned documents. - /// - public class SearchResult - { - public long TotalResults { get; } - public List Documents { get; } - - - internal SearchResult(RedisResult[] resp, bool hasContent, bool hasScores, bool hasPayloads) - { - // Calculate the step distance to walk over the results. - // The order of results is id, score (if withScore), payLoad (if hasPayloads), fields - int step = 1; - int scoreOffset = 0; - int contentOffset = 1; - int payloadOffset = 0; - if (hasScores) - { - step += 1; - scoreOffset = 1; - contentOffset += 1; - } - if (hasContent) - { - step += 1; - if (hasPayloads) - { - payloadOffset = scoreOffset + 1; - step += 1; - contentOffset += 1; - } - } - - // the first element is always the number of results - TotalResults = (long)resp[0]; - var docs = new List((resp.Length - 1) / step); - Documents = docs; - for (int i = 1; i < resp.Length; i += step) - { - - var id = (string)resp[i]; - double score = 1.0; - byte[] payload = null; - RedisValue[] fields = null; - if (hasScores) - { - score = (double)resp[i + scoreOffset]; - } - if (hasPayloads) - { - payload = (byte[])resp[i + payloadOffset]; - } - - if (hasContent) - { - fields = (RedisValue[])resp[i + contentOffset]; - } - - docs.Add(Document.Load(id, score, payload, fields)); - } - - - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/StackExchange.Redis.Modules.csproj b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/StackExchange.Redis.Modules.csproj deleted file mode 100644 index 673bb28..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/StackExchange.Redis.Modules.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - $(LibraryTargetFrameworks) - 0.1 - false - Redis;Search;Modules;RediSearch - - - - - \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/Throttling.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/Throttling.cs deleted file mode 100644 index 7770cb2..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Modules/Throttling.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; - -namespace StackExchange.Redis.Modules.Throttling -{ - public static class ThrottlingExtensions - { - public static ThrottleResult Throttle( - this IDatabase db, RedisKey key, int maxBurst, - int maxPerInterval, - int intervalSeconds = 60, int count = 1) - { - return new ThrottleResult(db.Execute("CL.THROTTLE", - key, maxBurst.Boxed(), maxPerInterval.Boxed(), intervalSeconds.Boxed(), count.Boxed())); - } - public async static Task ThrottleAsync( - this IDatabaseAsync db, RedisKey key, int maxBurst, - int maxPerInterval, - int intervalSeconds = 60, int count = 1) - { - return new ThrottleResult(await db.ExecuteAsync("CL.THROTTLE", - key, maxBurst.Boxed(), maxPerInterval.Boxed(), intervalSeconds.Boxed(), count.Boxed())); - } - - static readonly object[] _boxedInt32 = Enumerable.Range(-1, 128).Select(i => (object)i).ToArray(); - internal static object Boxed(this int value) - => value >= -1 && value <= 126 ? _boxedInt32[value + 1] : (object)value; - } - public struct ThrottleResult - { - internal ThrottleResult(RedisResult result) - { - var arr = (int[])result; - Permitted = arr[0] == 0; - TotalLimit = arr[1]; - RemainingLimit = arr[2]; - RetryAfterSeconds = arr[3]; - ResetAfterSeconds = arr[4]; - } - /// Whether the action was limited - public bool Permitted {get;} - /// The total limit of the key (max_burst + 1). This is equivalent to the common `X-RateLimit-Limit` HTTP header. - public int TotalLimit {get;} - /// The remaining limit of the key. Equivalent to `X-RateLimit-Remaining`. - public int RemainingLimit {get;} - /// The number of seconds until the user should retry, and always -1 if the action was allowed. Equivalent to `Retry-After`. - public int RetryAfterSeconds {get;} - /// The number of seconds until the limit will reset to its maximum capacity. Equivalent to `X-RateLimit-Reset`. - public int ResetAfterSeconds {get;} - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.StrongName/StackExchange.Redis.StrongName.csproj b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.StrongName/StackExchange.Redis.StrongName.csproj deleted file mode 100644 index 6b54c37..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.StrongName/StackExchange.Redis.StrongName.csproj +++ /dev/null @@ -1,72 +0,0 @@ - - - - $(LibraryTargetFrameworks) - High performance Redis client, incorporating both synchronous and asynchronous usage. - StackExchange.Redis.StrongName - $(DefineConstants);STRONG_NAME - true - true - StackExchange.Redis.StrongName - Async;Redis;Cache;PubSub;Messaging - Library - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(DefineConstants);FEATURE_SERIALIZATION;FEATURE_SOCKET_MODE_POLL - - - - $(DefineConstants);CORE_CLR - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.StrongName/build.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.StrongName/build.cmd deleted file mode 100644 index c2ab763..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.StrongName/build.cmd +++ /dev/null @@ -1 +0,0 @@ -dotnet msbuild "/t:Restore;Build;Pack" "/p:NuGetBuildTasksPackTargets='000'" "/p:PackageOutputPath=nupkgs" "/p:Configuration=Release" diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/AdhocTests.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/AdhocTests.cs deleted file mode 100644 index 274cb08..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/AdhocTests.cs +++ /dev/null @@ -1,35 +0,0 @@ -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Text; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class AdhocTests : TestBase - { - [Test] - public void TestAdhocCommandsAPI() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(); - - // needs explicit RedisKey type for key-based - // sharding to work; will still work with strings, - // but no key-based sharding support - RedisKey key = "some_key"; - - // note: if command renames are configured in - // the API, they will still work automatically - db.Execute("del", key); - db.Execute("set", key, "12"); - db.Execute("incrby", key, 4); - int i = (int) db.Execute("get", key); - - Assert.AreEqual(16, i); - - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/AsyncTests.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/AsyncTests.cs deleted file mode 100644 index 63d9265..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/AsyncTests.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Linq; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class AsyncTests : TestBase - { - protected override string GetConfiguration() - { - return PrimaryServer + ":" + PrimaryPortString; - } - -#if DEBUG // IRedisServerDebug and AllowConnect are only available if DEBUG is defined - [Test] - public void AsyncTasksReportFailureIfServerUnavailable() - { - SetExpectedAmbientFailureCount(-1); // this will get messy - - using(var conn = Create(allowAdmin: true)) - { - var server = conn.GetServer(PrimaryServer, PrimaryPort); - - RedisKey key = Me(); - var db = conn.GetDatabase(); - db.KeyDelete(key); - var a = db.SetAddAsync(key, "a"); - var b = db.SetAddAsync(key, "b"); - - Assert.AreEqual(true, conn.Wait(a)); - Assert.AreEqual(true, conn.Wait(b)); - - conn.AllowConnect = false; - server.SimulateConnectionFailure(); - var c = db.SetAddAsync(key, "c"); - - Assert.IsTrue(c.IsFaulted, "faulted"); - var ex = c.Exception.InnerExceptions.Single(); - Assert.IsInstanceOf(ex); - Assert.AreEqual("No connection is available to service this operation: SADD AsyncTasksReportFailureIfServerUnavailable", ex.Message); - } - } -#endif - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/BasicOps.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/BasicOps.cs deleted file mode 100644 index 48ea5d6..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/BasicOps.cs +++ /dev/null @@ -1,709 +0,0 @@ -using System; -using System.Diagnostics; -using System.Threading; -using System.Threading.Tasks; -#if FEATURE_BOOKSLEEVE -using BookSleeve; -#endif -using NUnit.Framework; -using StackExchange.Redis.KeyspaceIsolation; -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class BasicOpsTests : TestBase - { - [Test] - [TestCase(true)] - [TestCase(false)] - public void PingOnce(bool preserveOrder) - { - using (var muxer = Create()) - { - muxer.PreserveAsyncOrder = preserveOrder; - var conn = muxer.GetDatabase(); - - var task = conn.PingAsync(); - var duration = muxer.Wait(task); - Console.WriteLine("Ping took: " + duration); - Assert.IsTrue(duration.TotalMilliseconds > 0); - } - } - - [Test] - [TestCase(true)] - [TestCase(false)] - public void RapidDispose(bool preserverOrder) - { - RedisKey key = Me(); - using (var primary = Create()) - { - var conn = primary.GetDatabase(); - conn.KeyDelete(key); - - for (int i = 0; i < 10; i++) - { - using (var secondary = Create(fail: true)) - { - secondary.GetDatabase().StringIncrement(key, flags: CommandFlags.FireAndForget); - } - } - - Assert.AreEqual(10, (int)conn.StringGet(key)); - } - } - - [Test] - [TestCase(true)] - [TestCase(false)] - public void PingMany(bool preserveOrder) - { - using (var muxer = Create()) - { - muxer.PreserveAsyncOrder = preserveOrder; - var conn = muxer.GetDatabase(); - var tasks = new Task[10000]; - - for (int i = 0; i < tasks.Length; i++) - { - tasks[i] = conn.PingAsync(); - } - muxer.WaitAll(tasks); - Assert.IsTrue(tasks[0].Result.TotalMilliseconds > 0); - Assert.IsTrue(tasks[tasks.Length - 1].Result.TotalMilliseconds > 0); - } - } - - [Test] - public void GetWithNullKey() - { - using (var muxer = Create()) - { - var db = muxer.GetDatabase(); - string key = null; - Assert.Throws( - () => db.StringGet(key), - "A null key is not valid in this context"); - } - } - - [Test] - public void SetWithNullKey() - { - using (var muxer = Create()) - { - var db = muxer.GetDatabase(); - string key = null, value = "abc"; - Assert.Throws( - () => db.StringSet(key, value), - "A null key is not valid in this context"); - } - } - - [Test] - public void SetWithNullValue() - { - using (var muxer = Create()) - { - var db = muxer.GetDatabase(); - string key = Me(), value = null; - db.KeyDelete(key, CommandFlags.FireAndForget); - - db.StringSet(key, "abc", flags: CommandFlags.FireAndForget); - Assert.IsTrue(db.KeyExists(key)); - db.StringSet(key, value); - - var actual = (string)db.StringGet(key); - Assert.IsNull(actual); - Assert.IsFalse(db.KeyExists(key)); - } - } - - [Test] - public void SetWithDefaultValue() - { - using (var muxer = Create()) - { - var db = muxer.GetDatabase(); - string key = Me(); - var value = default(RedisValue); // this is kinda 0... ish - db.KeyDelete(key, CommandFlags.FireAndForget); - - db.StringSet(key, "abc", flags: CommandFlags.FireAndForget); - Assert.IsTrue(db.KeyExists(key)); - db.StringSet(key, value); - - var actual = (string)db.StringGet(key); - Assert.IsNull(actual); - Assert.IsFalse(db.KeyExists(key)); - } - } - - [Test] - public void SetWithZeroValue() - { - using (var muxer = Create()) - { - var db = muxer.GetDatabase(); - string key = Me(); - long value = 0; - db.KeyDelete(key, CommandFlags.FireAndForget); - - db.StringSet(key, "abc", flags: CommandFlags.FireAndForget); - Assert.IsTrue(db.KeyExists(key)); - db.StringSet(key, value); - - var actual = (string)db.StringGet(key); - Assert.AreEqual("0", actual); - Assert.IsTrue(db.KeyExists(key)); - } - } - - [Test] - [TestCase(true)] - [TestCase(false)] - public void GetSetAsync(bool preserveOrder) - { - using (var muxer = Create()) - { - muxer.PreserveAsyncOrder = preserveOrder; - var conn = muxer.GetDatabase(); - - RedisKey key = Me(); - var d0 = conn.KeyDeleteAsync(key); - var d1 = conn.KeyDeleteAsync(key); - var g1 = conn.StringGetAsync(key); - var s1 = conn.StringSetAsync(key, "123"); - var g2 = conn.StringGetAsync(key); - var d2 = conn.KeyDeleteAsync(key); - - muxer.Wait(d0); - Assert.IsFalse(muxer.Wait(d1)); - Assert.IsNull((string)muxer.Wait(g1)); - Assert.IsTrue(muxer.Wait(g1).IsNull); - muxer.Wait(s1); - Assert.AreEqual("123", (string)muxer.Wait(g2)); - Assert.AreEqual(123, (int)muxer.Wait(g2)); - Assert.IsFalse(muxer.Wait(g2).IsNull); - Assert.IsTrue(muxer.Wait(d2)); - } - } - - [Test] - [TestCase(true)] - [TestCase(false)] - public void GetSetSync(bool preserveOrder) - { - using (var muxer = Create()) - { - muxer.PreserveAsyncOrder = preserveOrder; - var conn = muxer.GetDatabase(); - - RedisKey key = Me(); - conn.KeyDelete(key); - var d1 = conn.KeyDelete(key); - var g1 = conn.StringGet(key); - conn.StringSet(key, "123"); - var g2 = conn.StringGet(key); - var d2 = conn.KeyDelete(key); - - Assert.IsFalse(d1); - Assert.IsNull((string)g1); - Assert.IsTrue(g1.IsNull); - - Assert.AreEqual("123", (string)g2); - Assert.AreEqual(123, (int)g2); - Assert.IsFalse(g2.IsNull); - Assert.IsTrue(d2); - } - } - - [Test] - [TestCase(true, true)] - [TestCase(true, false)] - [TestCase(false, true)] - [TestCase(false, false)] - public void MassiveBulkOpsAsync(bool preserveOrder, bool withContinuation) - { -#if DEBUG - var oldAsyncCompletionCount = ConnectionMultiplexer.GetAsyncCompletionWorkerCount(); -#endif - using (var muxer = Create()) - { - muxer.PreserveAsyncOrder = preserveOrder; - RedisKey key = "MBOA"; - var conn = muxer.GetDatabase(); - muxer.Wait(conn.PingAsync()); - -#if CORE_CLR - int number = 0; -#endif - Action nonTrivial = delegate - { -#if !CORE_CLR - Thread.SpinWait(5); -#else - for (int i = 0; i < 50; i++) - { - number++; - } -#endif - }; - var watch = Stopwatch.StartNew(); - for (int i = 0; i <= AsyncOpsQty; i++) - { - var t = conn.StringSetAsync(key, i); - if (withContinuation) t.ContinueWith(nonTrivial); - } - int val = (int)muxer.Wait(conn.StringGetAsync(key)); - Assert.AreEqual(AsyncOpsQty, val); - watch.Stop(); - Console.WriteLine("{2}: Time for {0} ops: {1}ms ({3}, {4}); ops/s: {5}", AsyncOpsQty, watch.ElapsedMilliseconds, Me(), - withContinuation ? "with continuation" : "no continuation", preserveOrder ? "preserve order" : "any order", - AsyncOpsQty / watch.Elapsed.TotalSeconds); -#if DEBUG - Console.WriteLine("Async completion workers: " + (ConnectionMultiplexer.GetAsyncCompletionWorkerCount() - oldAsyncCompletionCount)); -#endif - } - } - - [Test] - [TestCase(false, false)] - [TestCase(true, true)] - [TestCase(true, false)] - public void GetWithExpiry(bool exists, bool hasExpiry) - { - using(var conn = Create()) - { - var db = conn.GetDatabase(); - RedisKey key = Me(); - db.KeyDelete(key); - if (exists) - { - if (hasExpiry) - db.StringSet(key, "val", TimeSpan.FromMinutes(5)); - else - db.StringSet(key, "val"); - } - var async = db.StringGetWithExpiryAsync(key); - var syncResult = db.StringGetWithExpiry(key); - var asyncResult = db.Wait(async); - - if(exists) - { - Assert.AreEqual("val", (string)asyncResult.Value); - Assert.AreEqual(hasExpiry, asyncResult.Expiry.HasValue); - if (hasExpiry) Assert.IsTrue(asyncResult.Expiry.Value.TotalMinutes >= 4.9 && asyncResult.Expiry.Value.TotalMinutes <= 5); - Assert.AreEqual("val", (string)syncResult.Value); - Assert.AreEqual(hasExpiry, syncResult.Expiry.HasValue); - if (hasExpiry) Assert.IsTrue(syncResult.Expiry.Value.TotalMinutes >= 4.9 && syncResult.Expiry.Value.TotalMinutes <= 5); - } - else - { - Assert.IsTrue(asyncResult.Value.IsNull); - Assert.IsFalse(asyncResult.Expiry.HasValue); - Assert.IsTrue(syncResult.Value.IsNull); - Assert.IsFalse(syncResult.Expiry.HasValue); - } - } - } - [Test] - public void GetWithExpiryWrongTypeAsync() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(); - RedisKey key = Me(); - db.KeyDelete(key); - db.SetAdd(key, "abc"); - Assert.Throws(() => - { - try - { - var async = db.Wait(db.StringGetWithExpiryAsync(key)); - } - catch (AggregateException ex) - { - throw ex.InnerExceptions[0]; - } - Assert.Fail(); - }, - "A null key is not valid in this context"); - } - } - - [Test] - public void GetWithExpiryWrongTypeSync() - { - Assert.Throws(() => - { - using (var conn = Create()) - { - var db = conn.GetDatabase(); - RedisKey key = Me(); - db.KeyDelete(key); - db.SetAdd(key, "abc"); - db.StringGetWithExpiry(key); - Assert.Fail(); - } - }, - "WRONGTYPE Operation against a key holding the wrong kind of value"); - } - -#if FEATURE_BOOKSLEEVE - [Test] - [TestCase(true, true, ResultCompletionMode.ConcurrentIfContinuation)] - [TestCase(true, false, ResultCompletionMode.ConcurrentIfContinuation)] - [TestCase(false, true, ResultCompletionMode.ConcurrentIfContinuation)] - [TestCase(false, false, ResultCompletionMode.ConcurrentIfContinuation)] - [TestCase(true, true, ResultCompletionMode.Concurrent)] - [TestCase(true, false, ResultCompletionMode.Concurrent)] - [TestCase(false, true, ResultCompletionMode.Concurrent)] - [TestCase(false, false, ResultCompletionMode.Concurrent)] - [TestCase(true, true, ResultCompletionMode.PreserveOrder)] - [TestCase(true, false, ResultCompletionMode.PreserveOrder)] - [TestCase(false, true, ResultCompletionMode.PreserveOrder)] - [TestCase(false, false, ResultCompletionMode.PreserveOrder)] - public void MassiveBulkOpsAsyncOldStyle(bool withContinuation, bool suspendFlush, ResultCompletionMode completionMode) - { - using (var conn = GetOldStyleConnection()) - { - const int db = 0; - string key = "MBOQ"; - conn.CompletionMode = completionMode; - conn.Wait(conn.Server.Ping()); - Action nonTrivial = delegate - { - Thread.SpinWait(5); - }; - var watch = Stopwatch.StartNew(); - - if (suspendFlush) conn.SuspendFlush(); - try - { - - for (int i = 0; i <= AsyncOpsQty; i++) - { - var t = conn.Strings.Set(db, key, i); - if (withContinuation) t.ContinueWith(nonTrivial); - } - } finally - { - if (suspendFlush) conn.ResumeFlush(); - } - int val = (int)conn.Wait(conn.Strings.GetInt64(db, key)); - Assert.AreEqual(AsyncOpsQty, val); - watch.Stop(); - Console.WriteLine("{2}: Time for {0} ops: {1}ms ({3}, {4}, {5}); ops/s: {6}", AsyncOpsQty, watch.ElapsedMilliseconds, Me(), - withContinuation ? "with continuation" : "no continuation", - suspendFlush ? "suspend flush" : "flush at whim", - completionMode, AsyncOpsQty / watch.Elapsed.TotalSeconds); - } - } -#endif - - [Test] - [TestCase(true, 1)] - [TestCase(false, 1)] - [TestCase(true, 5)] - [TestCase(false, 5)] - [TestCase(true, 10)] - [TestCase(false, 10)] - [TestCase(true, 50)] - [TestCase(false, 50)] - public void MassiveBulkOpsSync(bool preserveOrder, int threads) - { - int workPerThread = SyncOpsQty / threads; - using (var muxer = Create()) - { - muxer.PreserveAsyncOrder = preserveOrder; - RedisKey key = "MBOS"; - var conn = muxer.GetDatabase(); - conn.KeyDelete(key); -#if DEBUG - long oldAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount(); - long oldWorkerCount = ConnectionMultiplexer.GetAsyncCompletionWorkerCount(); -#endif - var timeTaken = RunConcurrent(delegate - { - for (int i = 0; i < workPerThread; i++) - { - conn.StringIncrement(key); - } - }, threads); - - int val = (int)conn.StringGet(key); - Assert.AreEqual(workPerThread * threads, val); - Console.WriteLine("{2}: Time for {0} ops on {4} threads: {1}ms ({3}); ops/s: {5}", - threads * workPerThread, timeTaken.TotalMilliseconds, Me() - , preserveOrder ? "preserve order" : "any order", threads, (workPerThread * threads) / timeTaken.TotalSeconds); -#if DEBUG - long newAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount(); - long newWorkerCount = ConnectionMultiplexer.GetAsyncCompletionWorkerCount(); - Console.WriteLine("ResultBox allocations: {0}; workers {1}", newAlloc - oldAlloc, newWorkerCount - oldWorkerCount); - Assert.IsTrue(newAlloc - oldAlloc <= 2 * threads, "number of box allocations"); -#endif - } - } - -#if FEATURE_BOOKSLEEVE - [Test] - [TestCase(ResultCompletionMode.Concurrent, 1)] - [TestCase(ResultCompletionMode.ConcurrentIfContinuation, 1)] - [TestCase(ResultCompletionMode.PreserveOrder, 1)] - [TestCase(ResultCompletionMode.Concurrent, 5)] - [TestCase(ResultCompletionMode.ConcurrentIfContinuation, 5)] - [TestCase(ResultCompletionMode.PreserveOrder, 5)] - [TestCase(ResultCompletionMode.Concurrent, 10)] - [TestCase(ResultCompletionMode.ConcurrentIfContinuation, 10)] - [TestCase(ResultCompletionMode.PreserveOrder, 10)] - [TestCase(ResultCompletionMode.Concurrent, 50)] - [TestCase(ResultCompletionMode.ConcurrentIfContinuation, 50)] - [TestCase(ResultCompletionMode.PreserveOrder, 50)] - public void MassiveBulkOpsSyncOldStyle(ResultCompletionMode completionMode, int threads) - { - int workPerThread = SyncOpsQty / threads; - - using (var conn = GetOldStyleConnection()) - { - const int db = 0; - string key = "MBOQ"; - conn.CompletionMode = completionMode; - conn.Wait(conn.Keys.Remove(db, key)); - - var timeTaken = RunConcurrent(delegate - { - for (int i = 0; i < workPerThread; i++) - { - conn.Wait(conn.Strings.Increment(db, key)); - } - }, threads); - - int val = (int)conn.Wait(conn.Strings.GetInt64(db, key)); - Assert.AreEqual(workPerThread * threads, val); - - Console.WriteLine("{2}: Time for {0} ops on {4} threads: {1}ms ({3}); ops/s: {5}", workPerThread * threads, timeTaken.TotalMilliseconds, Me(), - completionMode, threads, (workPerThread * threads) / timeTaken.TotalSeconds); - } - } -#endif - - [Test] - [TestCase(true, 1)] - [TestCase(false, 1)] - [TestCase(true, 5)] - [TestCase(false, 5)] - public void MassiveBulkOpsFireAndForget(bool preserveOrder, int threads) - { - using (var muxer = Create()) - { - muxer.PreserveAsyncOrder = preserveOrder; -#if DEBUG - long oldAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount(); -#endif - RedisKey key = "MBOF"; - var conn = muxer.GetDatabase(); - conn.Ping(); - - conn.KeyDelete(key, CommandFlags.FireAndForget); - int perThread = AsyncOpsQty / threads; - var elapsed = RunConcurrent(delegate - { - for (int i = 0; i < perThread; i++) - { - conn.StringIncrement(key, flags: CommandFlags.FireAndForget); - } - conn.Ping(); - }, threads); - var val = (long)conn.StringGet(key); - Assert.AreEqual(perThread * threads, val); - - Console.WriteLine("{2}: Time for {0} ops over {5} threads: {1:###,###}ms ({3}); ops/s: {4:###,###,##0}", - val, elapsed.TotalMilliseconds, Me(), - preserveOrder ? "preserve order" : "any order", - val / elapsed.TotalSeconds, threads); -#if DEBUG - long newAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount(); - Console.WriteLine("ResultBox allocations: {0}", - newAlloc - oldAlloc); - Assert.IsTrue(newAlloc - oldAlloc <= 4); -#endif - } - } - - -#if DEBUG - [Test] - [TestCase(true)] - [TestCase(false)] - public void TestQuit(bool preserveOrder) - { - SetExpectedAmbientFailureCount(1); - using (var muxer = Create(allowAdmin: true)) - { - muxer.PreserveAsyncOrder = preserveOrder; - var db = muxer.GetDatabase(); - string key = Guid.NewGuid().ToString(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.StringSet(key, key, flags: CommandFlags.FireAndForget); - GetServer(muxer).Quit(CommandFlags.FireAndForget); - var watch = Stopwatch.StartNew(); - try - { - db.Ping(); - Assert.Fail(); - } - catch (RedisConnectionException) { } - watch.Stop(); - Console.WriteLine("Time to notice quit: {0}ms ({1})", watch.ElapsedMilliseconds, - preserveOrder ? "preserve order" : "any order"); - Thread.Sleep(20); - Debug.WriteLine("Pinging..."); - Assert.AreEqual(key, (string)db.StringGet(key)); - } - } - [Test] - [TestCase(true)] - [TestCase(false)] - public void TestSevered(bool preserveOrder) - { - SetExpectedAmbientFailureCount(2); - using (var muxer = Create(allowAdmin: true)) - { - muxer.PreserveAsyncOrder = preserveOrder; - var db = muxer.GetDatabase(); - string key = Guid.NewGuid().ToString(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.StringSet(key, key, flags: CommandFlags.FireAndForget); - GetServer(muxer).SimulateConnectionFailure(); - var watch = Stopwatch.StartNew(); - db.Ping(); - watch.Stop(); - Console.WriteLine("Time to re-establish: {0}ms ({1})", watch.ElapsedMilliseconds, - preserveOrder ? "preserve order" : "any order"); - Thread.Sleep(20); - Debug.WriteLine("Pinging..."); - Assert.AreEqual(key, (string)db.StringGet(key)); - } - } -#endif - - - - [Test] - [TestCase(true)] - [TestCase(false)] - public void IncrAsync(bool preserveOrder) - { - using (var muxer = Create()) - { - muxer.PreserveAsyncOrder = preserveOrder; - var conn = muxer.GetDatabase(); - RedisKey key = Me(); - conn.KeyDelete(key, CommandFlags.FireAndForget); - var nix = conn.KeyExistsAsync(key); - var a = conn.StringGetAsync(key); - var b = conn.StringIncrementAsync(key); - var c = conn.StringGetAsync(key); - var d = conn.StringIncrementAsync(key, 10); - var e = conn.StringGetAsync(key); - var f = conn.StringDecrementAsync(key, 11); - var g = conn.StringGetAsync(key); - var h = conn.KeyExistsAsync(key); - Assert.IsFalse(muxer.Wait(nix)); - Assert.IsTrue(muxer.Wait(a).IsNull); - Assert.AreEqual(0, (long)muxer.Wait(a)); - Assert.AreEqual(1, muxer.Wait(b)); - Assert.AreEqual(1, (long)muxer.Wait(c)); - Assert.AreEqual(11, muxer.Wait(d)); - Assert.AreEqual(11, (long)muxer.Wait(e)); - Assert.AreEqual(0, muxer.Wait(f)); - Assert.AreEqual(0, (long)muxer.Wait(g)); - Assert.IsTrue(muxer.Wait(h)); - } - } - [Test] - [TestCase(true)] - [TestCase(false)] - public void IncrSync(bool preserveOrder) - { - using (var muxer = Create()) - { - muxer.PreserveAsyncOrder = preserveOrder; - var conn = muxer.GetDatabase(); - RedisKey key = Me(); - conn.KeyDelete(key, CommandFlags.FireAndForget); - var nix = conn.KeyExists(key); - var a = conn.StringGet(key); - var b = conn.StringIncrement(key); - var c = conn.StringGet(key); - var d = conn.StringIncrement(key, 10); - var e = conn.StringGet(key); - var f = conn.StringDecrement(key, 11); - var g = conn.StringGet(key); - var h = conn.KeyExists(key); - Assert.IsFalse(nix); - Assert.IsTrue(a.IsNull); - Assert.AreEqual(0, (long)a); - Assert.AreEqual(1, b); - Assert.AreEqual(1, (long)c); - Assert.AreEqual(11, d); - Assert.AreEqual(11, (long)e); - Assert.AreEqual(0, f); - Assert.AreEqual(0, (long)g); - Assert.IsTrue(h); - } - } - - [Test] - public void IncrDifferentSizes() - { - using (var muxer = Create()) - { - var db = muxer.GetDatabase(); - RedisKey key = Me(); - db.KeyDelete(key, CommandFlags.FireAndForget); - int expected = 0; - Incr(db, key, -129019, ref expected); - Incr(db, key, -10023, ref expected); - Incr(db, key, -9933, ref expected); - Incr(db, key, -23, ref expected); - Incr(db, key, -7, ref expected); - Incr(db, key, -1, ref expected); - Incr(db, key, 0, ref expected); - Incr(db, key, 1, ref expected); - Incr(db, key, 9, ref expected); - Incr(db, key, 11, ref expected); - Incr(db, key, 345, ref expected); - Incr(db, key, 4982, ref expected); - Incr(db, key, 13091, ref expected); - Incr(db, key, 324092, ref expected); - Assert.AreNotEqual(0, expected); - var sum = (long)db.StringGet(key); - Assert.AreEqual(expected, sum); - } - } - - private void Incr(IDatabase database, RedisKey key, int delta, ref int total) - { - database.StringIncrement(key, delta, CommandFlags.FireAndForget); - total += delta; - } - - [Test] - public void WrappedDatabasePrefixIntegration() - { - using (var conn = Create()) - { - var db = conn.GetDatabase().WithKeyPrefix("abc"); - db.KeyDelete("count"); - db.StringIncrement("count"); - db.StringIncrement("count"); - db.StringIncrement("count"); - - int count = (int)conn.GetDatabase().StringGet("abccount"); - Assert.AreEqual(3, count); - } - } - } - -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/BatchWrapperTests.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/BatchWrapperTests.cs deleted file mode 100644 index c991c6d..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/BatchWrapperTests.cs +++ /dev/null @@ -1,31 +0,0 @@ -#if FEATURE_MOQ -using Moq; -using NUnit.Framework; -using StackExchange.Redis.KeyspaceIsolation; -using System.Text; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public sealed class BatchWrapperTests - { - private Mock mock; - private BatchWrapper wrapper; - - //[TestFixtureSetUp] - [OneTimeSetUpAttribute] - public void Initialize() - { - mock = new Mock(); - wrapper = new BatchWrapper(mock.Object, Encoding.UTF8.GetBytes("prefix:")); - } - - [Test] - public void Execute() - { - wrapper.Execute(); - mock.Verify(_ => _.Execute(), Times.Once()); - } - } -} -#endif \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Bits.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Bits.cs deleted file mode 100644 index 91a470a..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Bits.cs +++ /dev/null @@ -1,23 +0,0 @@ -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Bits : TestBase - { - [Test] - public void BasicOps() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(); - RedisKey key = Me(); - - db.KeyDelete(key, CommandFlags.FireAndForget); - db.StringSetBit(key, 10, true); - Assert.True(db.StringGetBit(key, 10)); - Assert.False(db.StringGetBit(key, 11)); - } - } - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Cluster.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Cluster.cs deleted file mode 100644 index 545d958..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Cluster.cs +++ /dev/null @@ -1,673 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Cluster : TestBase - { - //private const string ClusterIp = "192.168.0.15"; // marc - //private const string ClusterIp = "10.110.11.102"; // kmontrose - private const string ClusterIp = "127.0.0.1"; - private const int ServerCount = 6, FirstPort = 7000; - - protected override string GetConfiguration() - { - var server = ClusterIp; - if (string.Equals(Environment.MachineName, "MARC-LAPTOP", StringComparison.OrdinalIgnoreCase)) - { - server = "192.168.56.101"; - } - return string.Join(",", - from port in Enumerable.Range(FirstPort, ServerCount) - select server + ":" + port) + ",connectTimeout=10000"; - } - - [Test] - public void ExportConfiguration() - { - if (File.Exists("cluster.zip")) File.Delete("cluster.zip"); - Assert.IsFalse(File.Exists("cluster.zip")); - using (var muxer = Create(allowAdmin: true)) - using(var file = File.Create("cluster.zip")) - { - muxer.ExportConfiguration(file); - } - Assert.IsTrue(File.Exists("cluster.zip")); - } - - [Test] - public void ConnectUsesSingleSocket() - { - for(int i = 0; i<10;i++) - { - using (var muxer = Create(failMessage: i + ": ")) - { - var eps = muxer.GetEndPoints(); - foreach (var ep in eps) - { - var srv = muxer.GetServer(ep); - var counters = srv.GetCounters(); - Assert.AreEqual(1, counters.Interactive.SocketCount, i + "; interactive, " + ep.ToString()); - Assert.AreEqual(1, counters.Subscription.SocketCount, i + "; subscription, " + ep.ToString()); - } - } - } - } - - - [Test] - public void CanGetTotalStats() - { - using(var muxer = Create()) - { - var counters = muxer.GetCounters(); - Console.WriteLine(counters); - } - } - - [Test] - public void Connect() - { - using (var muxer = Create()) - { - var endpoints = muxer.GetEndPoints(); - - Assert.AreEqual(ServerCount, endpoints.Length); - var expectedPorts = new HashSet(Enumerable.Range(FirstPort, ServerCount)); - int masters = 0, slaves = 0; - var failed = new List(); - foreach (var endpoint in endpoints) - { - var server = muxer.GetServer(endpoint); - if (!server.IsConnected) - { - failed.Add(endpoint); - } - Assert.AreEqual(endpoint, server.EndPoint, "endpoint:" + endpoint); - Assert.IsInstanceOf(endpoint, "endpoint-type:" + endpoint); - Assert.IsTrue(expectedPorts.Remove(((IPEndPoint)endpoint).Port), "port:" + endpoint); - Assert.AreEqual(ServerType.Cluster, server.ServerType, "server-type:" + endpoint); - if (server.IsSlave) slaves++; - else masters++; - } - if (failed.Count != 0) - { - Console.WriteLine("{0} failues", failed.Count); - foreach (var fail in failed) - { - Console.WriteLine(fail); - } - Assert.Fail("not all servers connected"); - } - - Assert.AreEqual(ServerCount / 2, slaves, "slaves"); - Assert.AreEqual(ServerCount / 2, masters, "masters"); - - } - } - - [Test] - public void TestIdentity() - { - using(var conn = Create()) - { - RedisKey key = Guid.NewGuid().ToByteArray(); - var ep = conn.GetDatabase().IdentifyEndpoint(key); - Assert.AreEqual(ep, conn.GetServer(ep).ClusterConfiguration.GetBySlot(key).EndPoint); - } - } - - [Test] - public void IntentionalWrongServer() - { - using (var conn = Create()) - { - var endpoints = conn.GetEndPoints(); - var servers = endpoints.Select(e => conn.GetServer(e)); - - var key = Me(); - const string value = "abc"; - var db = conn.GetDatabase(); - db.KeyDelete(key); - db.StringSet(key, value); - servers.First().Ping(); - var config = servers.First().ClusterConfiguration; - Assert.IsNotNull(config); - int slot = conn.HashSlot(key); - var rightMasterNode = config.GetBySlot(key); - Assert.IsNotNull(rightMasterNode); - - - -#if DEBUG - string a = conn.GetServer(rightMasterNode.EndPoint).StringGet(db.Database, key); - Assert.AreEqual(value, a, "right master"); - - var node = config.Nodes.FirstOrDefault(x => !x.IsSlave && x.NodeId != rightMasterNode.NodeId); - Assert.IsNotNull(node); - if (node != null) - { - string b = conn.GetServer(node.EndPoint).StringGet(db.Database, key); - Assert.AreEqual(value, b, "wrong master, allow redirect"); - - try - { - string c = conn.GetServer(node.EndPoint).StringGet(db.Database, key, CommandFlags.NoRedirect); - Assert.Fail("wrong master, no redirect"); - } catch (RedisServerException ex) - { - Assert.AreEqual("MOVED " + slot + " " + rightMasterNode.EndPoint.ToString(), ex.Message, "wrong master, no redirect"); - } - } - - node = config.Nodes.FirstOrDefault(x => x.IsSlave && x.ParentNodeId == rightMasterNode.NodeId); - Assert.IsNotNull(node); - if (node != null) - { - string d = conn.GetServer(node.EndPoint).StringGet(db.Database, key); - Assert.AreEqual(value, d, "right slave"); - } - - node = config.Nodes.FirstOrDefault(x => x.IsSlave && x.ParentNodeId != rightMasterNode.NodeId); - Assert.IsNotNull(node); - if (node != null) - { - string e = conn.GetServer(node.EndPoint).StringGet(db.Database, key); - Assert.AreEqual(value, e, "wrong slave, allow redirect"); - - try - { - string f = conn.GetServer(node.EndPoint).StringGet(db.Database, key, CommandFlags.NoRedirect); - Assert.Fail("wrong slave, no redirect"); - } - catch (RedisServerException ex) - { - Assert.AreEqual("MOVED " + slot + " " + rightMasterNode.EndPoint.ToString(), ex.Message, "wrong slave, no redirect"); - } - } -#endif - - } - } - - [Test] - public void TransactionWithMultiServerKeys() - { - Assert.Throws(() => - { - using (var muxer = Create()) - { - // connect - var cluster = muxer.GetDatabase(); - var anyServer = muxer.GetServer(muxer.GetEndPoints()[0]); - anyServer.Ping(); - Assert.AreEqual(ServerType.Cluster, anyServer.ServerType); - var config = anyServer.ClusterConfiguration; - Assert.IsNotNull(config); - - // invent 2 keys that we believe are served by different nodes - string x = Guid.NewGuid().ToString(), y; - var xNode = config.GetBySlot(x); - int abort = 1000; - do - { - y = Guid.NewGuid().ToString(); - } while (--abort > 0 && config.GetBySlot(y) == xNode); - if (abort == 0) Assert.Inconclusive("failed to find a different node to use"); - var yNode = config.GetBySlot(y); - Console.WriteLine("x={0}, served by {1}", x, xNode.NodeId); - Console.WriteLine("y={0}, served by {1}", y, yNode.NodeId); - Assert.AreNotEqual(xNode.NodeId, yNode.NodeId, "same node"); - - // wipe those keys - cluster.KeyDelete(x, CommandFlags.FireAndForget); - cluster.KeyDelete(y, CommandFlags.FireAndForget); - - // create a transaction that attempts to assign both keys - var tran = cluster.CreateTransaction(); - tran.AddCondition(Condition.KeyNotExists(x)); - tran.AddCondition(Condition.KeyNotExists(y)); - var setX = tran.StringSetAsync(x, "x-val"); - var setY = tran.StringSetAsync(y, "y-val"); - bool success = tran.Execute(); - - Assert.Fail("Expected single-slot rules to apply"); - // the rest no longer applies while we are following single-slot rules - - //// check that everything was aborted - //Assert.IsFalse(success, "tran aborted"); - //Assert.IsTrue(setX.IsCanceled, "set x cancelled"); - //Assert.IsTrue(setY.IsCanceled, "set y cancelled"); - //var existsX = cluster.KeyExistsAsync(x); - //var existsY = cluster.KeyExistsAsync(y); - //Assert.IsFalse(cluster.Wait(existsX), "x exists"); - //Assert.IsFalse(cluster.Wait(existsY), "y exists"); - } - }, - "Multi-key operations must involve a single slot; keys can use 'hash tags' to help this, i.e. '{/users/12345}/account' and '{/users/12345}/contacts' will always be in the same slot"); - } - - [Test] - public void TransactionWithSameServerKeys() - { - Assert.Throws(() => - { - using (var muxer = Create()) - { - // connect - var cluster = muxer.GetDatabase(); - var anyServer = muxer.GetServer(muxer.GetEndPoints()[0]); - anyServer.Ping(); - var config = anyServer.ClusterConfiguration; - Assert.IsNotNull(config); - - // invent 2 keys that we believe are served by different nodes - string x = Guid.NewGuid().ToString(), y; - var xNode = config.GetBySlot(x); - int abort = 1000; - do - { - y = Guid.NewGuid().ToString(); - } while (--abort > 0 && config.GetBySlot(y) != xNode); - if (abort == 0) Assert.Inconclusive("failed to find a key with the same node to use"); - var yNode = config.GetBySlot(y); - Console.WriteLine("x={0}, served by {1}", x, xNode.NodeId); - Console.WriteLine("y={0}, served by {1}", y, yNode.NodeId); - Assert.AreEqual(xNode.NodeId, yNode.NodeId, "same node"); - - // wipe those keys - cluster.KeyDelete(x, CommandFlags.FireAndForget); - cluster.KeyDelete(y, CommandFlags.FireAndForget); - - // create a transaction that attempts to assign both keys - var tran = cluster.CreateTransaction(); - tran.AddCondition(Condition.KeyNotExists(x)); - tran.AddCondition(Condition.KeyNotExists(y)); - var setX = tran.StringSetAsync(x, "x-val"); - var setY = tran.StringSetAsync(y, "y-val"); - bool success = tran.Execute(); - - Assert.Fail("Expected single-slot rules to apply"); - // the rest no longer applies while we are following single-slot rules - - //// check that everything was aborted - //Assert.IsTrue(success, "tran aborted"); - //Assert.IsFalse(setX.IsCanceled, "set x cancelled"); - //Assert.IsFalse(setY.IsCanceled, "set y cancelled"); - //var existsX = cluster.KeyExistsAsync(x); - //var existsY = cluster.KeyExistsAsync(y); - //Assert.IsTrue(cluster.Wait(existsX), "x exists"); - //Assert.IsTrue(cluster.Wait(existsY), "y exists"); - } - }, - "Multi-key operations must involve a single slot; keys can use 'hash tags' to help this, i.e. '{/users/12345}/account' and '{/users/12345}/contacts' will always be in the same slot"); - } - - [Test] - public void TransactionWithSameSlotKeys() - { - using (var muxer = Create()) - { - // connect - var cluster = muxer.GetDatabase(); - var anyServer = muxer.GetServer(muxer.GetEndPoints()[0]); - anyServer.Ping(); - var config = anyServer.ClusterConfiguration; - Assert.IsNotNull(config); - - // invent 2 keys that we believe are in the same slot - var guid = Guid.NewGuid().ToString(); - string x = "/{" + guid + "}/foo", y = "/{" + guid + "}/bar"; - - Assert.AreEqual(muxer.HashSlot(x), muxer.HashSlot(y)); - var xNode = config.GetBySlot(x); - var yNode = config.GetBySlot(y); - Console.WriteLine("x={0}, served by {1}", x, xNode.NodeId); - Console.WriteLine("y={0}, served by {1}", y, yNode.NodeId); - Assert.AreEqual(xNode.NodeId, yNode.NodeId, "same node"); - - // wipe those keys - cluster.KeyDelete(x, CommandFlags.FireAndForget); - cluster.KeyDelete(y, CommandFlags.FireAndForget); - - // create a transaction that attempts to assign both keys - var tran = cluster.CreateTransaction(); - tran.AddCondition(Condition.KeyNotExists(x)); - tran.AddCondition(Condition.KeyNotExists(y)); - var setX = tran.StringSetAsync(x, "x-val"); - var setY = tran.StringSetAsync(y, "y-val"); - bool success = tran.Execute(); - - // check that everything was aborted - Assert.IsTrue(success, "tran aborted"); - Assert.IsFalse(setX.IsCanceled, "set x cancelled"); - Assert.IsFalse(setY.IsCanceled, "set y cancelled"); - var existsX = cluster.KeyExistsAsync(x); - var existsY = cluster.KeyExistsAsync(y); - Assert.IsTrue(cluster.Wait(existsX), "x exists"); - Assert.IsTrue(cluster.Wait(existsY), "y exists"); - } - } - - [Test] - [TestCase(null, 10)] - [TestCase(null, 100)] - [TestCase("abc", 10)] - [TestCase("abc", 100)] - - public void Keys(string pattern, int pageSize) - { - using (var conn = Create(allowAdmin: true)) - { - var cluster = conn.GetDatabase(); - var server = conn.GetEndPoints().Select(x => conn.GetServer(x)).First(x => !x.IsSlave); - server.FlushAllDatabases(); - try - { - Assert.IsFalse(server.Keys(pattern: pattern, pageSize: pageSize).Any()); - Console.WriteLine("Complete: '{0}' / {1}", pattern, pageSize); - } catch - { - Console.WriteLine("Failed: '{0}' / {1}", pattern, pageSize); - throw; - } - } - } - - [Test] - [TestCase("", 0)] - [TestCase("abc", 7638)] - [TestCase("{abc}", 7638)] - [TestCase("abcdef", 15101)] - [TestCase("abc{abc}def", 7638)] - [TestCase("c", 7365)] - [TestCase("g", 7233)] - [TestCase("d", 11298)] - - [TestCase("user1000", 3443)] - [TestCase("{user1000}", 3443)] - [TestCase("abc{user1000}", 3443)] - [TestCase("abc{user1000}def", 3443)] - [TestCase("{user1000}.following", 3443)] - [TestCase("{user1000}.followers", 3443)] - - [TestCase("foo{}{bar}", 8363)] - - [TestCase("foo{{bar}}zap", 4015)] - [TestCase("{bar", 4015)] - - [TestCase("foo{bar}{zap}", 5061)] - [TestCase("bar", 5061)] - - public void HashSlots(string key, int slot) - { - using(var muxer = Create(connectTimeout: 500, pause: false)) - { - Assert.AreEqual(slot, muxer.HashSlot(key)); - } - } - - - [Test] - public void SScan() - { - using (var conn = Create()) - { - RedisKey key = "a"; - var db = conn.GetDatabase(); - db.KeyDelete(key); - - int totalUnfiltered = 0, totalFiltered = 0; - for (int i = 0; i < 1000; i++) - { - db.SetAdd(key, i); - totalUnfiltered += i; - if (i.ToString().Contains("3")) totalFiltered += i; - } - var unfilteredActual = db.SetScan(key).Select(x => (int)x).Sum(); - var filteredActual = db.SetScan(key, "*3*").Select(x => (int)x).Sum(); - Assert.AreEqual(totalUnfiltered, unfilteredActual); - Assert.AreEqual(totalFiltered, filteredActual); - } - } - - [Test] - public void GetConfig() - { - using(var muxer = Create(allowAdmin: true)) - { - var endpoints = muxer.GetEndPoints(); - var server = muxer.GetServer(endpoints.First()); - var nodes = server.ClusterNodes(); - - Assert.AreEqual(endpoints.Length, nodes.Nodes.Count); - foreach(var node in nodes.Nodes.OrderBy(x => x)) - { - Console.WriteLine(node); - } - } - } - - [Test] - public void AccessRandomKeys() - { - using(var conn = Create(allowAdmin: true)) - { - - var cluster = conn.GetDatabase(); - int slotMovedCount = 0; - conn.HashSlotMoved += (s, a) => - { - Console.WriteLine("{0} moved from {1} to {2}", a.HashSlot, Describe(a.OldEndPoint), Describe(a.NewEndPoint)); - Interlocked.Increment(ref slotMovedCount); - }; - var pairs = new Dictionary(); - const int COUNT = 500; - Task[] send = new Task[COUNT]; - int index = 0; - - var servers = conn.GetEndPoints().Select(x => conn.GetServer(x)); - foreach (var server in servers) - { - if (!server.IsSlave) - { - server.Ping(); - server.FlushAllDatabases(); - } - } - - for(int i = 0; i < COUNT; i++) - { - var key = Guid.NewGuid().ToString(); - var value = Guid.NewGuid().ToString(); - pairs.Add(key, value); - send[index++] = cluster.StringSetAsync(key, value); - } - conn.WaitAll(send); - - var expected = new string[COUNT]; - var actual = new Task[COUNT]; - index = 0; - foreach (var pair in pairs) - { - expected[index] = pair.Value; - actual[index] = cluster.StringGetAsync(pair.Key); - index++; - } - cluster.WaitAll(actual); - for(int i = 0; i < COUNT; i++) - { - Assert.AreEqual(expected[i], (string)actual[i].Result); - } - - int total = 0; - Parallel.ForEach(servers, server => - { - if (!server.IsSlave) - { - int count = server.Keys(pageSize: 100).Count(); - Console.WriteLine("{0} has {1} keys", server.EndPoint, count); - Interlocked.Add(ref total, count); - } - }); - - foreach (var server in servers) - { - var counters = server.GetCounters(); - Console.WriteLine(counters); - } - int final = Interlocked.CompareExchange(ref total, 0, 0); - Assert.AreEqual(COUNT, final); - Assert.AreEqual(0, Interlocked.CompareExchange(ref slotMovedCount, 0, 0), "slot moved count"); - } - } - - [Test] - [TestCase(CommandFlags.DemandMaster, false)] - [TestCase(CommandFlags.DemandSlave, true)] - [TestCase(CommandFlags.PreferMaster, false)] - [TestCase(CommandFlags.PreferSlave, true)] - public void GetFromRightNodeBasedOnFlags(CommandFlags flags, bool isSlave) - { - using(var muxer = Create(allowAdmin: true)) - { - var db = muxer.GetDatabase(); - for(int i = 0; i < 1000; i++) - { - var key = Guid.NewGuid().ToString(); - var endpoint = db.IdentifyEndpoint(key, flags); - var server = muxer.GetServer(endpoint); - Assert.AreEqual(isSlave, server.IsSlave, key); - } - } - } - - private static string Describe(EndPoint endpoint) - { - return endpoint?.ToString() ?? "(unknown)"; - } - - class TestProfiler : IProfiler - { - public object MyContext = new object(); - - public object GetContext() - { - return MyContext; - } - } - - [Test] - public void SimpleProfiling() - { - using (var conn = Create()) - { - var profiler = new TestProfiler(); - - conn.RegisterProfiler(profiler); - conn.BeginProfiling(profiler.MyContext); - var db = conn.GetDatabase(); - db.StringSet("hello", "world"); - var val = db.StringGet("hello"); - Assert.AreEqual("world", (string)val); - - var msgs = conn.FinishProfiling(profiler.MyContext); - Assert.AreEqual(2, msgs.Count()); - Assert.IsTrue(msgs.Any(m => m.Command == "GET")); - Assert.IsTrue(msgs.Any(m => m.Command == "SET")); - } - } - -#if DEBUG - [Test] - public void MovedProfiling() - { - const string Key = "redirected-key"; - const string Value = "redirected-value"; - - var profiler = new TestProfiler(); - - using (var conn = Create()) - { - conn.RegisterProfiler(profiler); - - var endpoints = conn.GetEndPoints(); - var servers = endpoints.Select(e => conn.GetServer(e)); - - conn.BeginProfiling(profiler.MyContext); - var db = conn.GetDatabase(); - db.KeyDelete(Key); - db.StringSet(Key, Value); - var config = servers.First().ClusterConfiguration; - Assert.IsNotNull(config); - - int slot = conn.HashSlot(Key); - var rightMasterNode = config.GetBySlot(Key); - Assert.IsNotNull(rightMasterNode); - - string a = conn.GetServer(rightMasterNode.EndPoint).StringGet(db.Database, Key); - Assert.AreEqual(Value, a, "right master"); - - var wrongMasterNode = config.Nodes.FirstOrDefault(x => !x.IsSlave && x.NodeId != rightMasterNode.NodeId); - Assert.IsNotNull(wrongMasterNode); - - string b = conn.GetServer(wrongMasterNode.EndPoint).StringGet(db.Database, Key); - Assert.AreEqual(Value, b, "wrong master, allow redirect"); - - var msgs = conn.FinishProfiling(profiler.MyContext).ToList(); - - // verify that things actually got recorded properly, and the retransmission profilings are connected as expected - { - // expect 1 DEL, 1 SET, 1 GET (to right master), 1 GET (to wrong master) that was responded to by an ASK, and 1 GET (to right master or a slave of it) - Assert.AreEqual(5, msgs.Count); - Assert.AreEqual(1, msgs.Count(c => c.Command == "DEL")); - Assert.AreEqual(1, msgs.Count(c => c.Command == "SET")); - Assert.AreEqual(3, msgs.Count(c => c.Command == "GET")); - - var toRightMasterNotRetransmission = msgs.Where(m => m.Command == "GET" && m.EndPoint.Equals(rightMasterNode.EndPoint) && m.RetransmissionOf == null); - Assert.AreEqual(1, toRightMasterNotRetransmission.Count()); - - var toWrongMasterWithoutRetransmission = msgs.Where(m => m.Command == "GET" && m.EndPoint.Equals(wrongMasterNode.EndPoint) && m.RetransmissionOf == null); - Assert.AreEqual(1, toWrongMasterWithoutRetransmission.Count()); - - var toRightMasterOrSlaveAsRetransmission = msgs.Where(m => m.Command == "GET" && (m.EndPoint.Equals(rightMasterNode.EndPoint) || rightMasterNode.Children.Any(c => m.EndPoint.Equals(c.EndPoint))) && m.RetransmissionOf != null); - Assert.AreEqual(1, toRightMasterOrSlaveAsRetransmission.Count()); - - var originalWrongMaster = toWrongMasterWithoutRetransmission.Single(); - var retransmissionToRight = toRightMasterOrSlaveAsRetransmission.Single(); - - Assert.IsTrue(object.ReferenceEquals(originalWrongMaster, retransmissionToRight.RetransmissionOf)); - } - - foreach(var msg in msgs) - { - Assert.IsTrue(msg.CommandCreated != default(DateTime)); - Assert.IsTrue(msg.CreationToEnqueued > TimeSpan.Zero); - Assert.IsTrue(msg.EnqueuedToSending > TimeSpan.Zero); - Assert.IsTrue(msg.SentToResponse > TimeSpan.Zero); - Assert.IsTrue(msg.ResponseToCompletion > TimeSpan.Zero); - Assert.IsTrue(msg.ElapsedTime > TimeSpan.Zero); - - if (msg.RetransmissionOf != null) - { - // imprecision of DateTime.UtcNow makes this pretty approximate - Assert.IsTrue(msg.RetransmissionOf.CommandCreated <= msg.CommandCreated); - Assert.AreEqual(RetransmissionReasonType.Moved, msg.RetransmissionReason.Value); - } - else - { - Assert.IsFalse(msg.RetransmissionReason.HasValue); - } - } - } - } -#endif - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Commands.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Commands.cs deleted file mode 100644 index a255ac9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Commands.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Net; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Commands - { - [Test] - public void Basic() - { - var config = ConfigurationOptions.Parse(".,$PING=p"); - Assert.AreEqual(1, config.EndPoints.Count); - config.SetDefaultPorts(); - Assert.Contains(new DnsEndPoint(".",6379), config.EndPoints); - var map = config.CommandMap; - Assert.AreEqual("$PING=p", map.ToString()); - Assert.AreEqual(".:6379,$PING=p", config.ToString()); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Config.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Config.cs deleted file mode 100644 index 812c0cb..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Config.cs +++ /dev/null @@ -1,338 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Config : TestBase - { - - [Test] - public void VerifyReceiveConfigChangeBroadcast() - { - - var config = this.GetConfiguration(); - using (var sender = Create(allowAdmin: true)) - using (var receiver = Create(syncTimeout: 2000)) - { - int total = 0; - receiver.ConfigurationChangedBroadcast += (s, a) => - { - Console.WriteLine("Config changed: " + (a.EndPoint == null ? "(none)" : a.EndPoint.ToString())); - Interlocked.Increment(ref total); - }; - Thread.Sleep(500); - // send a reconfigure/reconnect message - long count = sender.PublishReconfigure(); - GetServer(receiver).Ping(); - GetServer(receiver).Ping(); - Assert.IsTrue(count == -1 || count >= 2, "subscribers"); - Assert.IsTrue(Interlocked.CompareExchange(ref total, 0, 0) >= 1, "total (1st)"); - - Interlocked.Exchange(ref total, 0); - - // and send a second time via a re-master operation - var server = GetServer(sender); - if (server.IsSlave) Assert.Inconclusive("didn't expect a slave"); - server.MakeMaster(ReplicationChangeOptions.Broadcast); - Thread.Sleep(100); - GetServer(receiver).Ping(); - GetServer(receiver).Ping(); - Assert.IsTrue(Interlocked.CompareExchange(ref total, 0, 0) >= 1, "total (2nd)"); - } - } - - [Test] - public void TalkToNonsenseServer() - { - var config = new ConfigurationOptions - { - AbortOnConnectFail = false, - EndPoints = - { - { "127.0.0.1:1234" } - }, - ConnectTimeout = 200 - }; - var log = new StringWriter(); - using(var conn = ConnectionMultiplexer.Connect(config, log)) - { - Console.WriteLine(log); - Assert.IsFalse(conn.IsConnected); - } - } - - [Test] - public void TestManaulHeartbeat() - { - using (var muxer = Create(keepAlive: 2)) - { - var conn = muxer.GetDatabase(); - conn.Ping(); - - var before = muxer.OperationCount; - - Console.WriteLine("sleeping to test heartbeat..."); - Thread.Sleep(TimeSpan.FromSeconds(5)); - - var after = muxer.OperationCount; - - Assert.IsTrue(after >= before + 4); - - } - } - - [Test] - [TestCase(0)] - [TestCase(10)] - [TestCase(100)] - [TestCase(200)] - public void GetSlowlog(int count) - { - using(var muxer = Create(allowAdmin: true)) - { - var rows = GetServer(muxer).SlowlogGet(count); - Assert.IsNotNull(rows); - } - } - [Test] - public void ClearSlowlog() - { - using (var muxer = Create(allowAdmin: true)) - { - GetServer(muxer).SlowlogReset(); - } - } - - [Test] - public void ClientName() - { - using (var muxer = Create(clientName: "Test Rig", allowAdmin: true)) - { - Assert.AreEqual("Test Rig", muxer.ClientName); - - var conn = muxer.GetDatabase(); - conn.Ping(); -#if DEBUG - var name = GetServer(muxer).ClientGetName(); - Assert.AreEqual("TestRig", name); -#endif - } - } - - [Test] - public void DefaultClientName() - { - using (var muxer = Create(allowAdmin: true)) - { - Assert.AreEqual(Environment.MachineName, muxer.ClientName); - var conn = muxer.GetDatabase(); - conn.Ping(); -#if DEBUG - var name = GetServer(muxer).ClientGetName(); - Assert.AreEqual(Environment.MachineName, name); -#endif - } - } - - [Test] - public void ReadConfigWithConfigDisabled() - { - using (var muxer = Create(allowAdmin: true, disabledCommands: new[] { "config", "info" })) - { - var conn = GetServer(muxer); - Assert.Throws(() => - { - var all = conn.ConfigGet(); - }, - "This operation has been disabled in the command-map and cannot be used: CONFIG"); - } - } - [Test] - public void ReadConfig() - { - using (var muxer = Create(allowAdmin: true)) - { - Console.WriteLine("about to get config"); - var conn = GetServer(muxer); - var all = conn.ConfigGet(); - Assert.IsTrue(all.Length > 0, "any"); - -#if !CORE_CLR - var pairs = all.ToDictionary(x => (string)x.Key, x => (string)x.Value, StringComparer.InvariantCultureIgnoreCase); -#else - var pairs = all.ToDictionary(x => (string)x.Key, x => (string)x.Value, StringComparer.OrdinalIgnoreCase); -#endif - - Assert.AreEqual(all.Length, pairs.Count); - Assert.IsTrue(pairs.ContainsKey("timeout"), "timeout"); - var val = int.Parse(pairs["timeout"]); - - Assert.IsTrue(pairs.ContainsKey("port"), "port"); - val = int.Parse(pairs["port"]); - Assert.AreEqual(PrimaryPort, val); - } - } - - [Test] - public async System.Threading.Tasks.Task TestConfigureAsync() - { - using(var muxer = Create()) - { - Thread.Sleep(1000); - Debug.WriteLine("About to reconfigure....."); - await muxer.ConfigureAsync().ConfigureAwait(false); - Debug.WriteLine("Reconfigured"); - } - } - [Test] - public void TestConfigureSync() - { - using (var muxer = Create()) - { - Thread.Sleep(1000); - Debug.WriteLine("About to reconfigure....."); - muxer.Configure(); - Debug.WriteLine("Reconfigured"); - } - } - - [Test] - public void GetTime() - { - using (var muxer = Create()) - { - var server = GetServer(muxer); - var serverTime = server.Time(); - Console.WriteLine(serverTime); - var delta = Math.Abs((DateTime.UtcNow - serverTime).TotalSeconds); - - Assert.IsTrue(delta < 5); - } - } - - [Test] - public void DebugObject() - { - using (var muxer = Create(allowAdmin: true)) - { - var db = muxer.GetDatabase(); - RedisKey key = Me(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.StringIncrement(key, flags: CommandFlags.FireAndForget); - var debug = (string)db.DebugObject(key); - Assert.IsNotNull(debug); - Assert.IsTrue(debug.Contains("encoding:int serializedlength:2")); - } - } - - [Test] - public void GetInfo() - { - using(var muxer = Create(allowAdmin: true)) - { - var server = GetServer(muxer); - var info1 = server.Info(); - Assert.IsTrue(info1.Length > 5); - Console.WriteLine("All sections"); - foreach(var group in info1) - { - Console.WriteLine(group.Key); - } - var first = info1.First(); - Console.WriteLine("Full info for: " + first.Key); - foreach (var setting in first) - { - Console.WriteLine("{0} ==> {1}", setting.Key, setting.Value); - } - - var info2 = server.Info("cpu"); - Assert.AreEqual(1, info2.Length); - var cpu = info2.Single(); - Assert.IsTrue(cpu.Count() > 2); - Assert.AreEqual("CPU", cpu.Key); - Assert.IsTrue(cpu.Any(x => x.Key == "used_cpu_sys")); - Assert.IsTrue(cpu.Any(x => x.Key == "used_cpu_user")); - } - } - - [Test] - public void GetInfoRaw() - { - using (var muxer = Create(allowAdmin: true)) - { - var server = GetServer(muxer); - var info = server.InfoRaw(); - Assert.IsTrue(info.Contains("used_cpu_sys")); - Assert.IsTrue(info.Contains("used_cpu_user")); - } - } - - [Test] - public void GetClients() - { - var name = Guid.NewGuid().ToString(); - using (var muxer = Create(clientName: name, allowAdmin: true)) - { - var server = GetServer(muxer); - var clients = server.ClientList(); - Assert.IsTrue(clients.Length > 0, "no clients"); // ourselves! - Assert.IsTrue(clients.Any(x => x.Name == name), "expected: " + name); - } - } - - [Test] - public void SlowLog() - { - using (var muxer = Create(allowAdmin: true)) - { - var server = GetServer(muxer); - var slowlog = server.SlowlogGet(); - server.SlowlogReset(); - } - } - - [Test] - public void TestAutomaticHeartbeat() - { - RedisValue oldTimeout = RedisValue.Null; - using (var configMuxer = Create(allowAdmin: true)) - { - try - { - var conn = configMuxer.GetDatabase(); - var srv = GetServer(configMuxer); - oldTimeout = srv.ConfigGet("timeout")[0].Value; - srv.ConfigSet("timeout", 5); - - using(var innerMuxer = Create()) - { - var innerConn = innerMuxer.GetDatabase(); - innerConn.Ping(); // need to wait to pick up configuration etc - - var before = innerMuxer.OperationCount; - - Console.WriteLine("sleeping to test heartbeat..."); - Thread.Sleep(TimeSpan.FromSeconds(8)); - - var after = innerMuxer.OperationCount; - Assert.IsTrue(after >= before + 4); - - } - } - finally - { - if(!oldTimeout.IsNull) - { - var srv = GetServer(configMuxer); - srv.ConfigSet("timeout", oldTimeout); - } - } - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectFailTimeout.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectFailTimeout.cs deleted file mode 100644 index afe63b9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectFailTimeout.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Threading; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class ConnectFailTimeout : TestBase - { -#if DEBUG - [TestCase] - public void NoticesConnectFail() - { - SetExpectedAmbientFailureCount(-1); - using (var conn = Create(allowAdmin: true)) - { - var server = conn.GetServer(conn.GetEndPoints()[0]); - conn.IgnoreConnect = true; - conn.ConnectionFailed += (s,a) => { - System.Console.WriteLine("Disconnected: " + EndPointCollection.ToString(a.EndPoint)); - }; - conn.ConnectionRestored += (s,a) => { - System.Console.WriteLine("Reconnected: " + EndPointCollection.ToString(a.EndPoint)); - }; - server.SimulateConnectionFailure(); - Thread.Sleep(2000); - try - { - server.Ping(); - Assert.Fail("Did not expect PING to succeed"); - } catch(RedisConnectionException) { /* expected */ } - - conn.IgnoreConnect = false; - Thread.Sleep(2000); - var time = server.Ping(); - System.Console.WriteLine(time); - } - } -#endif - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectToUnexistingHost.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectToUnexistingHost.cs deleted file mode 100644 index 7981767..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectToUnexistingHost.cs +++ /dev/null @@ -1,51 +0,0 @@ -using NUnit.Framework; -using System.Diagnostics; -using System.Threading; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class ConnectToUnexistingHost : TestBase - { -#if DEBUG - [Test] - [TestCase(CompletionType.Any)] - [TestCase(CompletionType.Sync)] - [TestCase(CompletionType.Async)] - public void ConnectToUnexistingHostFailsWithinTimeout(CompletionType completionType) - { - var sw = Stopwatch.StartNew(); - - try - { - var config = new ConfigurationOptions - { - EndPoints = { { "invalid", 1234 } }, - ConnectTimeout = 1000 - }; - - SocketManager.ConnectCompletionType = completionType; - - using (var muxer = ConnectionMultiplexer.Connect(config)) - { - Thread.Sleep(10000); - } - - Assert.Fail("Connect should fail with RedisConnectionException exception"); - } - catch (RedisConnectionException) - { - var elapsed = sw.ElapsedMilliseconds; - if (elapsed > 9000) - { - Assert.Fail("Connect should fail within ConnectTimeout"); - } - } - finally - { - SocketManager.ConnectCompletionType = CompletionType.Any; - } - } -#endif - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectingFailDetection.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectingFailDetection.cs deleted file mode 100644 index e3e218f..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectingFailDetection.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Threading; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class ConnectingFailDetection : TestBase - { -#if DEBUG - [Test] - public void FastNoticesFailOnConnectingSync() - { - try - { - using (var muxer = Create(keepAlive: 1, connectTimeout: 10000, allowAdmin: true)) - { - var conn = muxer.GetDatabase(); - conn.Ping(); - - var server = muxer.GetServer(muxer.GetEndPoints()[0]); - - muxer.AllowConnect = false; - SocketManager.ConnectCompletionType = CompletionType.Sync; - - server.SimulateConnectionFailure(); - - Assert.IsFalse(muxer.IsConnected); - - // should reconnect within 1 keepalive interval - muxer.AllowConnect = true; - Console.WriteLine("Waiting for reconnect"); - Thread.Sleep(2000); - - Assert.IsTrue(muxer.IsConnected); - } - } - finally - { - SocketManager.ConnectCompletionType = CompletionType.Any; - ClearAmbientFailures(); - } - } - - [Test] - public void ConnectsWhenBeginConnectCompletesSynchronously() - { - try - { - SocketManager.ConnectCompletionType = CompletionType.Sync; - - using (var muxer = Create(keepAlive: 1, connectTimeout: 3000)) - { - var conn = muxer.GetDatabase(); - conn.Ping(); - - Assert.IsTrue(muxer.IsConnected); - } - } - finally - { - SocketManager.ConnectCompletionType = CompletionType.Any; - ClearAmbientFailures(); - } - } - - [Test] - public void FastNoticesFailOnConnectingAsync() - { - try - { - - using (var muxer = Create(keepAlive: 1, connectTimeout: 10000, allowAdmin: true)) - { - var conn = muxer.GetDatabase(); - conn.Ping(); - - var server = muxer.GetServer(muxer.GetEndPoints()[0]); - - muxer.AllowConnect = false; - SocketManager.ConnectCompletionType = CompletionType.Async; - - server.SimulateConnectionFailure(); - - Assert.IsFalse(muxer.IsConnected); - - // should reconnect within 1 keepalive interval - muxer.AllowConnect = true; - Console.WriteLine("Waiting for reconnect"); - Thread.Sleep(2000); - - Assert.IsTrue(muxer.IsConnected); - } - } - finally - { - SocketManager.ConnectCompletionType = CompletionType.Any; - ClearAmbientFailures(); - } - } - - [Test] - public void ReconnectsOnStaleConnection() - { - try - { - using (var muxer = Create(keepAlive: 1, connectTimeout: 3000)) - { - var conn = muxer.GetDatabase(); - conn.Ping(); - - Assert.IsTrue(muxer.IsConnected); - - PhysicalConnection.EmulateStaleConnection = true; - Thread.Sleep(500); - Assert.IsFalse(muxer.IsConnected); - - PhysicalConnection.EmulateStaleConnection = false; - Thread.Sleep(1000); - Assert.IsTrue(muxer.IsConnected); - } - } - finally - { - PhysicalConnection.EmulateStaleConnection = false; - ClearAmbientFailures(); - } - } - -#endif - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectionFailedErrors.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectionFailedErrors.cs deleted file mode 100644 index 5e28b72..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectionFailedErrors.cs +++ /dev/null @@ -1,146 +0,0 @@ -using NUnit.Framework; -using System.Threading; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class ConnectionFailedErrors : TestBase - { - [Test] - [TestCase(true)] - [TestCase(false)] - public void SSLCertificateValidationError(bool isCertValidationSucceeded) - { - string name, password; - GetAzureCredentials(out name, out password); - var options = new ConfigurationOptions(); - options.EndPoints.Add(name + ".redis.cache.windows.net"); - options.Ssl = true; - options.Password = password; - options.CertificateValidation += (sender, cert, chain, errors) => { return isCertValidationSucceeded; }; - options.AbortOnConnectFail = false; - - using (var connection = ConnectionMultiplexer.Connect(options)) - { - connection.ConnectionFailed += (object sender, ConnectionFailedEventArgs e) => - { - Assert.That(e.FailureType, Is.EqualTo(ConnectionFailureType.AuthenticationFailure)); - }; - if (!isCertValidationSucceeded) - { - //validate that in this case it throws an certificatevalidation exception - var ex = Assert.Throws(() => connection.GetDatabase().Ping()); - var rde = (RedisConnectionException)ex.InnerException; - Assert.That(rde.FailureType, Is.EqualTo(ConnectionFailureType.AuthenticationFailure)); - Assert.That(rde.InnerException.Message, Is.EqualTo("The remote certificate is invalid according to the validation procedure.")); - } - else - { - Assert.DoesNotThrow(() => connection.GetDatabase().Ping()); - } - - //wait for a second for connectionfailed event to fire - Thread.Sleep(1000); - } - - - } - - [Test] - public void AuthenticationFailureError() - { - string name, password; - GetAzureCredentials(out name, out password); - var options = new ConfigurationOptions(); - options.EndPoints.Add(name + ".redis.cache.windows.net"); - options.Ssl = true; - options.Password = ""; - options.AbortOnConnectFail = false; - using (var muxer = ConnectionMultiplexer.Connect(options)) - { - muxer.ConnectionFailed += (object sender, ConnectionFailedEventArgs e) => - { - Assert.That(e.FailureType, Is.EqualTo(ConnectionFailureType.AuthenticationFailure)); - }; - var ex = Assert.Throws(() => muxer.GetDatabase().Ping()); - var rde = (RedisConnectionException)ex.InnerException; - Assert.That(ex.CommandStatus, Is.EqualTo(CommandStatus.WaitingToBeSent)); - Assert.That(rde.FailureType, Is.EqualTo(ConnectionFailureType.AuthenticationFailure)); - Assert.That(rde.InnerException.Message, Is.EqualTo("Error: NOAUTH Authentication required. Verify if the Redis password provided is correct.")); - //wait for a second for connectionfailed event to fire - Thread.Sleep(1000); - } - } - - [Test] - public void SocketFailureError() - { - var options = new ConfigurationOptions(); - options.EndPoints.Add(".redis.cache.windows.net"); - options.Ssl = true; - options.Password = ""; - options.AbortOnConnectFail = false; - using (var muxer = ConnectionMultiplexer.Connect(options)) - { - var ex = Assert.Throws(() => muxer.GetDatabase().Ping()); - var rde = (RedisConnectionException)ex.InnerException; - Assert.That(rde.FailureType, Is.EqualTo(ConnectionFailureType.SocketFailure)); - } - } -#if DEBUG // needs AllowConnect, which is DEBUG only - [Test] - public void AbortOnConnectFailFalseConnectTimeoutError() - { - string name, password; - GetAzureCredentials(out name, out password); - var options = new ConfigurationOptions(); - options.EndPoints.Add(name + ".redis.cache.windows.net"); - options.Ssl = true; - options.ConnectTimeout = 0; - options.Password = password; - using (var muxer = ConnectionMultiplexer.Connect(options)) - { - var ex = Assert.Throws(() => muxer.GetDatabase().Ping()); - Assert.That(ex.Message, Does.Contain("ConnectTimeout")); - } - } - - [Test] - public void CheckFailureRecovered() - { - try - { - using (var muxer = Create(keepAlive: 1, connectTimeout: 10000, allowAdmin: true)) - { - var conn = muxer.GetDatabase(); - var server = muxer.GetServer(muxer.GetEndPoints()[0]); - - muxer.AllowConnect = false; - SocketManager.ConnectCompletionType = CompletionType.Async; - - server.SimulateConnectionFailure(); - - Assert.AreEqual(ConnectionFailureType.SocketFailure, ((RedisConnectionException)muxer.GetServerSnapshot()[0].LastException).FailureType); - - // should reconnect within 1 keepalive interval - muxer.AllowConnect = true; - Thread.Sleep(2000); - - Assert.Null(muxer.GetServerSnapshot()[0].LastException); - } - } - finally - { - SocketManager.ConnectCompletionType = CompletionType.Any; - ClearAmbientFailures(); - } - } - -#endif - [Test] - public void TryGetAzureRoleInstanceIdNoThrow() - { - Assert.IsNull(ConnectionMultiplexer.TryGetAzureRoleInstanceIdNoThrow()); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectionReconnectRetryPolicyTests.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectionReconnectRetryPolicyTests.cs deleted file mode 100644 index bf9edb1..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectionReconnectRetryPolicyTests.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class TransientErrorTests : TestBase - { - - [TestCase] - public void TestExponentialRetry() - { - IReconnectRetryPolicy exponentialRetry = new ExponentialRetry(5000); - Assert.False(exponentialRetry.ShouldRetry(0, 0)); - Assert.True(exponentialRetry.ShouldRetry(1, 5600)); - Assert.True(exponentialRetry.ShouldRetry(2, 6050)); - Assert.False(exponentialRetry.ShouldRetry(2, 4050)); - } - - [TestCase] - public void TestExponentialMaxRetry() - { - IReconnectRetryPolicy exponentialRetry = new ExponentialRetry(5000); - Assert.True(exponentialRetry.ShouldRetry(long.MaxValue, (int)TimeSpan.FromSeconds(30).TotalMilliseconds)); - } - - [TestCase] - public void TestLinearRetry() - { - IReconnectRetryPolicy linearRetry = new LinearRetry(5000); - Assert.False(linearRetry.ShouldRetry(0, 0)); - Assert.False(linearRetry.ShouldRetry(2, 4999)); - Assert.True(linearRetry.ShouldRetry(1, 5000)); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectionShutdown.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectionShutdown.cs deleted file mode 100644 index 30f26c8..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ConnectionShutdown.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Diagnostics; -using System.Threading; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class ConnectionShutdown : TestBase - { - protected override string GetConfiguration() - { - return PrimaryServer + ":" + PrimaryPortString; - } - - [Test] - public void ShutdownRaisesConnectionFailedAndRestore() - { - using(var conn = Create(allowAdmin: true)) - { - int failed = 0, restored = 0; - Stopwatch watch = Stopwatch.StartNew(); - conn.ConnectionFailed += (sender,args)=> - { - Console.WriteLine(watch.Elapsed + ": failed: " + EndPointCollection.ToString(args.EndPoint) + "/" + args.ConnectionType); - Interlocked.Increment(ref failed); - }; - conn.ConnectionRestored += (sender, args) => - { - Console.WriteLine(watch.Elapsed + ": restored: " + EndPointCollection.ToString(args.EndPoint) + "/" + args.ConnectionType); - Interlocked.Increment(ref restored); - }; - var db = conn.GetDatabase(); - db.Ping(); - Assert.AreEqual(0, Interlocked.CompareExchange(ref failed, 0, 0)); - Assert.AreEqual(0, Interlocked.CompareExchange(ref restored, 0, 0)); - -#if DEBUG - conn.AllowConnect = false; - var server = conn.GetServer(PrimaryServer, PrimaryPort); - - SetExpectedAmbientFailureCount(2); - server.SimulateConnectionFailure(); - - db.Ping(CommandFlags.FireAndForget); - Thread.Sleep(250); - Assert.AreEqual(2, Interlocked.CompareExchange(ref failed, 0, 0), "failed"); - Assert.AreEqual(0, Interlocked.CompareExchange(ref restored, 0, 0), "restored"); - conn.AllowConnect = true; - db.Ping(CommandFlags.FireAndForget); - Thread.Sleep(1500); - Assert.AreEqual(2, Interlocked.CompareExchange(ref failed, 0, 0), "failed"); - Assert.AreEqual(2, Interlocked.CompareExchange(ref restored, 0, 0), "restored"); -#endif - watch.Stop(); - } - - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/DatabaseWrapperTests.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/DatabaseWrapperTests.cs deleted file mode 100644 index ce22aa9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/DatabaseWrapperTests.cs +++ /dev/null @@ -1,937 +0,0 @@ -#if FEATURE_MOQ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Net; -using System.Text; -using Moq; -using NUnit.Framework; -using StackExchange.Redis.KeyspaceIsolation; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public sealed class DatabaseWrapperTests - { - private Mock mock; - private DatabaseWrapper wrapper; - - //[TestFixtureSetUp] - [OneTimeSetUp] - public void Initialize() - { - mock = new Mock(); - wrapper = new DatabaseWrapper(mock.Object, Encoding.UTF8.GetBytes("prefix:")); - } - - [Test] - public void CreateBatch() - { - object asyncState = new object(); - IBatch innerBatch = new Mock().Object; - mock.Setup(_ => _.CreateBatch(asyncState)).Returns(innerBatch); - IBatch wrappedBatch = wrapper.CreateBatch(asyncState); - mock.Verify(_ => _.CreateBatch(asyncState)); - Assert.IsInstanceOf(wrappedBatch); - Assert.AreSame(innerBatch, ((BatchWrapper)wrappedBatch).Inner); - } - - [Test] - public void CreateTransaction() - { - object asyncState = new object(); - ITransaction innerTransaction = new Mock().Object; - mock.Setup(_ => _.CreateTransaction(asyncState)).Returns(innerTransaction); - ITransaction wrappedTransaction = wrapper.CreateTransaction(asyncState); - mock.Verify(_ => _.CreateTransaction(asyncState)); - Assert.IsInstanceOf(wrappedTransaction); - Assert.AreSame(innerTransaction, ((TransactionWrapper)wrappedTransaction).Inner); - } - - [Test] - public void DebugObject() - { - wrapper.DebugObject("key", CommandFlags.HighPriority); - mock.Verify(_ => _.DebugObject("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void get_Database() - { - mock.SetupGet(_ => _.Database).Returns(123); - Assert.AreEqual(123, wrapper.Database); - } - - [Test] - public void HashDecrement_1() - { - wrapper.HashDecrement("key", "hashField", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.HashDecrement("prefix:key", "hashField", 123, CommandFlags.HighPriority)); - } - - [Test] - public void HashDecrement_2() - { - wrapper.HashDecrement("key", "hashField", 1.23, CommandFlags.HighPriority); - mock.Verify(_ => _.HashDecrement("prefix:key", "hashField", 1.23, CommandFlags.HighPriority)); - } - - [Test] - public void HashDelete_1() - { - wrapper.HashDelete("key", "hashField", CommandFlags.HighPriority); - mock.Verify(_ => _.HashDelete("prefix:key", "hashField", CommandFlags.HighPriority)); - } - - [Test] - public void HashDelete_2() - { - RedisValue[] hashFields = new RedisValue[0]; - wrapper.HashDelete("key", hashFields, CommandFlags.HighPriority); - mock.Verify(_ => _.HashDelete("prefix:key", hashFields, CommandFlags.HighPriority)); - } - - [Test] - public void HashExists() - { - wrapper.HashExists("key", "hashField", CommandFlags.HighPriority); - mock.Verify(_ => _.HashExists("prefix:key", "hashField", CommandFlags.HighPriority)); - } - - [Test] - public void HashGet_1() - { - wrapper.HashGet("key", "hashField", CommandFlags.HighPriority); - mock.Verify(_ => _.HashGet("prefix:key", "hashField", CommandFlags.HighPriority)); - } - - [Test] - public void HashGet_2() - { - RedisValue[] hashFields = new RedisValue[0]; - wrapper.HashGet("key", hashFields, CommandFlags.HighPriority); - mock.Verify(_ => _.HashGet("prefix:key", hashFields, CommandFlags.HighPriority)); - } - - [Test] - public void HashGetAll() - { - wrapper.HashGetAll("key", CommandFlags.HighPriority); - mock.Verify(_ => _.HashGetAll("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void HashIncrement_1() - { - wrapper.HashIncrement("key", "hashField", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.HashIncrement("prefix:key", "hashField", 123, CommandFlags.HighPriority)); - } - - [Test] - public void HashIncrement_2() - { - wrapper.HashIncrement("key", "hashField", 1.23, CommandFlags.HighPriority); - mock.Verify(_ => _.HashIncrement("prefix:key", "hashField", 1.23, CommandFlags.HighPriority)); - } - - [Test] - public void HashKeys() - { - wrapper.HashKeys("key", CommandFlags.HighPriority); - mock.Verify(_ => _.HashKeys("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void HashLength() - { - wrapper.HashLength("key", CommandFlags.HighPriority); - mock.Verify(_ => _.HashLength("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void HashScan() - { - wrapper.HashScan("key", "pattern", 123, flags: CommandFlags.HighPriority); - mock.Verify(_ => _.HashScan("prefix:key", "pattern", 123, 0, 0, CommandFlags.HighPriority)); - } - - [Test] - public void HashSet_1() - { - HashEntry[] hashFields = new HashEntry[0]; - wrapper.HashSet("key", hashFields, CommandFlags.HighPriority); - mock.Verify(_ => _.HashSet("prefix:key", hashFields, CommandFlags.HighPriority)); - } - - [Test] - public void HashSet_2() - { - wrapper.HashSet("key", "hashField", "value", When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.HashSet("prefix:key", "hashField", "value", When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void HashValues() - { - wrapper.HashValues("key", CommandFlags.HighPriority); - mock.Verify(_ => _.HashValues("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void HyperLogLogAdd_1() - { - wrapper.HyperLogLogAdd("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.HyperLogLogAdd("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void HyperLogLogAdd_2() - { - RedisValue[] values = new RedisValue[0]; - wrapper.HyperLogLogAdd("key", values, CommandFlags.HighPriority); - mock.Verify(_ => _.HyperLogLogAdd("prefix:key", values, CommandFlags.HighPriority)); - } - - [Test] - public void HyperLogLogLength() - { - wrapper.HyperLogLogLength("key", CommandFlags.HighPriority); - mock.Verify(_ => _.HyperLogLogLength("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void HyperLogLogMerge_1() - { - wrapper.HyperLogLogMerge("destination", "first", "second", CommandFlags.HighPriority); - mock.Verify(_ => _.HyperLogLogMerge("prefix:destination", "prefix:first", "prefix:second", CommandFlags.HighPriority)); - } - - [Test] - public void HyperLogLogMerge_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.HyperLogLogMerge("destination", keys, CommandFlags.HighPriority); - mock.Verify(_ => _.HyperLogLogMerge("prefix:destination", It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void IdentifyEndpoint() - { - wrapper.IdentifyEndpoint("key", CommandFlags.HighPriority); - mock.Verify(_ => _.IdentifyEndpoint("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void KeyDelete_1() - { - wrapper.KeyDelete("key", CommandFlags.HighPriority); - mock.Verify(_ => _.KeyDelete("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void KeyDelete_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.KeyDelete(keys, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyDelete(It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void KeyDump() - { - wrapper.KeyDump("key", CommandFlags.HighPriority); - mock.Verify(_ => _.KeyDump("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void KeyExists() - { - wrapper.KeyExists("key", CommandFlags.HighPriority); - mock.Verify(_ => _.KeyExists("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void KeyExpire_1() - { - TimeSpan expiry = TimeSpan.FromSeconds(123); - wrapper.KeyExpire("key", expiry, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyExpire("prefix:key", expiry, CommandFlags.HighPriority)); - } - - [Test] - public void KeyExpire_2() - { - DateTime expiry = DateTime.Now; - wrapper.KeyExpire("key", expiry, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyExpire("prefix:key", expiry, CommandFlags.HighPriority)); - } - - [Test] - public void KeyMigrate() - { - EndPoint toServer = new IPEndPoint(IPAddress.Loopback, 123); - wrapper.KeyMigrate("key", toServer, 123, 456, MigrateOptions.Copy, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyMigrate("prefix:key", toServer, 123, 456, MigrateOptions.Copy, CommandFlags.HighPriority)); - } - - [Test] - public void KeyMove() - { - wrapper.KeyMove("key", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyMove("prefix:key", 123, CommandFlags.HighPriority)); - } - - [Test] - public void KeyPersist() - { - wrapper.KeyPersist("key", CommandFlags.HighPriority); - mock.Verify(_ => _.KeyPersist("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void KeyRandom() - { - Assert.Throws(() => wrapper.KeyRandom()); - } - - [Test] - public void KeyRename() - { - wrapper.KeyRename("key", "newKey", When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyRename("prefix:key", "prefix:newKey", When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void KeyRestore() - { - Byte[] value = new Byte[0]; - TimeSpan expiry = TimeSpan.FromSeconds(123); - wrapper.KeyRestore("key", value, expiry, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyRestore("prefix:key", value, expiry, CommandFlags.HighPriority)); - } - - [Test] - public void KeyTimeToLive() - { - wrapper.KeyTimeToLive("key", CommandFlags.HighPriority); - mock.Verify(_ => _.KeyTimeToLive("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void KeyType() - { - wrapper.KeyType("key", CommandFlags.HighPriority); - mock.Verify(_ => _.KeyType("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void ListGetByIndex() - { - wrapper.ListGetByIndex("key", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.ListGetByIndex("prefix:key", 123, CommandFlags.HighPriority)); - } - - [Test] - public void ListInsertAfter() - { - wrapper.ListInsertAfter("key", "pivot", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.ListInsertAfter("prefix:key", "pivot", "value", CommandFlags.HighPriority)); - } - - [Test] - public void ListInsertBefore() - { - wrapper.ListInsertBefore("key", "pivot", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.ListInsertBefore("prefix:key", "pivot", "value", CommandFlags.HighPriority)); - } - - [Test] - public void ListLeftPop() - { - wrapper.ListLeftPop("key", CommandFlags.HighPriority); - mock.Verify(_ => _.ListLeftPop("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void ListLeftPush_1() - { - wrapper.ListLeftPush("key", "value", When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.ListLeftPush("prefix:key", "value", When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void ListLeftPush_2() - { - RedisValue[] values = new RedisValue[0]; - wrapper.ListLeftPush("key", values, CommandFlags.HighPriority); - mock.Verify(_ => _.ListLeftPush("prefix:key", values, CommandFlags.HighPriority)); - } - - [Test] - public void ListLength() - { - wrapper.ListLength("key", CommandFlags.HighPriority); - mock.Verify(_ => _.ListLength("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void ListRange() - { - wrapper.ListRange("key", 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.ListRange("prefix:key", 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void ListRemove() - { - wrapper.ListRemove("key", "value", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.ListRemove("prefix:key", "value", 123, CommandFlags.HighPriority)); - } - - [Test] - public void ListRightPop() - { - wrapper.ListRightPop("key", CommandFlags.HighPriority); - mock.Verify(_ => _.ListRightPop("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void ListRightPopLeftPush() - { - wrapper.ListRightPopLeftPush("source", "destination", CommandFlags.HighPriority); - mock.Verify(_ => _.ListRightPopLeftPush("prefix:source", "prefix:destination", CommandFlags.HighPriority)); - } - - [Test] - public void ListRightPush_1() - { - wrapper.ListRightPush("key", "value", When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.ListRightPush("prefix:key", "value", When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void ListRightPush_2() - { - RedisValue[] values = new RedisValue[0]; - wrapper.ListRightPush("key", values, CommandFlags.HighPriority); - mock.Verify(_ => _.ListRightPush("prefix:key", values, CommandFlags.HighPriority)); - } - - [Test] - public void ListSetByIndex() - { - wrapper.ListSetByIndex("key", 123, "value", CommandFlags.HighPriority); - mock.Verify(_ => _.ListSetByIndex("prefix:key", 123, "value", CommandFlags.HighPriority)); - } - - [Test] - public void ListTrim() - { - wrapper.ListTrim("key", 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.ListTrim("prefix:key", 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void LockExtend() - { - TimeSpan expiry = TimeSpan.FromSeconds(123); - wrapper.LockExtend("key", "value", expiry, CommandFlags.HighPriority); - mock.Verify(_ => _.LockExtend("prefix:key", "value", expiry, CommandFlags.HighPriority)); - } - - [Test] - public void LockQuery() - { - wrapper.LockQuery("key", CommandFlags.HighPriority); - mock.Verify(_ => _.LockQuery("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void LockRelease() - { - wrapper.LockRelease("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.LockRelease("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void LockTake() - { - TimeSpan expiry = TimeSpan.FromSeconds(123); - wrapper.LockTake("key", "value", expiry, CommandFlags.HighPriority); - mock.Verify(_ => _.LockTake("prefix:key", "value", expiry, CommandFlags.HighPriority)); - } - - [Test] - public void Publish() - { - wrapper.Publish("channel", "message", CommandFlags.HighPriority); - mock.Verify(_ => _.Publish("prefix:channel", "message", CommandFlags.HighPriority)); - } - - [Test] - public void ScriptEvaluate_1() - { - byte[] hash = new byte[0]; - RedisValue[] values = new RedisValue[0]; - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.ScriptEvaluate(hash, keys, values, CommandFlags.HighPriority); - mock.Verify(_ => _.ScriptEvaluate(hash, It.Is(valid), values, CommandFlags.HighPriority)); - } - - [Test] - public void ScriptEvaluate_2() - { - RedisValue[] values = new RedisValue[0]; - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.ScriptEvaluate("script", keys, values, CommandFlags.HighPriority); - mock.Verify(_ => _.ScriptEvaluate("script", It.Is(valid), values, CommandFlags.HighPriority)); - } - - [Test] - public void SetAdd_1() - { - wrapper.SetAdd("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.SetAdd("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void SetAdd_2() - { - RedisValue[] values = new RedisValue[0]; - wrapper.SetAdd("key", values, CommandFlags.HighPriority); - mock.Verify(_ => _.SetAdd("prefix:key", values, CommandFlags.HighPriority)); - } - - [Test] - public void SetCombine_1() - { - wrapper.SetCombine(SetOperation.Intersect, "first", "second", CommandFlags.HighPriority); - mock.Verify(_ => _.SetCombine(SetOperation.Intersect, "prefix:first", "prefix:second", CommandFlags.HighPriority)); - } - - [Test] - public void SetCombine_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.SetCombine(SetOperation.Intersect, keys, CommandFlags.HighPriority); - mock.Verify(_ => _.SetCombine(SetOperation.Intersect, It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void SetCombineAndStore_1() - { - wrapper.SetCombineAndStore(SetOperation.Intersect, "destination", "first", "second", CommandFlags.HighPriority); - mock.Verify(_ => _.SetCombineAndStore(SetOperation.Intersect, "prefix:destination", "prefix:first", "prefix:second", CommandFlags.HighPriority)); - } - - [Test] - public void SetCombineAndStore_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.SetCombineAndStore(SetOperation.Intersect, "destination", keys, CommandFlags.HighPriority); - mock.Verify(_ => _.SetCombineAndStore(SetOperation.Intersect, "prefix:destination", It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void SetContains() - { - wrapper.SetContains("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.SetContains("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void SetLength() - { - wrapper.SetLength("key", CommandFlags.HighPriority); - mock.Verify(_ => _.SetLength("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void SetMembers() - { - wrapper.SetMembers("key", CommandFlags.HighPriority); - mock.Verify(_ => _.SetMembers("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void SetMove() - { - wrapper.SetMove("source", "destination", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.SetMove("prefix:source", "prefix:destination", "value", CommandFlags.HighPriority)); - } - - [Test] - public void SetPop() - { - wrapper.SetPop("key", CommandFlags.HighPriority); - mock.Verify(_ => _.SetPop("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void SetRandomMember() - { - wrapper.SetRandomMember("key", CommandFlags.HighPriority); - mock.Verify(_ => _.SetRandomMember("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void SetRandomMembers() - { - wrapper.SetRandomMembers("key", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.SetRandomMembers("prefix:key", 123, CommandFlags.HighPriority)); - } - - [Test] - public void SetRemove_1() - { - wrapper.SetRemove("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.SetRemove("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void SetRemove_2() - { - RedisValue[] values = new RedisValue[0]; - wrapper.SetRemove("key", values, CommandFlags.HighPriority); - mock.Verify(_ => _.SetRemove("prefix:key", values, CommandFlags.HighPriority)); - } - - [Test] - public void SetScan() - { - wrapper.SetScan("key", "pattern", 123, flags: CommandFlags.HighPriority); - mock.Verify(_ => _.SetScan("prefix:key", "pattern", 123, 0, 0, CommandFlags.HighPriority)); - } - - [Test] - public void Sort() - { - RedisValue[] get = new RedisValue[] { "a", "#" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "#"; - - wrapper.Sort("key", 123, 456, Order.Descending, SortType.Alphabetic, "nosort", get, CommandFlags.HighPriority); - wrapper.Sort("key", 123, 456, Order.Descending, SortType.Alphabetic, "by", get, CommandFlags.HighPriority); - - mock.Verify(_ => _.Sort("prefix:key", 123, 456, Order.Descending, SortType.Alphabetic, "nosort", It.Is(valid), CommandFlags.HighPriority)); - mock.Verify(_ => _.Sort("prefix:key", 123, 456, Order.Descending, SortType.Alphabetic, "prefix:by", It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void SortAndStore() - { - RedisValue[] get = new RedisValue[] { "a", "#" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "#"; - - wrapper.SortAndStore("destination", "key", 123, 456, Order.Descending, SortType.Alphabetic, "nosort", get, CommandFlags.HighPriority); - wrapper.SortAndStore("destination", "key", 123, 456, Order.Descending, SortType.Alphabetic, "by", get, CommandFlags.HighPriority); - - mock.Verify(_ => _.SortAndStore("prefix:destination", "prefix:key", 123, 456, Order.Descending, SortType.Alphabetic, "nosort", It.Is(valid), CommandFlags.HighPriority)); - mock.Verify(_ => _.SortAndStore("prefix:destination", "prefix:key", 123, 456, Order.Descending, SortType.Alphabetic, "prefix:by", It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetAdd_1() - { - wrapper.SortedSetAdd("key", "member", 1.23, When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetAdd("prefix:key", "member", 1.23, When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetAdd_2() - { - SortedSetEntry[] values = new SortedSetEntry[0]; - wrapper.SortedSetAdd("key", values, When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetAdd("prefix:key", values, When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetCombineAndStore_1() - { - wrapper.SortedSetCombineAndStore(SetOperation.Intersect, "destination", "first", "second", Aggregate.Max, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetCombineAndStore(SetOperation.Intersect, "prefix:destination", "prefix:first", "prefix:second", Aggregate.Max, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetCombineAndStore_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.SetCombineAndStore(SetOperation.Intersect, "destination", keys, CommandFlags.HighPriority); - mock.Verify(_ => _.SetCombineAndStore(SetOperation.Intersect, "prefix:destination", It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetDecrement() - { - wrapper.SortedSetDecrement("key", "member", 1.23, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetDecrement("prefix:key", "member", 1.23, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetIncrement() - { - wrapper.SortedSetIncrement("key", "member", 1.23, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetIncrement("prefix:key", "member", 1.23, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetLength() - { - wrapper.SortedSetLength("key", 1.23, 1.23, Exclude.Start, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetLength("prefix:key", 1.23, 1.23, Exclude.Start, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetLengthByValue() - { - wrapper.SortedSetLengthByValue("key", "min", "max", Exclude.Start, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetLengthByValue("prefix:key", "min", "max", Exclude.Start, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRangeByRank() - { - wrapper.SortedSetRangeByRank("key", 123, 456, Order.Descending, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRangeByRank("prefix:key", 123, 456, Order.Descending, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRangeByRankWithScores() - { - wrapper.SortedSetRangeByRankWithScores("key", 123, 456, Order.Descending, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRangeByRankWithScores("prefix:key", 123, 456, Order.Descending, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRangeByScore() - { - wrapper.SortedSetRangeByScore("key", 1.23, 1.23, Exclude.Start, Order.Descending, 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRangeByScore("prefix:key", 1.23, 1.23, Exclude.Start, Order.Descending, 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRangeByScoreWithScores() - { - wrapper.SortedSetRangeByScoreWithScores("key", 1.23, 1.23, Exclude.Start, Order.Descending, 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRangeByScoreWithScores("prefix:key", 1.23, 1.23, Exclude.Start, Order.Descending, 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRangeByValue() - { - wrapper.SortedSetRangeByValue("key", "min", "max", Exclude.Start, 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRangeByValue("prefix:key", "min", "max", Exclude.Start, 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRank() - { - wrapper.SortedSetRank("key", "member", Order.Descending, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRank("prefix:key", "member", Order.Descending, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRemove_1() - { - wrapper.SortedSetRemove("key", "member", CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRemove("prefix:key", "member", CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRemove_2() - { - RedisValue[] members = new RedisValue[0]; - wrapper.SortedSetRemove("key", members, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRemove("prefix:key", members, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRemoveRangeByRank() - { - wrapper.SortedSetRemoveRangeByRank("key", 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRemoveRangeByRank("prefix:key", 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRemoveRangeByScore() - { - wrapper.SortedSetRemoveRangeByScore("key", 1.23, 1.23, Exclude.Start, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRemoveRangeByScore("prefix:key", 1.23, 1.23, Exclude.Start, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRemoveRangeByValue() - { - wrapper.SortedSetRemoveRangeByValue("key", "min", "max", Exclude.Start, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRemoveRangeByValue("prefix:key", "min", "max", Exclude.Start, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetScan() - { - wrapper.SortedSetScan("key", "pattern", 123, flags: CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetScan("prefix:key", "pattern", 123, 0, 0, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetScore() - { - wrapper.SortedSetScore("key", "member", CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetScore("prefix:key", "member", CommandFlags.HighPriority)); - } - - [Test] - public void StringAppend() - { - wrapper.StringAppend("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.StringAppend("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void StringBitCount() - { - wrapper.StringBitCount("key", 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.StringBitCount("prefix:key", 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void StringBitOperation_1() - { - wrapper.StringBitOperation(Bitwise.Xor, "destination", "first", "second", CommandFlags.HighPriority); - mock.Verify(_ => _.StringBitOperation(Bitwise.Xor, "prefix:destination", "prefix:first", "prefix:second", CommandFlags.HighPriority)); - } - - [Test] - public void StringBitOperation_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.StringBitOperation(Bitwise.Xor, "destination", keys, CommandFlags.HighPriority); - mock.Verify(_ => _.StringBitOperation(Bitwise.Xor, "prefix:destination", It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void StringBitPosition() - { - wrapper.StringBitPosition("key", true, 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.StringBitPosition("prefix:key", true, 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void StringDecrement_1() - { - wrapper.StringDecrement("key", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.StringDecrement("prefix:key", 123, CommandFlags.HighPriority)); - } - - [Test] - public void StringDecrement_2() - { - wrapper.StringDecrement("key", 1.23, CommandFlags.HighPriority); - mock.Verify(_ => _.StringDecrement("prefix:key", 1.23, CommandFlags.HighPriority)); - } - - [Test] - public void StringGet_1() - { - wrapper.StringGet("key", CommandFlags.HighPriority); - mock.Verify(_ => _.StringGet("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void StringGet_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.StringGet(keys, CommandFlags.HighPriority); - mock.Verify(_ => _.StringGet(It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void StringGetBit() - { - wrapper.StringGetBit("key", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.StringGetBit("prefix:key", 123, CommandFlags.HighPriority)); - } - - [Test] - public void StringGetRange() - { - wrapper.StringGetRange("key", 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.StringGetRange("prefix:key", 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void StringGetSet() - { - wrapper.StringGetSet("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.StringGetSet("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void StringGetWithExpiry() - { - wrapper.StringGetWithExpiry("key", CommandFlags.HighPriority); - mock.Verify(_ => _.StringGetWithExpiry("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void StringIncrement_1() - { - wrapper.StringIncrement("key", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.StringIncrement("prefix:key", 123, CommandFlags.HighPriority)); - } - - [Test] - public void StringIncrement_2() - { - wrapper.StringIncrement("key", 1.23, CommandFlags.HighPriority); - mock.Verify(_ => _.StringIncrement("prefix:key", 1.23, CommandFlags.HighPriority)); - } - - [Test] - public void StringLength() - { - wrapper.StringLength("key", CommandFlags.HighPriority); - mock.Verify(_ => _.StringLength("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void StringSet_1() - { - TimeSpan expiry = TimeSpan.FromSeconds(123); - wrapper.StringSet("key", "value", expiry, When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.StringSet("prefix:key", "value", expiry, When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void StringSet_2() - { - KeyValuePair[] values = new KeyValuePair[] { new KeyValuePair("a", "x"), new KeyValuePair("b", "y") }; - Expression[], bool>> valid = _ => _.Length == 2 && _[0].Key == "prefix:a" && _[0].Value == "x" && _[1].Key == "prefix:b" && _[1].Value == "y"; - wrapper.StringSet(values, When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.StringSet(It.Is(valid), When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void StringSetBit() - { - wrapper.StringSetBit("key", 123, true, CommandFlags.HighPriority); - mock.Verify(_ => _.StringSetBit("prefix:key", 123, true, CommandFlags.HighPriority)); - } - - [Test] - public void StringSetRange() - { - wrapper.StringSetRange("key", 123, "value", CommandFlags.HighPriority); - mock.Verify(_ => _.StringSetRange("prefix:key", 123, "value", CommandFlags.HighPriority)); - } - } -} -#endif \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Databases.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Databases.cs deleted file mode 100644 index b444dc8..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Databases.cs +++ /dev/null @@ -1,70 +0,0 @@ -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Databases : TestBase - { - - [Test] - public void CountKeys() - { - using (var muxer = Create(allowAdmin:true)) - { - var server = GetServer(muxer); - server.FlushDatabase(0, CommandFlags.FireAndForget); - server.FlushDatabase(1, CommandFlags.FireAndForget); - } - using (var muxer = Create()) - { - RedisKey key = Me(); - var db0 = muxer.GetDatabase(0); - var db1 = muxer.GetDatabase(1); - db0.StringSet("abc", "def", flags: CommandFlags.FireAndForget); - db0.StringIncrement(key, flags: CommandFlags.FireAndForget); - db1.StringIncrement(key, flags: CommandFlags.FireAndForget); - - var server = GetServer(muxer); - var c0 = server.DatabaseSizeAsync(0); - var c1 = server.DatabaseSizeAsync(1); - - - Assert.AreEqual(2, muxer.Wait(c0)); - Assert.AreEqual(1, muxer.Wait(c1)); - - } - } - [Test] - public void MultiDatabases() - { - using (var muxer = Create()) - { - RedisKey key = Me(); - var db0 = muxer.GetDatabase(0); - var db1 = muxer.GetDatabase(1); - var db2 = muxer.GetDatabase(2); - db0.Ping(); - - db0.KeyDelete(key, CommandFlags.FireAndForget); - db1.KeyDelete(key, CommandFlags.FireAndForget); - db2.KeyDelete(key, CommandFlags.FireAndForget); - - muxer.WaitAll( - db0.StringSetAsync(key, "a"), - db1.StringSetAsync(key, "b"), - db2.StringSetAsync(key, "c") - ); - - var a = db0.StringGetAsync(key); - var b = db1.StringGetAsync(key); - var c = db2.StringGetAsync(key); - muxer.WaitAll(a, b, c); - - Assert.AreEqual("a", (string)muxer.Wait(a), "db:0"); - Assert.AreEqual("b", (string)muxer.Wait(b), "db:1"); - Assert.AreEqual("c", (string)muxer.Wait(c), "db:2"); - - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/DefaultPorts.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/DefaultPorts.cs deleted file mode 100644 index dbfded6..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/DefaultPorts.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.Linq; -using System.Net; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class DefaultPorts - { - [Test] - [TestCase("foo", 6379)] - [TestCase("foo:6379", 6379)] - [TestCase("foo:6380", 6380)] - [TestCase("foo,ssl=false", 6379)] - [TestCase("foo:6379,ssl=false", 6379)] - [TestCase("foo:6380,ssl=false", 6380)] - - [TestCase("foo,ssl=true", 6380)] - [TestCase("foo:6379,ssl=true", 6379)] - [TestCase("foo:6380,ssl=true", 6380)] - [TestCase("foo:6381,ssl=true", 6381)] - public void ConfigStringRoundTripWithDefaultPorts(string config, int expectedPort) - { - var options = ConfigurationOptions.Parse(config); - string backAgain = options.ToString(); - Assert.AreEqual(config, backAgain.Replace("=True","=true").Replace("=False", "=false")); - - options.SetDefaultPorts(); // normally it is the multiplexer that calls this, not us - Assert.AreEqual(expectedPort, ((DnsEndPoint)options.EndPoints.Single()).Port); - } - - [Test] - [TestCase("foo", 0, false, 6379)] - [TestCase("foo", 6379, false, 6379)] - [TestCase("foo", 6380, false, 6380)] - - [TestCase("foo", 0, true, 6380)] - [TestCase("foo", 6379, true, 6379)] - [TestCase("foo", 6380, true, 6380)] - [TestCase("foo", 6381, true, 6381)] - - public void ConfigManualWithDefaultPorts(string host, int port, bool useSsl, int expectedPort) - { - var options = new ConfigurationOptions(); - if(port == 0) - { - options.EndPoints.Add(host); - } else - { - options.EndPoints.Add(host, port); - } - if (useSsl) options.Ssl = true; - - options.SetDefaultPorts(); // normally it is the multiplexer that calls this, not us - Assert.AreEqual(expectedPort, ((DnsEndPoint)options.EndPoints.Single()).Port); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ExceptionFactoryTests.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ExceptionFactoryTests.cs deleted file mode 100644 index 92c5c1e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/ExceptionFactoryTests.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class ExceptionFactoryTests : TestBase - { - [Test] - public void NullLastException() - { - using (var muxer = Create(keepAlive: 1, connectTimeout: 10000, allowAdmin: true)) - { - var conn = muxer.GetDatabase(); - Assert.Null(muxer.GetServerSnapshot()[0].LastException); - var ex = ExceptionFactory.NoConnectionAvailable(true, true, new RedisCommand(), null, null, muxer.GetServerSnapshot()); - Assert.Null(ex.InnerException); - } - - } - - [Test] - public void NullSnapshot() - { - var ex = ExceptionFactory.NoConnectionAvailable(true, true, new RedisCommand(), null, null, null); - Assert.Null(ex.InnerException); - } -#if DEBUG // needs debug connection features - [Test] - public void MultipleEndpointsThrowAggregateException() - { - try - { - using (var muxer = Create(keepAlive: 1, connectTimeout: 10000, allowAdmin: true)) - { - var conn = muxer.GetDatabase(); - muxer.AllowConnect = false; - SocketManager.ConnectCompletionType = CompletionType.Async; - - foreach (var endpoint in muxer.GetEndPoints()) - { - muxer.GetServer(endpoint).SimulateConnectionFailure(); - } - - var ex = ExceptionFactory.NoConnectionAvailable(true, true, new RedisCommand(), null, null, muxer.GetServerSnapshot()); - Assert.IsInstanceOf(ex); - Assert.IsInstanceOf(ex.InnerException); - var aggException = (AggregateException)ex.InnerException; - Assert.That(aggException.InnerExceptions.Count, Is.EqualTo(2)); - for (int i = 0; i < aggException.InnerExceptions.Count; i++) - { - Assert.That(((RedisConnectionException)aggException.InnerExceptions[i]).FailureType, Is.EqualTo(ConnectionFailureType.SocketFailure)); - } - } - } - finally - { - SocketManager.ConnectCompletionType = CompletionType.Any; - ClearAmbientFailures(); - } - } - - [Test] - public void NullInnerExceptionForMultipleEndpointsWithNoLastException() - { - try - { - using (var muxer = Create(keepAlive: 1, connectTimeout: 10000, allowAdmin: true)) - { - var conn = muxer.GetDatabase(); - muxer.AllowConnect = false; - SocketManager.ConnectCompletionType = CompletionType.Async; - var ex = ExceptionFactory.NoConnectionAvailable(true, true, new RedisCommand(), null, null, muxer.GetServerSnapshot()); - Assert.IsInstanceOf(ex); - Assert.Null(ex.InnerException); - } - } - finally - { - SocketManager.ConnectCompletionType = CompletionType.Any; - ClearAmbientFailures(); - } - } - - [Test] - public void ServerTakesPrecendenceOverSnapshot() - { - try - { - using (var muxer = Create(keepAlive: 1, connectTimeout: 10000, allowAdmin: true)) - { - var conn = muxer.GetDatabase(); - muxer.AllowConnect = false; - SocketManager.ConnectCompletionType = CompletionType.Async; - - muxer.GetServer(muxer.GetEndPoints()[0]).SimulateConnectionFailure(); - - var ex = ExceptionFactory.NoConnectionAvailable(true, true, new RedisCommand(), null,muxer.GetServerSnapshot()[0], muxer.GetServerSnapshot()); - Assert.IsInstanceOf(ex); - Assert.IsInstanceOf(ex.InnerException); - Assert.That(muxer.GetServerSnapshot()[0].LastException, Is.EqualTo(ex.InnerException)); - } - } - finally - { - SocketManager.ConnectCompletionType = CompletionType.Any; - ClearAmbientFailures(); - } - - } -#endif - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Expiry.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Expiry.cs deleted file mode 100644 index 7e82f3b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Expiry.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Expiry : TestBase - { - static string[] GetMap(bool disablePTimes) - { - if(disablePTimes) - { - return new[] { "pexpire", "pexpireat", "pttl" }; - } - return null; - } - [Test] - [TestCase(true)] - [TestCase(false)] - public void TestBasicExpiryTimeSpan(bool disablePTimes) - { - using(var muxer = Create(disabledCommands: GetMap(disablePTimes))) - { - RedisKey key = Me(); - var conn = muxer.GetDatabase(); - conn.KeyDelete(key, CommandFlags.FireAndForget); - - conn.StringSet(key, "new value", flags: CommandFlags.FireAndForget); - var a = conn.KeyTimeToLiveAsync(key); - conn.KeyExpire(key, TimeSpan.FromHours(1), CommandFlags.FireAndForget); - var b = conn.KeyTimeToLiveAsync(key); - conn.KeyExpire(key, (TimeSpan?)null, CommandFlags.FireAndForget); - var c = conn.KeyTimeToLiveAsync(key); - conn.KeyExpire(key, TimeSpan.FromHours(1.5), CommandFlags.FireAndForget); - var d = conn.KeyTimeToLiveAsync(key); - conn.KeyExpire(key, TimeSpan.MaxValue, CommandFlags.FireAndForget); - var e = conn.KeyTimeToLiveAsync(key); - - Assert.IsNull(muxer.Wait(a)); - var time = muxer.Wait(b); - Assert.IsNotNull(time); - Assert.IsTrue(time > TimeSpan.FromMinutes(59.9) && time <= TimeSpan.FromMinutes(60)); - Assert.IsNull(muxer.Wait(c)); - time = muxer.Wait(d); - Assert.IsNotNull(time); - Assert.IsTrue(time > TimeSpan.FromMinutes(89.9) && time <= TimeSpan.FromMinutes(90)); - Assert.IsNull(muxer.Wait(e)); - } - } - - [Test] - [TestCase(true, true)] - [TestCase(false, true)] - [TestCase(true, false)] - [TestCase(false, false)] - public void TestBasicExpiryDateTime(bool disablePTimes, bool utc) - { - using (var muxer = Create(disabledCommands: GetMap(disablePTimes))) - { - RedisKey key = Me(); - var conn = muxer.GetDatabase(); - conn.KeyDelete(key, CommandFlags.FireAndForget); - - var now = utc ? DateTime.UtcNow : new DateTime(DateTime.UtcNow.Ticks + TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time").BaseUtcOffset.Ticks, DateTimeKind.Local); - conn.StringSet(key, "new value", flags: CommandFlags.FireAndForget); - var a = conn.KeyTimeToLiveAsync(key); - conn.KeyExpire(key, now.AddHours(1), CommandFlags.FireAndForget); - var b = conn.KeyTimeToLiveAsync(key); - conn.KeyExpire(key, (DateTime?)null, CommandFlags.FireAndForget); - var c = conn.KeyTimeToLiveAsync(key); - conn.KeyExpire(key, now.AddHours(1.5), CommandFlags.FireAndForget); - var d = conn.KeyTimeToLiveAsync(key); - conn.KeyExpire(key, DateTime.MaxValue, CommandFlags.FireAndForget); - var e = conn.KeyTimeToLiveAsync(key); - - Assert.IsNull(muxer.Wait(a)); - var time = muxer.Wait(b); - Assert.IsNotNull(time); - Console.WriteLine(time); - Assert.IsTrue(time > TimeSpan.FromMinutes(59.9) && time <= TimeSpan.FromMinutes(60)); - Assert.IsNull(muxer.Wait(c)); - time = muxer.Wait(d); - Assert.IsNotNull(time); - Assert.IsTrue(time > TimeSpan.FromMinutes(89.9) && time <= TimeSpan.FromMinutes(90)); - Assert.IsNull(muxer.Wait(e)); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/FloatingPoint.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/FloatingPoint.cs deleted file mode 100644 index c4d9bb9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/FloatingPoint.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class FloatingPoint : TestBase - { - static bool Within(double x, double y, double delta) - { - return Math.Abs(x - y) <= delta; - } - [Test] - public void IncrDecrFloatingPoint() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(); - RedisKey key = Me(); - db.KeyDelete(key, CommandFlags.FireAndForget); - double[] incr = - { - 12.134, - -14561.0000002, - 125.3421, - -2.49892498 - }, decr = - { - 99.312, - 12, - -35 - }; - double sum = 0; - foreach (var value in incr) - { - db.StringIncrement(key, value, CommandFlags.FireAndForget); - sum += value; - } - foreach (var value in decr) - { - db.StringDecrement(key, value, CommandFlags.FireAndForget); - sum -= value; - } - var val = (double)db.StringGet(key); - - Assert.IsTrue(Within(sum, val, 0.0001)); - } - } - - [Test] - public async void IncrDecrFloatingPointAsync() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(); - RedisKey key = Me(); - db.KeyDelete(key, CommandFlags.FireAndForget); - double[] incr = - { - 12.134, - -14561.0000002, - 125.3421, - -2.49892498 - }, decr = - { - 99.312, - 12, - -35 - }; - double sum = 0; - foreach (var value in incr) - { - await db.StringIncrementAsync(key, value).ConfigureAwait(false); - sum += value; - } - foreach (var value in decr) - { - await db.StringDecrementAsync(key, value).ConfigureAwait(false); - sum -= value; - } - var val = (double)await db.StringGetAsync(key).ConfigureAwait(false); - - Assert.IsTrue(Within(sum, val, 0.0001)); - } - } - - [Test] - public void HashIncrDecrFloatingPoint() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(); - RedisKey key = Me(); - RedisValue field = "foo"; - db.KeyDelete(key, CommandFlags.FireAndForget); - double[] incr = - { - 12.134, - -14561.0000002, - 125.3421, - -2.49892498 - }, decr = - { - 99.312, - 12, - -35 - }; - double sum = 0; - foreach (var value in incr) - { - db.HashIncrement(key, field, value, CommandFlags.FireAndForget); - sum += value; - } - foreach (var value in decr) - { - db.HashDecrement(key, field, value, CommandFlags.FireAndForget); - sum -= value; - } - var val = (double)db.HashGet(key, field); - - Assert.IsTrue(Within(sum, val, 0.0001)); - } - } - - [Test] - public async void HashIncrDecrFloatingPointAsync() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(); - RedisKey key = Me(); - RedisValue field = "bar"; - db.KeyDelete(key, CommandFlags.FireAndForget); - double[] incr = - { - 12.134, - -14561.0000002, - 125.3421, - -2.49892498 - }, decr = - { - 99.312, - 12, - -35 - }; - double sum = 0; - foreach (var value in incr) - { - await db.HashIncrementAsync(key, field, value).ConfigureAwait(false); - sum += value; - } - foreach (var value in decr) - { - await db.HashDecrementAsync(key, field, value).ConfigureAwait(false); - sum -= value; - } - var val = (double)await db.HashGetAsync(key, field).ConfigureAwait(false); - - Assert.IsTrue(Within(sum, val, 0.0001)); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/GeoTests.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/GeoTests.cs deleted file mode 100644 index 5f64299..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/GeoTests.cs +++ /dev/null @@ -1,187 +0,0 @@ -using NUnit.Framework; -using System; -using System.IO; -using System.Linq; - -namespace StackExchange.Redis.Tests -{ - public class AzureTestAttribute : TestAttribute - { - - } - [TestFixture] - public class GeoTests : TestBase - { - private ConnectionMultiplexer Create() - { - string name, password; - GetAzureCredentials(out name, out password); - var options = new ConfigurationOptions(); - options.EndPoints.Add(name + ".redis.cache.windows.net"); - options.Ssl = true; - options.ConnectTimeout = 5000; - options.Password = password; - options.TieBreaker = ""; - var log = new StringWriter(); - var conn = ConnectionMultiplexer.Connect(options, log); - var s = log.ToString(); - Console.WriteLine(s); - return conn; - } - public const int Db = 0; - - public static GeoEntry - palermo = new GeoEntry(13.361389, 38.115556, "Palermo"), - catania = new GeoEntry(15.087269, 37.502669, "Catania"), - agrigento = new GeoEntry(13.5765, 37.311, "Agrigento"), - cefal = new GeoEntry(14.0188, 38.0084, "Cefal"); - public static GeoEntry[] all = { palermo, catania, agrigento , cefal }; - [AzureTest] - public void GeoAdd() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(Db); - RedisKey key = Me(); - db.KeyDelete(key); - - // add while not there - Assert.IsTrue(db.GeoAdd(key, cefal.Longitude, cefal.Latitude, cefal.Member)); - Assert.AreEqual(2, db.GeoAdd(key, new GeoEntry[] { palermo, catania })); - Assert.IsTrue(db.GeoAdd(key, agrigento)); - - // now add again - Assert.IsFalse(db.GeoAdd(key, cefal.Longitude, cefal.Latitude, cefal.Member)); - Assert.AreEqual(0, db.GeoAdd(key, new GeoEntry[] { palermo, catania })); - Assert.IsFalse(db.GeoAdd(key, agrigento)); - - - } - } - - [AzureTest] - public void GetDistance() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(Db); - RedisKey key = Me(); - db.KeyDelete(key); - db.GeoAdd(key, all); - var val = db.GeoDistance(key, "Palermo", "Catania", GeoUnit.Meters); - Assert.IsTrue(val.HasValue); - var rounded = Math.Round(val.Value, 10); - Assert.AreEqual(166274.1516, val); - - - val = db.GeoDistance(key, "Palermo", "Nowhere", GeoUnit.Meters); - Assert.IsFalse(val.HasValue); - } - } - - [AzureTest] - public void GeoHash() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(Db); - RedisKey key = Me(); - db.KeyDelete(key); - db.GeoAdd(key, all); - - var hashes = db.GeoHash(key, new RedisValue[] { palermo.Member, "Nowhere", agrigento.Member }); - Assert.AreEqual(3, hashes.Length); - Assert.AreEqual("sqc8b49rny0", hashes[0]); - Assert.IsNull(hashes[1]); - Assert.AreEqual("sq9skbq0760", hashes[2]); - - var hash = db.GeoHash(key, "Palermo"); - Assert.AreEqual("sqc8b49rny0", hash); - - hash = db.GeoHash(key, "Nowhere"); - Assert.IsNull(hash); - } - } - - [AzureTest] - public void GeoGetPosition() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(Db); - RedisKey key = Me(); - db.KeyDelete(key); - db.GeoAdd(key, all); - - var pos = db.GeoPosition(key, palermo.Member); - Assert.IsTrue(pos.HasValue); - Assert.AreEqual(Math.Round(palermo.Longitude, 6), Math.Round(pos.Value.Longitude, 6)); - Assert.AreEqual(Math.Round(palermo.Latitude, 6), Math.Round(pos.Value.Latitude, 6)); - - pos = db.GeoPosition(key, "Nowhere"); - Assert.IsFalse(pos.HasValue); - } - } - - [AzureTest] - public void GeoRemove() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(Db); - RedisKey key = Me(); - db.KeyDelete(key); - db.GeoAdd(key, all); - - var pos = db.GeoPosition(key, "Palermo"); - Assert.IsTrue(pos.HasValue); - - Assert.IsFalse(db.GeoRemove(key, "Nowhere")); - Assert.IsTrue(db.GeoRemove(key, "Palermo")); - Assert.IsFalse(db.GeoRemove(key, "Palermo")); - - pos = db.GeoPosition(key, "Palermo"); - Assert.IsFalse(pos.HasValue); - } - } - - [AzureTest] - public void GeoRadius() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(Db); - RedisKey key = Me(); - db.KeyDelete(key); - db.GeoAdd(key, all); - - var results = db.GeoRadius(key, cefal.Member, 60, GeoUnit.Miles, 2, Order.Ascending); - Assert.AreEqual(2, results.Length); - - Assert.AreEqual(results[0].Member, cefal.Member); - Assert.AreEqual(0, results[0].Distance.Value); - Assert.AreEqual(Math.Round(results[0].Position.Value.Longitude, 5), Math.Round(cefal.Position.Longitude, 5)); - Assert.AreEqual(Math.Round(results[0].Position.Value.Latitude, 5), Math.Round(cefal.Position.Latitude, 5)); - Assert.IsFalse(results[0].Hash.HasValue); - - Assert.AreEqual(results[1].Member, palermo.Member); - Assert.AreEqual(Math.Round(36.5319, 6), Math.Round(results[1].Distance.Value, 6)); - Assert.AreEqual(Math.Round(results[1].Position.Value.Longitude, 5), Math.Round(palermo.Position.Longitude, 5)); - Assert.AreEqual(Math.Round(results[1].Position.Value.Latitude, 5), Math.Round(palermo.Position.Latitude, 5)); - Assert.IsFalse(results[1].Hash.HasValue); - - results = db.GeoRadius(key, cefal.Member, 60, GeoUnit.Miles, 2, Order.Ascending, GeoRadiusOptions.None); - Assert.AreEqual(2, results.Length); - Assert.AreEqual(results[0].Member, cefal.Member); - Assert.IsFalse(results[0].Position.HasValue); - Assert.IsFalse(results[0].Distance.HasValue); - Assert.IsFalse(results[0].Hash.HasValue); - - Assert.AreEqual(results[1].Member, palermo.Member); - Assert.IsFalse(results[1].Position.HasValue); - Assert.IsFalse(results[1].Distance.HasValue); - Assert.IsFalse(results[1].Hash.HasValue); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/HyperLogLog.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/HyperLogLog.cs deleted file mode 100644 index 32a50e9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/HyperLogLog.cs +++ /dev/null @@ -1,41 +0,0 @@ -using NUnit.Framework; -using System.IO; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class HyperLogLog : TestBase - { - [Test] - public void SingleKeyLength() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(); - RedisKey key = "hll1"; - - db.HyperLogLogAdd(key, "a"); - db.HyperLogLogAdd(key, "b"); - db.HyperLogLogAdd(key, "c"); - - Assert.IsTrue(db.HyperLogLogLength(key) > 0); - } - } - - [Test] - public void MultiKeyLength() - { - using (var conn = Create(useSharedSocketManager: true)) - { - var db = conn.GetDatabase(); - RedisKey[] keys = { "hll1", "hll2", "hll3" }; - - db.HyperLogLogAdd(keys[0], "a"); - db.HyperLogLogAdd(keys[1], "b"); - db.HyperLogLogAdd(keys[2], "c"); - - Assert.IsTrue(db.HyperLogLogLength(keys) > 0); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/BgSaveResponse.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/BgSaveResponse.cs deleted file mode 100644 index 661ca55..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/BgSaveResponse.cs +++ /dev/null @@ -1,23 +0,0 @@ -using NUnit.Framework; - -namespace StackExchange.Redis.Tests.Issues -{ - [TestFixture] - public class BgSaveResponse : TestBase - { - [Test] -#pragma warning disable 0618 - [TestCase(SaveType.ForegroundSave)] -#pragma warning restore 0618 - [TestCase(SaveType.BackgroundSave)] - [TestCase(SaveType.BackgroundRewriteAppendOnlyFile)] - public void ShouldntThrowException(SaveType saveType) - { - using (var conn = Create(null, null, true)) - { - var Server = GetServer(conn); - Server.Save(saveType); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/DefaultDatabase.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/DefaultDatabase.cs deleted file mode 100644 index 34ea7b0..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/DefaultDatabase.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.IO; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests.Issues -{ - [TestFixture] - public class DefaultDatabase : TestBase - { - [Test] - public void UnspecifiedDbId_ReturnsNull() - { - var config = ConfigurationOptions.Parse("localhost"); - Assert.IsNull(config.DefaultDatabase); - } - - [Test] - public void SpecifiedDbId_ReturnsExpected() - { - var config = ConfigurationOptions.Parse("localhost,defaultDatabase=3"); - Assert.AreEqual(3, config.DefaultDatabase); - } - - [Test] - public void ConfigurationOptions_UnspecifiedDefaultDb() - { - var log = new StringWriter(); - try - { - using (var conn = ConnectionMultiplexer.Connect($"{PrimaryServer}:{PrimaryPort}", log)) { - var db = conn.GetDatabase(); - Assert.AreEqual(0, db.Database); - } - } - finally - { - Console.WriteLine(log); - } - } - - [Test] - public void ConfigurationOptions_SpecifiedDefaultDb() - { - var log = new StringWriter(); - try - { - using (var conn = ConnectionMultiplexer.Connect($"{PrimaryServer}:{PrimaryPort},defaultDatabase=3", log)) { - var db = conn.GetDatabase(); - Assert.AreEqual(3, db.Database); - } - } - finally - { - Console.WriteLine(log); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue118.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue118.cs deleted file mode 100644 index 6200b9a..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue118.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace StackExchange.Redis.Tests.Issues -{ - class Issue118 - { - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue182.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue182.cs deleted file mode 100644 index 2a920fe..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue182.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Linq; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests.Issues -{ - [TestFixture] - public class Issue182 : TestBase - { - protected override string GetConfiguration() - { - return "127.0.0.1:6379,responseTimeout=10000"; - } - [Test] - public void SetMembers() - { - using (var conn = Create()) - { - conn.ConnectionFailed += (s, a) => - { - Console.WriteLine(a.FailureType); - Console.WriteLine(a.Exception.Message); - Console.WriteLine(a.Exception.StackTrace); - }; - var db = conn.GetDatabase(); - - var key = Me(); - const int count = (int)5e6; - - db.KeyDeleteAsync(key).Wait(); - foreach (var _ in Enumerable.Range(0, count)) - db.SetAdd(key, Guid.NewGuid().ToByteArray(), CommandFlags.FireAndForget); - - Assert.AreEqual(count, db.SetLengthAsync(key).Result, "SCARD for set"); - - var task = db.SetMembersAsync(key); - task.Wait(); - Assert.AreEqual(count, task.Result.Length, "SMEMBERS result length"); - } - } - - [Test] - public void SetUnion() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(); - - var key1 = Me() + ":1"; - var key2 = Me() + ":2"; - var dstkey = Me() + ":dst"; - - db.KeyDeleteAsync(key1).Wait(); - db.KeyDeleteAsync(key2).Wait(); - db.KeyDeleteAsync(dstkey).Wait(); - - const int count = (int)5e6; - foreach (var _ in Enumerable.Range(0, count)) - { - db.SetAdd(key1, Guid.NewGuid().ToByteArray(), CommandFlags.FireAndForget); - db.SetAdd(key2, Guid.NewGuid().ToByteArray(), CommandFlags.FireAndForget); - } - Assert.AreEqual(count, db.SetLengthAsync(key1).Result, "SCARD for set 1"); - Assert.AreEqual(count, db.SetLengthAsync(key2).Result, "SCARD for set 2"); - - db.SetCombineAndStoreAsync(SetOperation.Union, dstkey, key1, key2).Wait(); - var dstLen = db.SetLength(dstkey); - Assert.AreEqual(count * 2, dstLen, "SCARD for destination set"); - } - } - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue25.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue25.cs deleted file mode 100644 index 113a538..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue25.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests.Issues -{ - [TestFixture] - public class Issue25 : TestBase - { - [Test] - public void CaseInsensitive() - { - var options = ConfigurationOptions.Parse("ssl=true"); - Assert.IsTrue(options.Ssl); - Assert.AreEqual("ssl=True", options.ToString()); - - options = ConfigurationOptions.Parse("SSL=TRUE"); - Assert.IsTrue(options.Ssl); - Assert.AreEqual("ssl=True", options.ToString()); - } - - [Test] - public void UnkonwnKeywordHandling_Ignore() - { - var options = ConfigurationOptions.Parse("ssl2=true", true); - } - [Test] - public void UnkonwnKeywordHandling_ExplicitFail() - { - Assert.Throws(() => { - var options = ConfigurationOptions.Parse("ssl2=true", false); - }, - "Keyword 'ssl2' is not supported"); - } - [Test] - public void UnkonwnKeywordHandling_ImplicitFail() - { - Assert.Throws(() => { - var options = ConfigurationOptions.Parse("ssl2=true"); - }, - "Keyword 'ssl2' is not supported"); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue6.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue6.cs deleted file mode 100644 index f4a23d0..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/Issue6.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests.Issues -{ - [TestFixture] - public class Issue6 : TestBase - { - [Test] - public void ShouldWorkWithoutEchoOrPing() - { - using(var conn = Create(proxy: Proxy.Twemproxy)) - { - Console.WriteLine("config: " + conn.Configuration); - var db = conn.GetDatabase(); - var time = db.Ping(); - Console.WriteLine("ping time: " + time); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO22786599.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO22786599.cs deleted file mode 100644 index 4829e47..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO22786599.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Diagnostics; -using System.Linq; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests.Issues -{ - [TestFixture] - public class SO22786599 : TestBase - { - [Test] - public void Execute() - { - string CurrentIdsSetDbKey = Me() + ".x"; - string CurrentDetailsSetDbKey = Me() + ".y"; - - RedisValue[] stringIds = Enumerable.Range(1, 750).Select(i => (RedisValue)(i + " id")).ToArray(); - RedisValue[] stringDetails = Enumerable.Range(1, 750).Select(i => (RedisValue)(i + " detail")).ToArray(); - - using (var conn = Create()) - { - var db = conn.GetDatabase(); - var tran = db.CreateTransaction(); - - tran.SetAddAsync(CurrentIdsSetDbKey, stringIds); - tran.SetAddAsync(CurrentDetailsSetDbKey, stringDetails); - - var watch = Stopwatch.StartNew(); - var isOperationSuccessful = tran.Execute(); - watch.Stop(); - System.Console.WriteLine("{0}ms", watch.ElapsedMilliseconds); - Assert.IsTrue(isOperationSuccessful); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO23949477.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO23949477.cs deleted file mode 100644 index 7f9a8ac..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO23949477.cs +++ /dev/null @@ -1,38 +0,0 @@ -using NUnit.Framework; - -namespace StackExchange.Redis.Tests.Issues -{ - [TestFixture] - public class SO23949477 : TestBase - { - [Test] - public void Execute() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(0); - RedisKey key = Me(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.SortedSetAdd(key, "c", 3, When.Always, CommandFlags.FireAndForget); - db.SortedSetAdd(key, - new[] { - new SortedSetEntry("a", 1), - new SortedSetEntry("b", 2), - new SortedSetEntry("d", 4), - new SortedSetEntry("e", 5) - }, - When.Always, - CommandFlags.FireAndForget); - var pairs = db.SortedSetRangeByScoreWithScores( - key, order: Order.Descending, take: 3); - Assert.AreEqual(3, pairs.Length); - Assert.AreEqual(5, pairs[0].Score); - Assert.AreEqual("e", (string)pairs[0].Element); - Assert.AreEqual(4, pairs[1].Score); - Assert.AreEqual("d", (string)pairs[1].Element); - Assert.AreEqual(3, pairs[2].Score); - Assert.AreEqual("c", (string)pairs[2].Element); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO24807536.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO24807536.cs deleted file mode 100644 index cd46462..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO24807536.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Threading; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests.Issues -{ - [TestFixture] - public class SO24807536 : TestBase - { - public void Exec() - { - var key = Me(); - using(var conn = Create()) - { - var cache = conn.GetDatabase(); - - // setup some data - cache.KeyDelete(key); - cache.HashSet(key, "full", "some value"); - cache.KeyExpire(key, TimeSpan.FromSeconds(3)); - - // test while exists - var exists = cache.KeyExists(key); - var ttl = cache.KeyTimeToLive(key); - var fullWait = cache.HashGetAsync(key, "full", flags: CommandFlags.None); - Assert.IsTrue(exists, "key exists"); - Assert.IsNotNull(ttl, "ttl"); - Assert.AreEqual("some value", (string)fullWait.Result); - - // wait for expiry - Thread.Sleep(TimeSpan.FromSeconds(4)); - - // test once expired - exists = cache.KeyExists(key); - ttl = cache.KeyTimeToLive(key); - fullWait = cache.HashGetAsync(key, "full", flags: CommandFlags.None); - Assert.IsFalse(exists, "key exists"); - Assert.IsNull(ttl, "ttl"); - Assert.IsNull((string)fullWait.Result); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO25113323.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO25113323.cs deleted file mode 100644 index e569bef..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO25113323.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Threading; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests.Issues -{ - [TestFixture] - public class SO25113323 : TestBase - { - [Test] - public void SetExpirationToPassed() - { - var key = Me(); - using (var conn = Create()) - { - // Given - var cache = conn.GetDatabase(); - cache.KeyDelete(key); - cache.HashSet(key, "full", "test", When.NotExists, CommandFlags.PreferMaster); - - Thread.Sleep(10 * 1000); - - // When - var expiresOn = DateTime.UtcNow.AddSeconds(-10); - - var firstResult = cache.KeyExpire(key, expiresOn, CommandFlags.PreferMaster); - var secondResult = cache.KeyExpire(key, expiresOn, CommandFlags.PreferMaster); - var exists = cache.KeyExists(key); - var ttl = cache.KeyTimeToLive(key); - - // Then - Assert.IsTrue(firstResult, "first"); // could set the first time, but this nukes the key - Assert.IsFalse(secondResult, "second"); // can't set, since nuked - Assert.IsFalse(exists, "exists"); // does not exist since nuked - Assert.IsNull(ttl, "ttl"); // no expiry since nuked - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO25567566.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO25567566.cs deleted file mode 100644 index e9724c9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Issues/SO25567566.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Threading.Tasks; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests.Issues -{ - [TestFixture] - public class SO25567566 : TestBase - { - protected override string GetConfiguration() - { - return "127.0.0.1:6379"; - } - [Test] - public async void Execute() - { - using(var conn = ConnectionMultiplexer.Connect(GetConfiguration())) // Create()) - { - for(int i = 0; i < 100; i++) - { - Assert.AreEqual("ok", await DoStuff(conn).ConfigureAwait(false)); - - } - } - } - private async Task DoStuff(ConnectionMultiplexer conn) - { - var db = conn.GetDatabase(); - - var timeout = Task.Delay(5000); - var len = db.ListLengthAsync("list"); - - if (await Task.WhenAny(timeout, len).ConfigureAwait(false) != len) - { - return "Timeout getting length"; - } - - - if ((await len.ConfigureAwait(false)) == 0) - { - db.ListRightPush("list", "foo", flags: CommandFlags.FireAndForget); - } - var tran = db.CreateTransaction(); - var x = tran.ListRightPopLeftPushAsync("list", "list2"); - var y = tran.SetAddAsync("set", "bar"); - var z = tran.KeyExpireAsync("list2", TimeSpan.FromSeconds(60)); - timeout = Task.Delay(5000); - - var exec = tran.ExecuteAsync(); - // SWAP THESE TWO - bool ok = await Task.WhenAny(exec, timeout).ConfigureAwait(false) == exec; - //bool ok = true; - - if (ok) - { - if (await exec.ConfigureAwait(false)) - { - await Task.WhenAll(x, y, z).ConfigureAwait(false); - - var db2 = conn.GetDatabase(); - db2.HashGet("hash", "whatever"); - return "ok"; - } - else - { - return "Transaction aborted"; - } - } - else - { - return "Timeout during exec"; - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Keys.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Keys.cs deleted file mode 100644 index 688bd03..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Keys.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System.Linq; -using System.Text; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Keys : TestBase - { - [Test] - public void TestScan() - { - using(var muxer = Create(allowAdmin: true)) - { - const int Database = 4; - var db = muxer.GetDatabase(Database); - GetServer(muxer).FlushDatabase(flags: CommandFlags.FireAndForget); - - const int Count = 1000; - for (int i = 0; i < Count; i++) - db.StringSet("x" + i, "y" + i, flags: CommandFlags.FireAndForget); - - var count = GetServer(muxer).Keys(Database).Count(); - Assert.AreEqual(Count, count); - } - } - - [Test] - public void RandomKey() - { - using(var conn = Create(allowAdmin: true)) - { - var db = conn.GetDatabase(); - conn.GetServer(PrimaryServer, PrimaryPort).FlushDatabase(); - string anyKey = db.KeyRandom(); - - Assert.IsNull(anyKey); - db.StringSet("abc", "def"); - byte[] keyBytes = db.KeyRandom(); - - Assert.AreEqual("abc", Encoding.UTF8.GetString(keyBytes)); - } - } - - [Test] - public void Zeros() - { - using(var conn = Create()) - { - var db = conn.GetDatabase(); - db.KeyDelete("abc"); - db.StringSet("abc", 123); - int k = (int)db.StringGet("abc"); - Assert.AreEqual(123, k); - - db.KeyDelete("abc"); - int i = (int)db.StringGet("abc"); - Assert.AreEqual(0, i); - - Assert.IsTrue(db.StringGet("abc").IsNull); - int? value = (int?)db.StringGet("abc"); - Assert.IsFalse(value.HasValue); - - } - } - - [Test] - public void PrependAppend() - { - { - // simple - RedisKey key = "world"; - var ret = key.Prepend("hello"); - Assert.AreEqual("helloworld", (string)ret); - } - - { - RedisKey key1 = "world"; - RedisKey key2 = Encoding.UTF8.GetBytes("hello"); - var key3 = key1.Prepend(key2); - Assert.IsTrue(object.ReferenceEquals(key1.KeyValue, key3.KeyValue)); - Assert.IsTrue(object.ReferenceEquals(key2.KeyValue, key3.KeyPrefix)); - Assert.AreEqual("helloworld", (string)key3); - } - - { - RedisKey key = "hello"; - var ret = key.Append("world"); - Assert.AreEqual("helloworld", (string)ret); - } - - { - RedisKey key1 = Encoding.UTF8.GetBytes("hello"); - RedisKey key2 = "world"; - var key3 = key1.Append(key2); - Assert.IsTrue(object.ReferenceEquals(key2.KeyValue, key3.KeyValue)); - Assert.IsTrue(object.ReferenceEquals(key1.KeyValue, key3.KeyPrefix)); - Assert.AreEqual("helloworld", (string)key3); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/KeysAndValues.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/KeysAndValues.cs deleted file mode 100644 index 9f2859d..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/KeysAndValues.cs +++ /dev/null @@ -1,208 +0,0 @@ -using System; -using System.Globalization; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class KeysAndValues - { - [Test] - public void TestValues() - { - RedisValue @default = default(RedisValue); - CheckNull(@default); - - RedisValue nullString = (string)null; - CheckNull(nullString); - - RedisValue nullBlob = (byte[])null; - CheckNull(nullBlob); - - RedisValue emptyString = ""; - CheckNotNull(emptyString); - - RedisValue emptyBlob = new byte[0]; - CheckNotNull(emptyBlob); - - RedisValue a0 = new string('a', 1); - CheckNotNull(a0); - RedisValue a1 = new string('a', 1); - CheckNotNull(a1); - RedisValue b0 = new [] { (byte)'b' }; - CheckNotNull(b0); - RedisValue b1 = new [] { (byte)'b' }; - CheckNotNull(b1); - - RedisValue i4 = 1; - CheckNotNull(i4); - RedisValue i8 = 1L; - CheckNotNull(i8); - - RedisValue bool1 = true; - CheckNotNull(bool1); - RedisValue bool2 = false; - CheckNotNull(bool2); - RedisValue bool3 = true; - CheckNotNull(bool3); - - CheckSame(a0, a0); - CheckSame(a1, a1); - CheckSame(a0, a1); - - CheckSame(b0, b0); - CheckSame(b1, b1); - CheckSame(b0, b1); - - CheckSame(i4, i4); - CheckSame(i8, i8); - CheckSame(i4, i8); - - CheckSame(bool1, bool3); - CheckNotSame(bool1, bool2); - } - - private void CheckSame(RedisValue x, RedisValue y) - { - Assert.IsTrue(Equals(x, y)); - Assert.IsTrue(x.Equals(y)); - Assert.IsTrue(y.Equals(x)); - Assert.IsTrue(x.GetHashCode() == y.GetHashCode()); - } - private void CheckNotSame(RedisValue x, RedisValue y) - { - Assert.IsFalse(Equals(x, y)); - Assert.IsFalse(x.Equals(y)); - Assert.IsFalse(y.Equals(x)); - Assert.IsFalse(x.GetHashCode() == y.GetHashCode()); // well, very unlikely - } - - private void CheckNotNull(RedisValue value) - { - Assert.IsFalse(value.IsNull); - Assert.IsNotNull((byte[])value); - Assert.IsNotNull((string)value); - Assert.AreNotEqual(-1, value.GetHashCode()); - - Assert.IsNotNull((string)value); - Assert.IsNotNull((byte[])value); - - CheckSame(value, value); - CheckNotSame(value, default(RedisValue)); - CheckNotSame(value, (string)null); - CheckNotSame(value, (byte[])null); - } - private void CheckNull(RedisValue value) - { - Assert.IsTrue(value.IsNull); - Assert.IsTrue(value.IsNullOrEmpty); - Assert.IsFalse(value.IsInteger); - Assert.AreEqual(-1, value.GetHashCode()); - - Assert.IsNull((string)value); - Assert.IsNull((byte[])value); - - Assert.AreEqual(0, (int)value); - Assert.AreEqual(0L, (long)value); - - CheckSame(value, value); - CheckSame(value, default(RedisValue)); - CheckSame(value, (string)null); - CheckSame(value, (byte[])null); - } - - - [Test] - public void ValuesAreConvertible() - { - RedisValue val = 123; - object o = val; - byte[] blob = (byte[])Convert.ChangeType(o, typeof(byte[])); - - Assert.AreEqual(3, blob.Length); - Assert.AreEqual((byte)'1', blob[0]); - Assert.AreEqual((byte)'2', blob[1]); - Assert.AreEqual((byte)'3', blob[2]); - - Assert.AreEqual((double)123, Convert.ToDouble(o)); - - IConvertible c = (IConvertible)o; - Assert.AreEqual((short)123, c.ToInt16(CultureInfo.InvariantCulture)); - Assert.AreEqual((int)123, c.ToInt32(CultureInfo.InvariantCulture)); - Assert.AreEqual((long)123, c.ToInt64(CultureInfo.InvariantCulture)); - Assert.AreEqual((float)123, c.ToSingle(CultureInfo.InvariantCulture)); - Assert.AreEqual("123", c.ToString(CultureInfo.InvariantCulture)); - Assert.AreEqual((double)123, c.ToDouble(CultureInfo.InvariantCulture)); - Assert.AreEqual((decimal)123, c.ToDecimal(CultureInfo.InvariantCulture)); - Assert.AreEqual((ushort)123, c.ToUInt16(CultureInfo.InvariantCulture)); - Assert.AreEqual((uint)123, c.ToUInt32(CultureInfo.InvariantCulture)); - Assert.AreEqual((ulong)123, c.ToUInt64(CultureInfo.InvariantCulture)); - - blob = (byte[])c.ToType(typeof(byte[]), CultureInfo.InvariantCulture); - Assert.AreEqual(3, blob.Length); - Assert.AreEqual((byte)'1', blob[0]); - Assert.AreEqual((byte)'2', blob[1]); - Assert.AreEqual((byte)'3', blob[2]); - } - - [Test] - public void CanBeDynamic() - { - RedisValue val = "abc"; - object o = val; - dynamic d = o; - byte[] blob = (byte[])d; // could be in a try/catch - Assert.AreEqual(3, blob.Length); - Assert.AreEqual((byte)'a', blob[0]); - Assert.AreEqual((byte)'b', blob[1]); - Assert.AreEqual((byte)'c', blob[2]); - } - - [Test] - public void TryParse() - { - { - RedisValue val = "1"; - int i; - Assert.IsTrue(val.TryParse(out i)); - Assert.AreEqual(1, i); - long l; - Assert.IsTrue(val.TryParse(out l)); - Assert.AreEqual(1L, l); - double d; - Assert.IsTrue(val.TryParse(out d)); - Assert.AreEqual(1.0, l); - } - - { - RedisValue val = "8675309"; - int i; - Assert.IsTrue(val.TryParse(out i)); - Assert.AreEqual(8675309, i); - long l; - Assert.IsTrue(val.TryParse(out l)); - Assert.AreEqual(8675309L, l); - double d; - Assert.IsTrue(val.TryParse(out d)); - Assert.AreEqual(8675309.0, l); - } - - { - RedisValue val = "3.14159"; - double d; - Assert.IsTrue(val.TryParse(out d)); - Assert.AreEqual(3.14159, d); - } - - { - RedisValue val = "not a real number"; - int i; - Assert.IsFalse(val.TryParse(out i)); - long l; - Assert.IsFalse(val.TryParse(out l)); - double d; - Assert.IsFalse(val.TryParse(out d)); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Lex.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Lex.cs deleted file mode 100644 index dd4271b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Lex.cs +++ /dev/null @@ -1,98 +0,0 @@ -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Lex : TestBase - { - - [Test] - public void QueryRangeAndLengthByLex() - { - using(var conn = Create()) - { - var db = conn.GetDatabase(); - RedisKey key = Me(); - db.KeyDelete(key); - - db.SortedSetAdd(key, - new SortedSetEntry[] - { - new SortedSetEntry("a", 0), - new SortedSetEntry("b", 0), - new SortedSetEntry("c", 0), - new SortedSetEntry("d", 0), - new SortedSetEntry("e", 0), - new SortedSetEntry("f", 0), - new SortedSetEntry("g", 0), - }); - - var set = db.SortedSetRangeByValue(key, default(RedisValue), "c"); - var count = db.SortedSetLengthByValue(key, default(RedisValue), "c"); - Equate(set, count, "a", "b", "c"); - - set = db.SortedSetRangeByValue(key, default(RedisValue), "c", Exclude.Stop); - count = db.SortedSetLengthByValue(key, default(RedisValue), "c", Exclude.Stop); - Equate(set, count, "a", "b"); - - set = db.SortedSetRangeByValue(key, "aaa", "g", Exclude.Stop); - count = db.SortedSetLengthByValue(key, "aaa", "g", Exclude.Stop); - Equate(set, count, "b", "c", "d", "e", "f"); - - set = db.SortedSetRangeByValue(key, "aaa", "g", Exclude.Stop, 1, 3); - Equate(set, set.Length, "c", "d", "e"); - } - } - - [Test] - public void RemoveRangeByLex() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(); - RedisKey key = Me(); - db.KeyDelete(key); - - db.SortedSetAdd(key, - new SortedSetEntry[] - { - new SortedSetEntry("aaaa", 0), - new SortedSetEntry("b", 0), - new SortedSetEntry("c", 0), - new SortedSetEntry("d", 0), - new SortedSetEntry("e", 0), - }); - db.SortedSetAdd(key, - new SortedSetEntry[] - { - new SortedSetEntry("foo", 0), - new SortedSetEntry("zap", 0), - new SortedSetEntry("zip", 0), - new SortedSetEntry("ALPHA", 0), - new SortedSetEntry("alpha", 0), - }); - - var set = db.SortedSetRangeByRank(key); - Equate(set, set.Length, "ALPHA", "aaaa", "alpha", "b", "c", "d", "e", "foo", "zap", "zip"); - - long removed = db.SortedSetRemoveRangeByValue(key, "alpha", "omega"); - Assert.AreEqual(6, removed); - - set = db.SortedSetRangeByRank(key); - Equate(set, set.Length, "ALPHA", "aaaa", "zap", "zip"); - } - } - - - - private void Equate(RedisValue[] actual, long count, params string[] expected) - { - Assert.AreEqual(count, expected.Length); - Assert.AreEqual(expected.Length, actual.Length); - for(int i = 0; i < actual.Length; i++) - { - Assert.AreEqual(expected[i], (string)actual[i]); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Lists.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Lists.cs deleted file mode 100644 index 1b585eb..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Lists.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Linq; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Lists : TestBase - { - [Test] - public void Ranges() - { - using(var conn = Create()) - { - var db = conn.GetDatabase(); - RedisKey key = Me(); - - db.KeyDelete(key, CommandFlags.FireAndForget); - db.ListRightPush(key, "abcdefghijklmnopqrstuvwxyz".Select(x => (RedisValue)x.ToString()).ToArray()); - - Assert.AreEqual(26, db.ListLength(key)); - Assert.AreEqual("abcdefghijklmnopqrstuvwxyz", string.Concat(db.ListRange(key))); - - var last10 = db.ListRange(key, -10, -1); - Assert.AreEqual("qrstuvwxyz", string.Concat(last10)); - db.ListTrim(key, 0, -11); - - Assert.AreEqual(16, db.ListLength(key)); - Assert.AreEqual("abcdefghijklmnop", string.Concat(db.ListRange(key))); - - - - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Locking.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Locking.cs deleted file mode 100644 index 8b51ff5..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Locking.cs +++ /dev/null @@ -1,271 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Locking : TestBase - { - [Test] - [TestCaseSource(nameof(TestModes))] - public void AggressiveParallel(TestMode testMode) - { - int count = 2; - int errorCount = 0; - ManualResetEvent evt = new ManualResetEvent(false); - using (var c1 = Create(testMode)) - using (var c2 = Create(testMode)) - { - WaitCallback cb = obj => - { - var conn = (IDatabase)obj; - conn.Multiplexer.ErrorMessage += delegate { Interlocked.Increment(ref errorCount); }; - - for (int i = 0; i < 1000; i++) - { - conn.LockTakeAsync("abc", "def", TimeSpan.FromSeconds(5)); - } - conn.Ping(); - if (Interlocked.Decrement(ref count) == 0) evt.Set(); - }; - int db = testMode == TestMode.Twemproxy ? 0 : 2; - ThreadPool.QueueUserWorkItem(cb, c1.GetDatabase(db)); - ThreadPool.QueueUserWorkItem(cb, c2.GetDatabase(db)); - evt.WaitOne(8000); - } - Assert.AreEqual(0, Interlocked.CompareExchange(ref errorCount, 0, 0)); - } - - protected override string GetConfiguration() - { - return PrimaryServer + ":" + PrimaryPortString; - } - [Test] - public void TestOpCountByVersionLocal_UpLevel() - { - using (var conn = Create()) - { - TestLockOpCountByVersion(conn, 1, false); - TestLockOpCountByVersion(conn, 1, true); - - //TestManualLockOpCountByVersion(conn, 5, false); - //TestManualLockOpCountByVersion(conn, 3, true); - } - } - //[Test] - //public void TestOpCountByVersionLocal_DownLevel() - //{ - // using (var conn = Config.GetUnsecuredConnection(open: false)) - // { - // conn.SetServerVersion(new Version(2, 6, 0), ServerType.Master); - // TestLockOpCountByVersion(conn, 5, false); - // TestLockOpCountByVersion(conn, 3, true); - // //TestManualLockOpCountByVersion(conn, 5, false); - // //TestManualLockOpCountByVersion(conn, 3, true); - // } - //} - - //[Test] - //public void TestOpCountByVersionRemote() - //{ - // using (var conn = Config.GetRemoteConnection(open: false)) - // { - // TestLockOpCountByVersion(conn, 1, false); - // TestLockOpCountByVersion(conn, 1, true); - // //TestManualLockOpCountByVersion(conn, 1, false); - // //TestManualLockOpCountByVersion(conn, 1, true); - // } - //} - public void TestLockOpCountByVersion(ConnectionMultiplexer conn, int expected, bool existFirst) - { - const int DB = 0, LockDuration = 30; - RedisKey Key = Me(); - - var db = conn.GetDatabase(DB); - db.KeyDelete(Key); - RedisValue newVal = "us:" + Guid.NewGuid().ToString(); - RedisValue expectedVal = newVal; - if (existFirst) - { - expectedVal = "other:" + Guid.NewGuid().ToString(); - db.StringSet(Key, expectedVal, TimeSpan.FromSeconds(LockDuration)); - } - long countBefore = GetServer(conn).GetCounters().Interactive.OperationCount; - - var taken = db.LockTake(Key, newVal, TimeSpan.FromSeconds(LockDuration)); - - long countAfter = GetServer(conn).GetCounters().Interactive.OperationCount; - var valAfter = db.StringGet(Key); - - Assert.AreEqual(!existFirst, taken, "lock taken"); - Assert.AreEqual(expectedVal, valAfter, "taker"); - Assert.AreEqual(expected, countAfter - countBefore, "expected ops"); - // note we get a ping from GetCounters - } - - private ConnectionMultiplexer Create(TestMode mode) - { - switch(mode) - { - case TestMode.MultiExec: - return Create(); - case TestMode.NoMultiExec: - return Create(disabledCommands: new[] { "multi", "exec" }); - case TestMode.Twemproxy: - return Create(proxy: Proxy.Twemproxy); - default: - throw new NotSupportedException(mode.ToString()); - } - } - - public enum TestMode - { - MultiExec, - NoMultiExec, - Twemproxy - } - public static IEnumerable TestModes() - { - return (TestMode[])Enum.GetValues(typeof(TestMode)); - } - [Test] - [TestCaseSource(nameof(TestModes))] - public void TakeLockAndExtend(TestMode mode) - { - bool withTran = mode == TestMode.MultiExec; - using (var conn = Create(mode)) - { - RedisValue right = Guid.NewGuid().ToString(), - wrong = Guid.NewGuid().ToString(); - - int DB = mode == TestMode.Twemproxy ? 0 : 7; - RedisKey Key = "lock-key"; - - var db = conn.GetDatabase(DB); - - db.KeyDelete(Key); - - - var t1 = db.LockTakeAsync(Key, right, TimeSpan.FromSeconds(20)); - var t1b = db.LockTakeAsync(Key, wrong, TimeSpan.FromSeconds(10)); - var t2 = db.LockQueryAsync(Key); - var t3 = withTran ? db.LockReleaseAsync(Key, wrong) : null; - var t4 = db.LockQueryAsync(Key); - var t5 = withTran ? db.LockExtendAsync(Key, wrong, TimeSpan.FromSeconds(60)) : null; - var t6 = db.LockQueryAsync(Key); - var t7 = db.KeyTimeToLiveAsync(Key); - var t8 = db.LockExtendAsync(Key, right, TimeSpan.FromSeconds(60)); - var t9 = db.LockQueryAsync(Key); - var t10 = db.KeyTimeToLiveAsync(Key); - var t11 = db.LockReleaseAsync(Key, right); - var t12 = db.LockQueryAsync(Key); - var t13 = db.LockTakeAsync(Key, wrong, TimeSpan.FromSeconds(10)); - - - Assert.IsNotNull(right); - Assert.IsNotNull(wrong); - Assert.AreNotEqual(right, wrong); - Assert.IsTrue(conn.Wait(t1), "1"); - Assert.IsFalse(conn.Wait(t1b), "1b"); - Assert.AreEqual(right, conn.Wait(t2), "2"); - if(withTran) Assert.IsFalse(conn.Wait(t3), "3"); - Assert.AreEqual(right, conn.Wait(t4), "4"); - if (withTran) Assert.IsFalse(conn.Wait(t5), "5"); - Assert.AreEqual(right, conn.Wait(t6), "6"); - var ttl = conn.Wait(t7).Value.TotalSeconds; - Assert.IsTrue(ttl > 0 && ttl <= 20, "7"); - Assert.IsTrue(conn.Wait(t8), "8"); - Assert.AreEqual(right, conn.Wait(t9), "9"); - ttl = conn.Wait(t10).Value.TotalSeconds; - Assert.IsTrue(ttl > 50 && ttl <= 60, "10"); - Assert.IsTrue(conn.Wait(t11), "11"); - Assert.IsNull((string)conn.Wait(t12), "12"); - Assert.IsTrue(conn.Wait(t13), "13"); - } - } - - - //public void TestManualLockOpCountByVersion(RedisConnection conn, int expected, bool existFirst) - //{ - // const int DB = 0, LockDuration = 30; - // const string Key = "TestManualLockOpCountByVersion"; - // conn.Wait(conn.Open()); - // conn.Keys.Remove(DB, Key); - // var newVal = "us:" + Config.CreateUniqueName(); - // string expectedVal = newVal; - // if (existFirst) - // { - // expectedVal = "other:" + Config.CreateUniqueName(); - // conn.Strings.Set(DB, Key, expectedVal, LockDuration); - // } - // int countBefore = conn.GetCounters().MessagesSent; - - // var tran = conn.CreateTransaction(); - // tran.AddCondition(Condition.KeyNotExists(DB, Key)); - // tran.Strings.Set(DB, Key, newVal, LockDuration); - // var taken = conn.Wait(tran.Execute()); - - // int countAfter = conn.GetCounters().MessagesSent; - // var valAfter = conn.Wait(conn.Strings.GetString(DB, Key)); - // Assert.AreEqual(!existFirst, taken, "lock taken (manual)"); - // Assert.AreEqual(expectedVal, valAfter, "taker (manual)"); - // Assert.AreEqual(expected, (countAfter - countBefore) - 1, "expected ops (including ping) (manual)"); - // // note we get a ping from GetCounters - //} - - - - [Test] - [TestCaseSource(nameof(TestModes))] - public void TestBasicLockNotTaken(TestMode testMode) - { - using (var conn = Create(testMode)) - { - int errorCount = 0; - conn.ErrorMessage += delegate { Interlocked.Increment(ref errorCount); }; - Task taken = null; - Task newValue = null; - Task ttl = null; - - const int LOOP = 50; - var db = conn.GetDatabase(0); - for (int i = 0; i < LOOP; i++) - { - db.KeyDeleteAsync("lock-not-exists"); - taken = db.LockTakeAsync("lock-not-exists", "new-value", TimeSpan.FromSeconds(10)); - newValue = db.StringGetAsync("lock-not-exists"); - ttl = db.KeyTimeToLiveAsync("lock-not-exists"); - } - Assert.IsTrue(conn.Wait(taken), "taken"); - Assert.AreEqual("new-value", (string)conn.Wait(newValue)); - var ttlValue = conn.Wait(ttl).Value.TotalSeconds; - Assert.IsTrue(ttlValue >= 8 && ttlValue <= 10, "ttl"); - - Assert.AreEqual(0, errorCount); - } - } - - [Test] - [TestCaseSource(nameof(TestModes))] - public void TestBasicLockTaken(TestMode testMode) - { - using (var conn = Create(testMode)) - { - var db = conn.GetDatabase(0); - db.KeyDelete("lock-exists"); - db.StringSet("lock-exists", "old-value", TimeSpan.FromSeconds(20)); - var taken = db.LockTakeAsync("lock-exists", "new-value", TimeSpan.FromSeconds(10)); - var newValue = db.StringGetAsync("lock-exists"); - var ttl = db.KeyTimeToLiveAsync("lock-exists"); - - Assert.IsFalse(conn.Wait(taken), "taken"); - Assert.AreEqual("old-value", (string)conn.Wait(newValue)); - var ttlValue = conn.Wait(ttl).Value.TotalSeconds; - Assert.IsTrue(ttlValue >= 18 && ttlValue <= 20, "ttl"); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Migrate.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Migrate.cs deleted file mode 100644 index d5d2e81..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Migrate.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Linq; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - public class Migrate : TestBase - { - public void Basic() - { - var fromConfig = new ConfigurationOptions { EndPoints = { { PrimaryServer, SecurePort } }, Password = SecurePassword }; - var toConfig = new ConfigurationOptions { EndPoints = { { PrimaryServer, PrimaryPort } } }; - using (var from = ConnectionMultiplexer.Connect(fromConfig)) - using (var to = ConnectionMultiplexer.Connect(toConfig)) - { - RedisKey key = Me(); - var fromDb = from.GetDatabase(); - var toDb = to.GetDatabase(); - fromDb.KeyDelete(key); - toDb.KeyDelete(key); - fromDb.StringSet(key, "foo"); - var dest = to.GetEndPoints(true).Single(); - fromDb.KeyMigrate(key, dest); - Assert.IsFalse(fromDb.KeyExists(key)); - Assert.IsTrue(toDb.KeyExists(key)); - string s = toDb.StringGet(key); - Assert.AreEqual("foo", s); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/MultiAdd.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/MultiAdd.cs deleted file mode 100644 index 59ed19b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/MultiAdd.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System.Linq; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class MultiAdd : TestBase - { - [Test] - public void AddSortedSetEveryWay() - { - using(var conn = Create()) - { - var db = conn.GetDatabase(3); - - RedisKey key = Me(); - db.KeyDelete(key); - db.SortedSetAdd(key, "a", 1); - db.SortedSetAdd(key, new[] { - new SortedSetEntry("b", 2) }); - db.SortedSetAdd(key, new[] { - new SortedSetEntry("c", 3), - new SortedSetEntry("d", 4)}); - db.SortedSetAdd(key, new[] { - new SortedSetEntry("e", 5), - new SortedSetEntry("f", 6), - new SortedSetEntry("g", 7)}); - db.SortedSetAdd(key, new[] { - new SortedSetEntry("h", 8), - new SortedSetEntry("i", 9), - new SortedSetEntry("j", 10), - new SortedSetEntry("k", 11)}); - var vals = db.SortedSetRangeByScoreWithScores(key); - string s = string.Join(",", vals.OrderByDescending(x => x.Score).Select(x => x.Element)); - Assert.AreEqual("k,j,i,h,g,f,e,d,c,b,a", s); - s = string.Join(",", vals.OrderBy(x => x.Score).Select(x => x.Score)); - Assert.AreEqual("1,2,3,4,5,6,7,8,9,10,11", s); - } - } - - [Test] - public void AddHashEveryWay() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(3); - - RedisKey key = Me(); - db.KeyDelete(key); - db.HashSet(key, "a", 1); - db.HashSet(key, new[] { - new HashEntry("b", 2) }); - db.HashSet(key, new[] { - new HashEntry("c", 3), - new HashEntry("d", 4)}); - db.HashSet(key, new[] { - new HashEntry("e", 5), - new HashEntry("f", 6), - new HashEntry("g", 7)}); - db.HashSet(key, new[] { - new HashEntry("h", 8), - new HashEntry("i", 9), - new HashEntry("j", 10), - new HashEntry("k", 11)}); - var vals = db.HashGetAll(key); - string s = string.Join(",", vals.OrderByDescending(x => (double)x.Value).Select(x => x.Name)); - Assert.AreEqual("k,j,i,h,g,f,e,d,c,b,a", s); - s = string.Join(",", vals.OrderBy(x => (double)x.Value).Select(x => x.Value)); - Assert.AreEqual("1,2,3,4,5,6,7,8,9,10,11", s); - } - } - - [Test] - public void AddSetEveryWay() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(3); - - RedisKey key = Me(); - db.KeyDelete(key); - db.SetAdd(key, "a"); - db.SetAdd(key, new RedisValue[] { "b" }); - db.SetAdd(key, new RedisValue[] { "c", "d" }); - db.SetAdd(key, new RedisValue[] { "e", "f", "g" }); - db.SetAdd(key, new RedisValue[] { "h", "i", "j","k" }); - - var vals = db.SetMembers(key); - string s = string.Join(",", vals.OrderByDescending(x => x)); - Assert.AreEqual("k,j,i,h,g,f,e,d,c,b,a", s); - } - } - - [Test] - public void AddSetEveryWayNumbers() - { - using (var conn = Create()) - { - var db = conn.GetDatabase(3); - - RedisKey key = Me(); - db.KeyDelete(key); - db.SetAdd(key, "a"); - db.SetAdd(key, new RedisValue[] { "1" }); - db.SetAdd(key, new RedisValue[] { "11", "2" }); - db.SetAdd(key, new RedisValue[] { "10", "3", "1.5" }); - db.SetAdd(key, new RedisValue[] { "2.2", "-1", "s", "t" }); - - var vals = db.SetMembers(key); - string s = string.Join(",", vals.OrderByDescending(x => x)); - Assert.AreEqual("t,s,a,11,10,3,2.2,2,1.5,1,-1", s); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/MultiMaster.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/MultiMaster.cs deleted file mode 100644 index 3744ebf..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/MultiMaster.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Net; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class MultiMaster : TestBase - { - protected override string GetConfiguration() - { - return PrimaryServer + ":" + SecurePort + "," + PrimaryServer + ":" + PrimaryPort + ",password=" + SecurePassword; - } - - [Test] - public void CannotFlushSlave() - { - Assert.Throws(() => { - ConfigurationOptions config = GetMasterSlaveConfig(); - using (var conn = ConnectionMultiplexer.Connect(config)) - { - var servers = conn.GetEndPoints().Select(e => conn.GetServer(e)); - var slave = servers.First(x => x.IsSlave); - slave.FlushDatabase(); - } - }, - "Command cannot be issued to a slave: FLUSHDB"); - } - - [Test] - public void DeslaveGoesToPrimary() - { - ConfigurationOptions config = GetMasterSlaveConfig(); - using (var conn = ConnectionMultiplexer.Connect(config)) - { - - var primary = conn.GetServer(new IPEndPoint(IPAddress.Parse(PrimaryServer), PrimaryPort)); - var secondary = conn.GetServer(new IPEndPoint(IPAddress.Parse(PrimaryServer), SlavePort)); - - primary.Ping(); - secondary.Ping(); - - primary.MakeMaster(ReplicationChangeOptions.SetTiebreaker); - secondary.MakeMaster(ReplicationChangeOptions.None); - - primary.Ping(); - secondary.Ping(); - - using (var writer = new StringWriter()) - { - conn.Configure(writer); - string log = writer.ToString(); - - Assert.IsTrue(log.Contains("tie-break is unanimous at " + PrimaryServer + ":" + PrimaryPort), "unanimous"); - } - // k, so we know everyone loves 6379; is that what we get? - - var db = conn.GetDatabase(); - RedisKey key = Me(); - - EndPoint demandMaster, preferMaster, preferSlave, demandSlave; - preferMaster = db.IdentifyEndpoint(key, CommandFlags.PreferMaster); - demandMaster = db.IdentifyEndpoint(key, CommandFlags.DemandMaster); - preferSlave = db.IdentifyEndpoint(key, CommandFlags.PreferSlave); - - Assert.AreEqual(primary.EndPoint, demandMaster, "demand master"); - Assert.AreEqual(primary.EndPoint, preferMaster, "prefer master"); - Assert.AreEqual(primary.EndPoint, preferSlave, "prefer slave"); - - try - { - demandSlave = db.IdentifyEndpoint(key, CommandFlags.DemandSlave); - Assert.Fail("this should not have worked"); - } - catch (RedisConnectionException ex) - { - Assert.AreEqual("No connection is available to service this operation: EXISTS DeslaveGoesToPrimary", ex.Message); - } - - primary.MakeMaster(ReplicationChangeOptions.Broadcast | ReplicationChangeOptions.EnslaveSubordinates | ReplicationChangeOptions.SetTiebreaker); - - primary.Ping(); - secondary.Ping(); - - preferMaster = db.IdentifyEndpoint(key, CommandFlags.PreferMaster); - demandMaster = db.IdentifyEndpoint(key, CommandFlags.DemandMaster); - preferSlave = db.IdentifyEndpoint(key, CommandFlags.PreferSlave); - demandSlave = db.IdentifyEndpoint(key, CommandFlags.DemandSlave); - - Assert.AreEqual(primary.EndPoint, demandMaster, "demand master"); - Assert.AreEqual(primary.EndPoint, preferMaster, "prefer master"); - Assert.AreEqual(secondary.EndPoint, preferSlave, "prefer slave"); - Assert.AreEqual(secondary.EndPoint, preferSlave, "demand slave slave"); - - } - } - - private static ConfigurationOptions GetMasterSlaveConfig() - { - return new ConfigurationOptions - { - AllowAdmin = true, - SyncTimeout = 100000, - EndPoints = - { - { PrimaryServer, PrimaryPort }, - { PrimaryServer, SlavePort }, - } - }; - } - - [Test] - public void TestMultiNoTieBreak() - { - using (var log = new StringWriter()) - using (var conn = Create(log: log, tieBreaker: "")) - { - Console.WriteLine(log); - Assert.IsTrue(log.ToString().Contains("Choosing master arbitrarily")); - } - } - - [Test] - [TestCase(PrimaryServer + ":" + PrimaryPortString, PrimaryServer + ":" + PrimaryPortString, PrimaryServer + ":" + PrimaryPortString)] - [TestCase(PrimaryServer + ":" + SecurePortString, PrimaryServer + ":" + SecurePortString, PrimaryServer + ":" + SecurePortString)] - [TestCase(PrimaryServer + ":" + SecurePortString, PrimaryServer + ":" + PrimaryPortString, null)] - [TestCase(PrimaryServer + ":" + PrimaryPortString, PrimaryServer + ":" + SecurePortString, null)] - - [TestCase(null, PrimaryServer + ":" + PrimaryPortString, PrimaryServer + ":" + PrimaryPortString)] - [TestCase(PrimaryServer + ":" + PrimaryPortString, null, PrimaryServer + ":" + PrimaryPortString)] - [TestCase(null, PrimaryServer + ":" + SecurePortString, PrimaryServer + ":" + SecurePortString)] - [TestCase(PrimaryServer + ":" + SecurePortString, null, PrimaryServer + ":" + SecurePortString)] - [TestCase(null, null, null)] - - public void TestMultiWithTiebreak(string a, string b, string elected) - { - const string TieBreak = "__tie__"; - // set the tie-breakers to the expected state - using(var aConn = ConnectionMultiplexer.Connect(PrimaryServer + ":" + PrimaryPort)) - { - aConn.GetDatabase().StringSet(TieBreak, a); - } - using (var aConn = ConnectionMultiplexer.Connect(PrimaryServer + ":" + SecurePort + ",password=" + SecurePassword)) - { - aConn.GetDatabase().StringSet(TieBreak, b); - } - - // see what happens - using (var log = new StringWriter()) - using (var conn = Create(log: log, tieBreaker: TieBreak)) - { - string text = log.ToString(); - Console.WriteLine(text); - Assert.IsFalse(text.Contains("failed to nominate"), "failed to nominate"); - if (elected != null) - { - Assert.IsTrue(text.Contains("Elected: " + elected), "elected"); - } - int nullCount = (a == null ? 1 : 0) + (b == null ? 1 : 0); - if((a == b && nullCount == 0) || nullCount == 1) - { - Assert.IsTrue(text.Contains("tie-break is unanimous"), "unanimous"); - Assert.IsFalse(text.Contains("Choosing master arbitrarily"), "arbitrarily"); - } - else - { - Assert.IsFalse(text.Contains("tie-break is unanimous"), "unanimous"); - Assert.IsTrue(text.Contains("Choosing master arbitrarily"), "arbitrarily"); - } - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Naming.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Naming.cs deleted file mode 100644 index be5548e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Naming.cs +++ /dev/null @@ -1,258 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Naming - { - [Test] - [TestCase(typeof(IDatabase), false)] - [TestCase(typeof(IDatabaseAsync), true)] - [TestCase(typeof(Condition), false)] - public void CheckSignatures(Type type, bool isAsync) - { - // check that all methods and interfaces look appropriate for their sync/async nature - CheckName(type.GetTypeInfo(), isAsync); - var members = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); - foreach(var member in members) - { - if (member.Name.StartsWith("get_") || member.Name.StartsWith("set_") || member.Name.StartsWith("add_") || member.Name.StartsWith("remove_")) continue; - CheckMethod(member, isAsync); - } - } - - [Test] - public void ShowReadOnlyOperations() - { - var msg = typeof(ConnectionMultiplexer).GetTypeInfo().Assembly.GetType("StackExchange.Redis.Message"); - Assert.IsNotNull(msg, "Message"); - var cmd = typeof(ConnectionMultiplexer).GetTypeInfo().Assembly.GetType("StackExchange.Redis.RedisCommand"); - Assert.IsNotNull(cmd, "RedisCommand"); - var method = msg.GetMethod("IsMasterOnly", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); - Assert.IsNotNull(method, "IsMasterOnly"); - object[] args = new object[1]; - - List masterSlave = new List(); - List masterOnly = new List(); - foreach (var val in Enum.GetValues(cmd)) - { - args[0] = val; - bool isMasterOnly = (bool)method.Invoke(null, args); - (isMasterOnly ? masterOnly : masterSlave).Add(val); - - if(!isMasterOnly) - { - Console.WriteLine(val); - } - } - Console.WriteLine("master-only: {0}, vs master/slave: {1}", masterOnly.Count, masterSlave.Count); - Console.WriteLine(); - Console.WriteLine("master-only:"); - foreach (var val in masterOnly) Console.WriteLine(val); - Console.WriteLine(); - Console.WriteLine("master/slave:"); - foreach (var val in masterSlave) Console.WriteLine(val); - } - - [Test] - [TestCase(typeof(IDatabase))] - [TestCase(typeof(IDatabaseAsync))] - public void CheckDatabaseMethodsUseKeys(Type type) - { - foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) - { - if (IgnoreMethodConventions(method)) continue; - - switch(method.Name) - { - case "KeyRandom": - case "KeyRandomAsync": - case "Publish": - case "PublishAsync": - continue; // they're fine, but don't want to widen check to return type - } - - bool usesKey = method.GetParameters().Any(p => UsesKey(p.ParameterType)); - Assert.IsTrue(usesKey, type.Name + ":" + method.Name); - } - } - static bool UsesKey(Type type) - { - if (type == typeof(RedisKey)) return true; - - if(type.IsArray) - { - if (UsesKey(type.GetElementType())) return true; - } - if(type.GetTypeInfo().IsGenericType) // KVP, etc - { - var args = type.GetGenericArguments(); - if (args.Any(UsesKey)) return true; - } - return false; - } - - static bool IgnoreMethodConventions(MethodInfo method) - { - string name = method.Name; - if (name.StartsWith("get_") || name.StartsWith("set_") || name.StartsWith("add_") || name.StartsWith("remove_")) return true; - switch(name) - { - case "CreateBatch": - case "CreateTransaction": - case "IsConnected": - case "SetScan": - case "SortedSetScan": - case "HashScan": - case "SubscribedEndpoint": - return true; - } - return false; - } - [Test] - [TestCase(typeof(IDatabase), typeof(IDatabaseAsync))] - [TestCase(typeof(IDatabaseAsync), typeof(IDatabase))] - public void CheckSyncAsyncMethodsMatch(Type from, Type to) - { - const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; - int count = 0; - foreach (var method in from.GetMethods(flags)) - { - if (IgnoreMethodConventions(method)) continue; - - string name = method.Name, huntName; - - if (name.EndsWith("Async")) huntName = name.Substring(0, name.Length - 5); - else huntName = name + "Async"; - - Type huntType; - if (method.ReturnType == null || method.ReturnType == typeof(void)) - { - huntType = typeof(Task); - } - else if (method.ReturnType == typeof(Task)) - { - huntType = null; - } - else if (method.ReturnType.GetTypeInfo().IsSubclassOf(typeof(Task))) - { - huntType = method.ReturnType.GetGenericArguments()[0]; - } - else - { - huntType = typeof(Task<>).MakeGenericType(method.ReturnType); - } - var pFrom = method.GetParameters(); - Type[] args = pFrom.Select(x => x.ParameterType).ToArray(); - Assert.AreEqual(typeof(CommandFlags), args.Last()); -#if !CORE_CLR - var found = to.GetMethod(huntName, flags, null, method.CallingConvention, args, null); -#else - var found = to.GetMethods(flags) - .SingleOrDefault(m => m.Name == huntName && m.HasMatchingParameterTypes(args)); -#endif - Assert.IsNotNull(found, "Found " + name + ", no " + huntName); - var pTo = found.GetParameters(); - - for(int i = 0; i < pFrom.Length;i++) - { - Assert.AreEqual(pFrom[i].Name, pTo[i].Name, method.Name + ":" + pFrom[i].Name); - Assert.AreEqual(pFrom[i].ParameterType, pTo[i].ParameterType, method.Name + ":" + pFrom[i].Name); - } - - - count++; - } - Console.WriteLine("Validated: {0} ({1} methods)", from.Name, count); - } - - static readonly Type ignoreType = typeof(ConnectionMultiplexer).GetTypeInfo().Assembly.GetType("StackExchange.Redis.IgnoreNamePrefixAttribute"); - void CheckMethod(MethodInfo method, bool isAsync) - { - -#if DEBUG -#if !CORE_CLR - bool ignorePrefix = ignoreType != null && Attribute.IsDefined(method, ignoreType); -#else - bool ignorePrefix = ignoreType != null && method.IsDefined(ignoreType); -#endif - if (ignorePrefix) - { -#if !CORE_CLR - Attribute attrib = Attribute.GetCustomAttribute(method, ignoreType); -#else - Attribute attrib = method.GetCustomAttribute(ignoreType); -#endif - if ((bool)attrib.GetType().GetProperty("IgnoreEntireMethod").GetValue(attrib)) - { - return; - } - } - string shortName = method.Name, fullName = method.DeclaringType.Name + "." + shortName; - CheckName(method, isAsync); - if (!ignorePrefix) - { - Assert.IsTrue(shortName.StartsWith("Hash") || shortName.StartsWith("Key") - || shortName.StartsWith("String") || shortName.StartsWith("List") - || shortName.StartsWith("SortedSet") || shortName.StartsWith("Set") - || shortName.StartsWith("Debug") || shortName.StartsWith("Lock") - || shortName.StartsWith("Script") || shortName.StartsWith("HyperLogLog") - , fullName + ":Prefix"); - } - - Assert.IsFalse(shortName.Contains("If"), fullName + ":If"); // should probably be a When option - - var returnType = method.ReturnType ?? typeof(void); - if (isAsync) - { - Assert.IsTrue(typeof(Task).IsAssignableFrom(returnType), fullName + ":Task"); - } - else - { - Assert.IsFalse(typeof(Task).IsAssignableFrom(returnType), fullName + ":Task"); - } -#endif - } - - void CheckName(MemberInfo member, bool isAsync) - { - if (isAsync) Assert.IsTrue(member.Name.EndsWith("Async"), member.Name + ":Name - end *Async"); - else Assert.IsFalse(member.Name.EndsWith("Async"), member.Name + ":Name - don't end *Async"); - } - } - - public static class ReflectionExtensions - { -#if !CORE_CLR - public static Type GetTypeInfo(this Type type) - { - return type; - } - -#else - public static bool HasMatchingParameterTypes(this MethodInfo method, Type[] paramTypes) - { - var types = method.GetParameters().Select(pi => pi.ParameterType).ToArray(); - if (types.Length != paramTypes.Length) - { - return false; - } - - for (int i = 0; i < types.Length; i++) - { - if (types[i] != paramTypes[i]) - { - return false; - } - } - - return true; - } -#endif - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/PreserveOrder.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/PreserveOrder.cs deleted file mode 100644 index f09c91b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/PreserveOrder.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class PreserveOrder : TestBase - { - [Test] - [TestCase(true)] - [TestCase(false)] - public void Execute(bool preserveAsyncOrder) - { - using (var conn = Create()) - { - var sub = conn.GetSubscriber(); - var received = new List(); - Console.WriteLine("Subscribing..."); - const int COUNT = 1000; - sub.Subscribe("foo", (channel, message) => - { - lock (received) - { - received.Add((int)message); - if (received.Count == COUNT) - Monitor.PulseAll(received); // wake the test rig - } - Thread.Sleep(1); // you kinda need to be slow, otherwise - // the pool will end up doing everything on one thread - }); - conn.PreserveAsyncOrder = preserveAsyncOrder; - Console.WriteLine(); - Console.WriteLine("Sending ({0})...", (preserveAsyncOrder ? "preserved order" : "any order")); - lock (received) - { - received.Clear(); - // we'll also use received as a wait-detection mechanism; sneaky - - // note: this does not do any cheating; - // it all goes to the server and back - for (int i = 0; i < COUNT; i++) - { - sub.Publish("foo", i); - } - - Console.WriteLine("Allowing time for delivery etc..."); - var watch = Stopwatch.StartNew(); - if (!Monitor.Wait(received, 10000)) - { - Console.WriteLine("Timed out; expect less data"); - } - watch.Stop(); - Console.WriteLine("Checking..."); - lock (received) - { - Console.WriteLine("Received: {0} in {1}ms", received.Count, watch.ElapsedMilliseconds); - int wrongOrder = 0; - for (int i = 0; i < Math.Min(COUNT, received.Count); i++) - { - if (received[i] != i) wrongOrder++; - } - Console.WriteLine("Out of order: " + wrongOrder); - if (preserveAsyncOrder) Assert.AreEqual(0, wrongOrder); - else Assert.AreNotEqual(0, wrongOrder); - } - } - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Profiling.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Profiling.cs deleted file mode 100644 index 9cc5d12..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Profiling.cs +++ /dev/null @@ -1,596 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -#if CORE_CLR -using System.Reflection; -#endif -using System.Threading.Tasks; -using NUnit.Framework; -using System.Threading; -using System.Collections.Concurrent; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Profiling : TestBase - { - class TestProfiler : IProfiler - { - public object MyContext = new object(); - - public object GetContext() - { - return MyContext; - } - } - - [Test] - public void Simple() - { - using (var conn = Create()) - { - var profiler = new TestProfiler(); - - conn.RegisterProfiler(profiler); - conn.BeginProfiling(profiler.MyContext); - var db = conn.GetDatabase(4); - db.StringSet("hello", "world"); - var val = db.StringGet("hello"); - Assert.AreEqual("world", (string)val); - - var cmds = conn.FinishProfiling(profiler.MyContext); - Assert.AreEqual(2, cmds.Count()); - - var set = cmds.SingleOrDefault(cmd => cmd.Command == "SET"); - Assert.IsNotNull(set); - var get = cmds.SingleOrDefault(cmd => cmd.Command == "GET"); - Assert.IsNotNull(get); - - Assert.IsTrue(set.CommandCreated <= get.CommandCreated); - - Assert.AreEqual(4, set.Db); - Assert.AreEqual(conn.GetEndPoints()[0], set.EndPoint); - Assert.IsTrue(set.CreationToEnqueued > TimeSpan.Zero); - Assert.IsTrue(set.EnqueuedToSending > TimeSpan.Zero); - Assert.IsTrue(set.SentToResponse > TimeSpan.Zero); - Assert.IsTrue(set.ResponseToCompletion > TimeSpan.Zero); - Assert.IsTrue(set.ElapsedTime > TimeSpan.Zero); - Assert.IsTrue(set.ElapsedTime > set.CreationToEnqueued && set.ElapsedTime > set.EnqueuedToSending && set.ElapsedTime > set.SentToResponse); - Assert.IsTrue(set.RetransmissionOf == null); - Assert.IsTrue(set.RetransmissionReason == null); - - Assert.AreEqual(4, get.Db); - Assert.AreEqual(conn.GetEndPoints()[0], get.EndPoint); - Assert.IsTrue(get.CreationToEnqueued > TimeSpan.Zero); - Assert.IsTrue(get.EnqueuedToSending > TimeSpan.Zero); - Assert.IsTrue(get.SentToResponse > TimeSpan.Zero); - Assert.IsTrue(get.ResponseToCompletion > TimeSpan.Zero); - Assert.IsTrue(get.ElapsedTime > TimeSpan.Zero); - Assert.IsTrue(get.ElapsedTime > get.CreationToEnqueued && get.ElapsedTime > get.EnqueuedToSending && get.ElapsedTime > get.SentToResponse); - Assert.IsTrue(get.RetransmissionOf == null); - Assert.IsTrue(get.RetransmissionReason == null); - } - } - - [Test] - public void ManyThreads() - { - using (var conn = Create()) - { - var profiler = new TestProfiler(); - - conn.RegisterProfiler(profiler); - conn.BeginProfiling(profiler.MyContext); - - var threads = new List(); - - for (var i = 0; i < 16; i++) - { - var db = conn.GetDatabase(i); - - threads.Add( - new Thread( - delegate() - { - var threadTasks = new List(); - - for (var j = 0; j < 1000; j++) - { - var task = db.StringSetAsync("" + j, "" + j); - threadTasks.Add(task); - } - - Task.WaitAll(threadTasks.ToArray()); - } - ) - ); - } - - threads.ForEach(thread => thread.Start()); - threads.ForEach(thread => thread.Join()); - - var allVals = conn.FinishProfiling(profiler.MyContext); - - var kinds = allVals.Select(cmd => cmd.Command).Distinct().ToList(); - Assert.IsTrue(kinds.Count <= 2); - Assert.IsTrue(kinds.Contains("SET")); - if (kinds.Count == 2 && !kinds.Contains("SELECT")) - { - Assert.Fail("Non-SET, Non-SELECT command seen"); - } - - Assert.AreEqual(16 * 1000, allVals.Count()); - Assert.AreEqual(16, allVals.Select(cmd => cmd.Db).Distinct().Count()); - - for (var i = 0; i < 16; i++) - { - var setsInDb = allVals.Where(cmd => cmd.Db == i && cmd.Command == "SET").Count(); - Assert.AreEqual(1000, setsInDb); - } - } - } - - class TestProfiler2 : IProfiler - { - ConcurrentDictionary Contexts = new ConcurrentDictionary(); - - public void RegisterContext(object context) - { - Contexts[Thread.CurrentThread.ManagedThreadId] = context; - } - - public object GetContext() - { - object ret; - if (!Contexts.TryGetValue(Thread.CurrentThread.ManagedThreadId, out ret)) ret = null; - - return ret; - } - } - - [Test] - public void ManyContexts() - { - using (var conn = Create()) - { - var profiler = new TestProfiler2(); - conn.RegisterProfiler(profiler); - - var perThreadContexts = new List(); - for (var i = 0; i < 16; i++) - { - perThreadContexts.Add(new object()); - } - - var threads = new List(); - - var results = new IEnumerable[16]; - - for (var i = 0; i < 16; i++) - { - var ix = i; - var thread = - new Thread( - delegate() - { - var ctx = perThreadContexts[ix]; - profiler.RegisterContext(ctx); - - conn.BeginProfiling(ctx); - var db = conn.GetDatabase(ix); - - var allTasks = new List(); - - for (var j = 0; j < 1000; j++) - { - allTasks.Add(db.StringGetAsync("hello" + ix)); - allTasks.Add(db.StringSetAsync("hello" + ix, "world" + ix)); - } - - Task.WaitAll(allTasks.ToArray()); - - results[ix] = conn.FinishProfiling(ctx); - } - ); - - threads.Add(thread); - } - - threads.ForEach(t => t.Start()); - threads.ForEach(t => t.Join()); - - for (var i = 0; i < results.Length; i++) - { - var res = results[i]; - Assert.IsNotNull(res); - - var numGets = res.Count(r => r.Command == "GET"); - var numSets = res.Count(r => r.Command == "SET"); - - Assert.AreEqual(1000, numGets); - Assert.AreEqual(1000, numSets); - Assert.IsTrue(res.All(cmd => cmd.Db == i)); - } - } - } - - class TestProfiler3 : IProfiler - { - ConcurrentDictionary Contexts = new ConcurrentDictionary(); - - public void RegisterContext(object context) - { - Contexts[Thread.CurrentThread.ManagedThreadId] = context; - } - - public object AnyContext() - { - return Contexts.First().Value; - } - - public void Reset() - { - Contexts.Clear(); - } - - public object GetContext() - { - object ret; - if (!Contexts.TryGetValue(Thread.CurrentThread.ManagedThreadId, out ret)) ret = null; - - return ret; - } - } - - // This is a separate method for target=DEBUG purposes. - // In release builds, the runtime is smart enough to figure out - // that the contexts are unreachable and should be collected but in - // debug builds... well, it's not very smart. - object LeaksCollectedAndRePooled_Initialize(ConnectionMultiplexer conn, int threadCount) - { - var profiler = new TestProfiler3(); - conn.RegisterProfiler(profiler); - - var perThreadContexts = new List(); - for (var i = 0; i < threadCount; i++) - { - perThreadContexts.Add(new object()); - } - - var threads = new List(); - - var results = new IEnumerable[threadCount]; - - for (var i = 0; i < threadCount; i++) - { - var ix = i; - var thread = - new Thread( - delegate() - { - var ctx = perThreadContexts[ix]; - profiler.RegisterContext(ctx); - - conn.BeginProfiling(ctx); - var db = conn.GetDatabase(ix); - - var allTasks = new List(); - - for (var j = 0; j < 1000; j++) - { - allTasks.Add(db.StringGetAsync("hello" + ix)); - allTasks.Add(db.StringSetAsync("hello" + ix, "world" + ix)); - } - - Task.WaitAll(allTasks.ToArray()); - - // intentionally leaking! - } - ); - - threads.Add(thread); - } - - threads.ForEach(t => t.Start()); - threads.ForEach(t => t.Join()); - - var anyContext = profiler.AnyContext(); - profiler.Reset(); - - return anyContext; - } - - [Test] - public void LeaksCollectedAndRePooled() - { - const int ThreadCount = 16; - - using (var conn = Create()) - { - var anyContext = LeaksCollectedAndRePooled_Initialize(conn, ThreadCount); - - // force collection of everything but `anyContext` - GC.Collect(3, GCCollectionMode.Forced, blocking: true); - GC.WaitForPendingFinalizers(); - - Thread.Sleep(TimeSpan.FromMinutes(1.01)); - conn.FinishProfiling(anyContext); - - // make sure we haven't left anything in the active contexts dictionary - Assert.AreEqual(0, conn.profiledCommands.ContextCount); - Assert.AreEqual(ThreadCount, ConcurrentProfileStorageCollection.AllocationCount); - Assert.AreEqual(ThreadCount, ConcurrentProfileStorageCollection.CountInPool()); - } - } - - [Test] - public void ReuseStorage() - { - const int ThreadCount = 16; - - // have to reset so other tests don't clober - ConcurrentProfileStorageCollection.AllocationCount = 0; - - using (var conn = Create()) - { - var profiler = new TestProfiler2(); - conn.RegisterProfiler(profiler); - - var perThreadContexts = new List(); - for (var i = 0; i < 16; i++) - { - perThreadContexts.Add(new object()); - } - - var threads = new List(); - - var results = new List>[16]; - for (var i = 0; i < 16; i++) - { - results[i] = new List>(); - } - - for (var i = 0; i < ThreadCount; i++) - { - var ix = i; - var thread = - new Thread( - delegate() - { - for (var k = 0; k < 10; k++) - { - var ctx = perThreadContexts[ix]; - profiler.RegisterContext(ctx); - - conn.BeginProfiling(ctx); - var db = conn.GetDatabase(ix); - - var allTasks = new List(); - - for (var j = 0; j < 1000; j++) - { - allTasks.Add(db.StringGetAsync("hello" + ix)); - allTasks.Add(db.StringSetAsync("hello" + ix, "world" + ix)); - } - - Task.WaitAll(allTasks.ToArray()); - - results[ix].Add(conn.FinishProfiling(ctx)); - } - } - ); - - threads.Add(thread); - } - - threads.ForEach(t => t.Start()); - threads.ForEach(t => t.Join()); - - // only 16 allocations can ever be in flight at once - var allocCount = ConcurrentProfileStorageCollection.AllocationCount; - Assert.IsTrue(allocCount <= ThreadCount, allocCount.ToString()); - - // correctness check for all allocations - for (var i = 0; i < results.Length; i++) - { - var resList = results[i]; - foreach (var res in resList) - { - Assert.IsNotNull(res); - - var numGets = res.Count(r => r.Command == "GET"); - var numSets = res.Count(r => r.Command == "SET"); - - Assert.AreEqual(1000, numGets); - Assert.AreEqual(1000, numSets); - Assert.IsTrue(res.All(cmd => cmd.Db == i)); - } - } - - // no crossed streams - var everything = results.SelectMany(r => r).ToList(); - for (var i = 0; i < everything.Count; i++) - { - for (var j = 0; j < everything.Count; j++) - { - if (i == j) continue; - - if (object.ReferenceEquals(everything[i], everything[j])) - { - Assert.Fail("Profilings were jumbled"); - } - } - } - } - } - - [Test] - public void LowAllocationEnumerable() - { - const int OuterLoop = 10000; - - using(var conn = Create()) - { - var profiler = new TestProfiler(); - conn.RegisterProfiler(profiler); - - conn.BeginProfiling(profiler.MyContext); - - var db = conn.GetDatabase(); - - var allTasks = new List>(); - - foreach (var i in Enumerable.Range(0, OuterLoop)) - { - var t = - db.StringSetAsync("foo" + i, "bar" + i) - .ContinueWith( - async _ => - { - return (string)(await db.StringGetAsync("foo" + i).ConfigureAwait(false)); - } - ); - - var finalResult = t.Unwrap(); - allTasks.Add(finalResult); - } - - conn.WaitAll(allTasks.ToArray()); - - var res = conn.FinishProfiling(profiler.MyContext); - Assert.IsTrue(res.GetType().GetTypeInfo().IsValueType); - - using(var e = res.GetEnumerator()) - { - Assert.IsTrue(e.GetType().GetTypeInfo().IsValueType); - - Assert.IsTrue(e.MoveNext()); - var i = e.Current; - - e.Reset(); - Assert.IsTrue(e.MoveNext()); - var j = e.Current; - - Assert.IsTrue(object.ReferenceEquals(i, j)); - } - - Assert.AreEqual(OuterLoop * 2, res.Count()); - Assert.AreEqual(OuterLoop, res.Count(r => r.Command == "GET")); - Assert.AreEqual(OuterLoop, res.Count(r => r.Command == "SET")); - } - } - - class ToyProfiler : IProfiler - { - public ConcurrentDictionary Contexts = new ConcurrentDictionary(); - - public object GetContext() - { - object ctx; - if (!Contexts.TryGetValue(Thread.CurrentThread, out ctx)) ctx = null; - - return ctx; - } - } - - [Test] - public void ProfilingMD_Ex1() - { - using (var c = Create()) - { - ConnectionMultiplexer conn = c; - var profiler = new ToyProfiler(); - var thisGroupContext = new object(); - - conn.RegisterProfiler(profiler); - - var threads = new List(); - - for (var i = 0; i < 16; i++) - { - var db = conn.GetDatabase(i); - - var thread = - new Thread( - delegate() - { - var threadTasks = new List(); - - for (var j = 0; j < 1000; j++) - { - var task = db.StringSetAsync("" + j, "" + j); - threadTasks.Add(task); - } - - Task.WaitAll(threadTasks.ToArray()); - } - ); - - profiler.Contexts[thread] = thisGroupContext; - - threads.Add(thread); - } - - conn.BeginProfiling(thisGroupContext); - - threads.ForEach(thread => thread.Start()); - threads.ForEach(thread => thread.Join()); - - IEnumerable timings = conn.FinishProfiling(thisGroupContext); - - Assert.AreEqual(16000, timings.Count()); - } - } - - [Test] - public void ProfilingMD_Ex2() - { - using (var c = Create()) - { - ConnectionMultiplexer conn = c; - var profiler = new ToyProfiler(); - - conn.RegisterProfiler(profiler); - - var threads = new List(); - - var perThreadTimings = new ConcurrentDictionary>(); - - for (var i = 0; i < 16; i++) - { - var db = conn.GetDatabase(i); - - var thread = - new Thread( - delegate() - { - var threadTasks = new List(); - - conn.BeginProfiling(Thread.CurrentThread); - - for (var j = 0; j < 1000; j++) - { - var task = db.StringSetAsync("" + j, "" + j); - threadTasks.Add(task); - } - - Task.WaitAll(threadTasks.ToArray()); - - perThreadTimings[Thread.CurrentThread] = conn.FinishProfiling(Thread.CurrentThread).ToList(); - } - ); - - profiler.Contexts[thread] = thread; - - threads.Add(thread); - } - - threads.ForEach(thread => thread.Start()); - threads.ForEach(thread => thread.Join()); - - Assert.AreEqual(16, perThreadTimings.Count); - Assert.IsTrue(perThreadTimings.All(kv => kv.Value.Count == 1000)); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Program.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Program.cs deleted file mode 100644 index 43a7e60..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Program.cs +++ /dev/null @@ -1,18 +0,0 @@ -#if NUNITLITE && !CORE_CLR -using System; -using System.Reflection; -using NUnit.Common; -using NUnitLite; - -namespace StackExchange.Redis.Tests -{ - public class Program - { - public static int Main(string[] args) - { - return new AutoRun(typeof(TestBase).GetTypeInfo().Assembly) - .Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); - } - } -} -#endif \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Properties/AssemblyInfo.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 1337b60..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("StackExchange.Redis.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("StackExchange.Redis.Tests")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("70fae8f5-4f2f-4422-92c6-05bde74cdd52")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/PubSub.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/PubSub.cs deleted file mode 100644 index 2c7bc48..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/PubSub.cs +++ /dev/null @@ -1,427 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class PubSub : TestBase - { - - [Test] - public void ExplicitPublishMode() - { - using(var mx = Create(channelPrefix: "foo:")) - { - var pub = mx.GetSubscriber(); - int a = 0, b = 0, c = 0, d = 0; - pub.Subscribe(new RedisChannel("*bcd", RedisChannel.PatternMode.Literal), (x, y) => - { - Interlocked.Increment(ref a); - }); - pub.Subscribe(new RedisChannel("a*cd", RedisChannel.PatternMode.Pattern), (x, y) => - { - Interlocked.Increment(ref b); - }); - pub.Subscribe(new RedisChannel("ab*d", RedisChannel.PatternMode.Auto), (x, y) => - { - Interlocked.Increment(ref c); - }); - pub.Subscribe("abc*", (x, y) => - { - Interlocked.Increment(ref d); - }); - - Thread.Sleep(1000); - pub.Publish("abcd", "efg"); - Thread.Sleep(500); - Assert.AreEqual(0, VolatileWrapper.Read(ref a), "a1"); - Assert.AreEqual(1, VolatileWrapper.Read(ref b), "b1"); - Assert.AreEqual(1, VolatileWrapper.Read(ref c), "c1"); - Assert.AreEqual(1, VolatileWrapper.Read(ref d), "d1"); - - pub.Publish("*bcd", "efg"); - Thread.Sleep(500); - Assert.AreEqual(1, VolatileWrapper.Read(ref a), "a2"); - //Assert.AreEqual(1, VolatileWrapper.Read(ref b), "b2"); - //Assert.AreEqual(1, VolatileWrapper.Read(ref c), "c2"); - //Assert.AreEqual(1, VolatileWrapper.Read(ref d), "d2"); - - } - } - - [Test] - [TestCase(true, null, false)] - [TestCase(false, null, false)] - [TestCase(true, "", false)] - [TestCase(false, "", false)] - [TestCase(true, "Foo:", false)] - [TestCase(false, "Foo:", false)] - [TestCase(true, null, true)] - [TestCase(false, null, true)] - [TestCase(true, "", true)] - [TestCase(false, "", true)] - [TestCase(true, "Foo:", true)] - [TestCase(false, "Foo:", true)] - public void TestBasicPubSub(bool preserveOrder, string channelPrefix, bool wildCard) - { - using (var muxer = Create(channelPrefix: channelPrefix)) - { - muxer.PreserveAsyncOrder = preserveOrder; - var pub = GetServer(muxer); - var sub = muxer.GetSubscriber(); - Ping(muxer, pub, sub); - HashSet received = new HashSet(); - int secondHandler = 0; - string subChannel = wildCard ? "a*c" : "abc"; - const string pubChannel = "abc"; - Action handler1 = (channel, payload) => - { - lock (received) - { - if (channel == pubChannel) - { - received.Add(payload); - } else - { - Console.WriteLine((string)channel); - } - } - }, handler2 = (channel, payload) => - { - Interlocked.Increment(ref secondHandler); - }; - sub.Subscribe(subChannel, handler1); - sub.Subscribe(subChannel, handler2); - - lock (received) - { - Assert.AreEqual(0, received.Count); - } - Assert.AreEqual(0, VolatileWrapper.Read(ref secondHandler)); - var count = sub.Publish(pubChannel, "def"); - - Ping(muxer, pub, sub, 3); - - lock (received) - { - Assert.AreEqual(1, received.Count); - } - Assert.AreEqual(1, VolatileWrapper.Read(ref secondHandler)); - - // unsubscribe from first; should still see second - sub.Unsubscribe(subChannel, handler1); - count = sub.Publish(pubChannel, "ghi"); - Ping(muxer, pub, sub); - lock(received) - { - Assert.AreEqual(1, received.Count); - } - Assert.AreEqual(2, VolatileWrapper.Read(ref secondHandler)); - Assert.AreEqual(1, count); - - // unsubscribe from second; should see nothing this time - sub.Unsubscribe(subChannel, handler2); - count = sub.Publish(pubChannel, "ghi"); - Ping(muxer, pub, sub); - lock (received) - { - Assert.AreEqual(1, received.Count); - } - Assert.AreEqual(2, VolatileWrapper.Read(ref secondHandler)); - Assert.AreEqual(0, count); - } - } - - [Test] - [TestCase(true)] - [TestCase(false)] - public void TestBasicPubSubFireAndForget(bool preserveOrder) - { - using (var muxer = Create()) - { - muxer.PreserveAsyncOrder = preserveOrder; - var pub = GetServer(muxer); - var sub = muxer.GetSubscriber(); - - RedisChannel key = Guid.NewGuid().ToString(); - HashSet received = new HashSet(); - int secondHandler = 0; - Ping(muxer, pub, sub); - sub.Subscribe(key, (channel, payload) => - { - lock (received) - { - if (channel == key) - { - received.Add(payload); - } - } - }, CommandFlags.FireAndForget); - - - sub.Subscribe(key, (channel, payload) => - { - Interlocked.Increment(ref secondHandler); - }, CommandFlags.FireAndForget); - - lock (received) - { - Assert.AreEqual(0, received.Count); - } - Assert.AreEqual(0, VolatileWrapper.Read(ref secondHandler)); - Ping(muxer, pub, sub); - var count = sub.Publish(key, "def", CommandFlags.FireAndForget); - Ping(muxer, pub, sub); - - lock (received) - { - Assert.AreEqual(1, received.Count); - } - Assert.AreEqual(1, VolatileWrapper.Read(ref secondHandler)); - - sub.Unsubscribe(key); - count = sub.Publish(key, "ghi", CommandFlags.FireAndForget); - - Ping(muxer, pub, sub); - - lock (received) - { - Assert.AreEqual(1, received.Count); - } - Assert.AreEqual(0, count); - } - } - - static void Ping(ConnectionMultiplexer muxer, IServer pub, ISubscriber sub, int times = 1) - { - while (times-- > 0) - { - // both use async because we want to drain the completion managers, and the only - // way to prove that is to use TPL objects - var t1 = sub.PingAsync(); - var t2 = pub.PingAsync(); - Thread.Sleep(100); // especially useful when testing any-order mode - - if (!Task.WaitAll(new[] { t1, t2 }, muxer.TimeoutMilliseconds * 2)) throw new TimeoutException(); - } - } - - //protected override string GetConfiguration() - //{ - // return PrimaryServer + ":" + PrimaryPortString; - //} - - [Test] - [TestCase(true)] - [TestCase(false)] - public void TestPatternPubSub(bool preserveOrder) - { - using (var muxer = Create()) - { - muxer.PreserveAsyncOrder = preserveOrder; - var pub = GetServer(muxer); - var sub = muxer.GetSubscriber(); - - HashSet received = new HashSet(); - int secondHandler = 0; - sub.Subscribe("a*c", (channel, payload) => - { - lock(received) - { - if (channel == "abc") - { - received.Add(payload); - } - } - }); - - sub.Subscribe("a*c", (channel, payload) => - { - Interlocked.Increment(ref secondHandler); - }); - lock (received) - { - Assert.AreEqual(0, received.Count); - } - Assert.AreEqual(0, VolatileWrapper.Read(ref secondHandler)); - var count = sub.Publish("abc", "def"); - - Ping(muxer, pub, sub); - - lock(received) - { - Assert.AreEqual(1, received.Count); - } - Assert.AreEqual(1, VolatileWrapper.Read(ref secondHandler)); - - sub.Unsubscribe("a*c"); - count = sub.Publish("abc", "ghi"); - - Ping(muxer, pub, sub); - - lock(received) - { - Assert.AreEqual(1, received.Count); - } - Assert.AreEqual(0, count); - } - } - - [Test] - [TestCase(false)] - [TestCase(true)] - public void SubscriptionsSurviveMasterSwitch(bool useSharedSocketManager) - { - using (var a = Create(allowAdmin: true, useSharedSocketManager: useSharedSocketManager)) - using (var b = Create(allowAdmin: true, useSharedSocketManager: useSharedSocketManager)) - { - RedisChannel channel = Me(); - var subA = a.GetSubscriber(); - var subB = b.GetSubscriber(); - - long masterChanged = 0, aCount = 0, bCount = 0; - a.ConfigurationChangedBroadcast += delegate { - Console.WriteLine("a noticed config broadcast: " + Interlocked.Increment(ref masterChanged)); - }; - b.ConfigurationChangedBroadcast += delegate { - Console.WriteLine("b noticed config broadcast: " + Interlocked.Increment(ref masterChanged)); - }; - subA.Subscribe(channel, (ch, message) => { - Console.WriteLine("a got message: " + message); - Interlocked.Increment(ref aCount); - }); - subB.Subscribe(channel, (ch, message) => { - Console.WriteLine("b got message: " + message); - Interlocked.Increment(ref bCount); - }); - - - Assert.IsFalse(a.GetServer(PrimaryServer, PrimaryPort).IsSlave, PrimaryPortString + " is master via a"); - Assert.IsTrue(a.GetServer(PrimaryServer, SlavePort).IsSlave, SlavePortString + " is slave via a"); - Assert.IsFalse(b.GetServer(PrimaryServer, PrimaryPort).IsSlave, PrimaryPortString + " is master via b"); - Assert.IsTrue(b.GetServer(PrimaryServer, SlavePort).IsSlave, SlavePortString + " is slave via b"); - - - var epA = subA.SubscribedEndpoint(channel); - var epB = subB.SubscribedEndpoint(channel); - Console.WriteLine("a: " + EndPointCollection.ToString(epA)); - Console.WriteLine("b: " + EndPointCollection.ToString(epB)); - subA.Publish(channel, "a1"); - subB.Publish(channel, "b1"); - subA.Ping(); - subB.Ping(); - - Assert.AreEqual(2, Interlocked.Read(ref aCount), "a"); - Assert.AreEqual(2, Interlocked.Read(ref bCount), "b"); - Assert.AreEqual(0, Interlocked.Read(ref masterChanged), "master"); - - try - { - Interlocked.Exchange(ref masterChanged, 0); - Interlocked.Exchange(ref aCount, 0); - Interlocked.Exchange(ref bCount, 0); - Console.WriteLine("Changing master..."); - using (var sw = new StringWriter()) - { - a.GetServer(PrimaryServer, SlavePort).MakeMaster(ReplicationChangeOptions.All, sw); - Console.WriteLine(sw); - } - subA.Ping(); - subB.Ping(); - Console.WriteLine("Pausing..."); - Thread.Sleep(2000); - - Assert.IsTrue(a.GetServer(PrimaryServer, PrimaryPort).IsSlave, PrimaryPortString + " is slave via a"); - Assert.IsFalse(a.GetServer(PrimaryServer, SlavePort).IsSlave, SlavePortString + " is master via a"); - Assert.IsTrue(b.GetServer(PrimaryServer, PrimaryPort).IsSlave, PrimaryPortString + " is slave via b"); - Assert.IsFalse(b.GetServer(PrimaryServer, SlavePort).IsSlave, SlavePortString + " is master via b"); - - Console.WriteLine("Pause complete"); - var counters = a.GetCounters(); - Console.WriteLine("a outstanding: " + counters.TotalOutstanding); - counters = b.GetCounters(); - Console.WriteLine("b outstanding: " + counters.TotalOutstanding); - subA.Ping(); - subB.Ping(); - epA = subA.SubscribedEndpoint(channel); - epB = subB.SubscribedEndpoint(channel); - Console.WriteLine("a: " + EndPointCollection.ToString(epA)); - Console.WriteLine("b: " + EndPointCollection.ToString(epB)); - Console.WriteLine("a2 sent to: " + subA.Publish(channel, "a2")); - Console.WriteLine("b2 sent to: " + subB.Publish(channel, "b2")); - subA.Ping(); - subB.Ping(); - Console.WriteLine("Checking..."); - - Assert.AreEqual(2, Interlocked.Read(ref aCount), "a"); - Assert.AreEqual(2, Interlocked.Read(ref bCount), "b"); - Assert.AreEqual(4, Interlocked.CompareExchange(ref masterChanged, 0, 0), "master"); - } - finally - { - Console.WriteLine("Restoring configuration..."); - try - { - a.GetServer(PrimaryServer, PrimaryPort).MakeMaster(ReplicationChangeOptions.All); - } - catch - { } - } - } - } - - [Test] - public void SubscriptionsSurviveConnectionFailure() - { - -#if !DEBUG - Assert.Inconclusive("Needs #DEBUG"); -#endif - using(var muxer = Create( allowAdmin: true)) - { - RedisChannel channel = Me(); - var sub = muxer.GetSubscriber(); - int counter = 0; - sub.Subscribe(channel, delegate - { - Interlocked.Increment(ref counter); - }); - sub.Publish(channel, "abc"); - sub.Ping(); - Assert.AreEqual(1, VolatileWrapper.Read(ref counter), "counter"); - var server = GetServer(muxer); - Assert.AreEqual(1, server.GetCounters().Subscription.SocketCount, "sockets"); - -#if DEBUG - server.SimulateConnectionFailure(); - SetExpectedAmbientFailureCount(2); -#endif - - Thread.Sleep(100); - sub.Ping(); -#if DEBUG - Assert.AreEqual(2, server.GetCounters().Subscription.SocketCount, "sockets"); -#endif - sub.Publish(channel, "abc"); - sub.Ping(); - Assert.AreEqual(2, VolatileWrapper.Read(ref counter), "counter"); - } - } - } - - internal static class VolatileWrapper - { - public static int Read(ref int location) - { -#if !CORE_CLR - return Thread.VolatileRead(ref location); -#else - return Volatile.Read(ref location); -#endif - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/PubSubCommand.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/PubSubCommand.cs deleted file mode 100644 index 61cd210..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/PubSubCommand.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Linq; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class PubSubCommand : TestBase - { - [Test] - public void SubscriberCount() - { - using(var conn = Create()) - { - RedisChannel channel = Me() + Guid.NewGuid(); - var server = conn.GetServer(conn.GetEndPoints()[0]); - - var channels = server.SubscriptionChannels(Me() + "*"); - Assert.IsFalse(channels.Contains(channel)); - - long justWork = server.SubscriptionPatternCount(); - var count = server.SubscriptionSubscriberCount(channel); - Assert.AreEqual(0, count); - conn.GetSubscriber().Subscribe(channel, delegate { }); - count = server.SubscriptionSubscriberCount(channel); - Assert.AreEqual(1, count); - - channels = server.SubscriptionChannels(Me() + "*"); - Assert.IsTrue(channels.Contains(channel)); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/RealWorld.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/RealWorld.cs deleted file mode 100644 index 8d993d6..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/RealWorld.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.IO; -using System.Threading; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class RealWorld - { - [Test] - public void WhyDoesThisNotWork() - { - var sw = new StringWriter(); - Console.WriteLine("first:"); - using (var conn = ConnectionMultiplexer.Connect("localhost:6379,localhost:6380,name=Core (Q&A),tiebreaker=:RedisMaster,abortConnect=False", sw)) - { - Console.WriteLine(sw); - Console.WriteLine(); - Console.WriteLine("pausing..."); - Thread.Sleep(200); - Console.WriteLine("second:"); - - sw = new StringWriter(); - bool result = conn.Configure(sw); - Console.WriteLine("Returned: {0}", result); - Console.WriteLine(sw); - } - - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/SSDB.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/SSDB.cs deleted file mode 100644 index 9f5240e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/SSDB.cs +++ /dev/null @@ -1,27 +0,0 @@ -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class SSDB : TestBase - { - [Test] - public void ConnectToSSDB() - { - var config = new ConfigurationOptions - { - EndPoints = { { "ubuntu", 8888 } }, - CommandMap = CommandMap.SSDB - }; - RedisKey key = Me(); - using (var conn = ConnectionMultiplexer.Connect(config)) - { - var db = conn.GetDatabase(0); - db.KeyDelete(key); - Assert.IsTrue(db.StringGet(key).IsNull); - db.StringSet(key, "abc"); - Assert.AreEqual("abc", (string)db.StringGet(key)); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/SSL.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/SSL.cs deleted file mode 100644 index a4a8621..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/SSL.cs +++ /dev/null @@ -1,285 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Security.Cryptography.X509Certificates; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class SSL : TestBase - { - [Test] - [TestCase(null, true)] - [TestCase(null, false)] - [TestCase(6380, true)] - [TestCase(6379, false)] - public void ConnectToAzure(int? port, bool ssl) - { - string name, password; - GetAzureCredentials(out name, out password); - var options = new ConfigurationOptions(); - if (port == null) - { - options.EndPoints.Add(name + ".redis.cache.windows.net"); - } else - { - options.EndPoints.Add(name + ".redis.cache.windows.net", port.Value); - } - options.Ssl = ssl; - options.Password = password; - Console.WriteLine(options); - using(var connection = ConnectionMultiplexer.Connect(options)) - { - var ttl = connection.GetDatabase().Ping(); - Console.WriteLine(ttl); - } - } - - [Test] - [TestCase(false, false)] - [TestCase(true, false)] - [TestCase(true, true)] - public void ConnectToSSLServer(bool useSsl, bool specifyHost) - { - string host = null; - - const string path = @"D:\RedisSslHost.txt"; // because I choose not to advertise my server here! - if (File.Exists(path)) host = File.ReadLines(path).First(); - if (string.IsNullOrWhiteSpace(host)) Assert.Inconclusive("no ssl host specified at: " + path); - - var config = new ConfigurationOptions - { - CommandMap = CommandMap.Create( // looks like "config" is disabled - new Dictionary - { - { "config", null }, - { "cluster", null } - } - ), - EndPoints = { { host } }, - AllowAdmin = true, - SyncTimeout = Debugger.IsAttached ? int.MaxValue : 5000 - }; - if(useSsl) - { - config.Ssl = useSsl; - if (specifyHost) - { - config.SslHost = host; - } - config.CertificateValidation += (sender, cert, chain, errors) => - { - Console.WriteLine("errors: " + errors); - Console.WriteLine("cert issued to: " + cert.Subject); - return true; // fingers in ears, pretend we don't know this is wrong - }; - } - - var configString = config.ToString(); - Console.WriteLine("config: " + configString); - var clone = ConfigurationOptions.Parse(configString); - Assert.AreEqual(configString, clone.ToString(), "config string"); - - using(var log = new StringWriter()) - using (var muxer = ConnectionMultiplexer.Connect(config, log)) - { - Console.WriteLine("Connect log:"); - Console.WriteLine(log); - Console.WriteLine("===="); - muxer.ConnectionFailed += OnConnectionFailed; - muxer.InternalError += OnInternalError; - var db = muxer.GetDatabase(); - db.Ping(); - using (var file = File.Create("ssl-" + useSsl + "-" + specifyHost + ".zip")) - { - muxer.ExportConfiguration(file); - } - RedisKey key = "SE.Redis"; - - const int AsyncLoop = 2000; - // perf; async - db.KeyDelete(key, CommandFlags.FireAndForget); - var watch = Stopwatch.StartNew(); - for (int i = 0; i < AsyncLoop; i++) - { - db.StringIncrement(key, flags: CommandFlags.FireAndForget); - } - // need to do this inside the timer to measure the TTLB - long value = (long)db.StringGet(key); - watch.Stop(); - Assert.AreEqual(AsyncLoop, value); - Console.WriteLine("F&F: {0} INCR, {1:###,##0}ms, {2} ops/s; final value: {3}", - AsyncLoop, - (long)watch.ElapsedMilliseconds, - (long)(AsyncLoop / watch.Elapsed.TotalSeconds), - value); - - // perf: sync/multi-threaded - TestConcurrent(db, key, 30, 10); - //TestConcurrent(db, key, 30, 20); - //TestConcurrent(db, key, 30, 30); - //TestConcurrent(db, key, 30, 40); - //TestConcurrent(db, key, 30, 50); - } - } - - - private static void TestConcurrent(IDatabase db, RedisKey key, int SyncLoop, int Threads) - { - long value; - db.KeyDelete(key, CommandFlags.FireAndForget); - var time = RunConcurrent(delegate - { - for (int i = 0; i < SyncLoop; i++) - { - db.StringIncrement(key); - } - }, Threads, timeout: 45000); - value = (long)db.StringGet(key); - Assert.AreEqual(SyncLoop * Threads, value); - Console.WriteLine("Sync: {0} INCR using {1} threads, {2:###,##0}ms, {3} ops/s; final value: {4}", - SyncLoop * Threads, Threads, - (long)time.TotalMilliseconds, - (long)((SyncLoop * Threads) / time.TotalSeconds), - value); - } - - - - const string RedisLabsSslHostFile = @"d:\RedisLabsSslHost.txt"; - const string RedisLabsPfxPath = @"d:\RedisLabsUser.pfx"; - - [Test] - public void RedisLabsSSL() - { - if (!File.Exists(RedisLabsSslHostFile)) Assert.Inconclusive(); - string hostAndPort = File.ReadAllText(RedisLabsSslHostFile); - int timeout = 5000; - if (Debugger.IsAttached) timeout *= 100; - var options = new ConfigurationOptions - { - EndPoints = { hostAndPort }, - ConnectTimeout = timeout, - AllowAdmin = true, - CommandMap = CommandMap.Create(new HashSet { - "subscribe", "unsubscribe", "cluster" - }, false) - }; - if (!Directory.Exists(Me())) Directory.CreateDirectory(Me()); -#if LOGOUTPUT - ConnectionMultiplexer.EchoPath = Me(); -#endif - options.Ssl = true; - options.CertificateSelection += delegate { - return new X509Certificate2(RedisLabsPfxPath, ""); - }; - RedisKey key = Me(); - using(var conn = ConnectionMultiplexer.Connect(options)) - { - var db = conn.GetDatabase(); - db.KeyDelete(key); - string s = db.StringGet(key); - Assert.IsNull(s); - db.StringSet(key, "abc"); - s = db.StringGet(key); - Assert.AreEqual("abc", s); - - var latency = db.Ping(); - Console.WriteLine("RedisLabs latency: {0:###,##0.##}ms", latency.TotalMilliseconds); - - using (var file = File.Create("RedisLabs.zip")) - { - conn.ExportConfiguration(file); - } - } - } - - [Test] - [TestCase(false)] - [TestCase(true)] - public void RedisLabsEnvironmentVariableClientCertificate(bool setEnv) - { - try - { - if (setEnv) - { - Environment.SetEnvironmentVariable("SERedis_ClientCertPfxPath", RedisLabsPfxPath); - } - if (!File.Exists(RedisLabsSslHostFile)) Assert.Inconclusive(); - string hostAndPort = File.ReadAllText(RedisLabsSslHostFile); - int timeout = 5000; - if (Debugger.IsAttached) timeout *= 100; - var options = new ConfigurationOptions - { - EndPoints = { hostAndPort }, - ConnectTimeout = timeout, - AllowAdmin = true, - CommandMap = CommandMap.Create(new HashSet { - "subscribe", "unsubscribe", "cluster" - }, false) - }; - if (!Directory.Exists(Me())) Directory.CreateDirectory(Me()); -#if LOGOUTPUT - ConnectionMultiplexer.EchoPath = Me(); -#endif - options.Ssl = true; - RedisKey key = Me(); - using (var conn = ConnectionMultiplexer.Connect(options)) - { - if (!setEnv) Assert.Fail(); - - var db = conn.GetDatabase(); - db.KeyDelete(key); - string s = db.StringGet(key); - Assert.IsNull(s); - db.StringSet(key, "abc"); - s = db.StringGet(key); - Assert.AreEqual("abc", s); - - var latency = db.Ping(); - Console.WriteLine("RedisLabs latency: {0:###,##0.##}ms", latency.TotalMilliseconds); - - using (var file = File.Create("RedisLabs.zip")) - { - conn.ExportConfiguration(file); - } - } - } - catch(RedisConnectionException ex) - { - if(setEnv || ex.FailureType != ConnectionFailureType.UnableToConnect) - { - throw; - } - } - finally - { - Environment.SetEnvironmentVariable("SERedis_ClientCertPfxPath", null); - } - - } - - [Test] - public void SSLHostInferredFromEndpoints() { - var options = new ConfigurationOptions() { - EndPoints = { - { "mycache.rediscache.windows.net", 15000}, - { "mycache.rediscache.windows.net", 15001 }, - { "mycache.rediscache.windows.net", 15002 }, - } - }; - options.Ssl = true; - Assert.True(options.SslHost == "mycache.rediscache.windows.net"); - options = new ConfigurationOptions() { - EndPoints = { - { "121.23.23.45", 15000}, - } - }; - Assert.True(options.SslHost == null); - } - - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Scans.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Scans.cs deleted file mode 100644 index c05ad24..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Scans.cs +++ /dev/null @@ -1,358 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Scans : TestBase - { - [Test] - [TestCase(true)] - [TestCase(false)] - public void KeysScan(bool supported) - { - string[] disabledCommands = supported ? null : new[] { "scan" }; - using (var conn = Create(disabledCommands: disabledCommands, allowAdmin: true)) - { - const int DB = 7; - var db = conn.GetDatabase(DB); - var server = GetServer(conn); - server.FlushDatabase(DB); - for(int i = 0 ; i < 100 ; i++) - { - db.StringSet("KeysScan:" + i, Guid.NewGuid().ToString(), flags: CommandFlags.FireAndForget); - } - var seq = server.Keys(DB, pageSize:50); - bool isScanning = seq is IScanningCursor; - Assert.AreEqual(supported, isScanning, "scanning"); - Assert.AreEqual(100, seq.Distinct().Count()); - Assert.AreEqual(100, seq.Distinct().Count()); - Assert.AreEqual(100, server.Keys(DB, "KeysScan:*").Distinct().Count()); - // 7, 70, 71, ..., 79 - Assert.AreEqual(11, server.Keys(DB, "KeysScan:7*").Distinct().Count()); - } - } - - - public void ScansIScanning() - { - using (var conn = Create(allowAdmin: true)) - { - const int DB = 7; - var db = conn.GetDatabase(DB); - var server = GetServer(conn); - server.FlushDatabase(DB); - for (int i = 0; i < 100; i++) - { - db.StringSet("ScansRepeatable:" + i, Guid.NewGuid().ToString(), flags: CommandFlags.FireAndForget); - } - var seq = server.Keys(DB, pageSize: 15); - using(var iter = seq.GetEnumerator()) - { - IScanningCursor s0 = (IScanningCursor)seq, s1 = (IScanningCursor)iter; - - Assert.AreEqual(15, s0.PageSize); - Assert.AreEqual(15, s1.PageSize); - - // start at zero - Assert.AreEqual(0, s0.Cursor); - Assert.AreEqual(s0.Cursor, s1.Cursor); - - for(int i = 0 ; i < 47 ; i++) - { - Assert.IsTrue(iter.MoveNext()); - } - - // non-zero in the middle - Assert.AreNotEqual(0, s0.Cursor); - Assert.AreEqual(s0.Cursor, s1.Cursor); - - for (int i = 0; i < 53; i++) - { - Assert.IsTrue(iter.MoveNext()); - } - - // zero "next" at the end - Assert.IsFalse(iter.MoveNext()); - Assert.AreNotEqual(0, s0.Cursor); - Assert.AreNotEqual(0, s1.Cursor); - } - } - } - - public void ScanResume() - { - using (var conn = Create(allowAdmin: true)) - { - const int DB = 7; - var db = conn.GetDatabase(DB); - var server = GetServer(conn); - server.FlushDatabase(DB); - int i; - for (i = 0; i < 100; i++) - { - db.StringSet("ScanResume:" + i, Guid.NewGuid().ToString(), flags: CommandFlags.FireAndForget); - } - - var expected = new HashSet(); - long snapCursor = 0; - int snapOffset = 0, snapPageSize = 0; - - i = 0; - var seq = server.Keys(DB, pageSize: 15); - foreach(var key in seq) - { - i++; - if (i < 57) continue; - if (i == 57) - { - snapCursor = ((IScanningCursor)seq).Cursor; - snapOffset = ((IScanningCursor)seq).PageOffset; - snapPageSize = ((IScanningCursor)seq).PageSize; - } - expected.Add((string)key); - } - Assert.AreNotEqual(43, expected.Count); - Assert.AreNotEqual(0, snapCursor); - Assert.AreEqual(11, snapOffset); - Assert.AreEqual(15, snapPageSize); - - seq = server.Keys(DB, pageSize: 15, cursor: snapCursor, pageOffset: snapOffset); - var seqCur = (IScanningCursor)seq; - Assert.AreEqual(snapCursor, seqCur.Cursor); - Assert.AreEqual(snapPageSize, seqCur.PageSize); - Assert.AreEqual(snapOffset, seqCur.PageOffset); - using(var iter = seq.GetEnumerator()) - { - var iterCur = (IScanningCursor)iter; - Assert.AreEqual(snapCursor, iterCur.Cursor); - Assert.AreEqual(snapOffset, iterCur.PageOffset); - Assert.AreEqual(snapCursor, seqCur.Cursor); - Assert.AreEqual(snapOffset, seqCur.PageOffset); - - Assert.IsTrue(iter.MoveNext()); - Assert.AreEqual(snapCursor, iterCur.Cursor); - Assert.AreEqual(snapOffset, iterCur.PageOffset); - Assert.AreEqual(snapCursor, seqCur.Cursor); - Assert.AreEqual(snapOffset, seqCur.PageOffset); - - Assert.IsTrue(iter.MoveNext()); - Assert.AreEqual(snapCursor, iterCur.Cursor); - Assert.AreEqual(snapOffset + 1, iterCur.PageOffset); - Assert.AreEqual(snapCursor, seqCur.Cursor); - Assert.AreEqual(snapOffset + 1, seqCur.PageOffset); - } - - int count = 0; - foreach(var key in seq) - { - expected.Remove((string)key); - count++; - } - Assert.AreEqual(0, expected.Count); - Assert.AreEqual(44, count); // expect the initial item to be repeated - - } - } - - - - - [Test] - [TestCase(true)] - [TestCase(false)] - public void SetScan(bool supported) - { - string[] disabledCommands = supported ? null : new[] { "sscan" }; - using(var conn = Create(disabledCommands: disabledCommands)) - { - RedisKey key = Me(); - var db = conn.GetDatabase(); - db.KeyDelete(key); - - db.SetAdd(key, "a"); - db.SetAdd(key, "b"); - db.SetAdd(key, "c"); - var arr = db.SetScan(key).ToArray(); - Assert.AreEqual(3, arr.Length); - Assert.IsTrue(arr.Contains("a"), "a"); - Assert.IsTrue(arr.Contains("b"), "b"); - Assert.IsTrue(arr.Contains("c"), "c"); - } - } - - [Test] - [TestCase(true)] - [TestCase(false)] - public void SortedSetScan(bool supported) - { - string[] disabledCommands = supported ? null : new[] { "zscan" }; - using (var conn = Create(disabledCommands: disabledCommands)) - { - RedisKey key = Me(); - var db = conn.GetDatabase(); - db.KeyDelete(key); - - db.SortedSetAdd(key, "a", 1); - db.SortedSetAdd(key, "b", 2); - db.SortedSetAdd(key, "c", 3); - - var arr = db.SortedSetScan(key).ToArray(); - Assert.AreEqual(3, arr.Length); - Assert.IsTrue(arr.Any(x => x.Element == "a" && x.Score == 1), "a"); - Assert.IsTrue(arr.Any(x => x.Element == "b" && x.Score == 2), "b"); - Assert.IsTrue(arr.Any(x => x.Element == "c" && x.Score == 3), "c"); - - var dictionary = arr.ToDictionary(); - Assert.AreEqual(1, dictionary["a"]); - Assert.AreEqual(2, dictionary["b"]); - Assert.AreEqual(3, dictionary["c"]); - - var sDictionary = arr.ToStringDictionary(); - Assert.AreEqual(1, sDictionary["a"]); - Assert.AreEqual(2, sDictionary["b"]); - Assert.AreEqual(3, sDictionary["c"]); - - var basic = db.SortedSetRangeByRankWithScores(key, order: Order.Ascending).ToDictionary(); - Assert.AreEqual(3, basic.Count); - Assert.AreEqual(1, basic["a"]); - Assert.AreEqual(2, basic["b"]); - Assert.AreEqual(3, basic["c"]); - - basic = db.SortedSetRangeByRankWithScores(key, order: Order.Descending).ToDictionary(); - Assert.AreEqual(3, basic.Count); - Assert.AreEqual(1, basic["a"]); - Assert.AreEqual(2, basic["b"]); - Assert.AreEqual(3, basic["c"]); - - var basicArr = db.SortedSetRangeByScoreWithScores(key, order: Order.Ascending); - Assert.AreEqual(3, basicArr.Length); - Assert.AreEqual(1, basicArr[0].Score); - Assert.AreEqual(2, basicArr[1].Score); - Assert.AreEqual(3, basicArr[2].Score); - basic = basicArr.ToDictionary(); - Assert.AreEqual(3, basic.Count, "asc"); - Assert.AreEqual(1, basic["a"]); - Assert.AreEqual(2, basic["b"]); - Assert.AreEqual(3, basic["c"]); - - basicArr = db.SortedSetRangeByScoreWithScores(key, order: Order.Descending); - Assert.AreEqual(3, basicArr.Length); - Assert.AreEqual(3, basicArr[0].Score); - Assert.AreEqual(2, basicArr[1].Score); - Assert.AreEqual(1, basicArr[2].Score); - basic = basicArr.ToDictionary(); - Assert.AreEqual(3, basic.Count, "desc"); - Assert.AreEqual(1, basic["a"]); - Assert.AreEqual(2, basic["b"]); - Assert.AreEqual(3, basic["c"]); - } - } - - [Test] - [TestCase(true)] - [TestCase(false)] - public void HashScan(bool supported) - { - string[] disabledCommands = supported ? null : new[] { "hscan" }; - using (var conn = Create(disabledCommands: disabledCommands)) - { - RedisKey key = Me(); - var db = conn.GetDatabase(); - db.KeyDelete(key); - - db.HashSet(key, "a", "1"); - db.HashSet(key, "b", "2"); - db.HashSet(key, "c", "3"); - - var arr = db.HashScan(key).ToArray(); - Assert.AreEqual(3, arr.Length); - Assert.IsTrue(arr.Any(x => x.Name == "a" && x.Value == "1"), "a"); - Assert.IsTrue(arr.Any(x => x.Name == "b" && x.Value == "2"), "b"); - Assert.IsTrue(arr.Any(x => x.Name == "c" && x.Value == "3"), "c"); - - var dictionary = arr.ToDictionary(); - Assert.AreEqual(1, (long)dictionary["a"]); - Assert.AreEqual(2, (long)dictionary["b"]); - Assert.AreEqual(3, (long)dictionary["c"]); - - var sDictionary = arr.ToStringDictionary(); - Assert.AreEqual("1", sDictionary["a"]); - Assert.AreEqual("2", sDictionary["b"]); - Assert.AreEqual("3", sDictionary["c"]); - - - var basic = db.HashGetAll(key).ToDictionary(); - Assert.AreEqual(3, basic.Count); - Assert.AreEqual(1, (long)basic["a"]); - Assert.AreEqual(2, (long)basic["b"]); - Assert.AreEqual(3, (long)basic["c"]); - } - } - - [Test] - [TestCase(10)] - [TestCase(100)] - [TestCase(1000)] - [TestCase(10000)] - public void HashScanLarge(int pageSize) - { - using (var conn = Create()) - { - RedisKey key = Me(); - var db = conn.GetDatabase(); - db.KeyDelete(key); - - for(int i = 0; i < 2000;i++) - db.HashSet(key, "k" + i, "v" + i, flags: CommandFlags.FireAndForget); - - int count = db.HashScan(key, pageSize: pageSize).Count(); - Assert.AreEqual(2000, count); - } - } - - [Test] - [TestCase(10)] - [TestCase(100)] - [TestCase(1000)] - [TestCase(10000)] - public void SetScanLarge(int pageSize) - { - using (var conn = Create()) - { - RedisKey key = Me(); - var db = conn.GetDatabase(); - db.KeyDelete(key); - - for (int i = 0; i < 2000; i++) - db.SetAdd(key, "s" + i, flags: CommandFlags.FireAndForget); - - int count = db.SetScan(key, pageSize: pageSize).Count(); - Assert.AreEqual(2000, count); - } - } - - [Test] - [TestCase(10)] - [TestCase(100)] - [TestCase(1000)] - [TestCase(10000)] - public void SortedSetScanLarge(int pageSize) - { - using (var conn = Create()) - { - RedisKey key = Me(); - var db = conn.GetDatabase(); - db.KeyDelete(key); - - for (int i = 0; i < 2000; i++) - db.SortedSetAdd(key, "z" + i, i, flags: CommandFlags.FireAndForget); - - int count = db.SortedSetScan(key, pageSize: pageSize).Count(); - Assert.AreEqual(2000, count); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Scripting.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Scripting.cs deleted file mode 100644 index 8d2c398..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Scripting.cs +++ /dev/null @@ -1,513 +0,0 @@ -using System; -using System.Diagnostics; -using System.Linq; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Scripting : TestBase - { - [Test] - public void TestBasicScripting() - { - using (var conn = Create()) - { - RedisValue newId = Guid.NewGuid().ToString(); - RedisKey custKey = Me(); - var db = conn.GetDatabase(); - db.KeyDelete(custKey); - db.HashSet(custKey, "id", 123); - - var wasSet = (bool) db.ScriptEvaluate(@"if redis.call('hexists', KEYS[1], 'UniqueId') then return redis.call('hset', KEYS[1], 'UniqueId', ARGV[1]) else return 0 end", - new RedisKey[] { custKey }, new RedisValue[] { newId }); - - Assert.IsTrue(wasSet); - - wasSet = (bool)db.ScriptEvaluate(@"if redis.call('hexists', KEYS[1], 'UniqueId') then return redis.call('hset', KEYS[1], 'UniqueId', ARGV[1]) else return 0 end", - new RedisKey[] { custKey }, new RedisValue[] { newId }); - Assert.IsFalse(wasSet); - } - } - - [Test] - [TestCase(true)] - [TestCase(false)] - public void CheckLoads(bool async) - { - using (var conn0 = Create(allowAdmin: true)) - using (var conn1 = Create(allowAdmin: true)) - { - // note that these are on different connections (so we wouldn't expect - // the flush to drop the local cache - assume it is a surprise!) - var server = conn0.GetServer(PrimaryServer, PrimaryPort); - var db = conn1.GetDatabase(); - const string script = "return 1;"; - - // start empty - server.ScriptFlush(); - Assert.IsFalse(server.ScriptExists(script)); - - // run once, causes to be cached - Assert.IsTrue((bool)db.ScriptEvaluate(script)); - Assert.IsTrue(server.ScriptExists(script)); - - // can run again - Assert.IsTrue((bool)db.ScriptEvaluate(script)); - - // ditch the scripts; should no longer exist - db.Ping(); - server.ScriptFlush(); - Assert.IsFalse(server.ScriptExists(script)); - db.Ping(); - - if (async) - { - // now: fails the first time - try - { - db.Wait(db.ScriptEvaluateAsync(script)); - Assert.Fail(); - } - catch(AggregateException ex) - { - Assert.AreEqual(1, ex.InnerExceptions.Count); - Assert.IsInstanceOf(ex.InnerExceptions[0]); - Assert.AreEqual("NOSCRIPT No matching script. Please use EVAL.", ex.InnerExceptions[0].Message); - } - } else - { - // just works; magic - Assert.IsTrue((bool)db.ScriptEvaluate(script)); - } - - // but gets marked as unloaded, so we can use it again... - Assert.IsTrue((bool)db.ScriptEvaluate(script)); - - // which will cause it to be cached - Assert.IsTrue(server.ScriptExists(script)); - } - } - - [Test] - public void CompareScriptToDirect() - { - const string Script = "return redis.call('incr', KEYS[1])"; - - using (var conn = Create(allowAdmin: true)) - { - var server = conn.GetServer(PrimaryServer, PrimaryPort); - server.FlushAllDatabases(); - server.ScriptFlush(); - - server.ScriptLoad(Script); - var db = conn.GetDatabase(); - db.Ping(); // k, we're all up to date now; clean db, minimal script cache - - // we're using a pipeline here, so send 1000 messages, but for timing: only care about the last - const int LOOP = 5000; - RedisKey key = "foo"; - RedisKey[] keys = new[] { key }; // script takes an array - - // run via script - db.KeyDelete(key); - CollectGarbage(); - var watch = Stopwatch.StartNew(); - for(int i = 1; i < LOOP; i++) // the i=1 is to do all-but-one - { - db.ScriptEvaluate(Script, keys, flags: CommandFlags.FireAndForget); - } - var scriptResult = db.ScriptEvaluate(Script, keys); // last one we wait for (no F+F) - watch.Stop(); - TimeSpan scriptTime = watch.Elapsed; - - // run via raw op - db.KeyDelete(key); - CollectGarbage(); - watch = Stopwatch.StartNew(); - for (int i = 1; i < LOOP; i++) // the i=1 is to do all-but-one - { - db.StringIncrement(key, flags: CommandFlags.FireAndForget); - } - var directResult = db.StringIncrement(key); // last one we wait for (no F+F) - watch.Stop(); - TimeSpan directTime = watch.Elapsed; - - Assert.AreEqual(LOOP, (long)scriptResult, "script result"); - Assert.AreEqual(LOOP, (long)directResult, "direct result"); - - Console.WriteLine("script: {0}ms; direct: {1}ms", - scriptTime.TotalMilliseconds, - directTime.TotalMilliseconds); - } - } - - [Test] - public void TestCallByHash() - { - const string Script = "return redis.call('incr', KEYS[1])"; - - using (var conn = Create(allowAdmin: true)) - { - var server = conn.GetServer(PrimaryServer, PrimaryPort); - server.FlushAllDatabases(); - server.ScriptFlush(); - - byte[] hash = server.ScriptLoad(Script); - - var db = conn.GetDatabase(); - RedisKey[] keys = { Me() }; - - string hexHash = string.Concat(hash.Select(x => x.ToString("X2"))); - Assert.AreEqual("2BAB3B661081DB58BD2341920E0BA7CF5DC77B25", hexHash); - - db.ScriptEvaluate(hexHash, keys); - db.ScriptEvaluate(hash, keys); - - var count = (int)db.StringGet(keys)[0]; - Assert.AreEqual(2, count); - - } - } - - [Test] - public void SimpleLuaScript() - { - const string Script = "return @ident"; - - using(var conn = Create(allowAdmin: true)) - { - var server = conn.GetServer(PrimaryServer, PrimaryPort); - server.FlushAllDatabases(); - server.ScriptFlush(); - - var prepared = LuaScript.Prepare(Script); - - var db = conn.GetDatabase(); - - { - var val = prepared.Evaluate(db, new { ident = "hello" }); - Assert.AreEqual("hello", (string)val); - } - - { - var val = prepared.Evaluate(db, new { ident = 123 }); - Assert.AreEqual(123, (int)val); - } - - { - var val = prepared.Evaluate(db, new { ident = 123L }); - Assert.AreEqual(123L, (long)val); - } - - { - var val = prepared.Evaluate(db, new { ident = 1.1 }); - Assert.AreEqual(1.1, (double)val); - } - - { - var val = prepared.Evaluate(db, new { ident = true }); - Assert.AreEqual(true, (bool)val); - } - - { - var val = prepared.Evaluate(db, new { ident = new byte[] { 4, 5, 6 } }); - Assert.IsTrue(new byte [] { 4, 5, 6}.SequenceEqual((byte[])val)); - } - } - } - - [Test] - public void LuaScriptWithKeys() - { - const string Script = "redis.call('set', @key, @value)"; - - using (var conn = Create(allowAdmin: true)) - { - var server = conn.GetServer(PrimaryServer, PrimaryPort); - server.FlushAllDatabases(); - server.ScriptFlush(); - - var script = LuaScript.Prepare(Script); - - var db = conn.GetDatabase(); - - var p = new { key = (RedisKey)"testkey", value = 123 }; - - script.Evaluate(db, p); - var val = db.StringGet("testkey"); - Assert.AreEqual(123, (int)val); - - // no super clean way to extract this; so just abuse InternalsVisibleTo - RedisKey[] keys; - RedisValue[] args; - script.ExtractParameters(p, null, out keys, out args); - Assert.IsNotNull(keys); - Assert.AreEqual(1, keys.Length); - Assert.AreEqual("testkey", (string)keys[0]); - } - } - - [Test] - public void NoInlineReplacement() - { - const string Script = "redis.call('set', @key, 'hello@example')"; - using (var conn = Create(allowAdmin: true)) - { - var server = conn.GetServer(PrimaryServer, PrimaryPort); - server.FlushAllDatabases(); - server.ScriptFlush(); - - var script = LuaScript.Prepare(Script); - - Assert.AreEqual("redis.call('set', ARGV[1], 'hello@example')", script.ExecutableScript); - - var db = conn.GetDatabase(); - - var p = new { key = (RedisKey)"key" }; - - script.Evaluate(db, p); - var val = db.StringGet("key"); - Assert.AreEqual("hello@example", (string)val); - } - } - - [Test] - public void EscapeReplacement() - { - const string Script = "redis.call('set', @key, @@escapeMe)"; - var script = LuaScript.Prepare(Script); - - Assert.AreEqual("redis.call('set', ARGV[1], @escapeMe)", script.ExecutableScript); - } - - [Test] - public void SimpleLoadedLuaScript() - { - const string Script = "return @ident"; - - using (var conn = Create(allowAdmin: true)) - { - var server = conn.GetServer(PrimaryServer, PrimaryPort); - server.FlushAllDatabases(); - server.ScriptFlush(); - - var prepared = LuaScript.Prepare(Script); - var loaded = prepared.Load(server); - - var db = conn.GetDatabase(); - - { - var val = loaded.Evaluate(db, new { ident = "hello" }); - Assert.AreEqual("hello", (string)val); - } - - { - var val = loaded.Evaluate(db, new { ident = 123 }); - Assert.AreEqual(123, (int)val); - } - - { - var val = loaded.Evaluate(db, new { ident = 123L }); - Assert.AreEqual(123L, (long)val); - } - - { - var val = loaded.Evaluate(db, new { ident = 1.1 }); - Assert.AreEqual(1.1, (double)val); - } - - { - var val = loaded.Evaluate(db, new { ident = true }); - Assert.AreEqual(true, (bool)val); - } - - { - var val = loaded.Evaluate(db, new { ident = new byte[] { 4, 5, 6 } }); - Assert.IsTrue(new byte[] { 4, 5, 6 }.SequenceEqual((byte[])val)); - } - } - } - - [Test] - public void LoadedLuaScriptWithKeys() - { - const string Script = "redis.call('set', @key, @value)"; - - using (var conn = Create(allowAdmin: true)) - { - var server = conn.GetServer(PrimaryServer, PrimaryPort); - server.FlushAllDatabases(); - server.ScriptFlush(); - - var script = LuaScript.Prepare(Script); - var prepared = script.Load(server); - - var db = conn.GetDatabase(); - - var p = new { key = (RedisKey)"testkey", value = 123 }; - - prepared.Evaluate(db, p); - var val = db.StringGet("testkey"); - Assert.AreEqual(123, (int)val); - - // no super clean way to extract this; so just abuse InternalsVisibleTo - RedisKey[] keys; - RedisValue[] args; - prepared.Original.ExtractParameters(p, null, out keys, out args); - Assert.IsNotNull(keys); - Assert.AreEqual(1, keys.Length); - Assert.AreEqual("testkey", (string)keys[0]); - } - } - - [Test] - public void PurgeLuaScriptCache() - { - const string Script = "redis.call('set', @PurgeLuaScriptCacheKey, @PurgeLuaScriptCacheValue)"; - var first = LuaScript.Prepare(Script); - var fromCache = LuaScript.Prepare(Script); - - Assert.IsTrue(object.ReferenceEquals(first, fromCache)); - - LuaScript.PurgeCache(); - var shouldBeNew = LuaScript.Prepare(Script); - - Assert.IsFalse(object.ReferenceEquals(first, shouldBeNew)); - } - - static void _PurgeLuaScriptOnFinalize(string script) - { - var first = LuaScript.Prepare(script); - var fromCache = LuaScript.Prepare(script); - Assert.IsTrue(object.ReferenceEquals(first, fromCache)); - Assert.AreEqual(1, LuaScript.GetCachedScriptCount()); - } - - [Test] - public void PurgeLuaScriptOnFinalize() - { - const string Script = "redis.call('set', @PurgeLuaScriptOnFinalizeKey, @PurgeLuaScriptOnFinalizeValue)"; - LuaScript.PurgeCache(); - Assert.AreEqual(0, LuaScript.GetCachedScriptCount()); - - // This has to be a separate method to guarantee that the created LuaScript objects go out of scope, - // and are thus available to be GC'd - _PurgeLuaScriptOnFinalize(Script); - - GC.Collect(2, GCCollectionMode.Forced, blocking: true); - GC.WaitForPendingFinalizers(); - - Assert.AreEqual(0, LuaScript.GetCachedScriptCount()); - - var shouldBeNew = LuaScript.Prepare(Script); - Assert.AreEqual(1, LuaScript.GetCachedScriptCount()); - } - - [Test] - public void IDatabaseLuaScriptConvenienceMethods() - { - const string Script = "redis.call('set', @key, @value)"; - - using (var conn = Create(allowAdmin: true)) - { - var script = LuaScript.Prepare(Script); - var db = conn.GetDatabase(); - db.ScriptEvaluate(script, new { key = (RedisKey)"key", value = "value" }); - var val = db.StringGet("key"); - Assert.AreEqual("value", (string)val); - - var prepared = script.Load(conn.GetServer(conn.GetEndPoints()[0])); - - db.ScriptEvaluate(prepared, new { key = (RedisKey)"key2", value = "value2" }); - var val2 = db.StringGet("key2"); - Assert.AreEqual("value2", (string)val2); - } - } - - [Test] - public void IServerLuaScriptConvenienceMethods() - { - const string Script = "redis.call('set', @key, @value)"; - - using (var conn = Create(allowAdmin: true)) - { - var script = LuaScript.Prepare(Script); - var server = conn.GetServer(conn.GetEndPoints()[0]); - var db = conn.GetDatabase(); - - var prepared = server.ScriptLoad(script); - - db.ScriptEvaluate(prepared, new { key = (RedisKey)"key3", value = "value3" }); - var val = db.StringGet("key3"); - Assert.AreEqual("value3", (string)val); - } - } - - [Test] - public void LuaScriptPrefixedKeys() - { - const string Script = "redis.call('set', @key, @value)"; - var prepared = LuaScript.Prepare(Script); - var p = new { key = (RedisKey)"key", value = "hello" }; - - // no super clean way to extract this; so just abuse InternalsVisibleTo - RedisKey[] keys; - RedisValue[] args; - prepared.ExtractParameters(p, "prefix-", out keys, out args); - Assert.IsNotNull(keys); - Assert.AreEqual(1, keys.Length); - Assert.AreEqual("prefix-key", (string)keys[0]); - Assert.AreEqual(2, args.Length); - Assert.AreEqual("prefix-key", (string)args[0]); - Assert.AreEqual("hello", (string)args[1]); - } - - [Test] - public void LuaScriptWithWrappedDatabase() - { - const string Script = "redis.call('set', @key, @value)"; - - using (var conn = Create(allowAdmin: true)) - { - var db = conn.GetDatabase(0); - var wrappedDb = StackExchange.Redis.KeyspaceIsolation.DatabaseExtensions.WithKeyPrefix(db, "prefix-"); - - var prepared = LuaScript.Prepare(Script); - wrappedDb.ScriptEvaluate(prepared, new { key = (RedisKey)"mykey", value = 123 }); - var val1 = wrappedDb.StringGet("mykey"); - Assert.AreEqual(123, (int)val1); - - var val2 = db.StringGet("prefix-mykey"); - Assert.AreEqual(123, (int)val2); - - var val3 = db.StringGet("mykey"); - Assert.IsTrue(val3.IsNull); - } - } - - [Test] - public void LoadedLuaScriptWithWrappedDatabase() - { - const string Script = "redis.call('set', @key, @value)"; - - using (var conn = Create(allowAdmin: true)) - { - var db = conn.GetDatabase(0); - var wrappedDb = StackExchange.Redis.KeyspaceIsolation.DatabaseExtensions.WithKeyPrefix(db, "prefix2-"); - - var server = conn.GetServer(conn.GetEndPoints()[0]); - var prepared = LuaScript.Prepare(Script).Load(server); - wrappedDb.ScriptEvaluate(prepared, new { key = (RedisKey)"mykey", value = 123 }); - var val1 = wrappedDb.StringGet("mykey"); - Assert.AreEqual(123, (int)val1); - - var val2 = db.StringGet("prefix2-mykey"); - Assert.AreEqual(123, (int)val2); - - var val3 = db.StringGet("mykey"); - Assert.IsTrue(val3.IsNull); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Secure.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Secure.cs deleted file mode 100644 index 633e7d6..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Secure.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.Diagnostics; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Secure : TestBase - { - protected override string GetConfiguration() - { - return PrimaryServer + ":" + SecurePort + ",password=" + SecurePassword +",name=MyClient"; - } - - [Test] - [TestCase(true)] - [TestCase(false)] - public void MassiveBulkOpsFireAndForgetSecure(bool preserveOrder) - { - using (var muxer = Create()) - { - muxer.PreserveAsyncOrder = preserveOrder; -#if DEBUG - long oldAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount(); -#endif - RedisKey key = "MBOF"; - var conn = muxer.GetDatabase(); - conn.Ping(); - - var watch = Stopwatch.StartNew(); - - for (int i = 0; i <= AsyncOpsQty; i++) - { - conn.StringSet(key, i, flags: CommandFlags.FireAndForget); - } - int val = (int)conn.StringGet(key); - Assert.AreEqual(AsyncOpsQty, val); - watch.Stop(); - Console.WriteLine("{2}: Time for {0} ops: {1}ms ({3}); ops/s: {4}", AsyncOpsQty, watch.ElapsedMilliseconds, Me(), - preserveOrder ? "preserve order" : "any order", - AsyncOpsQty / watch.Elapsed.TotalSeconds); -#if DEBUG - long newAlloc = ConnectionMultiplexer.GetResultBoxAllocationCount(); - Console.WriteLine("ResultBox allocations: {0}", - newAlloc - oldAlloc); - Assert.IsTrue(newAlloc - oldAlloc <= 2); -#endif - } - } - - [Test] - public void CheckConfig() - { - var config = ConfigurationOptions.Parse(GetConfiguration()); - foreach(var ep in config.EndPoints) - Console.WriteLine(ep); - Assert.AreEqual(1, config.EndPoints.Count); - Assert.AreEqual("changeme", config.Password); - } - [Test] - public void Connect() - { - using(var server = Create()) - { - server.GetDatabase().Ping(); - } - } - [Test] - [TestCase("wrong")] - [TestCase("")] - public void ConnectWithWrongPassword(string password) - { - Assert.Throws(() => { - SetExpectedAmbientFailureCount(-1); - using (var server = Create(password: password, checkConnect: false)) - { - server.GetDatabase().Ping(); - } - }, - "No connection is available to service this operation: PING"); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Sentinel.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Sentinel.cs deleted file mode 100644 index b244762..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Sentinel.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Linq; -using System.Net; -using System.Threading; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture, Ignore("reason?")] - public class Sentinel - { - // TODO fill in these constants before running tests - private const string IP = "127.0.0.1"; - private const int Port = 26379; - private const string ServiceName = "mymaster"; - - private static readonly ConnectionMultiplexer Conn = GetConn(); - private static readonly IServer Server = Conn.GetServer(IP, Port); - - public static ConnectionMultiplexer GetConn() - { - // create a connection - var options = new ConfigurationOptions() - { - CommandMap = CommandMap.Sentinel, - EndPoints = { { IP, Port } }, - AllowAdmin = true, - TieBreaker = "", - ServiceName = ServiceName, - SyncTimeout = 5000 - }; - var connection = ConnectionMultiplexer.Connect(options, Console.Out); - Thread.Sleep(3000); - Assert.IsTrue(connection.IsConnected); - return connection; - } - - [Test] - public void PingTest() - { - var test = Server.Ping(); - Console.WriteLine("ping took {0} ms", test.TotalMilliseconds); - } - - [Test] - public void SentinelGetMasterAddressByNameTest() - { - var endpoint = Server.SentinelGetMasterAddressByName(ServiceName); - Assert.IsNotNull(endpoint); - var ipEndPoint = endpoint as IPEndPoint; - Assert.IsNotNull(ipEndPoint); - Console.WriteLine("{0}:{1}", ipEndPoint.Address, ipEndPoint.Port); - } - - [Test] - public void SentinelGetMasterAddressByNameNegativeTest() - { - var endpoint = Server.SentinelGetMasterAddressByName("FakeServiceName"); - Assert.IsNull(endpoint); - } - - [Test] - public void SentinelMasterTest() - { - var dict = Server.SentinelMaster(ServiceName).ToDictionary(); - Assert.AreEqual(ServiceName, dict["name"]); - foreach (var kvp in dict) - { - Console.WriteLine("{0}:{1}", kvp.Key, kvp.Value); - } - } - - [Test] - public void SentinelMastersTest() - { - var masterConfigs = Server.SentinelMasters(); - Assert.IsTrue(masterConfigs.First().ToDictionary().ContainsKey("name")); - foreach (var config in masterConfigs) - { - foreach (var kvp in config) - { - Console.WriteLine("{0}:{1}", kvp.Key, kvp.Value); - } - } - } - - [Test] - public void SentinelSlavesTest() - { - var slaveConfigs = Server.SentinelSlaves(ServiceName); - if (slaveConfigs.Any()) - { - Assert.IsTrue(slaveConfigs.First().ToDictionary().ContainsKey("name")); - } - foreach (var config in slaveConfigs) - { - foreach (var kvp in config) { - Console.WriteLine("{0}:{1}", kvp.Key, kvp.Value); - } - } - } - - [Test, Ignore("reason?")] - public void SentinelFailoverTest() - { - Server.SentinelFailover(ServiceName); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Sets.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Sets.cs deleted file mode 100644 index 0654a28..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Sets.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Linq; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Sets : TestBase - { - [Test] - public void SScan() - { - using (var conn = Create()) - { - var server = GetServer(conn); - - - RedisKey key = "a"; - var db = conn.GetDatabase(); - db.KeyDelete(key); - - int totalUnfiltered = 0, totalFiltered = 0; - for (int i = 0; i < 1000; i++) - { - db.SetAdd(key, i); - totalUnfiltered += i; - if (i.ToString().Contains("3")) totalFiltered += i; - } - var unfilteredActual = db.SetScan(key).Select(x => (int)x).Sum(); - Assert.AreEqual(totalUnfiltered, unfilteredActual); - if (server.Features.Scan) - { - var filteredActual = db.SetScan(key, "*3*").Select(x => (int)x).Sum(); - Assert.AreEqual(totalFiltered, filteredActual); - } - - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/StackExchange.Redis.Tests.csproj b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/StackExchange.Redis.Tests.csproj deleted file mode 100644 index 6ace5f7..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/StackExchange.Redis.Tests.csproj +++ /dev/null @@ -1,47 +0,0 @@ - - - - StackExchange.Redis.Tests - netcoreapp1.0 - $(TargetFramework) - StackExchange.Redis.Tests - StackExchange.Redis.Tests - true - false - $(PackageTargetFallback);portable-net45+win8 - 1.0.4 - false - false - false - false - false - false - false - false - - - - - - - - - - - - - - - $(DefineConstants);CORE_CLR - - - - - - - - - - - - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TaskTests.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TaskTests.cs deleted file mode 100644 index 04d958b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TaskTests.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class TaskTests - { -#if DEBUG - -#if !PLAT_SAFE_CONTINUATIONS // IsSyncSafe doesn't exist if PLAT_SAFE_CONTINUATIONS is defined - [Test] - [TestCase(SourceOrign.NewTCS, false)] - [TestCase(SourceOrign.Create, false)] - [TestCase(SourceOrign.CreateDenyExec, true)] - public void VerifyIsSyncSafe(SourceOrign origin, bool expected) - { - var source = Create(origin); - Assert.AreEqual(expected, TaskSource.IsSyncSafe(source.Task)); - } -#endif - static TaskCompletionSource Create(SourceOrign origin) - { - switch (origin) - { - case SourceOrign.NewTCS: return new TaskCompletionSource(); - case SourceOrign.Create: return TaskSource.Create(null); - case SourceOrign.CreateDenyExec: return TaskSource.CreateDenyExecSync(null); - default: throw new ArgumentOutOfRangeException(nameof(origin)); - } - } - [Test] - // regular framework behaviour: 2 out of 3 cause hijack - [TestCase(SourceOrign.NewTCS, AttachMode.ContinueWith, false)] - [TestCase(SourceOrign.NewTCS, AttachMode.ContinueWithExecSync, true)] - [TestCase(SourceOrign.NewTCS, AttachMode.Await, true)] - // Create is just a wrapper of ^^^; expect the same - [TestCase(SourceOrign.Create, AttachMode.ContinueWith, false)] - [TestCase(SourceOrign.Create, AttachMode.ContinueWithExecSync, true)] - [TestCase(SourceOrign.Create, AttachMode.Await, true)] - // deny exec-sync: none should cause hijack - [TestCase(SourceOrign.CreateDenyExec, AttachMode.ContinueWith, false)] - [TestCase(SourceOrign.CreateDenyExec, AttachMode.ContinueWithExecSync, false)] - [TestCase(SourceOrign.CreateDenyExec, AttachMode.Await, false)] - public void TestContinuationHijacking(SourceOrign origin, AttachMode attachMode, bool expectHijack) - { - TaskCompletionSource source = Create(origin); - - int settingThread = Environment.CurrentManagedThreadId; - var state = new AwaitState(); - state.Attach(source.Task, attachMode); - source.TrySetResult(123); - state.Wait(); // waits for the continuation to run - int from = state.Thread; - Assert.AreNotEqual(-1, from, "not set"); - if (expectHijack) - { - Assert.AreEqual(settingThread, from, "expected hijack; didn't happen"); - } - else - { - Assert.AreNotEqual(settingThread, from, "setter was hijacked"); - } - } - public enum SourceOrign - { - NewTCS, - Create, - CreateDenyExec - } - public enum AttachMode - { - ContinueWith, - ContinueWithExecSync, - Await - } - class AwaitState - { - public int Thread => continuationThread; - volatile int continuationThread = -1; - private ManualResetEventSlim evt = new ManualResetEventSlim(); - public void Wait() - { - if (!evt.Wait(5000)) throw new TimeoutException(); - } - public void Attach(Task task, AttachMode attachMode) - { - switch(attachMode) - { - case AttachMode.ContinueWith: - task.ContinueWith(Continue); - break; - case AttachMode.ContinueWithExecSync: - task.ContinueWith(Continue, TaskContinuationOptions.ExecuteSynchronously); - break; - case AttachMode.Await: - DoAwait(task); - break; - default: - throw new ArgumentOutOfRangeException(nameof(attachMode)); - } - } - private void Continue(Task task) - { - continuationThread = Environment.CurrentManagedThreadId; - evt.Set(); - } - private async void DoAwait(Task task) - { - await task.ConfigureAwait(false); - continuationThread = Environment.CurrentManagedThreadId; - evt.Set(); - } - } -#endif - } -} - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TestBase.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TestBase.cs deleted file mode 100644 index c172d9d..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TestBase.cs +++ /dev/null @@ -1,324 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -#if FEATURE_BOOKSLEEVE -using BookSleeve; -#endif -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - - public abstract class TestBase : IDisposable - { - - protected void CollectGarbage() - { - for (int i = 0; i < 3; i++) - { - GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); - GC.WaitForPendingFinalizers(); - } - } - private readonly SocketManager socketManager; - - protected TestBase() - { - socketManager = new SocketManager(GetType().Name); - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly")] - public void Dispose() - { - socketManager.Dispose(); - } -#if VERBOSE - protected const int AsyncOpsQty = 100, SyncOpsQty = 10; -#else - protected const int AsyncOpsQty = 100000, SyncOpsQty = 10000; -#endif - static TestBase() - { - TaskScheduler.UnobservedTaskException += (sender,args)=> - { - Console.WriteLine("Unobserved: " + args.Exception); - args.SetObserved(); -#if CORE_CLR - if (IgnorableExceptionPredicates.Any(predicate => predicate(args.Exception.InnerException))) return; -#endif - Interlocked.Increment(ref failCount); - lock (exceptions) - { - exceptions.Add(args.Exception.Message); - } - }; - } - -#if CORE_CLR - static Func[] IgnorableExceptionPredicates = new Func[] - { - e => e != null && e is ObjectDisposedException && e.Message.Equals("Cannot access a disposed object.\r\nObject name: 'System.Net.Sockets.NetworkStream'."), - e => e != null && e is IOException && e.Message.StartsWith("Unable to read data from the transport connection:") - }; -#endif - - protected void OnConnectionFailed(object sender, ConnectionFailedEventArgs e) - { - Interlocked.Increment(ref failCount); - lock(exceptions) - { - exceptions.Add("Connection failed: " + EndPointCollection.ToString(e.EndPoint) + "/" + e.ConnectionType); - } - } - - protected void OnInternalError(object sender, InternalErrorEventArgs e) - { - Interlocked.Increment(ref failCount); - lock (exceptions) - { - exceptions.Add("Internal error: " + e.Origin + ", " + EndPointCollection.ToString(e.EndPoint) + "/" + e.ConnectionType); - } - } - - static int failCount; - volatile int expectedFailCount; - [SetUp] - public void Setup() - { - ClearAmbientFailures(); - } - public void ClearAmbientFailures() - { - Collect(); - Interlocked.Exchange(ref failCount, 0); - expectedFailCount = 0; - lock(exceptions) - { - exceptions.Clear(); - } - } - private static readonly List exceptions = new List(); - public void SetExpectedAmbientFailureCount(int count) - { - expectedFailCount = count; - } - static void Collect() { - for (int i = 0; i < GC.MaxGeneration; i++) - { - GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true); - GC.WaitForPendingFinalizers(); - } - } - [TearDown] - public void Teardown() - { - Collect(); - if (expectedFailCount >= 0 && Interlocked.CompareExchange(ref failCount, 0, 0) != expectedFailCount) - { - var sb = new StringBuilder("There were ").Append(failCount).Append(" general ambient exceptions; expected ").Append(expectedFailCount); - lock(exceptions) - { - foreach(var item in exceptions.Take(5)) - { - sb.Append("; ").Append(item); - } - } - Assert.Fail(sb.ToString()); - } - } - - protected const int PrimaryPort = 6379, SlavePort = 6380, SecurePort = 6381; - protected const string PrimaryServer = "127.0.0.1", SecurePassword = "changeme", PrimaryPortString = "6379", SlavePortString = "6380", SecurePortString = "6381"; - internal static Task Swallow(Task task) - { - if (task != null) task.ContinueWith(swallowErrors, TaskContinuationOptions.OnlyOnFaulted); - return task; - } - private static readonly Action swallowErrors = SwallowErrors; - private static void SwallowErrors(Task task) - { - if (task != null) GC.KeepAlive(task.Exception); - } - protected IServer GetServer(ConnectionMultiplexer muxer) - { - EndPoint[] endpoints = muxer.GetEndPoints(); - IServer result = null; - foreach(var endpoint in endpoints) - { - var server = muxer.GetServer(endpoint); - if (server.IsSlave || !server.IsConnected) continue; - if(result != null) throw new InvalidOperationException("Requires exactly one master endpoint (found " + server.EndPoint + " and " + result.EndPoint + ")"); - result = server; - } - if(result == null) throw new InvalidOperationException("Requires exactly one master endpoint (found none)"); - return result; - } - - protected virtual ConnectionMultiplexer Create( - string clientName = null, int? syncTimeout = null, bool? allowAdmin = null, int? keepAlive = null, - int? connectTimeout = null, string password = null, string tieBreaker = null, TextWriter log = null, - bool fail = true, string[] disabledCommands = null, string[] enabledCommands = null, - bool checkConnect = true, bool pause = true, string failMessage = null, - string channelPrefix = null, bool useSharedSocketManager = true, Proxy? proxy = null) - { - if(pause) Thread.Sleep(250); // get a lot of glitches when hammering new socket creations etc; pace it out a bit - string configuration = GetConfiguration(); - var config = ConfigurationOptions.Parse(configuration); - if (disabledCommands != null && disabledCommands.Length != 0) - { - config.CommandMap = CommandMap.Create(new HashSet(disabledCommands), false); - } else if (enabledCommands != null && enabledCommands.Length != 0) - { - config.CommandMap = CommandMap.Create(new HashSet(enabledCommands), true); - } - - if(Debugger.IsAttached) - { - syncTimeout = int.MaxValue; - } - - if (useSharedSocketManager) config.SocketManager = socketManager; - if (channelPrefix != null) config.ChannelPrefix = channelPrefix; - if (tieBreaker != null) config.TieBreaker = tieBreaker; - if (password != null) config.Password = string.IsNullOrEmpty(password) ? null : password; - if (clientName != null) config.ClientName = clientName; - if (syncTimeout != null) config.SyncTimeout = syncTimeout.Value; - if (allowAdmin != null) config.AllowAdmin = allowAdmin.Value; - if (keepAlive != null) config.KeepAlive = keepAlive.Value; - if (connectTimeout != null) config.ConnectTimeout = connectTimeout.Value; - if (proxy != null) config.Proxy = proxy.Value; - var watch = Stopwatch.StartNew(); - var task = ConnectionMultiplexer.ConnectAsync(config, log ?? Console.Out); - if (!task.Wait(config.ConnectTimeout >= (int.MaxValue / 2) ? int.MaxValue : config.ConnectTimeout * 2)) - { - task.ContinueWith(x => - { - try - { - GC.KeepAlive(x.Exception); - } - catch - { } - }, TaskContinuationOptions.OnlyOnFaulted); - throw new TimeoutException("Connect timeout"); - } - watch.Stop(); - Console.WriteLine("Connect took: " + watch.ElapsedMilliseconds + "ms"); - var muxer = task.Result; - if (checkConnect) - { - if (!muxer.IsConnected) - { - if (fail) Assert.Fail(failMessage + "Server is not available"); - Assert.Inconclusive(failMessage + "Server is not available"); - } - } - muxer.InternalError += OnInternalError; - muxer.ConnectionFailed += OnConnectionFailed; - return muxer; - } - - protected virtual string GetConfiguration() - { - return PrimaryServer + ":" + PrimaryPort + "," + PrimaryServer + ":" + SlavePort; - } - - protected static string Me([CallerMemberName] string caller = null) - { - return caller; - } - -#if FEATURE_BOOKSLEEVE - protected static RedisConnection GetOldStyleConnection(bool open = true, bool allowAdmin = false, bool waitForOpen = false, int syncTimeout = 5000, int ioTimeout = 5000) - { - return GetOldStyleConnection(PrimaryServer, PrimaryPort, open, allowAdmin, waitForOpen, syncTimeout, ioTimeout); - } - private static RedisConnection GetOldStyleConnection(string host, int port, bool open = true, bool allowAdmin = false, bool waitForOpen = false, int syncTimeout = 5000, int ioTimeout = 5000) - { - var conn = new RedisConnection(host, port, syncTimeout: syncTimeout, ioTimeout: ioTimeout, allowAdmin: allowAdmin); - conn.Error += (s, args) => - { - Trace.WriteLine(args.Exception.Message, args.Cause); - }; - if (open) - { - var openAsync = conn.Open(); - if (waitForOpen) conn.Wait(openAsync); - } - return conn; - } -#endif - protected static TimeSpan RunConcurrent(Action work, int threads, int timeout = 10000, [CallerMemberName] string caller = null) - { - if (work == null) throw new ArgumentNullException(nameof(work)); - if (threads < 1) throw new ArgumentOutOfRangeException(nameof(threads)); - if(string.IsNullOrWhiteSpace(caller)) caller = Me(); - Stopwatch watch = null; - ManualResetEvent allDone = new ManualResetEvent(false); - object token = new object(); - int active = 0; - ThreadStart callback = delegate - { - lock (token) - { - int nowActive = Interlocked.Increment(ref active); - if (nowActive == threads) - { - watch = Stopwatch.StartNew(); - Monitor.PulseAll(token); - } - else - { - Monitor.Wait(token); - } - } - work(); - if (Interlocked.Decrement(ref active) == 0) - { - watch.Stop(); - allDone.Set(); - } - }; - - Thread[] threadArr = new Thread[threads]; - for (int i = 0; i < threads; i++) - { - var thd = new Thread(callback); - thd.Name = caller; - threadArr[i] = thd; - thd.Start(); - } - if (!allDone.WaitOne(timeout)) - { -#if !CORE_CLR - for (int i = 0; i < threads; i++) - { - var thd = threadArr[i]; - if (thd.IsAlive) thd.Abort(); - } -#endif - throw new TimeoutException(); - } - - return watch.Elapsed; - } - - - protected virtual void GetAzureCredentials(out string name, out string password) - { - var lines = File.ReadAllLines(@"d:\dev\azure.txt"); - if (lines == null || lines.Length != 2) - Assert.Inconclusive("azure credentials missing"); - name = lines[0]; - password = lines[1]; - } - - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TestInfoReplicationChecks.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TestInfoReplicationChecks.cs deleted file mode 100644 index f698be5..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TestInfoReplicationChecks.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Threading; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class TestInfoReplicationChecks : TestBase - { - [Test] - public void Exec() - { - using(var conn = Create()) - { - var parsed = ConfigurationOptions.Parse(conn.Configuration); - Assert.AreEqual(5, parsed.ConfigCheckSeconds); - var before = conn.GetCounters(); - Thread.Sleep(TimeSpan.FromSeconds(13)); - var after = conn.GetCounters(); - int done = (int)(after.Interactive.CompletedSynchronously - before.Interactive.CompletedSynchronously); - Assert.IsTrue(done >= 2); - } - } - protected override string GetConfiguration() - { - return base.GetConfiguration() + ",configCheckSeconds=5"; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TransactionWrapperTests.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TransactionWrapperTests.cs deleted file mode 100644 index cabd20c..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/TransactionWrapperTests.cs +++ /dev/null @@ -1,93 +0,0 @@ -#if FEATURE_MOQ -using System.Text; -using Moq; -using NUnit.Framework; -using StackExchange.Redis.KeyspaceIsolation; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public sealed class TransactionWrapperTests - { - private Mock mock; - private TransactionWrapper wrapper; - - [OneTimeSetUp] - public void Initialize() - { - mock = new Mock(); - wrapper = new TransactionWrapper(mock.Object, Encoding.UTF8.GetBytes("prefix:")); - } - - [Test] - public void AddCondition_HashEqual() - { - wrapper.AddCondition(Condition.HashEqual("key", "field", "value")); - mock.Verify(_ => _.AddCondition(It.Is(value => "prefix:key > field == value" == value.ToString()))); - } - - [Test] - public void AddCondition_HashNotEqual() - { - wrapper.AddCondition(Condition.HashNotEqual("key", "field", "value")); - mock.Verify(_ => _.AddCondition(It.Is(value => "prefix:key > field != value" == value.ToString()))); - } - - [Test] - public void AddCondition_HashExists() - { - wrapper.AddCondition(Condition.HashExists("key", "field")); - mock.Verify(_ => _.AddCondition(It.Is(value => "prefix:key > field exists" == value.ToString()))); - } - - [Test] - public void AddCondition_HashNotExists() - { - wrapper.AddCondition(Condition.HashNotExists("key", "field")); - mock.Verify(_ => _.AddCondition(It.Is(value => "prefix:key > field does not exists" == value.ToString()))); - } - - [Test] - public void AddCondition_KeyExists() - { - wrapper.AddCondition(Condition.KeyExists("key")); - mock.Verify(_ => _.AddCondition(It.Is(value => "prefix:key exists" == value.ToString()))); - } - - [Test] - public void AddCondition_KeyNotExists() - { - wrapper.AddCondition(Condition.KeyNotExists("key")); - mock.Verify(_ => _.AddCondition(It.Is(value => "prefix:key does not exists" == value.ToString()))); - } - - [Test] - public void AddCondition_StringEqual() - { - wrapper.AddCondition(Condition.StringEqual("key", "value")); - mock.Verify(_ => _.AddCondition(It.Is(value => "prefix:key == value" == value.ToString()))); - } - - [Test] - public void AddCondition_StringNotEqual() - { - wrapper.AddCondition(Condition.StringNotEqual("key", "value")); - mock.Verify(_ => _.AddCondition(It.Is(value => "prefix:key != value" == value.ToString()))); - } - - [Test] - public void ExecuteAsync() - { - wrapper.ExecuteAsync(CommandFlags.HighPriority); - mock.Verify(_ => _.ExecuteAsync(CommandFlags.HighPriority), Times.Once()); - } - - [Test] - public void Execute() - { - wrapper.Execute(CommandFlags.HighPriority); - mock.Verify(_ => _.Execute(CommandFlags.HighPriority), Times.Once()); - } - } -} -#endif \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Transactions.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Transactions.cs deleted file mode 100644 index 091431e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/Transactions.cs +++ /dev/null @@ -1,754 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class Transactions : TestBase - { - [Test] - public void BasicEmptyTran() - { - using(var muxer = Create()) - { - RedisKey key = Me(); - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - Assert.IsFalse(db.KeyExists(key)); - - var tran = db.CreateTransaction(); - - var result = tran.Execute(); - Assert.IsTrue(result); - } - } - - [Test] - [TestCase(false, false, true)] - [TestCase(false, true, false)] - [TestCase(true, false, false)] - [TestCase(true, true, true)] - public void BasicTranWithExistsCondition(bool demandKeyExists, bool keyExists, bool expectTran) - { - using (var muxer = Create(disabledCommands: new[] { "info", "config" })) - { - RedisKey key = Me(), key2 = Me() + "2"; - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.KeyDelete(key2, CommandFlags.FireAndForget); - if (keyExists) db.StringSet(key2, "any value", flags: CommandFlags.FireAndForget); - Assert.IsFalse(db.KeyExists(key)); - Assert.AreEqual(keyExists, db.KeyExists(key2)); - - var tran = db.CreateTransaction(); - var cond = tran.AddCondition(demandKeyExists ? Condition.KeyExists(key2) : Condition.KeyNotExists(key2)); - var incr = tran.StringIncrementAsync(key); - var exec = tran.ExecuteAsync(); - var get = db.StringGet(key); - - Assert.AreEqual(expectTran, db.Wait(exec), "expected tran result"); - if (demandKeyExists == keyExists) - { - Assert.IsTrue(db.Wait(exec), "eq: exec"); - Assert.IsTrue(cond.WasSatisfied, "eq: was satisfied"); - Assert.AreEqual(1, db.Wait(incr), "eq: incr"); - Assert.AreEqual(1, (long)get, "eq: get"); - } - else - { - Assert.IsFalse(db.Wait(exec), "neq: exec"); - Assert.False(cond.WasSatisfied, "neq: was satisfied"); - Assert.AreEqual(TaskStatus.Canceled, incr.Status, "neq: incr"); - Assert.AreEqual(0, (long)get, "neq: get"); - } - } - } - - [Test] - [TestCase("same", "same", true, true)] - [TestCase("x", "y", true, false)] - [TestCase("x", null, true, false)] - [TestCase(null, "y", true, false)] - [TestCase(null, null, true, true)] - - [TestCase("same", "same", false, false)] - [TestCase("x", "y", false, true)] - [TestCase("x", null, false, true)] - [TestCase(null, "y", false, true)] - [TestCase(null, null, false, false)] - public void BasicTranWithEqualsCondition(string expected, string value, bool expectEqual, bool expectTran) - { - using (var muxer = Create()) - { - RedisKey key = Me(), key2 = Me() + "2"; - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.KeyDelete(key2, CommandFlags.FireAndForget); - - if (value != null) db.StringSet(key2, value, flags: CommandFlags.FireAndForget); - Assert.IsFalse(db.KeyExists(key)); - Assert.AreEqual(value, (string)db.StringGet(key2)); - - var tran = db.CreateTransaction(); - var cond = tran.AddCondition(expectEqual ? Condition.StringEqual(key2, expected) : Condition.StringNotEqual(key2, expected)); - var incr = tran.StringIncrementAsync(key); - var exec = tran.ExecuteAsync(); - var get = db.StringGet(key); - - Assert.AreEqual(expectTran, db.Wait(exec), "expected tran result"); - if (expectEqual == (value == expected)) - { - Assert.IsTrue(db.Wait(exec), "eq: exec"); - Assert.IsTrue(cond.WasSatisfied, "eq: was satisfied"); - Assert.AreEqual(1, db.Wait(incr), "eq: incr"); - Assert.AreEqual(1, (long)get, "eq: get"); - } - else - { - Assert.IsFalse(db.Wait(exec), "neq: exec"); - Assert.False(cond.WasSatisfied, "neq: was satisfied"); - Assert.AreEqual(TaskStatus.Canceled, incr.Status, "neq: incr"); - Assert.AreEqual(0, (long)get, "neq: get"); - } - } - } - - - [Test] - [TestCase(false, false, true)] - [TestCase(false, true, false)] - [TestCase(true, false, false)] - [TestCase(true, true, true)] - public void BasicTranWithHashExistsCondition(bool demandKeyExists, bool keyExists, bool expectTran) - { - using (var muxer = Create(disabledCommands: new[] { "info", "config" })) - { - RedisKey key = Me(), key2 = Me() + "2"; - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.KeyDelete(key2, CommandFlags.FireAndForget); - RedisValue hashField = "field"; - if (keyExists) db.HashSet(key2, hashField, "any value", flags: CommandFlags.FireAndForget); - Assert.IsFalse(db.KeyExists(key)); - Assert.AreEqual(keyExists, db.HashExists(key2, hashField)); - - var tran = db.CreateTransaction(); - var cond = tran.AddCondition(demandKeyExists ? Condition.HashExists(key2, hashField) : Condition.HashNotExists(key2, hashField)); - var incr = tran.StringIncrementAsync(key); - var exec = tran.ExecuteAsync(); - var get = db.StringGet(key); - - Assert.AreEqual(expectTran, db.Wait(exec), "expected tran result"); - if (demandKeyExists == keyExists) - { - Assert.IsTrue(db.Wait(exec), "eq: exec"); - Assert.IsTrue(cond.WasSatisfied, "eq: was satisfied"); - Assert.AreEqual(1, db.Wait(incr), "eq: incr"); - Assert.AreEqual(1, (long)get, "eq: get"); - } - else - { - Assert.IsFalse(db.Wait(exec), "neq: exec"); - Assert.False(cond.WasSatisfied, "neq: was satisfied"); - Assert.AreEqual(TaskStatus.Canceled, incr.Status, "neq: incr"); - Assert.AreEqual(0, (long)get, "neq: get"); - } - } - } - - [Test] - [TestCase("same", "same", true, true)] - [TestCase("x", "y", true, false)] - [TestCase("x", null, true, false)] - [TestCase(null, "y", true, false)] - [TestCase(null, null, true, true)] - - [TestCase("same", "same", false, false)] - [TestCase("x", "y", false, true)] - [TestCase("x", null, false, true)] - [TestCase(null, "y", false, true)] - [TestCase(null, null, false, false)] - public void BasicTranWithHashEqualsCondition(string expected, string value, bool expectEqual, bool expectTran) - { - using (var muxer = Create()) - { - RedisKey key = Me(), key2 = Me() + "2"; - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.KeyDelete(key2, CommandFlags.FireAndForget); - - RedisValue hashField = "field"; - if (value != null) db.HashSet(key2, hashField, value, flags: CommandFlags.FireAndForget); - Assert.IsFalse(db.KeyExists(key)); - Assert.AreEqual(value, (string)db.HashGet(key2, hashField)); - - - var tran = db.CreateTransaction(); - var cond = tran.AddCondition(expectEqual ? Condition.HashEqual(key2, hashField, expected) : Condition.HashNotEqual(key2, hashField, expected)); - var incr = tran.StringIncrementAsync(key); - var exec = tran.ExecuteAsync(); - var get = db.StringGet(key); - - Assert.AreEqual(expectTran, db.Wait(exec), "expected tran result"); - if (expectEqual == (value == expected)) - { - Assert.IsTrue(db.Wait(exec), "eq: exec"); - Assert.IsTrue(cond.WasSatisfied, "eq: was satisfied"); - Assert.AreEqual(1, db.Wait(incr), "eq: incr"); - Assert.AreEqual(1, (long)get, "eq: get"); - } - else - { - Assert.IsFalse(db.Wait(exec), "neq: exec"); - Assert.False(cond.WasSatisfied, "neq: was satisfied"); - Assert.AreEqual(TaskStatus.Canceled, incr.Status, "neq: incr"); - Assert.AreEqual(0, (long)get, "neq: get"); - } - } - } - - [Test] - [TestCase(false, false, true)] - [TestCase(false, true, false)] - [TestCase(true, false, false)] - [TestCase(true, true, true)] - public void BasicTranWithListExistsCondition(bool demandKeyExists, bool keyExists, bool expectTran) - { - using (var muxer = Create(disabledCommands: new[] { "info", "config" })) - { - RedisKey key = Me(), key2 = Me() + "2"; - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.KeyDelete(key2, CommandFlags.FireAndForget); - if (keyExists) db.ListRightPush(key2, "any value", flags: CommandFlags.FireAndForget); - Assert.IsFalse(db.KeyExists(key)); - Assert.AreEqual(keyExists, db.KeyExists(key2)); - - var tran = db.CreateTransaction(); - var cond = tran.AddCondition(demandKeyExists ? Condition.ListIndexExists(key2, 0) : Condition.ListIndexNotExists(key2, 0)); - var push = tran.ListRightPushAsync(key, "any value"); - var exec = tran.ExecuteAsync(); - var get = db.ListGetByIndex(key, 0); - - Assert.AreEqual(expectTran, db.Wait(exec), "expected tran result"); - if (demandKeyExists == keyExists) - { - Assert.IsTrue(db.Wait(exec), "eq: exec"); - Assert.IsTrue(cond.WasSatisfied, "eq: was satisfied"); - Assert.AreEqual(1, db.Wait(push), "eq: push"); - Assert.AreEqual("any value", (string)get, "eq: get"); - } - else - { - Assert.IsFalse(db.Wait(exec), "neq: exec"); - Assert.False(cond.WasSatisfied, "neq: was satisfied"); - Assert.AreEqual(TaskStatus.Canceled, push.Status, "neq: push"); - Assert.AreEqual(null, (string)get, "neq: get"); - } - } - } - - [Test] - [TestCase("same", "same", true, true)] - [TestCase("x", "y", true, false)] - [TestCase("x", null, true, false)] - [TestCase(null, "y", true, false)] - [TestCase(null, null, true, true)] - - [TestCase("same", "same", false, false)] - [TestCase("x", "y", false, true)] - [TestCase("x", null, false, true)] - [TestCase(null, "y", false, true)] - [TestCase(null, null, false, false)] - public void BasicTranWithListEqualsCondition(string expected, string value, bool expectEqual, bool expectTran) - { - using (var muxer = Create()) - { - RedisKey key = Me(), key2 = Me() + "2"; - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.KeyDelete(key2, CommandFlags.FireAndForget); - - if (value != null) db.ListRightPush(key2, value, flags: CommandFlags.FireAndForget); - Assert.IsFalse(db.KeyExists(key)); - Assert.AreEqual(value, (string)db.ListGetByIndex(key2, 0)); - - var tran = db.CreateTransaction(); - var cond = tran.AddCondition(expectEqual ? Condition.ListIndexEqual(key2, 0, expected) : Condition.ListIndexNotEqual(key2, 0, expected)); - var push = tran.ListRightPushAsync(key, "any value"); - var exec = tran.ExecuteAsync(); - var get = db.ListGetByIndex(key, 0); - - Assert.AreEqual(expectTran, db.Wait(exec), "expected tran result"); - if (expectEqual == (value == expected)) - { - Assert.IsTrue(db.Wait(exec), "eq: exec"); - Assert.IsTrue(cond.WasSatisfied, "eq: was satisfied"); - Assert.AreEqual(1, db.Wait(push), "eq: push"); - Assert.AreEqual("any value", (string)get, "eq: get"); - } - else - { - Assert.IsFalse(db.Wait(exec), "neq: exec"); - Assert.False(cond.WasSatisfied, "neq: was satisfied"); - Assert.AreEqual(TaskStatus.Canceled, push.Status, "neq: push"); - Assert.AreEqual(null, (string)get, "neq: get"); - } - } - } - - public enum ComparisonType - { - Equal, - LessThan, - GreaterThan - } - - [Test] - [TestCase("five", ComparisonType.Equal, 5L, false)] - [TestCase("four", ComparisonType.Equal, 4L, true)] - [TestCase("three", ComparisonType.Equal, 3L, false)] - [TestCase("", ComparisonType.Equal, 2L, false)] - [TestCase("", ComparisonType.Equal, 0L, true)] - [TestCase(null, ComparisonType.Equal, 1L, false)] - [TestCase(null, ComparisonType.Equal, 0L, true)] - - [TestCase("five", ComparisonType.LessThan, 5L, true)] - [TestCase("four", ComparisonType.LessThan, 4L, false)] - [TestCase("three", ComparisonType.LessThan, 3L, false)] - [TestCase("", ComparisonType.LessThan, 2L, true)] - [TestCase("", ComparisonType.LessThan, 0L, false)] - [TestCase(null, ComparisonType.LessThan, 1L, true)] - [TestCase(null, ComparisonType.LessThan, 0L, false)] - - [TestCase("five", ComparisonType.GreaterThan, 5L, false)] - [TestCase("four", ComparisonType.GreaterThan, 4L, false)] - [TestCase("three", ComparisonType.GreaterThan, 3L, true)] - [TestCase("", ComparisonType.GreaterThan, 2L, false)] - [TestCase("", ComparisonType.GreaterThan, 0L, false)] - [TestCase(null, ComparisonType.GreaterThan, 1L, false)] - [TestCase(null, ComparisonType.GreaterThan, 0L, false)] - public void BasicTranWithStringLengthCondition(string value, ComparisonType type, long length, bool expectTran) - { - using (var muxer = Create()) - { - RedisKey key = Me(), key2 = Me() + "2"; - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.KeyDelete(key2, CommandFlags.FireAndForget); - - var expectSuccess = false; - Condition condition = null; - var valueLength = value?.Length ?? 0; - switch (type) { - case ComparisonType.Equal: - expectSuccess = valueLength == length; - condition = Condition.StringLengthEqual(key2, length); - Assert.That(condition.ToString(), Contains.Substring("String length == " + length)); - break; - case ComparisonType.GreaterThan: - expectSuccess = valueLength > length; - condition = Condition.StringLengthGreaterThan(key2, length); - Assert.That(condition.ToString(), Contains.Substring("String length > " + length)); - break; - case ComparisonType.LessThan: - expectSuccess = valueLength < length; - condition = Condition.StringLengthLessThan(key2, length); - Assert.That(condition.ToString(), Contains.Substring("String length < " + length)); - break; - } - - if (value != null) db.StringSet(key2, value, flags: CommandFlags.FireAndForget); - Assert.IsFalse(db.KeyExists(key)); - Assert.AreEqual(value, (string)db.StringGet(key2)); - - var tran = db.CreateTransaction(); - var cond = tran.AddCondition(condition); - var push = tran.StringSetAsync(key, "any value"); - var exec = tran.ExecuteAsync(); - var get = db.StringLength(key); - - Assert.AreEqual(expectTran, db.Wait(exec), "expected tran result"); - - if (expectSuccess) { - Assert.IsTrue(db.Wait(exec), "eq: exec"); - Assert.IsTrue(cond.WasSatisfied, "eq: was satisfied"); - Assert.AreEqual(true, db.Wait(push), "eq: push"); - Assert.AreEqual("any value".Length, get, "eq: get"); - } else { - Assert.IsFalse(db.Wait(exec), "neq: exec"); - Assert.False(cond.WasSatisfied, "neq: was satisfied"); - Assert.AreEqual(TaskStatus.Canceled, push.Status, "neq: push"); - Assert.AreEqual(0, get, "neq: get"); - } - } - } - - [Test] - [TestCase("five", ComparisonType.Equal, 5L, false)] - [TestCase("four", ComparisonType.Equal, 4L, true)] - [TestCase("three", ComparisonType.Equal, 3L, false)] - [TestCase("", ComparisonType.Equal, 2L, false)] - [TestCase("", ComparisonType.Equal, 0L, true)] - - [TestCase("five", ComparisonType.LessThan, 5L, true)] - [TestCase("four", ComparisonType.LessThan, 4L, false)] - [TestCase("three", ComparisonType.LessThan, 3L, false)] - [TestCase("", ComparisonType.LessThan, 2L, true)] - [TestCase("", ComparisonType.LessThan, 0L, false)] - - [TestCase("five", ComparisonType.GreaterThan, 5L, false)] - [TestCase("four", ComparisonType.GreaterThan, 4L, false)] - [TestCase("three", ComparisonType.GreaterThan, 3L, true)] - [TestCase("", ComparisonType.GreaterThan, 2L, false)] - [TestCase("", ComparisonType.GreaterThan, 0L, false)] - public void BasicTranWithHashLengthCondition(string value, ComparisonType type, long length, bool expectTran) - { - using (var muxer = Create()) - { - RedisKey key = Me(), key2 = Me() + "2"; - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.KeyDelete(key2, CommandFlags.FireAndForget); - - var expectSuccess = false; - Condition condition = null; - var valueLength = value?.Length ?? 0; - switch (type) { - case ComparisonType.Equal: - expectSuccess = valueLength == length; - condition = Condition.HashLengthEqual(key2, length); - break; - case ComparisonType.GreaterThan: - expectSuccess = valueLength > length; - condition = Condition.HashLengthGreaterThan(key2, length); - break; - case ComparisonType.LessThan: - expectSuccess = valueLength < length; - condition = Condition.HashLengthLessThan(key2, length); - break; - } - - for (var i = 0; i < valueLength; i++) { - db.HashSet(key2, i, value[i].ToString(), flags: CommandFlags.FireAndForget); - } - Assert.IsFalse(db.KeyExists(key)); - Assert.AreEqual(valueLength, db.HashLength(key2)); - - var tran = db.CreateTransaction(); - var cond = tran.AddCondition(condition); - var push = tran.StringSetAsync(key, "any value"); - var exec = tran.ExecuteAsync(); - var get = db.StringLength(key); - - Assert.AreEqual(expectTran, db.Wait(exec), "expected tran result"); - - if (expectSuccess) { - Assert.IsTrue(db.Wait(exec), "eq: exec"); - Assert.IsTrue(cond.WasSatisfied, "eq: was satisfied"); - Assert.AreEqual(true, db.Wait(push), "eq: push"); - Assert.AreEqual("any value".Length, get, "eq: get"); - } else { - Assert.IsFalse(db.Wait(exec), "neq: exec"); - Assert.False(cond.WasSatisfied, "neq: was satisfied"); - Assert.AreEqual(TaskStatus.Canceled, push.Status, "neq: push"); - Assert.AreEqual(0, get, "neq: get"); - } - } - } - - [Test] - [TestCase("five", ComparisonType.Equal, 5L, false)] - [TestCase("four", ComparisonType.Equal, 4L, true)] - [TestCase("three", ComparisonType.Equal, 3L, false)] - [TestCase("", ComparisonType.Equal, 2L, false)] - [TestCase("", ComparisonType.Equal, 0L, true)] - - [TestCase("five", ComparisonType.LessThan, 5L, true)] - [TestCase("four", ComparisonType.LessThan, 4L, false)] - [TestCase("three", ComparisonType.LessThan, 3L, false)] - [TestCase("", ComparisonType.LessThan, 2L, true)] - [TestCase("", ComparisonType.LessThan, 0L, false)] - - [TestCase("five", ComparisonType.GreaterThan, 5L, false)] - [TestCase("four", ComparisonType.GreaterThan, 4L, false)] - [TestCase("three", ComparisonType.GreaterThan, 3L, true)] - [TestCase("", ComparisonType.GreaterThan, 2L, false)] - [TestCase("", ComparisonType.GreaterThan, 0L, false)] - public void BasicTranWithSetCardinalityCondition(string value, ComparisonType type, long length, bool expectTran) - { - using (var muxer = Create()) - { - RedisKey key = Me(), key2 = Me() + "2"; - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.KeyDelete(key2, CommandFlags.FireAndForget); - - var expectSuccess = false; - Condition condition = null; - var valueLength = value?.Length ?? 0; - switch (type) { - case ComparisonType.Equal: - expectSuccess = valueLength == length; - condition = Condition.SetLengthEqual(key2, length); - break; - case ComparisonType.GreaterThan: - expectSuccess = valueLength > length; - condition = Condition.SetLengthGreaterThan(key2, length); - break; - case ComparisonType.LessThan: - expectSuccess = valueLength < length; - condition = Condition.SetLengthLessThan(key2, length); - break; - } - - for (var i = 0; i < valueLength; i++) { - db.SetAdd(key2, i, flags: CommandFlags.FireAndForget); - } - Assert.IsFalse(db.KeyExists(key)); - Assert.AreEqual(valueLength, db.SetLength(key2)); - - var tran = db.CreateTransaction(); - var cond = tran.AddCondition(condition); - var push = tran.StringSetAsync(key, "any value"); - var exec = tran.ExecuteAsync(); - var get = db.StringLength(key); - - Assert.AreEqual(expectTran, db.Wait(exec), "expected tran result"); - - if (expectSuccess) { - Assert.IsTrue(db.Wait(exec), "eq: exec"); - Assert.IsTrue(cond.WasSatisfied, "eq: was satisfied"); - Assert.AreEqual(true, db.Wait(push), "eq: push"); - Assert.AreEqual("any value".Length, get, "eq: get"); - } else { - Assert.IsFalse(db.Wait(exec), "neq: exec"); - Assert.False(cond.WasSatisfied, "neq: was satisfied"); - Assert.AreEqual(TaskStatus.Canceled, push.Status, "neq: push"); - Assert.AreEqual(0, get, "neq: get"); - } - } - } - - [Test] - [TestCase("five", ComparisonType.Equal, 5L, false)] - [TestCase("four", ComparisonType.Equal, 4L, true)] - [TestCase("three", ComparisonType.Equal, 3L, false)] - [TestCase("", ComparisonType.Equal, 2L, false)] - [TestCase("", ComparisonType.Equal, 0L, true)] - - [TestCase("five", ComparisonType.LessThan, 5L, true)] - [TestCase("four", ComparisonType.LessThan, 4L, false)] - [TestCase("three", ComparisonType.LessThan, 3L, false)] - [TestCase("", ComparisonType.LessThan, 2L, true)] - [TestCase("", ComparisonType.LessThan, 0L, false)] - - [TestCase("five", ComparisonType.GreaterThan, 5L, false)] - [TestCase("four", ComparisonType.GreaterThan, 4L, false)] - [TestCase("three", ComparisonType.GreaterThan, 3L, true)] - [TestCase("", ComparisonType.GreaterThan, 2L, false)] - [TestCase("", ComparisonType.GreaterThan, 0L, false)] - public void BasicTranWithSortedSetCardinalityCondition(string value, ComparisonType type, long length, bool expectTran) - { - using (var muxer = Create()) - { - RedisKey key = Me(), key2 = Me() + "2"; - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.KeyDelete(key2, CommandFlags.FireAndForget); - - var expectSuccess = false; - Condition condition = null; - var valueLength = value?.Length ?? 0; - switch (type) { - case ComparisonType.Equal: - expectSuccess = valueLength == length; - condition = Condition.SortedSetLengthEqual(key2, length); - break; - case ComparisonType.GreaterThan: - expectSuccess = valueLength > length; - condition = Condition.SortedSetLengthGreaterThan(key2, length); - break; - case ComparisonType.LessThan: - expectSuccess = valueLength < length; - condition = Condition.SortedSetLengthLessThan(key2, length); - break; - } - - for (var i = 0; i < valueLength; i++) { - db.SortedSetAdd(key2, i, i, flags: CommandFlags.FireAndForget); - } - Assert.IsFalse(db.KeyExists(key)); - Assert.AreEqual(valueLength, db.SortedSetLength(key2)); - - var tran = db.CreateTransaction(); - var cond = tran.AddCondition(condition); - var push = tran.StringSetAsync(key, "any value"); - var exec = tran.ExecuteAsync(); - var get = db.StringLength(key); - - Assert.AreEqual(expectTran, db.Wait(exec), "expected tran result"); - - if (expectSuccess) { - Assert.IsTrue(db.Wait(exec), "eq: exec"); - Assert.IsTrue(cond.WasSatisfied, "eq: was satisfied"); - Assert.AreEqual(true, db.Wait(push), "eq: push"); - Assert.AreEqual("any value".Length, get, "eq: get"); - } else { - Assert.IsFalse(db.Wait(exec), "neq: exec"); - Assert.False(cond.WasSatisfied, "neq: was satisfied"); - Assert.AreEqual(TaskStatus.Canceled, push.Status, "neq: push"); - Assert.AreEqual(0, get, "neq: get"); - } - } - } - - [Test] - [TestCase("five", ComparisonType.Equal, 5L, false)] - [TestCase("four", ComparisonType.Equal, 4L, true)] - [TestCase("three", ComparisonType.Equal, 3L, false)] - [TestCase("", ComparisonType.Equal, 2L, false)] - [TestCase("", ComparisonType.Equal, 0L, true)] - - [TestCase("five", ComparisonType.LessThan, 5L, true)] - [TestCase("four", ComparisonType.LessThan, 4L, false)] - [TestCase("three", ComparisonType.LessThan, 3L, false)] - [TestCase("", ComparisonType.LessThan, 2L, true)] - [TestCase("", ComparisonType.LessThan, 0L, false)] - - [TestCase("five", ComparisonType.GreaterThan, 5L, false)] - [TestCase("four", ComparisonType.GreaterThan, 4L, false)] - [TestCase("three", ComparisonType.GreaterThan, 3L, true)] - [TestCase("", ComparisonType.GreaterThan, 2L, false)] - [TestCase("", ComparisonType.GreaterThan, 0L, false)] - public void BasicTranWithListLengthCondition(string value, ComparisonType type, long length, bool expectTran) - { - using (var muxer = Create()) - { - RedisKey key = Me(), key2 = Me() + "2"; - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - db.KeyDelete(key2, CommandFlags.FireAndForget); - - var expectSuccess = false; - Condition condition = null; - var valueLength = value?.Length ?? 0; - switch (type) { - case ComparisonType.Equal: - expectSuccess = valueLength == length; - condition = Condition.ListLengthEqual(key2, length); - break; - case ComparisonType.GreaterThan: - expectSuccess = valueLength > length; - condition = Condition.ListLengthGreaterThan(key2, length); - break; - case ComparisonType.LessThan: - expectSuccess = valueLength < length; - condition = Condition.ListLengthLessThan(key2, length); - break; - } - - for (var i = 0; i < valueLength; i++) { - db.ListRightPush(key2, i, flags: CommandFlags.FireAndForget); - } - Assert.IsFalse(db.KeyExists(key)); - Assert.AreEqual(valueLength, db.ListLength(key2)); - - var tran = db.CreateTransaction(); - var cond = tran.AddCondition(condition); - var push = tran.StringSetAsync(key, "any value"); - var exec = tran.ExecuteAsync(); - var get = db.StringLength(key); - - Assert.AreEqual(expectTran, db.Wait(exec), "expected tran result"); - - if (expectSuccess) { - Assert.IsTrue(db.Wait(exec), "eq: exec"); - Assert.IsTrue(cond.WasSatisfied, "eq: was satisfied"); - Assert.AreEqual(true, db.Wait(push), "eq: push"); - Assert.AreEqual("any value".Length, get, "eq: get"); - } else { - Assert.IsFalse(db.Wait(exec), "neq: exec"); - Assert.False(cond.WasSatisfied, "neq: was satisfied"); - Assert.AreEqual(TaskStatus.Canceled, push.Status, "neq: push"); - Assert.AreEqual(0, get, "neq: get"); - } - } - } - - [Test] - public async void BasicTran() - { - using (var muxer = Create()) - { - RedisKey key = Me(); - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - Assert.IsFalse(db.KeyExists(key)); - - var tran = db.CreateTransaction(); - var a = tran.StringIncrementAsync(key, 10); - var b = tran.StringIncrementAsync(key, 5); - var c = tran.StringGetAsync(key); - var d = tran.KeyExistsAsync(key); - var e = tran.KeyDeleteAsync(key); - var f = tran.KeyExistsAsync(key); - Assert.IsFalse(a.IsCompleted); - Assert.IsFalse(b.IsCompleted); - Assert.IsFalse(c.IsCompleted); - Assert.IsFalse(d.IsCompleted); - Assert.IsFalse(e.IsCompleted); - Assert.IsFalse(f.IsCompleted); - var result = db.Wait(tran.ExecuteAsync()); - Assert.IsTrue(result, "result"); - db.WaitAll(a, b, c, d, e, f); - Assert.IsTrue(a.IsCompleted, "a"); - Assert.IsTrue(b.IsCompleted, "b"); - Assert.IsTrue(c.IsCompleted, "c"); - Assert.IsTrue(d.IsCompleted, "d"); - Assert.IsTrue(e.IsCompleted, "e"); - Assert.IsTrue(f.IsCompleted, "f"); - - var g = db.KeyExists(key); - - - Assert.AreEqual(10, await a.ConfigureAwait(false)); - Assert.AreEqual(15, await b.ConfigureAwait(false)); - Assert.AreEqual(15, (long)await c.ConfigureAwait(false)); - Assert.IsTrue(await d.ConfigureAwait(false)); - Assert.IsTrue(await e.ConfigureAwait(false)); - Assert.IsFalse(await f.ConfigureAwait(false)); - Assert.IsFalse(g); - } - } - - [Test] - public void CombineFireAndForgetAndRegularAsyncInTransaction() - { - using (var muxer = Create()) - { - RedisKey key = Me(); - var db = muxer.GetDatabase(); - db.KeyDelete(key, CommandFlags.FireAndForget); - Assert.IsFalse(db.KeyExists(key)); - - var tran = db.CreateTransaction("state"); - var a = tran.StringIncrementAsync(key, 5); - var b = tran.StringIncrementAsync(key, 10, CommandFlags.FireAndForget); - var c = tran.StringIncrementAsync(key, 15); - Assert.IsTrue(tran.Execute()); - var count = (long)db.StringGet(key); - - Assert.AreEqual(5, db.Wait(a), "a"); - Assert.AreEqual("state", a.AsyncState); - Assert.AreEqual(0, db.Wait(b), "b"); - Assert.IsNull(b.AsyncState); - Assert.AreEqual(30, db.Wait(c), "c"); - Assert.AreEqual("state", a.AsyncState); - Assert.AreEqual(30, count, "count"); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/VPNTest.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/VPNTest.cs deleted file mode 100644 index 19fe9cb..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/VPNTest.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.IO; -using NUnit.Framework; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public class VPNTest : TestBase - { - - [Test] - [MaxTime(100000)] - [TestCase("co-devredis01.ds.stackexchange.com:6379")] - public void Execute(string config) - { - for (int i = 0; i < 50; i++) - { - var log = new StringWriter(); - try - { - var options = ConfigurationOptions.Parse(config); - options.SyncTimeout = 3000; - options.ConnectRetry = 5; - using (var conn = ConnectionMultiplexer.Connect(options, log)) - { - var ttl = conn.GetDatabase().Ping(); - Console.WriteLine(ttl); - } - } - catch - { - Console.WriteLine(log); - Assert.Fail(); - } - Console.WriteLine(); - Console.WriteLine("==="); - Console.WriteLine(); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/WithKeyPrefixTests.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/WithKeyPrefixTests.cs deleted file mode 100644 index 8496330..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/WithKeyPrefixTests.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using NUnit.Framework; -using StackExchange.Redis.KeyspaceIsolation; - -namespace StackExchange.Redis.Tests -{ - - [TestFixture] - public class WithKeyPrefixTests : TestBase - { - [Test] - public void BlankPrefixYieldsSame_Bytes() - { - using (var conn = Create()) - { - var raw = conn.GetDatabase(1); - var prefixed = raw.WithKeyPrefix(new byte[0]); - Assert.AreSame(raw, prefixed); - } - } - [Test] - public void BlankPrefixYieldsSame_String() - { - using (var conn = Create()) - { - var raw = conn.GetDatabase(1); - var prefixed = raw.WithKeyPrefix(""); - Assert.AreSame(raw, prefixed); - } - } - [Test] - public void NullPrefixIsError_Bytes() - { - Assert.Throws(() => { - using (var conn = Create()) - { - var raw = conn.GetDatabase(1); - var prefixed = raw.WithKeyPrefix((byte[])null); - } - }); - } - [Test] - public void NullPrefixIsError_String() - { - Assert.Throws(() => { - using (var conn = Create()) - { - var raw = conn.GetDatabase(1); - var prefixed = raw.WithKeyPrefix((string)null); - } - }); - } - - [Test] - [TestCase("abc")] - [TestCase("")] - [TestCase(null)] - public void NullDatabaseIsError(string prefix) - { - Assert.Throws(() => { - IDatabase raw = null; - var prefixed = raw.WithKeyPrefix(prefix); - }); - } - [Test] - public void BasicSmokeTest() - { - using(var conn = Create()) - { - var raw = conn.GetDatabase(1); - - var foo = raw.WithKeyPrefix("foo"); - var foobar = foo.WithKeyPrefix("bar"); - - string key = Me(); - - string s = Guid.NewGuid().ToString(), t = Guid.NewGuid().ToString(); - - foo.StringSet(key, s); - var val = (string)foo.StringGet(key); - Assert.AreEqual(s, val); // fooBasicSmokeTest - - foobar.StringSet(key, t); - val = (string)foobar.StringGet(key); - Assert.AreEqual(t, val); // foobarBasicSmokeTest - - val = (string)foo.StringGet("bar" + key); - Assert.AreEqual(t, val); // foobarBasicSmokeTest - - val = (string)raw.StringGet("foo" + key); - Assert.AreEqual(s, val); // fooBasicSmokeTest - - val = (string)raw.StringGet("foobar" + key); - Assert.AreEqual(t, val); // foobarBasicSmokeTest - } - } - [Test] - public void ConditionTest() - { - using(var conn = Create()) - { - var raw = conn.GetDatabase(2); - - var foo = raw.WithKeyPrefix("tran:"); - - raw.KeyDelete("tran:abc"); - raw.KeyDelete("tran:i"); - - // execute while key exists - raw.StringSet("tran:abc", "def"); - var tran = foo.CreateTransaction(); - tran.AddCondition(Condition.KeyExists("abc")); - tran.StringIncrementAsync("i"); - tran.Execute(); - - int i = (int)raw.StringGet("tran:i"); - Assert.AreEqual(1, i); - - // repeat without key - raw.KeyDelete("tran:abc"); - tran = foo.CreateTransaction(); - tran.AddCondition(Condition.KeyExists("abc")); - tran.StringIncrementAsync("i"); - tran.Execute(); - - i = (int)raw.StringGet("tran:i"); - Assert.AreEqual(1, i); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/WrapperBaseTests.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/WrapperBaseTests.cs deleted file mode 100644 index 00d8299..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/WrapperBaseTests.cs +++ /dev/null @@ -1,893 +0,0 @@ -#if FEATURE_MOQ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Net; -using System.Text; -using Moq; -using NUnit.Framework; -using StackExchange.Redis.KeyspaceIsolation; - -namespace StackExchange.Redis.Tests -{ - [TestFixture] - public sealed class WrapperBaseTests - { - private Mock mock; - private WrapperBase wrapper; - - [OneTimeSetUp] - public void Initialize() - { - mock = new Mock(); - wrapper = new WrapperBase(mock.Object, Encoding.UTF8.GetBytes("prefix:")); - } - - [Test] - public void DebugObjectAsync() - { - wrapper.DebugObjectAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.DebugObjectAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void HashDecrementAsync_1() - { - wrapper.HashDecrementAsync("key", "hashField", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.HashDecrementAsync("prefix:key", "hashField", 123, CommandFlags.HighPriority)); - } - - [Test] - public void HashDecrementAsync_2() - { - wrapper.HashDecrementAsync("key", "hashField", 1.23, CommandFlags.HighPriority); - mock.Verify(_ => _.HashDecrementAsync("prefix:key", "hashField", 1.23, CommandFlags.HighPriority)); - } - - [Test] - public void HashDeleteAsync_1() - { - wrapper.HashDeleteAsync("key", "hashField", CommandFlags.HighPriority); - mock.Verify(_ => _.HashDeleteAsync("prefix:key", "hashField", CommandFlags.HighPriority)); - } - - [Test] - public void HashDeleteAsync_2() - { - RedisValue[] hashFields = new RedisValue[0]; - wrapper.HashDeleteAsync("key", hashFields, CommandFlags.HighPriority); - mock.Verify(_ => _.HashDeleteAsync("prefix:key", hashFields, CommandFlags.HighPriority)); - } - - [Test] - public void HashExistsAsync() - { - wrapper.HashExistsAsync("key", "hashField", CommandFlags.HighPriority); - mock.Verify(_ => _.HashExistsAsync("prefix:key", "hashField", CommandFlags.HighPriority)); - } - - [Test] - public void HashGetAllAsync() - { - wrapper.HashGetAllAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.HashGetAllAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void HashGetAsync_1() - { - wrapper.HashGetAsync("key", "hashField", CommandFlags.HighPriority); - mock.Verify(_ => _.HashGetAsync("prefix:key", "hashField", CommandFlags.HighPriority)); - } - - [Test] - public void HashGetAsync_2() - { - RedisValue[] hashFields = new RedisValue[0]; - wrapper.HashGetAsync("key", hashFields, CommandFlags.HighPriority); - mock.Verify(_ => _.HashGetAsync("prefix:key", hashFields, CommandFlags.HighPriority)); - } - - [Test] - public void HashIncrementAsync_1() - { - wrapper.HashIncrementAsync("key", "hashField", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.HashIncrementAsync("prefix:key", "hashField", 123, CommandFlags.HighPriority)); - } - - [Test] - public void HashIncrementAsync_2() - { - wrapper.HashIncrementAsync("key", "hashField", 1.23, CommandFlags.HighPriority); - mock.Verify(_ => _.HashIncrementAsync("prefix:key", "hashField", 1.23, CommandFlags.HighPriority)); - } - - [Test] - public void HashKeysAsync() - { - wrapper.HashKeysAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.HashKeysAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void HashLengthAsync() - { - wrapper.HashLengthAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.HashLengthAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void HashSetAsync_1() - { - HashEntry[] hashFields = new HashEntry[0]; - wrapper.HashSetAsync("key", hashFields, CommandFlags.HighPriority); - mock.Verify(_ => _.HashSetAsync("prefix:key", hashFields, CommandFlags.HighPriority)); - } - - [Test] - public void HashSetAsync_2() - { - wrapper.HashSetAsync("key", "hashField", "value", When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.HashSetAsync("prefix:key", "hashField", "value", When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void HashValuesAsync() - { - wrapper.HashValuesAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.HashValuesAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void HyperLogLogAddAsync_1() - { - wrapper.HyperLogLogAddAsync("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.HyperLogLogAddAsync("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void HyperLogLogAddAsync_2() - { - RedisValue[] values = new RedisValue[0]; - wrapper.HyperLogLogAddAsync("key", values, CommandFlags.HighPriority); - mock.Verify(_ => _.HyperLogLogAddAsync("prefix:key", values, CommandFlags.HighPriority)); - } - - [Test] - public void HyperLogLogLengthAsync() - { - wrapper.HyperLogLogLengthAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.HyperLogLogLengthAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void HyperLogLogMergeAsync_1() - { - wrapper.HyperLogLogMergeAsync("destination", "first", "second", CommandFlags.HighPriority); - mock.Verify(_ => _.HyperLogLogMergeAsync("prefix:destination", "prefix:first", "prefix:second", CommandFlags.HighPriority)); - } - - [Test] - public void HyperLogLogMergeAsync_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.HyperLogLogMergeAsync("destination", keys, CommandFlags.HighPriority); - mock.Verify(_ => _.HyperLogLogMergeAsync("prefix:destination", It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void IdentifyEndpointAsync() - { - wrapper.IdentifyEndpointAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.IdentifyEndpointAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void IsConnected() - { - wrapper.IsConnected("key", CommandFlags.HighPriority); - mock.Verify(_ => _.IsConnected("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void KeyDeleteAsync_1() - { - wrapper.KeyDeleteAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.KeyDeleteAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void KeyDeleteAsync_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.KeyDeleteAsync(keys, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyDeleteAsync(It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void KeyDumpAsync() - { - wrapper.KeyDumpAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.KeyDumpAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void KeyExistsAsync() - { - wrapper.KeyExistsAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.KeyExistsAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void KeyExpireAsync_1() - { - TimeSpan expiry = TimeSpan.FromSeconds(123); - wrapper.KeyExpireAsync("key", expiry, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyExpireAsync("prefix:key", expiry, CommandFlags.HighPriority)); - } - - [Test] - public void KeyExpireAsync_2() - { - DateTime expiry = DateTime.Now; - wrapper.KeyExpireAsync("key", expiry, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyExpireAsync("prefix:key", expiry, CommandFlags.HighPriority)); - } - - [Test] - public void KeyMigrateAsync() - { - EndPoint toServer = new IPEndPoint(IPAddress.Loopback, 123); - wrapper.KeyMigrateAsync("key", toServer, 123, 456, MigrateOptions.Copy, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyMigrateAsync("prefix:key", toServer, 123, 456, MigrateOptions.Copy, CommandFlags.HighPriority)); - } - - [Test] - public void KeyMoveAsync() - { - wrapper.KeyMoveAsync("key", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyMoveAsync("prefix:key", 123, CommandFlags.HighPriority)); - } - - [Test] - public void KeyPersistAsync() - { - wrapper.KeyPersistAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.KeyPersistAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void KeyRandomAsync() - { - Assert.Throws(() => { - wrapper.KeyRandomAsync(); - }); - } - - [Test] - public void KeyRenameAsync() - { - wrapper.KeyRenameAsync("key", "newKey", When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyRenameAsync("prefix:key", "prefix:newKey", When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void KeyRestoreAsync() - { - Byte[] value = new Byte[0]; - TimeSpan expiry = TimeSpan.FromSeconds(123); - wrapper.KeyRestoreAsync("key", value, expiry, CommandFlags.HighPriority); - mock.Verify(_ => _.KeyRestoreAsync("prefix:key", value, expiry, CommandFlags.HighPriority)); - } - - [Test] - public void KeyTimeToLiveAsync() - { - wrapper.KeyTimeToLiveAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.KeyTimeToLiveAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void KeyTypeAsync() - { - wrapper.KeyTypeAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.KeyTypeAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void ListGetByIndexAsync() - { - wrapper.ListGetByIndexAsync("key", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.ListGetByIndexAsync("prefix:key", 123, CommandFlags.HighPriority)); - } - - [Test] - public void ListInsertAfterAsync() - { - wrapper.ListInsertAfterAsync("key", "pivot", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.ListInsertAfterAsync("prefix:key", "pivot", "value", CommandFlags.HighPriority)); - } - - [Test] - public void ListInsertBeforeAsync() - { - wrapper.ListInsertBeforeAsync("key", "pivot", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.ListInsertBeforeAsync("prefix:key", "pivot", "value", CommandFlags.HighPriority)); - } - - [Test] - public void ListLeftPopAsync() - { - wrapper.ListLeftPopAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.ListLeftPopAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void ListLeftPushAsync_1() - { - wrapper.ListLeftPushAsync("key", "value", When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.ListLeftPushAsync("prefix:key", "value", When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void ListLeftPushAsync_2() - { - RedisValue[] values = new RedisValue[0]; - wrapper.ListLeftPushAsync("key", values, CommandFlags.HighPriority); - mock.Verify(_ => _.ListLeftPushAsync("prefix:key", values, CommandFlags.HighPriority)); - } - - [Test] - public void ListLengthAsync() - { - wrapper.ListLengthAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.ListLengthAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void ListRangeAsync() - { - wrapper.ListRangeAsync("key", 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.ListRangeAsync("prefix:key", 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void ListRemoveAsync() - { - wrapper.ListRemoveAsync("key", "value", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.ListRemoveAsync("prefix:key", "value", 123, CommandFlags.HighPriority)); - } - - [Test] - public void ListRightPopAsync() - { - wrapper.ListRightPopAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.ListRightPopAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void ListRightPopLeftPushAsync() - { - wrapper.ListRightPopLeftPushAsync("source", "destination", CommandFlags.HighPriority); - mock.Verify(_ => _.ListRightPopLeftPushAsync("prefix:source", "prefix:destination", CommandFlags.HighPriority)); - } - - [Test] - public void ListRightPushAsync_1() - { - wrapper.ListRightPushAsync("key", "value", When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.ListRightPushAsync("prefix:key", "value", When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void ListRightPushAsync_2() - { - RedisValue[] values = new RedisValue[0]; - wrapper.ListRightPushAsync("key", values, CommandFlags.HighPriority); - mock.Verify(_ => _.ListRightPushAsync("prefix:key", values, CommandFlags.HighPriority)); - } - - [Test] - public void ListSetByIndexAsync() - { - wrapper.ListSetByIndexAsync("key", 123, "value", CommandFlags.HighPriority); - mock.Verify(_ => _.ListSetByIndexAsync("prefix:key", 123, "value", CommandFlags.HighPriority)); - } - - [Test] - public void ListTrimAsync() - { - wrapper.ListTrimAsync("key", 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.ListTrimAsync("prefix:key", 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void LockExtendAsync() - { - TimeSpan expiry = TimeSpan.FromSeconds(123); - wrapper.LockExtendAsync("key", "value", expiry, CommandFlags.HighPriority); - mock.Verify(_ => _.LockExtendAsync("prefix:key", "value", expiry, CommandFlags.HighPriority)); - } - - [Test] - public void LockQueryAsync() - { - wrapper.LockQueryAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.LockQueryAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void LockReleaseAsync() - { - wrapper.LockReleaseAsync("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.LockReleaseAsync("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void LockTakeAsync() - { - TimeSpan expiry = TimeSpan.FromSeconds(123); - wrapper.LockTakeAsync("key", "value", expiry, CommandFlags.HighPriority); - mock.Verify(_ => _.LockTakeAsync("prefix:key", "value", expiry, CommandFlags.HighPriority)); - } - - [Test] - public void PublishAsync() - { - wrapper.PublishAsync("channel", "message", CommandFlags.HighPriority); - mock.Verify(_ => _.PublishAsync("prefix:channel", "message", CommandFlags.HighPriority)); - } - - [Test] - public void ScriptEvaluateAsync_1() - { - byte[] hash = new byte[0]; - RedisValue[] values = new RedisValue[0]; - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.ScriptEvaluateAsync(hash, keys, values, CommandFlags.HighPriority); - mock.Verify(_ => _.ScriptEvaluateAsync(hash, It.Is(valid), values, CommandFlags.HighPriority)); - } - - [Test] - public void ScriptEvaluateAsync_2() - { - RedisValue[] values = new RedisValue[0]; - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.ScriptEvaluateAsync("script", keys, values, CommandFlags.HighPriority); - mock.Verify(_ => _.ScriptEvaluateAsync("script", It.Is(valid), values, CommandFlags.HighPriority)); - } - - [Test] - public void SetAddAsync_1() - { - wrapper.SetAddAsync("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.SetAddAsync("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void SetAddAsync_2() - { - RedisValue[] values = new RedisValue[0]; - wrapper.SetAddAsync("key", values, CommandFlags.HighPriority); - mock.Verify(_ => _.SetAddAsync("prefix:key", values, CommandFlags.HighPriority)); - } - - [Test] - public void SetCombineAndStoreAsync_1() - { - wrapper.SetCombineAndStoreAsync(SetOperation.Intersect, "destination", "first", "second", CommandFlags.HighPriority); - mock.Verify(_ => _.SetCombineAndStoreAsync(SetOperation.Intersect, "prefix:destination", "prefix:first", "prefix:second", CommandFlags.HighPriority)); - } - - [Test] - public void SetCombineAndStoreAsync_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.SetCombineAndStoreAsync(SetOperation.Intersect, "destination", keys, CommandFlags.HighPriority); - mock.Verify(_ => _.SetCombineAndStoreAsync(SetOperation.Intersect, "prefix:destination", It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void SetCombineAsync_1() - { - wrapper.SetCombineAsync(SetOperation.Intersect, "first", "second", CommandFlags.HighPriority); - mock.Verify(_ => _.SetCombineAsync(SetOperation.Intersect, "prefix:first", "prefix:second", CommandFlags.HighPriority)); - } - - [Test] - public void SetCombineAsync_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.SetCombineAsync(SetOperation.Intersect, keys, CommandFlags.HighPriority); - mock.Verify(_ => _.SetCombineAsync(SetOperation.Intersect, It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void SetContainsAsync() - { - wrapper.SetContainsAsync("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.SetContainsAsync("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void SetLengthAsync() - { - wrapper.SetLengthAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.SetLengthAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void SetMembersAsync() - { - wrapper.SetMembersAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.SetMembersAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void SetMoveAsync() - { - wrapper.SetMoveAsync("source", "destination", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.SetMoveAsync("prefix:source", "prefix:destination", "value", CommandFlags.HighPriority)); - } - - [Test] - public void SetPopAsync() - { - wrapper.SetPopAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.SetPopAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void SetRandomMemberAsync() - { - wrapper.SetRandomMemberAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.SetRandomMemberAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void SetRandomMembersAsync() - { - wrapper.SetRandomMembersAsync("key", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.SetRandomMembersAsync("prefix:key", 123, CommandFlags.HighPriority)); - } - - [Test] - public void SetRemoveAsync_1() - { - wrapper.SetRemoveAsync("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.SetRemoveAsync("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void SetRemoveAsync_2() - { - RedisValue[] values = new RedisValue[0]; - wrapper.SetRemoveAsync("key", values, CommandFlags.HighPriority); - mock.Verify(_ => _.SetRemoveAsync("prefix:key", values, CommandFlags.HighPriority)); - } - - [Test] - public void SortAndStoreAsync() - { - RedisValue[] get = new RedisValue[] { "a", "#" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "#"; - - wrapper.SortAndStoreAsync("destination", "key", 123, 456, Order.Descending, SortType.Alphabetic, "nosort", get, CommandFlags.HighPriority); - wrapper.SortAndStoreAsync("destination", "key", 123, 456, Order.Descending, SortType.Alphabetic, "by", get, CommandFlags.HighPriority); - - mock.Verify(_ => _.SortAndStoreAsync("prefix:destination", "prefix:key", 123, 456, Order.Descending, SortType.Alphabetic, "nosort", It.Is(valid), CommandFlags.HighPriority)); - mock.Verify(_ => _.SortAndStoreAsync("prefix:destination", "prefix:key", 123, 456, Order.Descending, SortType.Alphabetic, "prefix:by", It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void SortAsync() - { - RedisValue[] get = new RedisValue[] { "a", "#" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "#"; - - wrapper.SortAsync("key", 123, 456, Order.Descending, SortType.Alphabetic, "nosort", get, CommandFlags.HighPriority); - wrapper.SortAsync("key", 123, 456, Order.Descending, SortType.Alphabetic, "by", get, CommandFlags.HighPriority); - - mock.Verify(_ => _.SortAsync("prefix:key", 123, 456, Order.Descending, SortType.Alphabetic, "nosort", It.Is(valid), CommandFlags.HighPriority)); - mock.Verify(_ => _.SortAsync("prefix:key", 123, 456, Order.Descending, SortType.Alphabetic, "prefix:by", It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetAddAsync_1() - { - wrapper.SortedSetAddAsync("key", "member", 1.23, When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetAddAsync("prefix:key", "member", 1.23, When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetAddAsync_2() - { - SortedSetEntry[] values = new SortedSetEntry[0]; - wrapper.SortedSetAddAsync("key", values, When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetAddAsync("prefix:key", values, When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetCombineAndStoreAsync_1() - { - wrapper.SortedSetCombineAndStoreAsync(SetOperation.Intersect, "destination", "first", "second", Aggregate.Max, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetCombineAndStoreAsync(SetOperation.Intersect, "prefix:destination", "prefix:first", "prefix:second", Aggregate.Max, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetCombineAndStoreAsync_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.SetCombineAndStoreAsync(SetOperation.Intersect, "destination", keys, CommandFlags.HighPriority); - mock.Verify(_ => _.SetCombineAndStoreAsync(SetOperation.Intersect, "prefix:destination", It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetDecrementAsync() - { - wrapper.SortedSetDecrementAsync("key", "member", 1.23, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetDecrementAsync("prefix:key", "member", 1.23, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetIncrementAsync() - { - wrapper.SortedSetIncrementAsync("key", "member", 1.23, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetIncrementAsync("prefix:key", "member", 1.23, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetLengthAsync() - { - wrapper.SortedSetLengthAsync("key", 1.23, 1.23, Exclude.Start, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetLengthAsync("prefix:key", 1.23, 1.23, Exclude.Start, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetLengthByValueAsync() - { - wrapper.SortedSetLengthByValueAsync("key", "min", "max", Exclude.Start, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetLengthByValueAsync("prefix:key", "min", "max", Exclude.Start, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRangeByRankAsync() - { - wrapper.SortedSetRangeByRankAsync("key", 123, 456, Order.Descending, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRangeByRankAsync("prefix:key", 123, 456, Order.Descending, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRangeByRankWithScoresAsync() - { - wrapper.SortedSetRangeByRankWithScoresAsync("key", 123, 456, Order.Descending, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRangeByRankWithScoresAsync("prefix:key", 123, 456, Order.Descending, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRangeByScoreAsync() - { - wrapper.SortedSetRangeByScoreAsync("key", 1.23, 1.23, Exclude.Start, Order.Descending, 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRangeByScoreAsync("prefix:key", 1.23, 1.23, Exclude.Start, Order.Descending, 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRangeByScoreWithScoresAsync() - { - wrapper.SortedSetRangeByScoreWithScoresAsync("key", 1.23, 1.23, Exclude.Start, Order.Descending, 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRangeByScoreWithScoresAsync("prefix:key", 1.23, 1.23, Exclude.Start, Order.Descending, 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRangeByValueAsync() - { - wrapper.SortedSetRangeByValueAsync("key", "min", "max", Exclude.Start, 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRangeByValueAsync("prefix:key", "min", "max", Exclude.Start, 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRankAsync() - { - wrapper.SortedSetRankAsync("key", "member", Order.Descending, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRankAsync("prefix:key", "member", Order.Descending, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRemoveAsync_1() - { - wrapper.SortedSetRemoveAsync("key", "member", CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRemoveAsync("prefix:key", "member", CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRemoveAsync_2() - { - RedisValue[] members = new RedisValue[0]; - wrapper.SortedSetRemoveAsync("key", members, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRemoveAsync("prefix:key", members, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRemoveRangeByRankAsync() - { - wrapper.SortedSetRemoveRangeByRankAsync("key", 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRemoveRangeByRankAsync("prefix:key", 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRemoveRangeByScoreAsync() - { - wrapper.SortedSetRemoveRangeByScoreAsync("key", 1.23, 1.23, Exclude.Start, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRemoveRangeByScoreAsync("prefix:key", 1.23, 1.23, Exclude.Start, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetRemoveRangeByValueAsync() - { - wrapper.SortedSetRemoveRangeByValueAsync("key", "min", "max", Exclude.Start, CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetRemoveRangeByValueAsync("prefix:key", "min", "max", Exclude.Start, CommandFlags.HighPriority)); - } - - [Test] - public void SortedSetScoreAsync() - { - wrapper.SortedSetScoreAsync("key", "member", CommandFlags.HighPriority); - mock.Verify(_ => _.SortedSetScoreAsync("prefix:key", "member", CommandFlags.HighPriority)); - } - - [Test] - public void StringAppendAsync() - { - wrapper.StringAppendAsync("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.StringAppendAsync("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void StringBitCountAsync() - { - wrapper.StringBitCountAsync("key", 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.StringBitCountAsync("prefix:key", 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void StringBitOperationAsync_1() - { - wrapper.StringBitOperationAsync(Bitwise.Xor, "destination", "first", "second", CommandFlags.HighPriority); - mock.Verify(_ => _.StringBitOperationAsync(Bitwise.Xor, "prefix:destination", "prefix:first", "prefix:second", CommandFlags.HighPriority)); - } - - [Test] - public void StringBitOperationAsync_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.StringBitOperationAsync(Bitwise.Xor, "destination", keys, CommandFlags.HighPriority); - mock.Verify(_ => _.StringBitOperationAsync(Bitwise.Xor, "prefix:destination", It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void StringBitPositionAsync() - { - wrapper.StringBitPositionAsync("key", true, 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.StringBitPositionAsync("prefix:key", true, 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void StringDecrementAsync_1() - { - wrapper.StringDecrementAsync("key", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.StringDecrementAsync("prefix:key", 123, CommandFlags.HighPriority)); - } - - [Test] - public void StringDecrementAsync_2() - { - wrapper.StringDecrementAsync("key", 1.23, CommandFlags.HighPriority); - mock.Verify(_ => _.StringDecrementAsync("prefix:key", 1.23, CommandFlags.HighPriority)); - } - - [Test] - public void StringGetAsync_1() - { - wrapper.StringGetAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.StringGetAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void StringGetAsync_2() - { - RedisKey[] keys = new RedisKey[] { "a", "b" }; - Expression> valid = _ => _.Length == 2 && _[0] == "prefix:a" && _[1] == "prefix:b"; - wrapper.StringGetAsync(keys, CommandFlags.HighPriority); - mock.Verify(_ => _.StringGetAsync(It.Is(valid), CommandFlags.HighPriority)); - } - - [Test] - public void StringGetBitAsync() - { - wrapper.StringGetBitAsync("key", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.StringGetBitAsync("prefix:key", 123, CommandFlags.HighPriority)); - } - - [Test] - public void StringGetRangeAsync() - { - wrapper.StringGetRangeAsync("key", 123, 456, CommandFlags.HighPriority); - mock.Verify(_ => _.StringGetRangeAsync("prefix:key", 123, 456, CommandFlags.HighPriority)); - } - - [Test] - public void StringGetSetAsync() - { - wrapper.StringGetSetAsync("key", "value", CommandFlags.HighPriority); - mock.Verify(_ => _.StringGetSetAsync("prefix:key", "value", CommandFlags.HighPriority)); - } - - [Test] - public void StringGetWithExpiryAsync() - { - wrapper.StringGetWithExpiryAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.StringGetWithExpiryAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void StringIncrementAsync_1() - { - wrapper.StringIncrementAsync("key", 123, CommandFlags.HighPriority); - mock.Verify(_ => _.StringIncrementAsync("prefix:key", 123, CommandFlags.HighPriority)); - } - - [Test] - public void StringIncrementAsync_2() - { - wrapper.StringIncrementAsync("key", 1.23, CommandFlags.HighPriority); - mock.Verify(_ => _.StringIncrementAsync("prefix:key", 1.23, CommandFlags.HighPriority)); - } - - [Test] - public void StringLengthAsync() - { - wrapper.StringLengthAsync("key", CommandFlags.HighPriority); - mock.Verify(_ => _.StringLengthAsync("prefix:key", CommandFlags.HighPriority)); - } - - [Test] - public void StringSetAsync_1() - { - TimeSpan expiry = TimeSpan.FromSeconds(123); - wrapper.StringSetAsync("key", "value", expiry, When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.StringSetAsync("prefix:key", "value", expiry, When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void StringSetAsync_2() - { - KeyValuePair[] values = new KeyValuePair[] { new KeyValuePair("a", "x"), new KeyValuePair("b", "y") }; - Expression[], bool>> valid = _ => _.Length == 2 && _[0].Key == "prefix:a" && _[0].Value == "x" && _[1].Key == "prefix:b" && _[1].Value == "y"; - wrapper.StringSetAsync(values, When.Exists, CommandFlags.HighPriority); - mock.Verify(_ => _.StringSetAsync(It.Is(valid), When.Exists, CommandFlags.HighPriority)); - } - - [Test] - public void StringSetBitAsync() - { - wrapper.StringSetBitAsync("key", 123, true, CommandFlags.HighPriority); - mock.Verify(_ => _.StringSetBitAsync("prefix:key", 123, true, CommandFlags.HighPriority)); - } - - [Test] - public void StringSetRangeAsync() - { - wrapper.StringSetRangeAsync("key", 123, "value", CommandFlags.HighPriority); - mock.Verify(_ => _.StringSetRangeAsync("prefix:key", 123, "value", CommandFlags.HighPriority)); - } - } -} -#endif diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/packages.config b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/packages.config deleted file mode 100644 index 96adc90..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.Tests/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.dll b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.dll new file mode 100644 index 0000000000000000000000000000000000000000..c10cc088d55f4e70b283056c5c56878a6836e5e2 GIT binary patch literal 357888 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
I?aX7jAO5Bh;@ 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 - OK - PONG \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.snk b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis.snk deleted file mode 100644 index 5666fddb1e2c0cd7ac6121dc2f7b3ed34b632b8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097Zk*101*p&-Jsi=r+s?zEh4tk1(PZf-t zm^56a0G!<;V#rT6j~q5w!7{VJ_fACr7Ot}8vs1R<{sQ?UpioB)uBNU#iDbm@&yP+hTg%@-` zJczRb@}fR}ccx0RLrS^FoI%jrqDBAt1=JR7ZbCb=zn=%F-Zfw^cO6MZt=ZzBoEJ2Z z;$9|WeuC!LpJ(6J@M(p~eH9!wIg=I9vSv=_o#x%vG7#IDK1L?ajbNp&u9ZBuxbe=A z2)3!XRJ}snM-HsJj#3&Ob=xa3x&(Ljj}fl}YI6US3HBH3dO{=E`{6jpYsm$`(paw<6RKvj!-VsB8~_z$ z71Gfy@U9rIjMh%NlvI6Nbf3|l4E>vPV*ayg%%kVosZo%mx9lp*K-_~IF9b=vScGZ? i?~;1>3gx6NIBwVfrBVT4)T%#rSz)ZLTMB~-olg)IStAVq diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/Properties/AssemblyInfo.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/Properties/AssemblyInfo.cs deleted file mode 100644 index aeae19e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("StackExchange.Redis")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("StackExchange.Redis")] -[assembly: AssemblyCopyright("Copyright © 2016")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f411ad3e-53ca-4104-9c63-b1af9657ca1c")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: AssemblyInformationalVersion("1.0.0.0")] - -[assembly: CLSCompliant(true)] \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange.Redis.csproj b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange.Redis.csproj deleted file mode 100644 index d64d196..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange.Redis.csproj +++ /dev/null @@ -1,70 +0,0 @@ - - - - $(LibraryTargetFrameworks) - High performance Redis client, incorporating both synchronous and asynchronous usage. - StackExchange.Redis - true - StackExchange.Redis - StackExchange.Redis - Async;Redis;Cache;PubSub;Messaging - Library - - - - - - - - - - - - - - - - - - - - - - - - - - - $(DefineConstants);FEATURE_SERIALIZATION;FEATURE_SOCKET_MODE_POLL - - - - $(DefineConstants);CORE_CLR - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/AssemblyInfoHack.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/AssemblyInfoHack.cs deleted file mode 100644 index 07307cf..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/AssemblyInfoHack.cs +++ /dev/null @@ -1,7 +0,0 @@ -// Yes, this is embarassing. However, in .NET Core the including AssemblyInfo (ifdef'd or not) will screw with -// your version numbers. Therefore, we need to move the attribute out into another file...this file. -// When .csproj merges in, this should be able to return to Properties/AssemblyInfo.cs -#if !STRONG_NAME -using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("StackExchange.Redis.Tests")] -#endif \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Aggregate.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Aggregate.cs deleted file mode 100644 index 662eca9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Aggregate.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// Specifies how elements should be aggregated when combining sorted sets - /// - public enum Aggregate - { - /// - /// The values of the combined elements are added - /// - Sum, - /// - /// The least value of the combined elements is used - /// - Min, - /// - /// The greatest value of the combined elements is used - /// - Max - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Bitwise.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Bitwise.cs deleted file mode 100644 index e09f26b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Bitwise.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// Bitwise operators - /// - public enum Bitwise - { - /// - /// And - /// - And, - /// - /// Or - /// - Or, - /// - /// Xor - /// - Xor, - /// - /// Not - /// - Not - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClientFlags.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClientFlags.cs deleted file mode 100644 index b99a007..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClientFlags.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - /// - /// The client flags can be a combination of: - /// O: the client is a slave in MONITOR mode - /// S: the client is a normal slave server - /// M: the client is a master - /// x: the client is in a MULTI/EXEC context - /// b: the client is waiting in a blocking operation - /// i: the client is waiting for a VM I/O (deprecated) - /// d: a watched keys has been modified - EXEC will fail - /// c: connection to be closed after writing entire reply - /// u: the client is unblocked - /// A: connection to be closed ASAP - /// N: no specific flag set - /// - [Flags] - public enum ClientFlags : long - { - /// - /// no specific flag set - /// - None = 0, - /// - /// the client is a slave in MONITOR mode - /// - SlaveMonitor = 1, - /// - /// the client is a normal slave server - /// - Slave = 2, - /// - /// the client is a master - /// - Master = 4, - /// - /// the client is in a MULTI/EXEC context - /// - Transaction = 8, - /// - /// the client is waiting in a blocking operation - /// - Blocked = 16, - /// - /// a watched keys has been modified - EXEC will fail - /// - TransactionDoomed = 32, - /// - /// connection to be closed after writing entire reply - /// - Closing = 64, - /// - /// the client is unblocked - /// - Unblocked = 128, - /// - /// connection to be closed ASAP - /// - CloseASAP = 256, - - } - - -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClientInfo.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClientInfo.cs deleted file mode 100644 index 6596fcf..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClientInfo.cs +++ /dev/null @@ -1,214 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Net; - -namespace StackExchange.Redis -{ - /// - /// Represents the state of an individual client connection to redis - /// - public sealed class ClientInfo - { - internal static readonly ResultProcessor Processor = new ClientInfoProcessor(); - - /// - /// Address (host and port) of the client - /// - public EndPoint Address { get; private set; } - - /// - /// total duration of the connection in seconds - /// - public int AgeSeconds { get; private set; } - - /// - /// current database ID - /// - public int Database { get; private set; } - - /// - /// The flags associated with this connection - /// - public ClientFlags Flags { get; private set; } - - /// - /// The client flags can be a combination of: - /// O: the client is a slave in MONITOR mode - /// S: the client is a normal slave server - /// M: the client is a master - /// x: the client is in a MULTI/EXEC context - /// b: the client is waiting in a blocking operation - /// i: the client is waiting for a VM I/O (deprecated) - /// d: a watched keys has been modified - EXEC will fail - /// c: connection to be closed after writing entire reply - /// u: the client is unblocked - /// A: connection to be closed ASAP - /// N: no specific flag set - /// - public string FlagsRaw { get; private set; } - - /// - /// The host of the client (typically an IP address) - /// - public string Host - { - get - { - string host; - int port; - return Format.TryGetHostPort(Address, out host, out port) ? host : null; - } - } - - /// - /// idle time of the connection in seconds - /// - public int IdleSeconds { get; private set; } - - /// - /// last command played - /// - public string LastCommand { get; private set; } - - /// - /// The name allocated to this connection, if any - /// - public string Name { get; private set; } - - /// - /// number of pattern matching subscriptions - /// - public int PatternSubscriptionCount { get; private set; } - - /// - /// The port of the client - /// - public int Port - { - get - { - string host; - int port; - return Format.TryGetHostPort(Address, out host, out port) ? port : 0; - } - } - /// - /// The raw content from redis - /// - public string Raw { get; private set; } - - /// - /// number of channel subscriptions - /// - public int SubscriptionCount { get; private set; } - - /// - /// number of commands in a MULTI/EXEC context - /// - public int TransactionCommandLength { get; private set; } - - /// - /// an unique 64-bit client ID (introduced in Redis 2.8.12). - /// - public long Id { get;private set; } - - /// - /// Format the object as a string - /// - public override string ToString() - { - string addr = Format.ToString(Address); - return string.IsNullOrWhiteSpace(Name) ? addr : (addr + " - " + Name); - } - - /// - /// The class of the connection - /// - public ClientType ClientType - { - get - { - if (SubscriptionCount != 0 || PatternSubscriptionCount != 0) return ClientType.PubSub; - if ((Flags & ClientFlags.Slave) != 0) return ClientType.Slave; - return ClientType.Normal; - } - } - - internal static ClientInfo[] Parse(string input) - { - if (input == null) return null; - - var clients = new List(); - using (var reader = new StringReader(input)) - { - string line; - while ((line = reader.ReadLine()) != null) - { - var client = new ClientInfo(); - client.Raw = line; - string[] tokens = line.Split(StringSplits.Space); - for (int i = 0; i < tokens.Length; i++) - { - string tok = tokens[i]; - int idx = tok.IndexOf('='); - if (idx < 0) continue; - string key = tok.Substring(0, idx), value = tok.Substring(idx + 1); - - switch (key) - { - case "addr": client.Address = Format.TryParseEndPoint(value); break; - case "age": client.AgeSeconds = Format.ParseInt32(value); break; - case "idle": client.IdleSeconds = Format.ParseInt32(value); break; - case "db": client.Database = Format.ParseInt32(value); break; - case "name": client.Name = value; break; - case "sub": client.SubscriptionCount = Format.ParseInt32(value); break; - case "psub": client.PatternSubscriptionCount = Format.ParseInt32(value); break; - case "multi": client.TransactionCommandLength = Format.ParseInt32(value); break; - case "cmd": client.LastCommand = value; break; - case "flags": - client.FlagsRaw = value; - ClientFlags flags = ClientFlags.None; - AddFlag(ref flags, value, ClientFlags.SlaveMonitor, 'O'); - AddFlag(ref flags, value, ClientFlags.Slave, 'S'); - AddFlag(ref flags, value, ClientFlags.Master, 'M'); - AddFlag(ref flags, value, ClientFlags.Transaction, 'x'); - AddFlag(ref flags, value, ClientFlags.Blocked, 'b'); - AddFlag(ref flags, value, ClientFlags.TransactionDoomed, 'd'); - AddFlag(ref flags, value, ClientFlags.Closing, 'c'); - AddFlag(ref flags, value, ClientFlags.Unblocked, 'u'); - AddFlag(ref flags, value, ClientFlags.CloseASAP, 'A'); - client.Flags = flags; - break; - case "id": client.Id = Format.ParseInt64(value); break; - } - } - clients.Add(client); - } - } - - return clients.ToArray(); - } - - static void AddFlag(ref ClientFlags value, string raw, ClientFlags toAdd, char token) - { - if (raw.IndexOf(token) >= 0) value |= toAdd; - } - - private class ClientInfoProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch(result.Type) - { - case ResultType.BulkString: - - var raw = result.GetString(); - var clients = Parse(raw); - SetResult(message, clients); - return true; - } - return false; - } - } - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClientType.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClientType.cs deleted file mode 100644 index 03888c0..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClientType.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// The class of the connection - /// - public enum ClientType - { - /// - /// Regular connections, including MONITOR connections - /// - Normal, - /// - /// Replication connections - /// - Slave, - /// - /// Subscription connections - /// - PubSub - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClusterConfiguration.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClusterConfiguration.cs deleted file mode 100644 index 7d1a033..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ClusterConfiguration.cs +++ /dev/null @@ -1,519 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Indicates a range of slots served by a cluster node - /// - public struct SlotRange : IEquatable, IComparable, IComparable - { - private readonly short from, to; - - /// - /// Create a new SlotRange value - /// - public SlotRange(int from, int to) - { - checked - { - this.from = (short)from; - this.to = (short)to; - } - } - - private SlotRange(short from, short to) - { - this.from = from; - this.to = to; - } - /// - /// The start of the range (inclusive) - /// - public int From => from; - - /// - /// The end of the range (inclusive) - /// - public int To => to; - - /// - /// Indicates whether two ranges are not equal - /// - public static bool operator !=(SlotRange x, SlotRange y) - { - return x.from != y.from || x.to != y.to; - } - - /// - /// Indicates whether two ranges are equal - /// - public static bool operator ==(SlotRange x, SlotRange y) - { - return x.from == y.from && x.to == y.to; - } - - /// - /// Try to parse a string as a range - /// - public static bool TryParse(string range, out SlotRange value) - { - if (string.IsNullOrWhiteSpace(range)) - { - value = default(SlotRange); - return false; - } - int i = range.IndexOf('-'); - short from, to; - if (i < 0) - { - if (TryParseInt16(range, 0, range.Length, out from)) - { - value = new SlotRange(from, from); - return true; - } - } - else - { - if (TryParseInt16(range, 0, i++, out from) && TryParseInt16(range, i, range.Length - i, out to)) - { - value = new SlotRange(from, to); - return true; - } - } - value = default(SlotRange); - return false; - } - - /// - /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object. - /// - public int CompareTo(SlotRange other) - { - int delta = (int)this.from - (int)other.from; - return delta == 0 ? (int)this.to - (int)other.to : delta; - } - - /// - /// See Object.Equals - /// - public override bool Equals(object obj) - { - if (obj is SlotRange) - { - return Equals((SlotRange)obj); - } - return false; - } - /// - /// Indicates whether two ranges are equal - /// - public bool Equals(SlotRange range) - { - return range.from == this.from && range.to == this.to; - } - - /// - /// See Object.GetHashCode() - /// - public override int GetHashCode() - { - int x = from, y = to; // makes CS0675 a little happier - return x | (y << 16); - } - - /// - /// See Object.ToString() - /// - public override string ToString() - { - return from == to ? from.ToString() : (from + "-" + to); - } - internal bool Includes(int hashSlot) - { - return hashSlot >= from && hashSlot <= to; - } - - static bool TryParseInt16(string s, int offset, int count, out short value) - { - checked - { - value = 0; - int tmp = 0; - for (int i = 0; i < count; i++) - { - char c = s[offset + i]; - if (c < '0' || c > '9') return false; - tmp = (tmp * 10) + (c - '0'); - } - value = (short)tmp; - return true; - } - } - - int IComparable.CompareTo(object obj) - { - return obj is SlotRange ? CompareTo((SlotRange)obj) : -1; - } - } - - /// - /// Describes the state of the cluster as reported by a single node - /// - public sealed class ClusterConfiguration - { - private readonly Dictionary nodeLookup = new Dictionary(); - - private readonly ServerSelectionStrategy serverSelectionStrategy; - internal ClusterConfiguration(ServerSelectionStrategy serverSelectionStrategy, string nodes, EndPoint origin) - { - // Beware: Any exception thrown here will wreak silent havoc like inability to connect to cluster nodes or non returning calls - this.serverSelectionStrategy = serverSelectionStrategy; - this.Origin = origin; - using (var reader = new StringReader(nodes)) - { - string line; - while ((line = reader.ReadLine()) != null) - { - if (string.IsNullOrWhiteSpace(line)) continue; - var node = new ClusterNode(this, line, origin); - - // Be resilient to ":0 {master,slave},fail,noaddr" nodes, and nodes where the endpoint doesn't parse - if (node.IsNoAddr || node.EndPoint == null) - continue; - - // Override the origin value with the endpoint advertised with the target node to - // make sure that things like clusterConfiguration[clusterConfiguration.Origin] - // will work as expected. - if (node.IsMyself) - this.Origin = node.EndPoint; - - if (nodeLookup.ContainsKey(node.EndPoint)) - { - // Deal with conflicting node entries for the same endpoint - // This can happen in dynamic environments when a node goes down and a new one is created - // to replace it. - if (!node.IsConnected) - { - // The node we're trying to add is probably about to become stale. Ignore it. - continue; - } - else if (!nodeLookup[node.EndPoint].IsConnected) - { - // The node we registered previously is probably stale. Replace it with a known good node. - nodeLookup[node.EndPoint] = node; - } - else - { - // We have conflicting connected nodes. There's nothing much we can do other than - // wait for the cluster state to converge and refresh on the next pass. - // The same is true if we have multiple disconnected nodes. - } - } - else - { - nodeLookup.Add(node.EndPoint, node); - } - } - } - } - - /// - /// Gets all nodes contained in the configuration - /// - /// - public ICollection Nodes => nodeLookup.Values; - - /// - /// The node that was asked for the configuration - /// - public EndPoint Origin { get; } - - /// - /// Obtain the node relating to a specified endpoint - /// - public ClusterNode this[EndPoint endpoint] - { - get - { - ClusterNode result; - return endpoint == null ? null - : nodeLookup.TryGetValue(endpoint, out result) ? result : null; - } - } - - internal ClusterNode this[string nodeId] - { - get - { - if (string.IsNullOrWhiteSpace(nodeId)) return null; - foreach (var pair in nodeLookup) - { - if (pair.Value.NodeId == nodeId) return pair.Value; - } - return null; - } - } - - /// - /// Gets the node that serves the specified slot - /// - public ClusterNode GetBySlot(int slot) - { - foreach(var node in Nodes) - { - if (!node.IsSlave && node.ServesSlot(slot)) return node; - } - return null; - } - /// - /// Gets the node that serves the specified slot - /// - public ClusterNode GetBySlot(RedisKey key) - { - return GetBySlot(serverSelectionStrategy.HashSlot(key)); - } - } - - - /// - /// Represents the configuration of a single node in a cluster configuration - /// - public sealed class ClusterNode : IEquatable, IComparable, IComparable - { - private static readonly ClusterNode Dummy = new ClusterNode(); - - private static readonly IList NoNodes = new ClusterNode[0]; - - private static readonly IList NoSlots = new SlotRange[0]; - - private readonly ClusterConfiguration configuration; - - private IList children; - - private ClusterNode parent; - - private string toString; - - internal ClusterNode() { } - internal ClusterNode(ClusterConfiguration configuration, string raw, EndPoint origin) - { - // http://redis.io/commands/cluster-nodes - this.configuration = configuration; - this.Raw = raw; - var parts = raw.Split(StringSplits.Space); - - var flags = parts[2].Split(StringSplits.Comma); - - // redis 4 changes the format of "cluster nodes" - adds @... to the endpoint - var ep = parts[1]; - int at = ep.IndexOf('@'); - if (at >= 0) ep = ep.Substring(0, at); - - EndPoint = Format.TryParseEndPoint(ep); - if (flags.Contains("myself")) - { - IsMyself = true; - if (EndPoint == null) - { - // Unconfigured cluster nodes might report themselves as endpoint ":{port}", - // hence the origin fallback value to make sure that we can address them - EndPoint = origin; - } - } - - NodeId = parts[0]; - IsSlave = flags.Contains("slave"); - IsNoAddr = flags.Contains("noaddr"); - ParentNodeId = string.IsNullOrWhiteSpace(parts[3]) ? null : parts[3]; - - List slots = null; - - for (int i = 8; i < parts.Length; i++) - { - SlotRange range; - if (SlotRange.TryParse(parts[i], out range)) - { - if(slots == null) slots = new List(parts.Length - i); - slots.Add(range); - } - } - this.Slots = slots?.AsReadOnly() ?? NoSlots; - this.IsConnected = parts[7] == "connected"; // Can be "connected" or "disconnected" - } - /// - /// Gets all child nodes of the current node - /// - public IList Children - { - get - { - if (children != null) return children; - - List nodes = null; - foreach (var node in configuration.Nodes) - { - if (node.ParentNodeId == this.NodeId) - { - if (nodes == null) nodes = new List(); - nodes.Add(node); - } - } - children = nodes?.AsReadOnly() ?? NoNodes; - return children; - } - } - - /// - /// Gets the endpoint of the current node - /// - public EndPoint EndPoint { get; } - - /// - /// Gets whether this is the node which responded to the CLUSTER NODES request - /// - public bool IsMyself { get; } - - /// - /// Gets whether this node is a slave - /// - public bool IsSlave { get; } - - /// - /// Gets whether this node is flagged as noaddr - /// - public bool IsNoAddr { get; } - - /// - /// Gets the node's connection status - /// - public bool IsConnected { get; } - - /// - /// Gets the unique node-id of the current node - /// - public string NodeId { get; } - - /// - /// Gets the parent node of the current node - /// - public ClusterNode Parent - { - get - { - if (parent != null) return parent == Dummy ? null : parent; - ClusterNode found = configuration[ParentNodeId]; - parent = found ?? Dummy; - return found; - } - } - - /// - /// Gets the unique node-id of the parent of the current node - /// - public string ParentNodeId { get; } - - /// - /// The configuration as reported by the server - /// - public string Raw { get; } - - /// - /// The slots owned by this server - /// - public IList Slots { get; } - - /// - /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object. - /// - public int CompareTo(ClusterNode other) - { - if (other == null) return -1; - - if (this.IsSlave != other.IsSlave) return IsSlave ? 1 : -1; // masters first - - if (IsSlave) // both slaves? compare by parent, so we get masters A, B, C and then slaves of A, B, C - { - int i = string.CompareOrdinal(this.ParentNodeId, other.ParentNodeId); - if (i != 0) return i; - } - return string.CompareOrdinal(this.NodeId, other.NodeId); - - } - - /// - /// See Object.Equals - /// - public override bool Equals(object obj) - { - return Equals(obj as ClusterNode); - } - - /// - /// Indicates whether two ClusterNode instances are equivalent - /// - public bool Equals(ClusterNode node) - { - if (node == null) return false; - - return this.ToString() == node.ToString(); // lazy, but effective - plus only computes once - } - - /// - /// See object.GetHashCode() - /// - public override int GetHashCode() - { - return ToString().GetHashCode(); - } - - /// - /// See Object.ToString() - /// - public override string ToString() - { - if (toString != null) return toString; - var sb = new StringBuilder().Append(NodeId).Append(" at ").Append(EndPoint); - if(IsSlave) - { - sb.Append(", slave of ").Append(ParentNodeId); - var parent = Parent; - if (parent != null) sb.Append(" at ").Append(parent.EndPoint); - } - var childCount = Children.Count; - switch(childCount) - { - case 0: break; - case 1: sb.Append(", 1 slave"); break; - default: sb.Append(", ").Append(childCount).Append(" slaves"); break; - } - if(Slots.Count != 0) - { - sb.Append(", slots: "); - foreach(var slot in Slots) - { - sb.Append(slot).Append(' '); - } - sb.Length -= 1; // remove tailing space - } - return toString = sb.ToString(); - } - internal bool ServesSlot(int hashSlot) - { - foreach (var slot in Slots) - { - if (slot.Includes(hashSlot)) return true; - } - return false; - } - - int IComparable.CompareTo(object obj) - { - return CompareTo(obj as ClusterNode); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandFlags.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandFlags.cs deleted file mode 100644 index 1a17a88..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandFlags.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - /// - /// Behaviour markers associated with a given command - /// - [Flags] - public enum CommandFlags - { - /// - /// Default behaviour. - /// - None = 0, - /// - /// This command may jump regular-priority commands that have not yet been written to the redis stream. - /// - HighPriority = 1, - /// - /// The caller is not interested in the result; the caller will immediately receive a default-value - /// of the expected return type (this value is not indicative of anything at the server). - /// - FireAndForget = 2, - - - /// - /// This operation should be performed on the master if it is available, but read operations may - /// be performed on a slave if no master is available. This is the default option. - /// - PreferMaster = 0, - - /// - /// This operation should only be performed on the master. - /// - DemandMaster = 4, - - /// - /// This operation should be performed on the slave if it is available, but will be performed on - /// a master if no slaves are available. Suitable for read operations only. - /// - PreferSlave = 8, - - /// - /// This operation should only be performed on a slave. Suitable for read operations only. - /// - DemandSlave = 12, - - // 16: reserved for additional "demand/prefer" options - - // 32: used for "asking" flag; never user-specified, so not visible on the public API - - /// - /// Indicates that this operation should not be forwarded to other servers as a result of an ASK or MOVED response - /// - NoRedirect = 64, - - // 128: used for "internal call"; never user-specified, so not visible on the public API - - // 256: used for "script unavailable"; never user-specified, so not visible on the public API - - /// - /// Indicates that script-related operations should use EVAL, not SCRIPT LOAD + EVALSHA - /// - NoScriptCache = 512, - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandMap.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandMap.cs deleted file mode 100644 index 8133350..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandMap.cs +++ /dev/null @@ -1,242 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Represents the commands mapped on a particular configuration - /// - public sealed class CommandMap - { - private readonly byte[][] map; - - internal CommandMap(byte[][] map) - { - this.map = map; - } - /// - /// The default commands specified by redis - /// - public static CommandMap Default { get; } = CreateImpl(null, null); - - /// - /// The commands available to https://github.com/twitter/twemproxy - /// - /// https://github.com/twitter/twemproxy/blob/master/notes/redis.md - public static CommandMap Twemproxy { get; } = CreateImpl(null, exclusions: new HashSet - { - // see https://github.com/twitter/twemproxy/blob/master/notes/redis.md - RedisCommand.KEYS, RedisCommand.MIGRATE, RedisCommand.MOVE, RedisCommand.OBJECT, RedisCommand.RANDOMKEY, - RedisCommand.RENAME, RedisCommand.RENAMENX, RedisCommand.SORT, RedisCommand.SCAN, - - RedisCommand.BITOP, RedisCommand.MSET, RedisCommand.MSETNX, - - RedisCommand.HSCAN, - - RedisCommand.BLPOP, RedisCommand.BRPOP, RedisCommand.BRPOPLPUSH, // yeah, me neither! - - RedisCommand.SSCAN, - - RedisCommand.ZSCAN, - - RedisCommand.PSUBSCRIBE, RedisCommand.PUBLISH, RedisCommand.PUNSUBSCRIBE, RedisCommand.SUBSCRIBE, RedisCommand.UNSUBSCRIBE, - - RedisCommand.DISCARD, RedisCommand.EXEC, RedisCommand.MULTI, RedisCommand.UNWATCH, RedisCommand.WATCH, - - RedisCommand.SCRIPT, - - RedisCommand.ECHO, RedisCommand.PING, RedisCommand.QUIT, RedisCommand.SELECT, - - RedisCommand.BGREWRITEAOF, RedisCommand.BGSAVE, RedisCommand.CLIENT, RedisCommand.CLUSTER, RedisCommand.CONFIG, RedisCommand.DBSIZE, - RedisCommand.DEBUG, RedisCommand.FLUSHALL, RedisCommand.FLUSHDB, RedisCommand.INFO, RedisCommand.LASTSAVE, RedisCommand.MONITOR, RedisCommand.SAVE, - RedisCommand.SHUTDOWN, RedisCommand.SLAVEOF, RedisCommand.SLOWLOG, RedisCommand.SYNC, RedisCommand.TIME - }); - - /// - /// The commands available to http://www.ideawu.com/ssdb/ - /// - /// http://www.ideawu.com/ssdb/docs/redis-to-ssdb.html - public static CommandMap SSDB { get; } = Create(new HashSet { - // see http://www.ideawu.com/ssdb/docs/redis-to-ssdb.html - "ping", - "get", "set", "del", "incr", "incrby", "mget", "mset", "keys", "getset", "setnx", - "hget", "hset", "hdel", "hincrby", "hkeys", "hvals", "hmget", "hmset", "hlen", - "zscore", "zadd", "zrem", "zrange", "zrangebyscore", "zincrby", "zdecrby", "zcard", - "llen", "lpush", "rpush", "lpop", "rpop", "lrange", "lindex" - }, true); - - /// - /// The commands available to http://redis.io/topics/sentinel - /// - /// http://redis.io/topics/sentinel - public static CommandMap Sentinel { get; } = Create(new HashSet { - // see http://redis.io/topics/sentinel - "ping", "info", "sentinel", "subscribe", "psubscribe", "unsubscribe", "punsubscribe" }, true); - - /// - /// Create a new CommandMap, customizing some commands - /// - public static CommandMap Create(Dictionary overrides) - { - if (overrides == null || overrides.Count == 0) return Default; - - if (ReferenceEquals(overrides.Comparer, StringComparer.OrdinalIgnoreCase)) - { - // that's ok; we're happy with ordinal/invariant case-insensitive - // (but not culture-specific insensitive; completely untested) - } - else - { - // need case insensitive - overrides = new Dictionary(overrides, StringComparer.OrdinalIgnoreCase); - } - return CreateImpl(overrides, null); - } - - /// - /// Creates a CommandMap by specifying which commands are available or unavailable - /// - public static CommandMap Create(HashSet commands, bool available = true) - { - - if (available) - { - var dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); - // nix everything - foreach (RedisCommand command in Enum.GetValues(typeof(RedisCommand))) - { - dictionary[command.ToString()] = null; - } - if (commands != null) - { - // then include (by removal) the things that are available - foreach (string command in commands) - { - dictionary.Remove(command); - } - } - return CreateImpl(dictionary, null); - } - else - { - HashSet exclusions = null; - if (commands != null) - { - // nix the things that are specified - foreach (var command in commands) - { - RedisCommand parsed; - if (Enum.TryParse(command, true, out parsed)) - { - (exclusions ?? (exclusions = new HashSet())).Add(parsed); - } - } - } - if (exclusions == null || exclusions.Count == 0) return Default; - return CreateImpl(null, exclusions); - } - - } - - /// - /// See Object.ToString() - /// - public override string ToString() - { - var sb = new StringBuilder(); - AppendDeltas(sb); - return sb.ToString(); - } - - internal void AppendDeltas(StringBuilder sb) - { - for (int i = 0; i < map.Length; i++) - { - var key = ((RedisCommand)i).ToString(); - var value = map[i] == null ? "" : Encoding.UTF8.GetString(map[i]); - if (key != value) - { - if (sb.Length != 0) sb.Append(','); - sb.Append('$').Append(key).Append('=').Append(value); - } - } - } - - internal void AssertAvailable(RedisCommand command) - { - if (map[(int)command] == null) throw ExceptionFactory.CommandDisabled(false, command, null, null); - } - - internal byte[] GetBytes(RedisCommand command) - { - return map[(int)command]; - } - internal byte[] GetBytes(string command) - { - if (command == null) return null; - if(Enum.TryParse(command, true, out RedisCommand cmd)) - { // we know that one! - return map[(int)cmd]; - } - var bytes = (byte[])_unknownCommands[command]; - if(bytes == null) - { - lock(_unknownCommands) - { // double-checked - bytes = (byte[])_unknownCommands[command]; - if(bytes == null) - { - bytes = Encoding.ASCII.GetBytes(command); - _unknownCommands[command] = bytes; - } - } - } - return bytes; - } - static readonly Hashtable _unknownCommands = new Hashtable(); - - internal bool IsAvailable(RedisCommand command) - { - return map[(int)command] != null; - } - - private static CommandMap CreateImpl(Dictionary caseInsensitiveOverrides, HashSet exclusions) - { - var commands = (RedisCommand[])Enum.GetValues(typeof(RedisCommand)); - - byte[][] map = new byte[commands.Length][]; - bool haveDelta = false; - for (int i = 0; i < commands.Length; i++) - { - int idx = (int)commands[i]; - string name = commands[i].ToString(), value = name; - - if (exclusions != null && exclusions.Contains(commands[i])) - { - map[idx] = null; - } - else - { - if (caseInsensitiveOverrides != null) - { - string tmp; - if (caseInsensitiveOverrides.TryGetValue(name, out tmp)) - { - value = tmp; - } - } - if (value != name) haveDelta = true; - // TODO: bug? - haveDelta = true; - byte[] val = string.IsNullOrWhiteSpace(value) ? null : Encoding.UTF8.GetBytes(value); - map[idx] = val; - } - } - if (!haveDelta && Default != null) return Default; - - return new CommandMap(map); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandStatus.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandStatus.cs deleted file mode 100644 index 550e2e8..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandStatus.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// track status of a command while communicating with Redis - /// - public enum CommandStatus - { - /// - /// command status unknown - /// - Unknown, - /// - /// ConnectionMultiplexer has not yet started writing this command to redis - /// - WaitingToBeSent, - /// - /// command has been sent to Redis - /// - Sent, - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandTrace.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandTrace.cs deleted file mode 100644 index 6e5fefb..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CommandTrace.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - /// - /// Represents the information known about long-running commands - /// - public sealed class CommandTrace - { - internal static readonly ResultProcessor Processor = new CommandTraceProcessor(); - - internal CommandTrace(long uniqueId, long time, long duration, RedisValue[] arguments) - { - UniqueId = uniqueId; - Time = RedisBase.UnixEpoch.AddSeconds(time); - // duration = The amount of time needed for its execution, in microseconds. - // A tick is equal to 100 nanoseconds, or one ten-millionth of a second. - // So 1 microsecond = 10 ticks - Duration = TimeSpan.FromTicks(duration * 10); - Arguments = arguments; - } - - /// - /// The array composing the arguments of the command. - /// - public RedisValue[] Arguments { get; private set; } - - /// - /// The amount of time needed for its execution - /// - public TimeSpan Duration { get; private set; } - - /// - /// The time at which the logged command was processed. - /// - public DateTime Time { get; private set; } - - /// - /// A unique progressive identifier for every slow log entry. - /// - /// The entry's unique ID can be used in order to avoid processing slow log entries multiple times (for instance you may have a script sending you an email alert for every new slow log entry). The ID is never reset in the course of the Redis server execution, only a server restart will reset it. - public long UniqueId { get; private set; } - - /// - /// Deduces a link to the redis documentation about the specified command - /// - public string GetHelpUrl() - { - if (Arguments == null || Arguments.Length == 0) return null; - - const string BaseUrl = "http://redis.io/commands/"; - - string encoded0 = Uri.EscapeUriString(((string)Arguments[0]).ToLowerInvariant()); - - if (Arguments.Length > 1) - { - - switch (encoded0) - { - case "script": - case "client": - case "cluster": - case "config": - case "debug": - case "pubsub": - string encoded1 = Uri.EscapeUriString(((string)Arguments[1]).ToLowerInvariant()); - return BaseUrl + encoded0 + "-" + encoded1; - } - } - return BaseUrl + encoded0; - } - - private class CommandTraceProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch(result.Type) - { - case ResultType.MultiBulk: - var parts = result.GetItems(); - CommandTrace[] arr = new CommandTrace[parts.Length]; - for (int i = 0; i < parts.Length; i++) - { - - var subParts = parts[i].GetItems(); - long uniqueid, time, duration; - if (!subParts[0].TryGetInt64(out uniqueid) || !subParts[1].TryGetInt64(out time) || !subParts[2].TryGetInt64(out duration)) - return false; - arr[i] = new CommandTrace(uniqueid, time, duration, subParts[3].GetItemsAsValues()); - } - SetResult(message, arr); - return true; - } - return false; - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Compat/ConvertHelper.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Compat/ConvertHelper.cs deleted file mode 100644 index 966f5c9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Compat/ConvertHelper.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - /// - /// Helper for Array.ConvertAll() as it's missing on .Net Core. - /// - public static class ConvertHelper - { - /// - /// Converts array of one type to an array of another type. - /// - /// Input type - /// Output type - /// source - /// selector - /// - public static TOutput[] ConvertAll(TInput[] source, Func selector) - { -#if CORE_CLR - TOutput[] arr = new TOutput[source.Length]; - for(int i = 0 ; i < arr.Length ; i++) - arr[i] = selector(source[i]); - return arr; -#else - return Array.ConvertAll(source, item => selector(item)); -#endif - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Compat/VolatileWrapper.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Compat/VolatileWrapper.cs deleted file mode 100644 index b86fb7a..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Compat/VolatileWrapper.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace StackExchange.Redis -{ - internal static class VolatileWrapper - { - public static int Read(ref int location) - { -#if !CORE_CLR - return System.Threading.Thread.VolatileRead(ref location); -#else - return System.Threading.Volatile.Read(ref location); -#endif - } - - public static void Write(ref int address, int value) - { -#if !CORE_CLR - System.Threading.Thread.VolatileWrite(ref address, value); -#else - System.Threading.Volatile.Write(ref address, value); -#endif - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CompletedDefaultTask.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CompletedDefaultTask.cs deleted file mode 100644 index e1775c4..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CompletedDefaultTask.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - internal static class CompletedTask - { - private static readonly Task @default = FromResult(default(T), null); - - public static Task Default(object asyncState) - { - return asyncState == null ? @default : FromResult(default(T), asyncState); - } - public static Task FromResult(T value, object asyncState) - { - // note we do not need to deny exec-sync here; the value will be known - // before we hand it to them - var tcs = TaskSource.Create(asyncState); - tcs.SetResult(value); - return tcs.Task; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CompletionManager.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CompletionManager.cs deleted file mode 100644 index cb67285..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/CompletionManager.cs +++ /dev/null @@ -1,195 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; - -namespace StackExchange.Redis -{ - sealed partial class CompletionManager - { - private static readonly WaitCallback processAsyncCompletionQueue = ProcessAsyncCompletionQueue, - anyOrderCompletionHandler = AnyOrderCompletionHandler; - - private readonly Queue asyncCompletionQueue = new Queue(); - - private readonly ConnectionMultiplexer multiplexer; - - private readonly string name; - - int activeAsyncWorkerThread = 0; - long completedSync, completedAsync, failedAsync; - public CompletionManager(ConnectionMultiplexer multiplexer, string name) - { - this.multiplexer = multiplexer; - this.name = name; - } - public void CompleteSyncOrAsync(ICompletable operation) - { - if (operation == null) return; - if (operation.TryComplete(false)) - { - multiplexer.Trace("Completed synchronously: " + operation, name); - Interlocked.Increment(ref completedSync); - return; - } - else - { - if (multiplexer.PreserveAsyncOrder) - { - multiplexer.Trace("Queueing for asynchronous completion", name); - bool startNewWorker; - lock (asyncCompletionQueue) - { - asyncCompletionQueue.Enqueue(operation); - startNewWorker = asyncCompletionQueue.Count == 1; - } - if (startNewWorker) - { - multiplexer.Trace("Starting new async completion worker", name); - OnCompletedAsync(); - ThreadPool.QueueUserWorkItem(processAsyncCompletionQueue, this); - } - } else - { - multiplexer.Trace("Using thread-pool for asynchronous completion", name); - ThreadPool.QueueUserWorkItem(anyOrderCompletionHandler, operation); - Interlocked.Increment(ref completedAsync); // k, *technically* we haven't actually completed this yet, but: close enough - } - } - } - internal void GetCounters(ConnectionCounters counters) - { - lock (asyncCompletionQueue) - { - counters.ResponsesAwaitingAsyncCompletion = asyncCompletionQueue.Count; - } - counters.CompletedSynchronously = Interlocked.Read(ref completedSync); - counters.CompletedAsynchronously = Interlocked.Read(ref completedAsync); - counters.FailedAsynchronously = Interlocked.Read(ref failedAsync); - } - - internal int GetOutstandingCount() - { - lock(asyncCompletionQueue) - { - return asyncCompletionQueue.Count; - } - } - - internal void GetStormLog(StringBuilder sb) - { - lock(asyncCompletionQueue) - { - if (asyncCompletionQueue.Count == 0) return; - sb.Append("Response awaiting completion: ").Append(asyncCompletionQueue.Count).AppendLine(); - int total = 0; - foreach(var item in asyncCompletionQueue) - { - if (++total >= 500) break; - item.AppendStormLog(sb); - sb.AppendLine(); - } - } - } - - private static void AnyOrderCompletionHandler(object state) - { - try - { - ConnectionMultiplexer.TraceWithoutContext("Completing async (any order): " + state); - ((ICompletable)state).TryComplete(true); - } - catch (Exception ex) - { - ConnectionMultiplexer.TraceWithoutContext("Async completion error: " + ex.Message); - } - } - - private static void ProcessAsyncCompletionQueue(object state) - { - ((CompletionManager)state).ProcessAsyncCompletionQueueImpl(); - } - - partial void OnCompletedAsync(); - private void ProcessAsyncCompletionQueueImpl() - { -#if NET40 - int currentThread = Thread.CurrentThread.ManagedThreadId; -#else - int currentThread = Environment.CurrentManagedThreadId; -#endif - - try - { - while (Interlocked.CompareExchange(ref activeAsyncWorkerThread, currentThread, 0) != 0) - { - // if we don't win the lock, check whether there is still work; if there is we - // need to retry to prevent a nasty race condition - lock(asyncCompletionQueue) - { - if (asyncCompletionQueue.Count == 0) return; // another thread drained it; can exit - } - Thread.Sleep(1); - } - int total = 0; - do - { - ICompletable next; - lock (asyncCompletionQueue) - { - next = asyncCompletionQueue.Count == 0 ? null - : asyncCompletionQueue.Dequeue(); - } - if (next == null) - { - // give it a moment and try again, noting that we might lose the battle - // when we pause - Interlocked.CompareExchange(ref activeAsyncWorkerThread, 0, currentThread); - if (SpinWait() && Interlocked.CompareExchange(ref activeAsyncWorkerThread, currentThread, 0) == 0) - { - // we paused, and we got the lock back; anything else? - lock (asyncCompletionQueue) - { - next = asyncCompletionQueue.Count == 0 ? null - : asyncCompletionQueue.Dequeue(); - } - } - } - if (next == null) break; // nothing to do <===== exit point - try - { - multiplexer.Trace("Completing async (ordered): " + next, name); - next.TryComplete(true); - Interlocked.Increment(ref completedAsync); - } - catch (Exception ex) - { - multiplexer.Trace("Async completion error: " + ex.Message, name); - Interlocked.Increment(ref failedAsync); - } - total++; - } while (true); - multiplexer.Trace("Async completion worker processed " + total + " operations", name); - } - finally - { - Interlocked.CompareExchange(ref activeAsyncWorkerThread, 0, currentThread); - } - } - - private bool SpinWait() - { - var sw = new SpinWait(); - byte maxSpins = 128; - do - { - if (sw.NextSpinWillYield) - return true; - maxSpins--; - } - while (maxSpins > 0); - - return false; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConcurrentProfileStorageCollection.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConcurrentProfileStorageCollection.cs deleted file mode 100644 index 008b1a6..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConcurrentProfileStorageCollection.cs +++ /dev/null @@ -1,227 +0,0 @@ -using System.Collections.Generic; -using System.Threading; - -namespace StackExchange.Redis -{ - /// - /// A collection of IProfiledCommands. - /// - /// This is a very light weight data structure, only supporting enumeration. - /// - /// While it implements IEnumerable, it there are fewer allocations if one uses - /// it's explicit GetEnumerator() method. Using `foreach` does this automatically. - /// - /// This type is not threadsafe. - /// - public struct ProfiledCommandEnumerable : IEnumerable - { - /// - /// Implements IEnumerator for ProfiledCommandEnumerable. - /// This implementation is comparable to List.Enumerator and Dictionary.Enumerator, - /// and is provided to reduce allocations in the common (ie. foreach) case. - /// - /// This type is not threadsafe. - /// - public struct Enumerator : IEnumerator - { - ProfileStorage Head; - ProfileStorage CurrentBacker; - - bool IsEmpty => Head == null; - bool IsUnstartedOrFinished => CurrentBacker == null; - - internal Enumerator(ProfileStorage head) - { - Head = head; - CurrentBacker = null; - } - - /// - /// The current element. - /// - public IProfiledCommand Current => CurrentBacker; - - object System.Collections.IEnumerator.Current => CurrentBacker; - - /// - /// Advances the enumeration, returning true if there is a new element to consume and false - /// if enumeration is complete. - /// - public bool MoveNext() - { - if (IsEmpty) return false; - - if (IsUnstartedOrFinished) - { - CurrentBacker = Head; - } - else - { - CurrentBacker = CurrentBacker.NextElement; - } - - return CurrentBacker != null; - } - - /// - /// Resets the enumeration. - /// - public void Reset() - { - CurrentBacker = null; - } - - /// - /// Disposes the enumeration. - /// subsequent attempts to enumerate results in undefined behavior. - /// - public void Dispose() - { - CurrentBacker = Head = null; - } - } - - ProfileStorage Head; - - internal ProfiledCommandEnumerable(ProfileStorage head) - { - Head = head; - } - - /// - /// Returns an implementor of IEnumerator that, provided it isn't accessed - /// though an interface, avoids allocations. - /// - /// `foreach` will automatically use this method. - /// - public Enumerator GetEnumerator() - { - return new Enumerator(Head); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } - - /// - /// A thread-safe collection tailored to the "always append, with high contention, then enumerate once with no contention" - /// behavior of our profiling. - /// - /// Performs better than ConcurrentBag, which is important since profiling code shouldn't impact timings. - /// - sealed class ConcurrentProfileStorageCollection - { - // internal for test purposes - internal static int AllocationCount = 0; - - // It is, by definition, impossible for an element to be in 2 intrusive collections - // and we force Enumeration to release any reference to the collection object - // so we can **always** pool these. - const int PoolSize = 64; - static ConcurrentProfileStorageCollection[] Pool = new ConcurrentProfileStorageCollection[PoolSize]; - - volatile ProfileStorage Head; - - private ConcurrentProfileStorageCollection() { } - - // for testing purposes only - internal static int CountInPool() - { - var ret = 0; - - for (var i = 0; i < PoolSize; i++) - { - var inPool = Pool[i]; - if (inPool != null) ret++; - } - - return ret; - } - - /// - /// This method is thread-safe. - /// - /// Adds an element to the bag. - /// - /// Order is not preserved. - /// - /// The element can only be a member of *one* bag. - /// - public void Add(ProfileStorage command) - { - do - { - var cur = Head; - command.NextElement = cur; - - // Interlocked references to volatile fields are perfectly cromulent -#pragma warning disable 420 - var got = Interlocked.CompareExchange(ref Head, command, cur); -#pragma warning restore 420 - - if (object.ReferenceEquals(got, cur)) break; - } while (true); - } - - /// - /// This method returns an enumerable view of the bag, and returns it to - /// an internal pool for reuse by GetOrCreate(). - /// - /// It is not thread safe. - /// - /// It should only be called once the bag is finished being mutated. - /// - public ProfiledCommandEnumerable EnumerateAndReturnForReuse() - { - var ret = new ProfiledCommandEnumerable(Head); - - ReturnForReuse(); - - return ret; - } - - /// - /// This returns the ConcurrentProfileStorageCollection to an internal pool for reuse by GetOrCreate(). - /// - public void ReturnForReuse() - { - // no need for interlocking, this isn't a thread safe method - Head = null; - - for (var i = 0; i < PoolSize; i++) - { - if (Interlocked.CompareExchange(ref Pool[i], this, null) == null) break; - } - } - - /// - /// Returns a ConcurrentProfileStorageCollection to use. - /// - /// It *may* have allocated a new one, or it may return one that has previously been released. - /// To return the collection, call EnumerateAndReturnForReuse() - /// - public static ConcurrentProfileStorageCollection GetOrCreate() - { - ConcurrentProfileStorageCollection found; - for (int i = 0; i < PoolSize; i++) - { - if ((found = Interlocked.Exchange(ref Pool[i], null)) != null) - { - return found; - } - } - - Interlocked.Increment(ref AllocationCount); - found = new ConcurrentProfileStorageCollection(); - - return found; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Condition.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Condition.cs deleted file mode 100644 index 6ce3a97..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Condition.cs +++ /dev/null @@ -1,621 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace StackExchange.Redis -{ - - /// - /// Describes a pre-condition used in a redis transaction - /// - public abstract class Condition - { - internal abstract Condition MapKeys(Func map); - - private Condition() { } - - /// - /// Enforces that the given hash-field must have the specified value - /// - public static Condition HashEqual(RedisKey key, RedisValue hashField, RedisValue value) - { - if (hashField.IsNull) throw new ArgumentNullException(nameof(hashField)); - if (value.IsNull) return HashNotExists(key, hashField); - return new EqualsCondition(key, hashField, true, value); - } - - /// - /// Enforces that the given hash-field must exist - /// - public static Condition HashExists(RedisKey key, RedisValue hashField) - { - if (hashField.IsNull) throw new ArgumentNullException(nameof(hashField)); - return new ExistsCondition(key, hashField, true); - } - - /// - /// Enforces that the given hash-field must not have the specified value - /// - public static Condition HashNotEqual(RedisKey key, RedisValue hashField, RedisValue value) - { - if (hashField.IsNull) throw new ArgumentNullException(nameof(hashField)); - if (value.IsNull) return HashExists(key, hashField); - return new EqualsCondition(key, hashField, false, value); - } - - /// - /// Enforces that the given hash-field must not exist - /// - public static Condition HashNotExists(RedisKey key, RedisValue hashField) - { - if (hashField.IsNull) throw new ArgumentNullException(nameof(hashField)); - return new ExistsCondition(key, hashField, false); - } - - /// - /// Enforces that the given key must exist - /// - public static Condition KeyExists(RedisKey key) - { - return new ExistsCondition(key, RedisValue.Null, true); - } - - /// - /// Enforces that the given key must not exist - /// - public static Condition KeyNotExists(RedisKey key) - { - return new ExistsCondition(key, RedisValue.Null, false); - } - - /// - /// Enforces that the given list index must have the specified value - /// - public static Condition ListIndexEqual(RedisKey key, long index, RedisValue value) - { - return new ListCondition(key, index, true, value); - } - - /// - /// Enforces that the given list index must exist - /// - public static Condition ListIndexExists(RedisKey key, long index) - { - return new ListCondition(key, index, true, null); - } - - /// - /// Enforces that the given list index must not have the specified value - /// - public static Condition ListIndexNotEqual(RedisKey key, long index, RedisValue value) - { - return new ListCondition(key, index, false, value); - } - - /// - /// Enforces that the given list index must not exist - /// - public static Condition ListIndexNotExists(RedisKey key, long index) - { - return new ListCondition(key, index, false, null); - } - - /// - /// Enforces that the given key must have the specified value - /// - public static Condition StringEqual(RedisKey key, RedisValue value) - { - if (value.IsNull) return KeyNotExists(key); - return new EqualsCondition(key, RedisValue.Null, true, value); - } - - /// - /// Enforces that the given key must not have the specified value - /// - public static Condition StringNotEqual(RedisKey key, RedisValue value) - { - if (value.IsNull) return KeyExists(key); - return new EqualsCondition(key, RedisValue.Null, false, value); - } - - /// - /// Enforces that the given hash length is a certain value - /// - public static Condition HashLengthEqual(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.Hash, 0, length); - } - - /// - /// Enforces that the given hash length is less than a certain value - /// - public static Condition HashLengthLessThan(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.Hash, 1, length); - } - - /// - /// Enforces that the given hash length is greater than a certain value - /// - public static Condition HashLengthGreaterThan(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.Hash, -1, length); - } - - /// - /// Enforces that the given string length is a certain value - /// - public static Condition StringLengthEqual(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.String, 0, length); - } - - /// - /// Enforces that the given string length is less than a certain value - /// - public static Condition StringLengthLessThan(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.String, 1, length); - } - - /// - /// Enforces that the given string length is greater than a certain value - /// - public static Condition StringLengthGreaterThan(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.String, -1, length); - } - - /// - /// Enforces that the given list length is a certain value - /// - public static Condition ListLengthEqual(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.List, 0, length); - } - - /// - /// Enforces that the given list length is less than a certain value - /// - public static Condition ListLengthLessThan(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.List, 1, length); - } - - /// - /// Enforces that the given list length is greater than a certain value - /// - public static Condition ListLengthGreaterThan(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.List, -1, length); - } - - /// - /// Enforces that the given set cardinality is a certain value - /// - public static Condition SetLengthEqual(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.Set, 0, length); - } - - /// - /// Enforces that the given set cardinality is less than a certain value - /// - public static Condition SetLengthLessThan(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.Set, 1, length); - } - - /// - /// Enforces that the given set cardinality is greater than a certain value - /// - public static Condition SetLengthGreaterThan(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.Set, -1, length); - } - - /// - /// Enforces that the given sorted set cardinality is a certain value - /// - public static Condition SortedSetLengthEqual(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.SortedSet, 0, length); - } - - /// - /// Enforces that the given sorted set cardinality is less than a certain value - /// - public static Condition SortedSetLengthLessThan(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.SortedSet, 1, length); - } - - /// - /// Enforces that the given sorted set cardinality is greater than a certain value - /// - public static Condition SortedSetLengthGreaterThan(RedisKey key, long length) - { - return new LengthCondition(key, RedisType.SortedSet, -1, length); - } - - internal abstract void CheckCommands(CommandMap commandMap); - - internal abstract IEnumerable CreateMessages(int db, ResultBox resultBox); - - internal abstract int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy); - internal abstract bool TryValidate(RawResult result, out bool value); - - internal sealed class ConditionProcessor : ResultProcessor - { - public static readonly ConditionProcessor Default = new ConditionProcessor(); - - public static Message CreateMessage(Condition condition, int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value = default(RedisValue)) - { - return new ConditionMessage(condition, db, flags, command, key, value); - } - - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - var msg = message as ConditionMessage; - var condition = msg?.Condition; - bool final; - if (condition != null && condition.TryValidate(result, out final)) - { - SetResult(message, final); - return true; - } - return false; - } - - private class ConditionMessage : Message.CommandKeyBase - { - public readonly Condition Condition; - private RedisValue value; - - public ConditionMessage(Condition condition, int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value) - : base(db, flags, command, key) - { - this.Condition = condition; - this.value = value; // note no assert here - } - - internal override void WriteImpl(PhysicalConnection physical) - { - if (value.IsNull) - { - physical.WriteHeader(command, 1); - physical.Write(Key); - } - else - { - physical.WriteHeader(command, 2); - physical.Write(Key); - physical.Write(value); - } - } - } - } - - internal class ExistsCondition : Condition - { - private readonly bool expectedResult; - private readonly RedisValue hashField; - private readonly RedisKey key; - - internal override Condition MapKeys(Func map) - { - return new ExistsCondition(map(key), hashField, expectedResult); - } - public ExistsCondition(RedisKey key, RedisValue hashField, bool expectedResult) - { - if (key.IsNull) throw new ArgumentException("key"); - this.key = key; - this.hashField = hashField; - this.expectedResult = expectedResult; - } - - public override string ToString() - { - return (hashField.IsNull ? key.ToString() : ((string)key) + " > " + hashField) - + (expectedResult ? " exists" : " does not exists"); - } - - internal override void CheckCommands(CommandMap commandMap) - { - commandMap.AssertAvailable(hashField.IsNull ? RedisCommand.EXISTS : RedisCommand.HEXISTS); - } - - internal override IEnumerable CreateMessages(int db, ResultBox resultBox) - { - yield return Message.Create(db, CommandFlags.None, RedisCommand.WATCH, key); - - var cmd = hashField.IsNull ? RedisCommand.EXISTS : RedisCommand.HEXISTS; - var message = ConditionProcessor.CreateMessage(this, db, CommandFlags.None, cmd, key, hashField); - message.SetSource(ConditionProcessor.Default, resultBox); - yield return message; - } - - internal override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - return serverSelectionStrategy.HashSlot(key); - } - internal override bool TryValidate(RawResult result, out bool value) - { - bool parsed; - if (ResultProcessor.DemandZeroOrOneProcessor.TryGet(result, out parsed)) - { - value = parsed == expectedResult; - ConnectionMultiplexer.TraceWithoutContext("exists: " + parsed + "; expected: " + expectedResult + "; voting: " + value); - return true; - } - value = false; - return false; - } - } - - internal class EqualsCondition : Condition - { - - internal override Condition MapKeys(Func map) - { - return new EqualsCondition(map(key), hashField, expectedEqual, expectedValue); - } - private readonly bool expectedEqual; - private readonly RedisValue hashField, expectedValue; - private readonly RedisKey key; - public EqualsCondition(RedisKey key, RedisValue hashField, bool expectedEqual, RedisValue expectedValue) - { - if (key.IsNull) throw new ArgumentException("key"); - this.key = key; - this.hashField = hashField; - this.expectedEqual = expectedEqual; - this.expectedValue = expectedValue; - } - - public override string ToString() - { - return (hashField.IsNull ? key.ToString() : ((string)key) + " > " + hashField) - + (expectedEqual ? " == " : " != ") - + expectedValue; - } - - internal override void CheckCommands(CommandMap commandMap) - { - commandMap.AssertAvailable(hashField.IsNull ? RedisCommand.GET : RedisCommand.HGET); - } - - internal sealed override IEnumerable CreateMessages(int db, ResultBox resultBox) - { - yield return Message.Create(db, CommandFlags.None, RedisCommand.WATCH, key); - - var cmd = hashField.IsNull ? RedisCommand.GET : RedisCommand.HGET; - var message = ConditionProcessor.CreateMessage(this, db, CommandFlags.None, cmd, key, hashField); - message.SetSource(ConditionProcessor.Default, resultBox); - yield return message; - } - - internal override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - return serverSelectionStrategy.HashSlot(key); - } - internal override bool TryValidate(RawResult result, out bool value) - { - switch (result.Type) - { - case ResultType.BulkString: - case ResultType.SimpleString: - case ResultType.Integer: - var parsed = result.AsRedisValue(); - value = (parsed == expectedValue) == expectedEqual; - ConnectionMultiplexer.TraceWithoutContext("actual: " + (string)parsed + "; expected: " + (string)expectedValue + - "; wanted: " + (expectedEqual ? "==" : "!=") + "; voting: " + value); - return true; - } - value = false; - return false; - } - } - - internal class ListCondition : Condition - { - internal override Condition MapKeys(Func map) - { - return new ListCondition(map(key), index, expectedResult, expectedValue); - } - private readonly bool expectedResult; - private readonly long index; - private readonly RedisValue? expectedValue; - private readonly RedisKey key; - public ListCondition(RedisKey key, long index, bool expectedResult, RedisValue? expectedValue) - { - if (key.IsNull) throw new ArgumentException(nameof(key)); - this.key = key; - this.index = index; - this.expectedResult = expectedResult; - this.expectedValue = expectedValue; - } - - public override string ToString() - { - return ((string)key) + "[" + index.ToString() + "]" - + (expectedValue.HasValue ? (expectedResult ? " == " : " != ") + expectedValue.Value : (expectedResult ? " exists" : " does not exist")); - } - - internal override void CheckCommands(CommandMap commandMap) - { - commandMap.AssertAvailable(RedisCommand.LINDEX); - } - - internal sealed override IEnumerable CreateMessages(int db, ResultBox resultBox) - { - yield return Message.Create(db, CommandFlags.None, RedisCommand.WATCH, key); - - var message = ConditionProcessor.CreateMessage(this, db, CommandFlags.None, RedisCommand.LINDEX, key, index); - message.SetSource(ConditionProcessor.Default, resultBox); - yield return message; - } - - internal override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - return serverSelectionStrategy.HashSlot(key); - } - internal override bool TryValidate(RawResult result, out bool value) - { - switch (result.Type) - { - case ResultType.BulkString: - case ResultType.SimpleString: - case ResultType.Integer: - var parsed = result.AsRedisValue(); - if (expectedValue.HasValue) - { - value = (parsed == expectedValue.Value) == expectedResult; - ConnectionMultiplexer.TraceWithoutContext("actual: " + (string)parsed + "; expected: " + (string)expectedValue.Value + - "; wanted: " + (expectedResult ? "==" : "!=") + "; voting: " + value); - } - else - { - value = (parsed.IsNull != expectedResult); - ConnectionMultiplexer.TraceWithoutContext("exists: " + parsed + "; expected: " + expectedResult + "; voting: " + value); - } - return true; - } - value = false; - return false; - } - } - - internal class LengthCondition : Condition - { - internal override Condition MapKeys(Func map) - { - return new LengthCondition(map(key), type, compareToResult, expectedLength); - } - private readonly int compareToResult; - private readonly long expectedLength; - private readonly RedisKey key; - private readonly RedisType type; - private readonly RedisCommand cmd; - - public LengthCondition(RedisKey key, RedisType type, int compareToResult, long expectedLength) - { - if (key.IsNull) throw new ArgumentException(nameof(key)); - this.key = key; - this.compareToResult = compareToResult; - this.expectedLength = expectedLength; - this.type = type; - switch (type) { - case RedisType.Hash: - cmd = RedisCommand.HLEN; - break; - - case RedisType.Set: - cmd = RedisCommand.SCARD; - break; - - case RedisType.List: - cmd = RedisCommand.LLEN; - break; - - case RedisType.SortedSet: - cmd = RedisCommand.ZCARD; - break; - - case RedisType.String: - cmd = RedisCommand.STRLEN; - break; - - default: - throw new ArgumentException(nameof(type)); - } - } - - public override string ToString() - { - return ((string)key) + " " + type + " length" + GetComparisonString() + expectedLength; - } - - private string GetComparisonString() - { - return compareToResult == 0 ? " == " : (compareToResult < 0 ? " > " : " < "); - } - - internal override void CheckCommands(CommandMap commandMap) - { - commandMap.AssertAvailable(cmd); - } - - internal sealed override IEnumerable CreateMessages(int db, ResultBox resultBox) - { - yield return Message.Create(db, CommandFlags.None, RedisCommand.WATCH, key); - - var message = ConditionProcessor.CreateMessage(this, db, CommandFlags.None, cmd, key); - message.SetSource(ConditionProcessor.Default, resultBox); - yield return message; - } - - internal override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - return serverSelectionStrategy.HashSlot(key); - } - internal override bool TryValidate(RawResult result, out bool value) - { - switch (result.Type) - { - case ResultType.BulkString: - case ResultType.SimpleString: - case ResultType.Integer: - var parsed = result.AsRedisValue(); - value = parsed.IsInteger && (expectedLength.CompareTo((long) parsed) == compareToResult); - ConnectionMultiplexer.TraceWithoutContext("actual: " + (string)parsed + "; expected: " + expectedLength + - "; wanted: " + GetComparisonString() + "; voting: " + value); - return true; - } - value = false; - return false; - } - } - - } - - /// - /// Indicates the status of a condition as part of a transaction - /// - public sealed class ConditionResult - { - internal readonly Condition Condition; - - private ResultBox resultBox; - - private volatile bool wasSatisfied; - - internal ConditionResult(Condition condition) - { - this.Condition = condition; - resultBox = ResultBox.Get(condition); - } - - /// - /// Indicates whether the condition was satisfied - /// - public bool WasSatisfied => wasSatisfied; - - internal IEnumerable CreateMessages(int db) - { - return Condition.CreateMessages(db, resultBox); - } - - internal ResultBox GetBox() { return resultBox; } - internal bool UnwrapBox() - { - if (resultBox != null) - { - Exception ex; - bool val; - ResultBox.UnwrapAndRecycle(resultBox, false, out val, out ex); - resultBox = null; - wasSatisfied = ex == null && val; - } - return wasSatisfied; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConfigurationOptions.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConfigurationOptions.cs deleted file mode 100644 index a7c31f1..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConfigurationOptions.cs +++ /dev/null @@ -1,726 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Security; -using System.Security.Authentication; -using System.Text; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - - /// - /// Specifies the proxy that is being used to communicate to redis - /// - public enum Proxy - { - /// - /// Direct communication to the redis server(s) - /// - None, - /// - /// Communication via twemproxy - /// - Twemproxy - } - - /// - /// The options relevant to a set of redis connections - /// - public sealed class ConfigurationOptions -#if !CORE_CLR - : ICloneable -#endif - { - internal const string DefaultTieBreaker = "__Booksleeve_TieBreak", DefaultConfigurationChannel = "__Booksleeve_MasterChanged"; - - private static class OptionKeys - { - public static int ParseInt32(string key, string value, int minValue = int.MinValue, int maxValue = int.MaxValue) - { - int tmp; - if (!Format.TryParseInt32(value, out tmp)) throw new ArgumentOutOfRangeException("Keyword '" + key + "' requires an integer value"); - if (tmp < minValue) throw new ArgumentOutOfRangeException("Keyword '" + key + "' has a minimum value of " + minValue); - if (tmp > maxValue) throw new ArgumentOutOfRangeException("Keyword '" + key + "' has a maximum value of " + maxValue); - return tmp; - } - - internal static bool ParseBoolean(string key, string value) - { - bool tmp; - if (!Format.TryParseBoolean(value, out tmp)) throw new ArgumentOutOfRangeException("Keyword '" + key + "' requires a boolean value"); - return tmp; - } - internal static Version ParseVersion(string key, string value) - { - Version tmp; - if (!System.Version.TryParse(value, out tmp)) throw new ArgumentOutOfRangeException("Keyword '" + key + "' requires a version value"); - return tmp; - } - internal static Proxy ParseProxy(string key, string value) - { - Proxy tmp; - if (!Enum.TryParse(value, true, out tmp)) throw new ArgumentOutOfRangeException("Keyword '" + key + "' requires a proxy value"); - return tmp; - } - - internal static SslProtocols ParseSslProtocols(string key, string value) - { - SslProtocols tmp; - //Flags expect commas as separators, but we need to use '|' since commas are already used in the connection string to mean something else - value = value?.Replace("|", ","); - - if (!Enum.TryParse(value, true, out tmp)) throw new ArgumentOutOfRangeException("Keyword '" + key + "' requires an SslProtocol value (multiple values separated by '|')."); - - return tmp; - } - - internal static void Unknown(string key) - { - throw new ArgumentException("Keyword '" + key + "' is not supported"); - } - - internal const string AllowAdmin = "allowAdmin", SyncTimeout = "syncTimeout", - ServiceName = "serviceName", ClientName = "name", KeepAlive = "keepAlive", - Version = "version", ConnectTimeout = "connectTimeout", Password = "password", - TieBreaker = "tiebreaker", WriteBuffer = "writeBuffer", Ssl = "ssl", SslHost = "sslHost", HighPrioritySocketThreads = "highPriorityThreads", - ConfigChannel = "configChannel", AbortOnConnectFail = "abortConnect", ResolveDns = "resolveDns", - ChannelPrefix = "channelPrefix", Proxy = "proxy", ConnectRetry = "connectRetry", - ConfigCheckSeconds = "configCheckSeconds", ResponseTimeout = "responseTimeout", DefaultDatabase = "defaultDatabase"; - internal const string SslProtocols = "sslProtocols"; - - private static readonly Dictionary normalizedOptions = new[] - { - AllowAdmin, SyncTimeout, - ServiceName, ClientName, KeepAlive, - Version, ConnectTimeout, Password, - TieBreaker, WriteBuffer, Ssl, SslHost, HighPrioritySocketThreads, - ConfigChannel, AbortOnConnectFail, ResolveDns, - ChannelPrefix, Proxy, ConnectRetry, - ConfigCheckSeconds, DefaultDatabase, - SslProtocols, - }.ToDictionary(x => x, StringComparer.OrdinalIgnoreCase); - - public static string TryNormalize(string value) - { - string tmp; - if(value != null && normalizedOptions.TryGetValue(value, out tmp)) - { - return tmp ?? ""; - } - return value ?? ""; - } - } - - - private readonly EndPointCollection endpoints = new EndPointCollection(); - - private bool? allowAdmin, abortOnConnectFail, highPrioritySocketThreads, resolveDns, ssl; - - private string clientName, serviceName, password, tieBreaker, sslHost, configChannel; - - private CommandMap commandMap; - - private Version defaultVersion; - - private int? keepAlive, syncTimeout, connectTimeout, responseTimeout, writeBuffer, connectRetry, configCheckSeconds, defaultDatabase; - - private Proxy? proxy; - - private IReconnectRetryPolicy reconnectRetryPolicy; - - /// - /// A LocalCertificateSelectionCallback delegate responsible for selecting the certificate used for authentication; note - /// that this cannot be specified in the configuration-string. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")] - public event LocalCertificateSelectionCallback CertificateSelection; - - /// - /// A RemoteCertificateValidationCallback delegate responsible for validating the certificate supplied by the remote party; note - /// that this cannot be specified in the configuration-string. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")] - public event RemoteCertificateValidationCallback CertificateValidation; - - /// - /// Gets or sets whether connect/configuration timeouts should be explicitly notified via a TimeoutException - /// - public bool AbortOnConnectFail { get { return abortOnConnectFail ?? GetDefaultAbortOnConnectFailSetting(); } set { abortOnConnectFail = value; } } - - /// - /// Indicates whether admin operations should be allowed - /// - public bool AllowAdmin { get { return allowAdmin.GetValueOrDefault(); } set { allowAdmin = value; } } - - /// - /// Indicates whether the connection should be encrypted - /// - [Obsolete("Please use .Ssl instead of .UseSsl"), -#if !CORE_CLR - Browsable(false), -#endif - EditorBrowsable(EditorBrowsableState.Never)] - public bool UseSsl { get { return Ssl; } set { Ssl = value; } } - - /// - /// Indicates whether the connection should be encrypted - /// - public bool Ssl { get { return ssl.GetValueOrDefault(); } set { ssl = value; } } - - /// - /// Configures which Ssl/TLS protocols should be allowed. If not set, defaults are chosen by the .NET framework. - /// - public SslProtocols? SslProtocols { get; set; } - - /// - /// Automatically encodes and decodes channels - /// - public RedisChannel ChannelPrefix { get;set; } - /// - /// The client name to use for all connections - /// - public string ClientName { get { return clientName; } set { clientName = value; } } - - /// - /// The number of times to repeat the initial connect cycle if no servers respond promptly - /// - public int ConnectRetry { get { return connectRetry ?? 3; } set { connectRetry = value; } } - - /// - /// The command-map associated with this configuration - /// - public CommandMap CommandMap - { - get - { - if (commandMap != null) return commandMap; - switch (Proxy) - { - case Proxy.Twemproxy: - return CommandMap.Twemproxy; - default: - return CommandMap.Default; - } - } - set - { - if (value == null) throw new ArgumentNullException(nameof(value)); - commandMap = value; - } - } - - /// - /// Channel to use for broadcasting and listening for configuration change notification - /// - public string ConfigurationChannel { get { return configChannel ?? DefaultConfigurationChannel; } set { configChannel = value; } } - - /// - /// Specifies the time in milliseconds that should be allowed for connection (defaults to 5 seconds unless SyncTimeout is higher) - /// - public int ConnectTimeout { - get { - if (connectTimeout.HasValue) return connectTimeout.GetValueOrDefault(); - return Math.Max(5000, SyncTimeout); - } - set { connectTimeout = value; } - } - - /// - /// The retry policy to be used for connection reconnects - /// - public IReconnectRetryPolicy ReconnectRetryPolicy { get { return reconnectRetryPolicy ?? (reconnectRetryPolicy = new LinearRetry(ConnectTimeout)); } set { reconnectRetryPolicy = value; } } - - - /// - /// The server version to assume - /// - public Version DefaultVersion { get { return defaultVersion ?? (IsAzureEndpoint() ? RedisFeatures.v3_0_0 : RedisFeatures.v2_0_0); } set { defaultVersion = value; } } - - /// - /// The endpoints defined for this configuration - /// - public EndPointCollection EndPoints => endpoints; - - /// - /// Use ThreadPriority.AboveNormal for SocketManager reader and writer threads (true by default). If false, ThreadPriority.Normal will be used. - /// - public bool HighPrioritySocketThreads { get { return highPrioritySocketThreads ?? true; } set { highPrioritySocketThreads = value; } } - - /// - /// Specifies the time in seconds at which connections should be pinged to ensure validity - /// - public int KeepAlive { get { return keepAlive.GetValueOrDefault(-1); } set { keepAlive = value; } } - - /// - /// The password to use to authenticate with the server - /// - public string Password { get { return password; } set { password = value; } } - - /// - /// Type of proxy to use (if any); for example Proxy.Twemproxy - /// - public Proxy Proxy { get { return proxy.GetValueOrDefault(); } set { proxy = value; } } - - /// - /// Indicates whether endpoints should be resolved via DNS before connecting. - /// If enabled the ConnectionMultiplexer will not re-resolve DNS - /// when attempting to re-connect after a connection failure. - /// - public bool ResolveDns { get { return resolveDns.GetValueOrDefault(); } set { resolveDns = value; } } - - /// - /// The service name used to resolve a service via sentinel - /// - public string ServiceName { get { return serviceName; } set { serviceName = value; } } - - /// - /// Gets or sets the SocketManager instance to be used with these options; if this is null a per-multiplexer - /// SocketManager is created automatically. - /// - public SocketManager SocketManager { get;set; } - /// - /// The target-host to use when validating SSL certificate; setting a value here enables SSL mode - /// - public string SslHost { get { return sslHost ?? InferSslHostFromEndpoints(); } set { sslHost = value; } } - - /// - /// Specifies the time in milliseconds that the system should allow for synchronous operations (defaults to 1 second) - /// - public int SyncTimeout { get { return syncTimeout.GetValueOrDefault(1000); } set { syncTimeout = value; } } - - /// - /// Specifies the time in milliseconds that the system should allow for responses before concluding that the socket is unhealthy - /// (defaults to SyncTimeout) - /// - public int ResponseTimeout { get { return responseTimeout ?? SyncTimeout; } set { responseTimeout = value; } } - - /// - /// Tie-breaker used to choose between masters (must match the endpoint exactly) - /// - public string TieBreaker { get { return tieBreaker ?? DefaultTieBreaker; } set { tieBreaker = value; } } - /// - /// The size of the output buffer to use - /// - public int WriteBuffer { get { return writeBuffer.GetValueOrDefault(4096); } set { writeBuffer = value; } } - - /// - /// Specifies the default database to be used when calling ConnectionMultiplexer.GetDatabase() without any parameters - /// - public int? DefaultDatabase { get { return defaultDatabase; } set { defaultDatabase = value; } } - - internal LocalCertificateSelectionCallback CertificateSelectionCallback { get { return CertificateSelection; } private set { CertificateSelection = value; } } - - // these just rip out the underlying handlers, bypassing the event accessors - needed when creating the SSL stream - internal RemoteCertificateValidationCallback CertificateValidationCallback { get { return CertificateValidation; } private set { CertificateValidation = value; } } - - /// - /// Check configuration every n seconds (every minute by default) - /// - public int ConfigCheckSeconds { get { return configCheckSeconds.GetValueOrDefault(60); } set { configCheckSeconds = value; } } - - /// - /// Parse the configuration from a comma-delimited configuration string - /// - /// is null. - /// is empty. - public static ConfigurationOptions Parse(string configuration) - { - var options = new ConfigurationOptions(); - options.DoParse(configuration, false); - return options; - } - /// - /// Parse the configuration from a comma-delimited configuration string - /// - /// is null. - /// is empty. - public static ConfigurationOptions Parse(string configuration, bool ignoreUnknown) - { - var options = new ConfigurationOptions(); - options.DoParse(configuration, ignoreUnknown); - return options; - } - - /// - /// Create a copy of the configuration - /// - public ConfigurationOptions Clone() - { - var options = new ConfigurationOptions - { - clientName = clientName, - serviceName = serviceName, - keepAlive = keepAlive, - syncTimeout = syncTimeout, - allowAdmin = allowAdmin, - defaultVersion = defaultVersion, - connectTimeout = connectTimeout, - password = password, - tieBreaker = tieBreaker, - writeBuffer = writeBuffer, - ssl = ssl, - sslHost = sslHost, - highPrioritySocketThreads = highPrioritySocketThreads, - configChannel = configChannel, - abortOnConnectFail = abortOnConnectFail, - resolveDns = resolveDns, - proxy = proxy, - commandMap = commandMap, - CertificateValidationCallback = CertificateValidationCallback, - CertificateSelectionCallback = CertificateSelectionCallback, - ChannelPrefix = ChannelPrefix.Clone(), - SocketManager = SocketManager, - connectRetry = connectRetry, - configCheckSeconds = configCheckSeconds, - responseTimeout = responseTimeout, - defaultDatabase = defaultDatabase, - ReconnectRetryPolicy = reconnectRetryPolicy, -#if !CORE_CLR - SslProtocols = SslProtocols, -#endif - }; - foreach (var item in endpoints) - options.endpoints.Add(item); - return options; - - } - - /// - /// Resolve the default port for any endpoints that did not have a port explicitly specified - /// - public void SetDefaultPorts() - { - endpoints.SetDefaultPorts(Ssl ? 6380 : 6379); - } - - /// - /// Returns the effective configuration string for this configuration, including Redis credentials. - /// - public override string ToString() - { - // include password to allow generation of configuration strings - // used for connecting multiplexer - return ToString(includePassword: true); - } - - /// - /// Returns the effective configuration string for this configuration - /// with the option to include or exclude the password from the string. - /// - public string ToString(bool includePassword) - { - var sb = new StringBuilder(); - foreach (var endpoint in endpoints) - { - Append(sb, Format.ToString(endpoint)); - } - Append(sb, OptionKeys.ClientName, clientName); - Append(sb, OptionKeys.ServiceName, serviceName); - Append(sb, OptionKeys.KeepAlive, keepAlive); - Append(sb, OptionKeys.SyncTimeout, syncTimeout); - Append(sb, OptionKeys.AllowAdmin, allowAdmin); - Append(sb, OptionKeys.Version, defaultVersion); - Append(sb, OptionKeys.ConnectTimeout, connectTimeout); - Append(sb, OptionKeys.Password, includePassword ? password : "*****"); - Append(sb, OptionKeys.TieBreaker, tieBreaker); - Append(sb, OptionKeys.WriteBuffer, writeBuffer); - Append(sb, OptionKeys.Ssl, ssl); - Append(sb, OptionKeys.SslHost, sslHost); - Append(sb, OptionKeys.HighPrioritySocketThreads, highPrioritySocketThreads); - Append(sb, OptionKeys.ConfigChannel, configChannel); - Append(sb, OptionKeys.AbortOnConnectFail, abortOnConnectFail); - Append(sb, OptionKeys.ResolveDns, resolveDns); - Append(sb, OptionKeys.ChannelPrefix, (string)ChannelPrefix); - Append(sb, OptionKeys.ConnectRetry, connectRetry); - Append(sb, OptionKeys.Proxy, proxy); - Append(sb, OptionKeys.ConfigCheckSeconds, configCheckSeconds); - Append(sb, OptionKeys.ResponseTimeout, responseTimeout); - Append(sb, OptionKeys.DefaultDatabase, defaultDatabase); - commandMap?.AppendDeltas(sb); - return sb.ToString(); - } - - internal bool HasDnsEndPoints() - { - foreach (var endpoint in endpoints) if (endpoint is DnsEndPoint) return true; - return false; - } - -#pragma warning disable 1998 // NET40 is sync, not async, currently - internal async Task ResolveEndPointsAsync(ConnectionMultiplexer multiplexer, TextWriter log) - { - Dictionary cache = new Dictionary(StringComparer.OrdinalIgnoreCase); - for (int i = 0; i < endpoints.Count; i++) - { - var dns = endpoints[i] as DnsEndPoint; - if (dns != null) - { - try - { - IPAddress ip; - if (dns.Host == ".") - { - endpoints[i] = new IPEndPoint(IPAddress.Loopback, dns.Port); - } - else if (cache.TryGetValue(dns.Host, out ip)) - { // use cache - endpoints[i] = new IPEndPoint(ip, dns.Port); - } - else - { - multiplexer.LogLocked(log, "Using DNS to resolve '{0}'...", dns.Host); -#if NET40 - var ips = Dns.GetHostAddresses(dns.Host); -#else - var ips = await Dns.GetHostAddressesAsync(dns.Host).ObserveErrors().ForAwait(); -#endif - if (ips.Length == 1) - { - ip = ips[0]; - multiplexer.LogLocked(log, "'{0}' => {1}", dns.Host, ip); - cache[dns.Host] = ip; - endpoints[i] = new IPEndPoint(ip, dns.Port); - } - } - } - catch (Exception ex) - { - multiplexer.OnInternalError(ex); - multiplexer.LogLocked(log, ex.Message); - } - } - } - } -#pragma warning restore 1998 - static void Append(StringBuilder sb, object value) - { - if (value == null) return; - string s = Format.ToString(value); - if (!string.IsNullOrWhiteSpace(s)) - { - if (sb.Length != 0) sb.Append(','); - sb.Append(s); - } - } - - static void Append(StringBuilder sb, string prefix, object value) - { - string s = value?.ToString(); - if (!string.IsNullOrWhiteSpace(s)) - { - if (sb.Length != 0) sb.Append(','); - if(!string.IsNullOrEmpty(prefix)) - { - sb.Append(prefix).Append('='); - } - sb.Append(s); - } - } - -#if !CORE_CLR - static bool IsOption(string option, string prefix) - { - return option.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase); - } -#endif - - void Clear() - { - clientName = serviceName = password = tieBreaker = sslHost = configChannel = null; - keepAlive = syncTimeout = connectTimeout = writeBuffer = connectRetry = configCheckSeconds = defaultDatabase = null; - allowAdmin = abortOnConnectFail = highPrioritySocketThreads = resolveDns = ssl = null; - defaultVersion = null; - endpoints.Clear(); - commandMap = null; - - CertificateSelection = null; - CertificateValidation = null; - ChannelPrefix = default(RedisChannel); - SocketManager = null; - } - -#if !CORE_CLR - object ICloneable.Clone() { return Clone(); } -#endif - - private void DoParse(string configuration, bool ignoreUnknown) - { - if (configuration == null) - { - throw new ArgumentNullException(nameof(configuration)); - } - - if (string.IsNullOrWhiteSpace(configuration)) - { - throw new ArgumentException("is empty", configuration); - } - - Clear(); - - // break it down by commas - var arr = configuration.Split(StringSplits.Comma); - Dictionary map = null; - foreach (var paddedOption in arr) - { - var option = paddedOption.Trim(); - - if (string.IsNullOrWhiteSpace(option)) continue; - - // check for special tokens - int idx = option.IndexOf('='); - if (idx > 0) - { - var key = option.Substring(0, idx).Trim(); - var value = option.Substring(idx + 1).Trim(); - - switch (OptionKeys.TryNormalize(key)) - { - case OptionKeys.SyncTimeout: - SyncTimeout = OptionKeys.ParseInt32(key, value, minValue: 1); - break; - case OptionKeys.AllowAdmin: - AllowAdmin = OptionKeys.ParseBoolean(key, value); - break; - case OptionKeys.AbortOnConnectFail: - AbortOnConnectFail = OptionKeys.ParseBoolean(key, value); - break; - case OptionKeys.ResolveDns: - ResolveDns = OptionKeys.ParseBoolean(key, value); - break; - case OptionKeys.ServiceName: - ServiceName = value; - break; - case OptionKeys.ClientName: - ClientName = value; - break; - case OptionKeys.ChannelPrefix: - ChannelPrefix = value; - break; - case OptionKeys.ConfigChannel: - ConfigurationChannel = value; - break; - case OptionKeys.KeepAlive: - KeepAlive = OptionKeys.ParseInt32(key, value); - break; - case OptionKeys.ConnectTimeout: - ConnectTimeout = OptionKeys.ParseInt32(key, value); - break; - case OptionKeys.ConnectRetry: - ConnectRetry = OptionKeys.ParseInt32(key, value); - break; - case OptionKeys.ConfigCheckSeconds: - ConfigCheckSeconds = OptionKeys.ParseInt32(key, value); - break; - case OptionKeys.Version: - DefaultVersion = OptionKeys.ParseVersion(key, value); - break; - case OptionKeys.Password: - Password = value; - break; - case OptionKeys.TieBreaker: - TieBreaker = value; - break; - case OptionKeys.Ssl: - Ssl = OptionKeys.ParseBoolean(key, value); - break; - case OptionKeys.SslHost: - SslHost = value; - break; - case OptionKeys.HighPrioritySocketThreads: - HighPrioritySocketThreads = OptionKeys.ParseBoolean(key, value); - break; - case OptionKeys.WriteBuffer: - WriteBuffer = OptionKeys.ParseInt32(key, value); - break; - case OptionKeys.Proxy: - Proxy = OptionKeys.ParseProxy(key, value); - break; - case OptionKeys.ResponseTimeout: - ResponseTimeout = OptionKeys.ParseInt32(key, value, minValue: 1); - break; - case OptionKeys.DefaultDatabase: - defaultDatabase = OptionKeys.ParseInt32(key, value); - break; -#if !CORE_CLR - case OptionKeys.SslProtocols: - SslProtocols = OptionKeys.ParseSslProtocols(key, value); - break; -#endif - default: - if (!string.IsNullOrEmpty(key) && key[0] == '$') - { - RedisCommand cmd; - var cmdName = option.Substring(1, idx - 1); - if (Enum.TryParse(cmdName, true, out cmd)) - { - if (map == null) map = new Dictionary(StringComparer.OrdinalIgnoreCase); - map[cmdName] = value; - } - } - else - { - if(!ignoreUnknown) OptionKeys.Unknown(key); - } - break; - } - } - else - { - var ep = Format.TryParseEndPoint(option); - if (ep != null && !endpoints.Contains(ep)) endpoints.Add(ep); - } - } - if (map != null && map.Count != 0) - { - CommandMap = CommandMap.Create(map); - } - } - - private bool GetDefaultAbortOnConnectFailSetting() - { - // Microsoft Azure team wants abortConnect=false by default - if (IsAzureEndpoint()) - return false; - - return true; - } - - private bool IsAzureEndpoint() - { - var result = false; - var dnsEndpoints = endpoints.Select(endpoint => endpoint as DnsEndPoint).Where(ep => ep != null); - foreach(var ep in dnsEndpoints) - { - int firstDot = ep.Host.IndexOf('.'); - if (firstDot >= 0) - { - var domain = ep.Host.Substring(firstDot).ToLowerInvariant(); - switch(domain) - { - case ".redis.cache.windows.net": - case ".redis.cache.chinacloudapi.cn": - case ".redis.cache.usgovcloudapi.net": - case ".redis.cache.cloudapi.de": - return true; - } - } - } - - return result; - } - - private string InferSslHostFromEndpoints() { - var dnsEndpoints = endpoints.Select(endpoint => endpoint as DnsEndPoint); - string dnsHost = dnsEndpoints.FirstOrDefault()?.Host; - if (dnsEndpoints.All(dnsEndpoint => (dnsEndpoint != null && dnsEndpoint.Host == dnsHost))) { - return dnsHost; - } - - return null; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionCounters.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionCounters.cs deleted file mode 100644 index 174f3f2..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionCounters.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Illustrates the counters associated with an individual connection - /// - public class ConnectionCounters - { - internal ConnectionCounters(ConnectionType connectionType) - { - ConnectionType = connectionType; - } - - /// - /// The number of operations that have been completed asynchronously - /// - public long CompletedAsynchronously { get; internal set; } - - /// - /// The number of operations that have been completed synchronously - /// - public long CompletedSynchronously { get; internal set; } - - /// - /// The type of this connection - /// - public ConnectionType ConnectionType { get; } - - /// - /// The number of operations that failed to complete asynchronously - /// - public long FailedAsynchronously { get; internal set; } - - /// - /// Indicates if there are any pending items or failures on this connection - /// - public bool IsEmpty => PendingUnsentItems == 0 && SentItemsAwaitingResponse == 0 && ResponsesAwaitingAsyncCompletion == 0 && FailedAsynchronously == 0; - - /// - /// Indicates the total number of messages despatched to a non-preferred endpoint, for example sent to a master - /// when the caller stated a preference of slave - /// - public long NonPreferredEndpointCount { get; internal set; } - - /// - /// The number of operations performed on this connection - /// - public long OperationCount { get; internal set; } - - /// - /// Operations that have been requested, but which have not yet been sent to the server - /// - public int PendingUnsentItems { get; internal set; } - - /// - /// Operations for which the response has been processed, but which are awaiting asynchronous completion - /// - public int ResponsesAwaitingAsyncCompletion { get; internal set; } - - /// - /// Operations that have been sent to the server, but which are awaiting a response - /// - public int SentItemsAwaitingResponse { get; internal set; } - - /// - /// The number of sockets used by this logical connection (total, including reconnects) - /// - public long SocketCount { get; internal set; } - - /// - /// The number of subscriptions (with and without patterns) currently held against this connection - /// - public long Subscriptions { get;internal set; } - - /// - /// Indicates the total number of outstanding items against this connection - /// - public int TotalOutstanding => PendingUnsentItems + SentItemsAwaitingResponse + ResponsesAwaitingAsyncCompletion; - - /// - /// Indicates the total number of writers items against this connection - /// - public int WriterCount { get; internal set; } - - /// - /// See Object.ToString() - /// - public override string ToString() - { - var sb = new StringBuilder(); - Append(sb); - return sb.ToString(); - } - - internal void Add(ConnectionCounters other) - { - if (other == null) return; - CompletedAsynchronously += other.CompletedAsynchronously; - CompletedSynchronously += other.CompletedSynchronously; - FailedAsynchronously += other.FailedAsynchronously; - OperationCount += other.OperationCount; - PendingUnsentItems += other.PendingUnsentItems; - ResponsesAwaitingAsyncCompletion += other.ResponsesAwaitingAsyncCompletion; - SentItemsAwaitingResponse += other.SentItemsAwaitingResponse; - SocketCount += other.SocketCount; - Subscriptions += other.Subscriptions; - WriterCount += other.WriterCount; - NonPreferredEndpointCount += other.NonPreferredEndpointCount; - } - - internal bool Any() - { - return CompletedAsynchronously != 0 || CompletedSynchronously != 0 - || FailedAsynchronously != 0 || OperationCount != 0 - || PendingUnsentItems != 0 || ResponsesAwaitingAsyncCompletion != 0 - || SentItemsAwaitingResponse != 0 || SocketCount != 0 - || Subscriptions != 0 || WriterCount != 0 - || NonPreferredEndpointCount != 0; - } - internal void Append(StringBuilder sb) - { - sb.Append("ops=").Append(OperationCount).Append(", qu=").Append(PendingUnsentItems) - .Append(", qs=").Append(SentItemsAwaitingResponse).Append(", qc=").Append(ResponsesAwaitingAsyncCompletion) - .Append(", wr=").Append(WriterCount); - if (Subscriptions != 0) sb.Append(", subs=").Append(Subscriptions); - if (FailedAsynchronously != 0) sb.Append(", async-fail=").Append(FailedAsynchronously); - if (CompletedSynchronously != 0) sb.Append(", sync=").Append(CompletedSynchronously); - if (CompletedAsynchronously != 0) sb.Append(", async=").Append(CompletedAsynchronously); - if (SocketCount != 0) sb.Append(", socks=").Append(SocketCount); - if (NonPreferredEndpointCount != 0) sb.Append(", non-pref=").Append(NonPreferredEndpointCount); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionFailedEventArgs.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionFailedEventArgs.cs deleted file mode 100644 index b575549..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionFailedEventArgs.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Net; -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Contains information about a server connection failure - /// - public sealed class ConnectionFailedEventArgs : EventArgs, ICompletable - { - private readonly EventHandler handler; - private readonly object sender; - internal ConnectionFailedEventArgs(EventHandler handler, object sender, EndPoint endPoint, ConnectionType connectionType, ConnectionFailureType failureType, Exception exception) - { - this.handler = handler; - this.sender = sender; - EndPoint = endPoint; - ConnectionType = connectionType; - Exception = exception; - FailureType = failureType; - } - - /// - /// Gets the connection-type of the failing connection - /// - public ConnectionType ConnectionType { get; } - - /// - /// Gets the failing server-endpoint - /// - public EndPoint EndPoint { get; } - - /// - /// Gets the exception if available (this can be null) - /// - public Exception Exception { get; } - - /// - /// The type of failure - /// - public ConnectionFailureType FailureType { get; } - - void ICompletable.AppendStormLog(StringBuilder sb) - { - sb.Append("event, connection-failed: "); - if (EndPoint == null) sb.Append("n/a"); - else sb.Append(Format.ToString(EndPoint)); - } - - bool ICompletable.TryComplete(bool isAsync) - { - return ConnectionMultiplexer.TryCompleteHandler(handler, sender, this, isAsync); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionFailureType.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionFailureType.cs deleted file mode 100644 index 9213de8..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionFailureType.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// The known types of connection failure - /// - public enum ConnectionFailureType - { - /// - /// This event is not a failure - /// - None, - /// - /// No viable connections were available for this operation - /// - UnableToResolvePhysicalConnection, - /// - /// The socket for this connection failed - /// - SocketFailure, - /// - /// Either SSL Stream or Redis authentication failed - /// - AuthenticationFailure, - /// - /// An unexpected response was received from the server - /// - ProtocolFailure, - /// - /// An unknown internal error occurred - /// - InternalFailure, - /// - /// The socket was closed - /// - SocketClosed, - /// - /// The socket was closed - /// - ConnectionDisposed, - /// - /// The database is loading and is not available for use - /// - Loading, - /// - /// It has not been possible to create an intial connection to the redis server(s) - /// - UnableToConnect - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.Profiling.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.Profiling.cs deleted file mode 100644 index 80c291f..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.Profiling.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - partial class ConnectionMultiplexer - { - private IProfiler profiler; - - // internal for test purposes - internal ProfileContextTracker profiledCommands; - - /// - /// Sets an IProfiler instance for this ConnectionMultiplexer. - /// - /// An IProfiler instances is used to determine which context to associate an - /// IProfiledCommand with. See BeginProfiling(object) and FinishProfiling(object) - /// for more details. - /// - public void RegisterProfiler(IProfiler profiler) - { - if (profiler == null) throw new ArgumentNullException(nameof(profiler)); - if (this.profiler != null) throw new InvalidOperationException("IProfiler already registered for this ConnectionMultiplexer"); - - this.profiler = profiler; - this.profiledCommands = new ProfileContextTracker(); - } - - /// - /// Begins profiling for the given context. - /// - /// If the same context object is returned by the registered IProfiler, the IProfiledCommands - /// will be associated with each other. - /// - /// Call FinishProfiling with the same context to get the assocated commands. - /// - /// Note that forContext cannot be a WeakReference or a WeakReference<T> - /// - public void BeginProfiling(object forContext) - { - if (profiler == null) throw new InvalidOperationException("Cannot begin profiling if no IProfiler has been registered with RegisterProfiler"); - if (forContext == null) throw new ArgumentNullException(nameof(forContext)); - if (forContext is WeakReference) throw new ArgumentException("Context object cannot be a WeakReference", nameof(forContext)); - - if (!profiledCommands.TryCreate(forContext)) - { - throw ExceptionFactory.BeganProfilingWithDuplicateContext(forContext); - } - } - - /// - /// Stops profiling for the given context, returns all IProfiledCommands associated. - /// - /// By default this may do a sweep for dead profiling contexts, you can disable this by passing "allowCleanupSweep: false". - /// - public ProfiledCommandEnumerable FinishProfiling(object forContext, bool allowCleanupSweep = true) - { - if (profiler == null) throw new InvalidOperationException("Cannot begin profiling if no IProfiler has been registered with RegisterProfiler"); - if (forContext == null) throw new ArgumentNullException(nameof(forContext)); - - ProfiledCommandEnumerable ret; - if (!profiledCommands.TryRemove(forContext, out ret)) - { - throw ExceptionFactory.FinishedProfilingWithInvalidContext(forContext); - } - - // conditional, because it could hurt and that may sometimes be unacceptable - if (allowCleanupSweep) - { - profiledCommands.TryCleanup(); - } - - return ret; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.ReaderWriter.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.ReaderWriter.cs deleted file mode 100644 index 224a503..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.ReaderWriter.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace StackExchange.Redis -{ - partial class ConnectionMultiplexer - { - internal SocketManager SocketManager => socketManager; - - private SocketManager socketManager; - private bool ownsSocketManager; - - partial void OnCreateReaderWriter(ConfigurationOptions configuration) - { - ownsSocketManager = configuration.SocketManager == null; - socketManager = configuration.SocketManager ?? new SocketManager(ClientName, configuration.HighPrioritySocketThreads); - } - - partial void OnCloseReaderWriter() - { - if (ownsSocketManager) socketManager?.Dispose(); - socketManager = null; - } - - internal void RequestWrite(PhysicalBridge bridge, bool forced) - { - if (bridge == null) return; - var tmp = SocketManager; - if (tmp != null) - { - Trace("Requesting write: " + bridge.Name); - tmp.RequestWrite(bridge, forced); - } - } - partial void OnWriterCreated(); - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.cs deleted file mode 100644 index e194b43..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionMultiplexer.cs +++ /dev/null @@ -1,2245 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using System.Reflection; -#if NET40 -using Microsoft.Runtime.CompilerServices; -#else -using System.IO.Compression; -using System.Runtime.CompilerServices; -#endif - -namespace StackExchange.Redis -{ - internal static partial class TaskExtensions - { - private static readonly Action observeErrors = ObverveErrors; - private static void ObverveErrors(this Task task) - { - if (task != null) GC.KeepAlive(task.Exception); - } - - public static Task ObserveErrors(this Task task) - { - task?.ContinueWith(observeErrors, TaskContinuationOptions.OnlyOnFaulted); - return task; - } - public static Task ObserveErrors(this Task task) - { - task?.ContinueWith(observeErrors, TaskContinuationOptions.OnlyOnFaulted); - return task; - } - - public static ConfiguredTaskAwaitable ForAwait(this Task task) - { - return task.ConfigureAwait(false); - } - public static ConfiguredTaskAwaitable ForAwait(this Task task) - { - return task.ConfigureAwait(false); - } - } - - /// - /// Represents an inter-related group of connections to redis servers - /// - public sealed partial class ConnectionMultiplexer : IConnectionMultiplexer, IDisposable - { - private static readonly string timeoutHelpLink = "http://stackexchange.github.io/StackExchange.Redis/Timeouts"; - - private static TaskFactory _factory = null; - - /// - /// Provides a way of overriding the default Task Factory. If not set, it will use the default Task.Factory. - /// Useful when top level code sets it's own factory which may interfere with Redis queries. - /// - public static TaskFactory Factory - { - get - { - return _factory ?? Task.Factory; - } - set - { - _factory = value; - - } - } - - /// - /// Get summary statistics associates with this server - /// - public ServerCounters GetCounters() - { - var snapshot = serverSnapshot; - - var counters = new ServerCounters(null); - for (int i = 0; i < snapshot.Length; i++) - { - counters.Add(snapshot[i].GetCounters()); - } - unprocessableCompletionManager.GetCounters(counters.Other); - return counters; - } - - /// - /// Gets the client-name that will be used on all new connections - /// - public string ClientName => configuration.ClientName ?? ConnectionMultiplexer.GetDefaultClientName(); - - private static string defaultClientName; - private static string GetDefaultClientName() - { - if (defaultClientName == null) - { - defaultClientName = TryGetAzureRoleInstanceIdNoThrow() ?? Environment.GetEnvironmentVariable("ComputerName"); - } - return defaultClientName; - } - - /// Tries to get the Roleinstance Id if Microsoft.WindowsAzure.ServiceRuntime is loaded. - /// In case of any failure, swallows the exception and returns null - internal static string TryGetAzureRoleInstanceIdNoThrow() - { - string roleInstanceId = null; - // TODO: CoreCLR port pending https://github.com/dotnet/coreclr/issues/919 -#if !CORE_CLR - try - { - Assembly asm = null; - foreach (var asmb in AppDomain.CurrentDomain.GetAssemblies()) - { - if (asmb.GetName().Name.Equals("Microsoft.WindowsAzure.ServiceRuntime")) - { - asm = asmb; - break; - } - } - if (asm == null) - return null; - - var type = asm.GetType("Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment"); - - // https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.serviceruntime.roleenvironment.isavailable.aspx if (!(bool)type.GetProperty("IsAvailable").GetValue(null, null)) return null; - - var currentRoleInstanceProp = type.GetProperty("CurrentRoleInstance"); - var currentRoleInstanceId = currentRoleInstanceProp.GetValue(null, null); - roleInstanceId = currentRoleInstanceId.GetType().GetProperty("Id").GetValue(currentRoleInstanceId, null).ToString(); - - if (String.IsNullOrEmpty(roleInstanceId)) - { - roleInstanceId = null; - } - } - catch (Exception) - { - //silently ignores the exception - roleInstanceId = null; - } -#endif - return roleInstanceId; - } - - /// - /// Gets the configuration of the connection - /// - public string Configuration => configuration.ToString(); - - internal void OnConnectionFailed(EndPoint endpoint, ConnectionType connectionType, ConnectionFailureType failureType, Exception exception, bool reconfigure) - { - if (isDisposed) return; - var handler = ConnectionFailed; - if (handler != null) - { - unprocessableCompletionManager.CompleteSyncOrAsync( - new ConnectionFailedEventArgs(handler, this, endpoint, connectionType, failureType, exception) - ); - } - if (reconfigure) - { - ReconfigureIfNeeded(endpoint, false, "connection failed"); - } - } - internal void OnInternalError(Exception exception, EndPoint endpoint = null, ConnectionType connectionType = ConnectionType.None, [System.Runtime.CompilerServices.CallerMemberName] string origin = null) - { - try - { - Trace("Internal error: " + origin + ", " + exception == null ? "unknown" : exception.Message); - if (isDisposed) return; - var handler = InternalError; - if (handler != null) - { - unprocessableCompletionManager.CompleteSyncOrAsync( - new InternalErrorEventArgs(handler, this, endpoint, connectionType, exception, origin) - ); - } - } - catch - { // our internal error event failed; whatcha gonna do, exactly? - } - } - - internal void OnConnectionRestored(EndPoint endpoint, ConnectionType connectionType) - { - if (isDisposed) return; - var handler = ConnectionRestored; - if (handler != null) - { - unprocessableCompletionManager.CompleteSyncOrAsync( - new ConnectionFailedEventArgs(handler, this, endpoint, connectionType, ConnectionFailureType.None, null) - ); - } - ReconfigureIfNeeded(endpoint, false, "connection restored"); - } - - - private void OnEndpointChanged(EndPoint endpoint, EventHandler handler) - { - if (isDisposed) return; - if (handler != null) - { - unprocessableCompletionManager.CompleteSyncOrAsync( - new EndPointEventArgs(handler, this, endpoint) - ); - } - } - internal void OnConfigurationChanged(EndPoint endpoint) - { - OnEndpointChanged(endpoint, ConfigurationChanged); - } - internal void OnConfigurationChangedBroadcast(EndPoint endpoint) - { - OnEndpointChanged(endpoint, ConfigurationChangedBroadcast); - } - - /// - /// A server replied with an error message; - /// - public event EventHandler ErrorMessage; - internal void OnErrorMessage(EndPoint endpoint, string message) - { - if (isDisposed) return; - var handler = ErrorMessage; - if (handler != null) - { - unprocessableCompletionManager.CompleteSyncOrAsync( - new RedisErrorEventArgs(handler, this, endpoint, message) - ); - } - } - -#if !NET40 - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")] - static void Write(ZipArchive zip, string name, Task task, Action callback) - { - var entry = zip.CreateEntry(name, -#if __MonoCS__ - CompressionLevel.Fastest -#else - CompressionLevel.Optimal -#endif - ); - using (var stream = entry.Open()) - using (var writer = new StreamWriter(stream)) - { - TaskStatus status = task.Status; - switch (status) - { - case TaskStatus.RanToCompletion: - T val = ((Task)task).Result; - callback(val, writer); - break; - case TaskStatus.Faulted: - writer.WriteLine(string.Join(", ", task.Exception.InnerExceptions.Select(x => x.Message))); - break; - default: - writer.WriteLine(status.ToString()); - break; - } - } - } - /// - /// Write the configuration of all servers to an output stream - /// - public void ExportConfiguration(Stream destination, ExportOptions options = ExportOptions.All) - { - if (destination == null) throw new ArgumentNullException(nameof(destination)); - - // what is possible, given the command map? - ExportOptions mask = 0; - if (CommandMap.IsAvailable(RedisCommand.INFO)) mask |= ExportOptions.Info; - if (CommandMap.IsAvailable(RedisCommand.CONFIG)) mask |= ExportOptions.Config; - if (CommandMap.IsAvailable(RedisCommand.CLIENT)) mask |= ExportOptions.Client; - if (CommandMap.IsAvailable(RedisCommand.CLUSTER)) mask |= ExportOptions.Cluster; - options &= mask; - - using (var zip = new ZipArchive(destination, ZipArchiveMode.Create, true)) - { - var arr = serverSnapshot; - foreach (var server in arr) - { - const CommandFlags flags = CommandFlags.None; - if (!server.IsConnected) continue; - var api = GetServer(server.EndPoint); - - List tasks = new List(); - if ((options & ExportOptions.Info) != 0) - { - tasks.Add(api.InfoRawAsync(flags: flags)); - } - if ((options & ExportOptions.Config) != 0) - { - tasks.Add(api.ConfigGetAsync(flags: flags)); - } - if ((options & ExportOptions.Client) != 0) - { - tasks.Add(api.ClientListAsync(flags: flags)); - } - if ((options & ExportOptions.Cluster) != 0) - { - tasks.Add(api.ClusterNodesRawAsync(flags: flags)); - } - - WaitAllIgnoreErrors(tasks.ToArray()); - - int index = 0; - var prefix = Format.ToString(server.EndPoint); - if ((options & ExportOptions.Info) != 0) - { - Write(zip, prefix + "/info.txt", tasks[index++], WriteNormalizingLineEndings); - } - if ((options & ExportOptions.Config) != 0) - { - Write[]>(zip, prefix + "/config.txt", tasks[index++], (settings, writer) => - { - foreach (var setting in settings) - { - writer.WriteLine("{0}={1}", setting.Key, setting.Value); - } - }); - } - if ((options & ExportOptions.Client) != 0) - { - Write(zip, prefix + "/clients.txt", tasks[index++], (clients, writer) => - { - foreach (var client in clients) - { - writer.WriteLine(client.Raw); - } - }); - } - if ((options & ExportOptions.Cluster) != 0) - { - Write(zip, prefix + "/nodes.txt", tasks[index++], WriteNormalizingLineEndings); - } - } - } - } -#endif - - internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options, TextWriter log) - { - CommandMap.AssertAvailable(RedisCommand.SLAVEOF); - if (!configuration.AllowAdmin) throw ExceptionFactory.AdminModeNotEnabled(IncludeDetailInExceptions, RedisCommand.SLAVEOF, null, server); - - if (server == null) throw new ArgumentNullException(nameof(server)); - var srv = new RedisServer(this, server, null); - if (!srv.IsConnected) throw ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, IncludePerformanceCountersInExceptions, RedisCommand.SLAVEOF, null, server, GetServerSnapshot()); - - if (log == null) log = TextWriter.Null; - CommandMap.AssertAvailable(RedisCommand.SLAVEOF); - - const CommandFlags flags = CommandFlags.NoRedirect | CommandFlags.HighPriority; - Message msg; - - LogLocked(log, "Checking {0} is available...", Format.ToString(srv.EndPoint)); - try - { - srv.Ping(flags); // if it isn't happy, we're not happy - } catch (Exception ex) - { - LogLocked(log, "Operation failed on {0}, aborting: {1}", Format.ToString(srv.EndPoint), ex.Message); - throw; - } - - var nodes = serverSnapshot; - RedisValue newMaster = Format.ToString(server.EndPoint); - - RedisKey tieBreakerKey = default(RedisKey); - // try and write this everywhere; don't worry if some folks reject our advances - if ((options & ReplicationChangeOptions.SetTiebreaker) != 0 && !string.IsNullOrWhiteSpace(configuration.TieBreaker) - && CommandMap.IsAvailable(RedisCommand.SET)) - { - tieBreakerKey = configuration.TieBreaker; - - foreach (var node in nodes) - { - if (!node.IsConnected) continue; - LogLocked(log, "Attempting to set tie-breaker on {0}...", Format.ToString(node.EndPoint)); - msg = Message.Create(0, flags, RedisCommand.SET, tieBreakerKey, newMaster); - node.QueueDirectFireAndForget(msg, ResultProcessor.DemandOK); - } - } - - // deslave... - LogLocked(log, "Making {0} a master...", Format.ToString(srv.EndPoint)); - try - { - srv.SlaveOf(null, flags); - } catch (Exception ex) - { - LogLocked(log, "Operation failed on {0}, aborting: {1}", Format.ToString(srv.EndPoint), ex.Message); - throw; - } - - // also, in case it was a slave a moment ago, and hasn't got the tie-breaker yet, we re-send the tie-breaker to this one - if (!tieBreakerKey.IsNull) - { - LogLocked(log, "Resending tie-breaker to {0}...", Format.ToString(server.EndPoint)); - msg = Message.Create(0, flags, RedisCommand.SET, tieBreakerKey, newMaster); - server.QueueDirectFireAndForget(msg, ResultProcessor.DemandOK); - } - - - - // try and broadcast this everywhere, to catch the maximum audience - if ((options & ReplicationChangeOptions.Broadcast) != 0 && ConfigurationChangedChannel != null - && CommandMap.IsAvailable(RedisCommand.PUBLISH)) - { - RedisValue channel = ConfigurationChangedChannel; - foreach (var node in nodes) - { - if (!node.IsConnected) continue; - LogLocked(log, "Broadcasting via {0}...", Format.ToString(node.EndPoint)); - msg = Message.Create(-1, flags, RedisCommand.PUBLISH, channel, newMaster); - node.QueueDirectFireAndForget(msg, ResultProcessor.Int64); - } - } - - - if ((options & ReplicationChangeOptions.EnslaveSubordinates) != 0) - { - foreach (var node in nodes) - { - if (node == server || node.ServerType != ServerType.Standalone) continue; - - LogLocked(log, "Enslaving {0}...", Format.ToString(node.EndPoint)); - msg = RedisServer.CreateSlaveOfMessage(server.EndPoint, flags); - node.QueueDirectFireAndForget(msg, ResultProcessor.DemandOK); - } - } - - // and reconfigure the muxer - LogLocked(log, "Reconfiguring all endpoints..."); - if (!ReconfigureAsync(false, true, log, srv.EndPoint, "make master").ObserveErrors().Wait(5000)) - { - LogLocked(log, "Verifying the configuration was incomplete; please verify"); - } - } - - /// - /// Used internally to synchronize loggine without depending on locking the log instance - /// - private object LogSyncLock => UniqueId; - -// we know this has strong identity: readonly and unique to us - - internal void LogLocked(TextWriter log, string line) - { - if (log != null) lock (LogSyncLock) { log.WriteLine(line); } - } - internal void LogLocked(TextWriter log, string line, object arg) - { - if (log != null) lock (LogSyncLock) { log.WriteLine(line, arg); } - } - internal void LogLocked(TextWriter log, string line, object arg0, object arg1) - { - if (log != null) lock (LogSyncLock) { log.WriteLine(line, arg0, arg1); } - } - internal void LogLocked(TextWriter log, string line, object arg0, object arg1, object arg2) - { - if (log != null) lock (LogSyncLock) { log.WriteLine(line, arg0, arg1, arg2); } - } - internal void LogLocked(TextWriter log, string line, params object[] args) - { - if (log != null) lock (LogSyncLock) { log.WriteLine(line, args); } - } - - internal void CheckMessage(Message message) - { - if (!configuration.AllowAdmin && message.IsAdmin) - throw ExceptionFactory.AdminModeNotEnabled(IncludeDetailInExceptions, message.Command, message, null); - CommandMap.AssertAvailable(message.Command); - } - - static void WriteNormalizingLineEndings(string source, StreamWriter writer) - { - using (var reader = new StringReader(source)) - { - string line; - while ((line = reader.ReadLine()) != null) - writer.WriteLine(line); // normalize line endings - } - } - - /// - /// Raised whenever a physical connection fails - /// - public event EventHandler ConnectionFailed; - - /// - /// Raised whenever an internal error occurs (this is primarily for debugging) - /// - public event EventHandler InternalError; - - /// - /// Raised whenever a physical connection is established - /// - public event EventHandler ConnectionRestored; - - /// - /// Raised when configuration changes are detected - /// - public event EventHandler ConfigurationChanged; - - /// - /// Raised when nodes are explicitly requested to reconfigure via broadcast; - /// this usually means master/slave changes - /// - public event EventHandler ConfigurationChangedBroadcast; - - /// - /// Gets the timeout associated with the connections - /// - public int TimeoutMilliseconds => timeoutMilliseconds; - - /// - /// Gets all endpoints defined on the server - /// - /// - public EndPoint[] GetEndPoints(bool configuredOnly = false) - { - if (configuredOnly) return configuration.EndPoints.ToArray(); - - return ConvertHelper.ConvertAll(serverSnapshot, x => x.EndPoint); - } - - private readonly int timeoutMilliseconds; - - private readonly ConfigurationOptions configuration; - - - internal bool TryResend(int hashSlot, Message message, EndPoint endpoint, bool isMoved) - { - return serverSelectionStrategy.TryResend(hashSlot, message, endpoint, isMoved); - } - - - /// - /// Wait for a given asynchronous operation to complete (or timeout) - /// - public void Wait(Task task) - { - if (task == null) throw new ArgumentNullException(nameof(task)); - if (!task.Wait(timeoutMilliseconds)) throw new TimeoutException(); - } - - /// - /// Wait for a given asynchronous operation to complete (or timeout) - /// - - public T Wait(Task task) - { - if (task == null) throw new ArgumentNullException(nameof(task)); - if (!task.Wait(timeoutMilliseconds)) throw new TimeoutException(); - return task.Result; - } - /// - /// Wait for the given asynchronous operations to complete (or timeout) - /// - public void WaitAll(params Task[] tasks) - { - if (tasks == null) throw new ArgumentNullException(nameof(tasks)); - if (tasks.Length == 0) return; - if (!Task.WaitAll(tasks, timeoutMilliseconds)) throw new TimeoutException(); - } - - private bool WaitAllIgnoreErrors(Task[] tasks) - { - return WaitAllIgnoreErrors(tasks, timeoutMilliseconds); - } - private static bool WaitAllIgnoreErrors(Task[] tasks, int timeout) - { - if (tasks == null) throw new ArgumentNullException(nameof(tasks)); - if (tasks.Length == 0) return true; - var watch = Stopwatch.StartNew(); - try - { - // if none error, great - if (Task.WaitAll(tasks, timeout)) return true; - } - catch - { } - // if we get problems, need to give the non-failing ones time to finish - // to be fair and reasonable - for (int i = 0; i < tasks.Length; i++) - { - var task = tasks[i]; - if (!task.IsCanceled && !task.IsCompleted && !task.IsFaulted) - { - var remaining = timeout - checked((int)watch.ElapsedMilliseconds); - if (remaining <= 0) return false; - try - { - task.Wait(remaining); - } - catch - { } - } - } - return false; - } - -#if !CORE_CLR - private void LogLockedWithThreadPoolStats(TextWriter log, string message, out int busyWorkerCount) - { - busyWorkerCount = 0; - if(log != null) - { - var sb = new StringBuilder(); - sb.Append(message); - string iocp, worker; - busyWorkerCount = GetThreadPoolStats(out iocp, out worker); - sb.Append(", IOCP: ").Append(iocp).Append(", WORKER: ").Append(worker); - LogLocked(log, sb.ToString()); - } - } -#endif - - static bool AllComplete(Task[] tasks) - { - for(int i = 0 ; i < tasks.Length ; i++) - { - var task = tasks[i]; - if (!task.IsCanceled && !task.IsCompleted && !task.IsFaulted) - return false; - } - return true; - } - private async Task WaitAllIgnoreErrorsAsync(Task[] tasks, int timeoutMilliseconds, TextWriter log) - { - if (tasks == null) throw new ArgumentNullException(nameof(tasks)); - if (tasks.Length == 0) - { - LogLocked(log, "No tasks to await"); - return true; - } - - if (AllComplete(tasks)) - { - LogLocked(log, "All tasks are already complete"); - return true; - } - - var watch = Stopwatch.StartNew(); -#if !CORE_CLR - int busyWorkerCount; - LogLockedWithThreadPoolStats(log, "Awaiting task completion", out busyWorkerCount); -#endif - try - { - // if none error, great - var remaining = timeoutMilliseconds - checked((int)watch.ElapsedMilliseconds); - if (remaining <= 0) - { -#if !CORE_CLR - LogLockedWithThreadPoolStats(log, "Timeout before awaiting for tasks", out busyWorkerCount); -#endif - return false; - } - -#if NET40 - var allTasks = TaskEx.WhenAll(tasks).ObserveErrors(); - var any = TaskEx.WhenAny(allTasks, TaskEx.Delay(remaining)).ObserveErrors(); -#else - var allTasks = Task.WhenAll(tasks).ObserveErrors(); - var any = Task.WhenAny(allTasks, Task.Delay(remaining)).ObserveErrors(); -#endif - bool all = await any.ForAwait() == allTasks; -#if !CORE_CLR - LogLockedWithThreadPoolStats(log, all ? "All tasks completed cleanly" : "Not all tasks completed cleanly", out busyWorkerCount); -#endif - return all; - } - catch - { } - - // if we get problems, need to give the non-failing ones time to finish - // to be fair and reasonable - for (int i = 0; i < tasks.Length; i++) - { - var task = tasks[i]; - if (!task.IsCanceled && !task.IsCompleted && !task.IsFaulted) - { - var remaining = timeoutMilliseconds - checked((int)watch.ElapsedMilliseconds); - if (remaining <= 0) - { -#if !CORE_CLR - LogLockedWithThreadPoolStats(log, "Timeout awaiting tasks", out busyWorkerCount); -#endif - return false; - } - try - { -#if NET40 - var any = TaskEx.WhenAny(task, TaskEx.Delay(remaining)).ObserveErrors(); -#else - var any = Task.WhenAny(task, Task.Delay(remaining)).ObserveErrors(); -#endif - await any.ForAwait(); - } - catch - { } - } - } -#if !CORE_CLR - LogLockedWithThreadPoolStats(log, "Finished awaiting tasks", out busyWorkerCount); -#endif - return false; - } - - - /// - /// Raised when a hash-slot has been relocated - /// - public event EventHandler HashSlotMoved; - - internal void OnHashSlotMoved(int hashSlot, EndPoint old, EndPoint @new) - { - var handler = HashSlotMoved; - if (handler != null) - { - unprocessableCompletionManager.CompleteSyncOrAsync( - new HashSlotMovedEventArgs(handler, this, hashSlot, old, @new) - ); - } - } - - /// - /// Compute the hash-slot of a specified key - /// - public int HashSlot(RedisKey key) - { - return serverSelectionStrategy.HashSlot(key); - } - - internal ServerEndPoint AnyConnected(ServerType serverType, uint startOffset, RedisCommand command, CommandFlags flags) - { - var tmp = serverSnapshot; - int len = tmp.Length; - ServerEndPoint fallback = null; - for (int i = 0; i < len; i++) - { - var server = tmp[(int)(((uint)i + startOffset) % len)]; - if (server != null && server.ServerType == serverType && server.IsSelectable(command)) - { - if (server.IsSlave) - { - switch (flags) - { - case CommandFlags.DemandSlave: - case CommandFlags.PreferSlave: - return server; - case CommandFlags.PreferMaster: - fallback = server; - break; - } - } else - { - switch (flags) - { - case CommandFlags.DemandMaster: - case CommandFlags.PreferMaster: - return server; - case CommandFlags.PreferSlave: - fallback = server; - break; - } - } - } - } - return fallback; - } - - volatile bool isDisposed; - internal bool IsDisposed => isDisposed; - - /// - /// Create a new ConnectionMultiplexer instance - /// - public static async Task ConnectAsync(string configuration, TextWriter log = null) - { - IDisposable killMe = null; - try - { - var muxer = CreateMultiplexer(configuration); - killMe = muxer; - bool configured = await muxer.ReconfigureAsync(true, false, log, null, "connect").ObserveErrors().ForAwait(); - if (!configured) - { - throw ExceptionFactory.UnableToConnect(muxer.RawConfig.AbortOnConnectFail, muxer.failureMessage); - } - killMe = null; - return muxer; - } finally - { - if (killMe != null) try { killMe.Dispose(); } catch { } - } - } - - /// - /// Create a new ConnectionMultiplexer instance - /// - public static async Task ConnectAsync(ConfigurationOptions configuration, TextWriter log = null) - { - IDisposable killMe = null; - try - { - var muxer = CreateMultiplexer(configuration); - killMe = muxer; - bool configured = await muxer.ReconfigureAsync(true, false, log, null, "connect").ObserveErrors().ForAwait(); - if (!configured) - { - throw ExceptionFactory.UnableToConnect(muxer.RawConfig.AbortOnConnectFail, muxer.failureMessage); - } - killMe = null; - return muxer; - } finally - { - if (killMe != null) try { killMe.Dispose(); } catch { } - } - } - - static ConnectionMultiplexer CreateMultiplexer(object configuration) - { - if (configuration == null) throw new ArgumentNullException(nameof(configuration)); - ConfigurationOptions config; - if (configuration is string) - { - config = ConfigurationOptions.Parse((string)configuration); - } else if (configuration is ConfigurationOptions) - { - config = ((ConfigurationOptions)configuration).Clone(); - } else - { - throw new ArgumentException("configuration"); - } - if (config.EndPoints.Count == 0) throw new ArgumentException("No endpoints specified", nameof(configuration)); - config.SetDefaultPorts(); - return new ConnectionMultiplexer(config); - } - /// - /// Create a new ConnectionMultiplexer instance - /// - public static ConnectionMultiplexer Connect(string configuration, TextWriter log = null) - { - return ConnectImpl(() => CreateMultiplexer(configuration), log); - } - - /// - /// Create a new ConnectionMultiplexer instance - /// - public static ConnectionMultiplexer Connect(ConfigurationOptions configuration, TextWriter log = null) - { - return ConnectImpl(() => CreateMultiplexer(configuration), log); - } - - private static ConnectionMultiplexer ConnectImpl(Func multiplexerFactory, TextWriter log) - { - IDisposable killMe = null; - try - { - var muxer = multiplexerFactory(); - killMe = muxer; - // note that task has timeouts internally, so it might take *just over* the regular timeout - var task = muxer.ReconfigureAsync(true, false, log, null, "connect"); - - if (!task.Wait(muxer.SyncConnectTimeout(true))) - { - task.ObserveErrors(); - if (muxer.RawConfig.AbortOnConnectFail) - { - throw ExceptionFactory.UnableToConnect(muxer.RawConfig.AbortOnConnectFail, "ConnectTimeout"); - } - else - { - muxer.LastException = ExceptionFactory.UnableToConnect(muxer.RawConfig.AbortOnConnectFail, "ConnectTimeout"); - } - } - if (!task.Result) throw ExceptionFactory.UnableToConnect(muxer.RawConfig.AbortOnConnectFail, muxer.failureMessage); - killMe = null; - return muxer; - } - finally - { - if (killMe != null) try { killMe.Dispose(); } catch { } - } - } - - private string failureMessage; - private readonly Hashtable servers = new Hashtable(); - private volatile ServerEndPoint[] serverSnapshot = NilServers; - - private static readonly ServerEndPoint[] NilServers = new ServerEndPoint[0]; - - internal ServerEndPoint GetServerEndPoint(EndPoint endpoint) - { - if (endpoint == null) return null; - var server = (ServerEndPoint)servers[endpoint]; - if (server == null) - { - lock (servers) - { - server = (ServerEndPoint)servers[endpoint]; - if (server == null) - { - if (isDisposed) throw new ObjectDisposedException(ToString()); - - server = new ServerEndPoint(this, endpoint, null); - // ^^ this could indirectly cause servers to become changes, so treble-check! - if (!servers.ContainsKey(endpoint)) - { - servers.Add(endpoint, server); - } - - var newSnapshot = serverSnapshot; - Array.Resize(ref newSnapshot, newSnapshot.Length + 1); - newSnapshot[newSnapshot.Length - 1] = server; - serverSnapshot = newSnapshot; - } - - } - } - return server; - } - - internal readonly CommandMap CommandMap; - private ConnectionMultiplexer(ConfigurationOptions configuration) - { - if (configuration == null) throw new ArgumentNullException(nameof(configuration)); - IncludeDetailInExceptions = true; - IncludePerformanceCountersInExceptions = false; - - this.configuration = configuration; - - var map = CommandMap = configuration.CommandMap; - if (!string.IsNullOrWhiteSpace(configuration.Password)) map.AssertAvailable(RedisCommand.AUTH); - - if(!map.IsAvailable(RedisCommand.ECHO) && !map.IsAvailable(RedisCommand.PING) && !map.IsAvailable(RedisCommand.TIME)) - { // I mean really, give me a CHANCE! I need *something* to check the server is available to me... - // see also: SendTracer (matching logic) - map.AssertAvailable(RedisCommand.EXISTS); - } - - PreserveAsyncOrder = true; // safest default - timeoutMilliseconds = configuration.SyncTimeout; - - OnCreateReaderWriter(configuration); - unprocessableCompletionManager = new CompletionManager(this, "multiplexer"); - serverSelectionStrategy = new ServerSelectionStrategy(this); - - var configChannel = configuration.ConfigurationChannel; - if (!string.IsNullOrWhiteSpace(configChannel)) - { - ConfigurationChangedChannel = Encoding.UTF8.GetBytes(configChannel); - } - lastHeartbeatTicks = Environment.TickCount; - } - - partial void OnCreateReaderWriter(ConfigurationOptions configuration); - - internal const int MillisecondsPerHeartbeat = 1000; - - private static readonly TimerCallback heartbeat = state => - { - ((ConnectionMultiplexer)state).OnHeartbeat(); - }; - - private int _activeHeartbeatErrors; - private void OnHeartbeat() - { - try - { - int now = Environment.TickCount; - Interlocked.Exchange(ref lastHeartbeatTicks, now); - Interlocked.Exchange(ref lastGlobalHeartbeatTicks, now); - Trace("heartbeat"); - - var tmp = serverSnapshot; - for (int i = 0; i < tmp.Length; i++) - tmp[i].OnHeartbeat(); - } - catch (Exception ex) - { - if (Interlocked.CompareExchange(ref _activeHeartbeatErrors, 1, 0) == 0) - { - try - { - OnInternalError(ex); - } - finally - { - Interlocked.Exchange(ref _activeHeartbeatErrors, 0); - } - } - } - } - - private int lastHeartbeatTicks; - private static int lastGlobalHeartbeatTicks = Environment.TickCount; - internal long LastHeartbeatSecondsAgo { - get { - if (pulse == null) return -1; - return unchecked(Environment.TickCount - VolatileWrapper.Read(ref lastHeartbeatTicks)) / 1000; - } - } - - internal Exception LastException { get; set; } - - internal static long LastGlobalHeartbeatSecondsAgo => unchecked(Environment.TickCount - VolatileWrapper.Read(ref lastGlobalHeartbeatTicks)) / 1000; - - internal CompletionManager UnprocessableCompletionManager => unprocessableCompletionManager; - - /// - /// Obtain a pub/sub subscriber connection to the specified server - /// - public ISubscriber GetSubscriber(object asyncState = null) - { - if (RawConfig.Proxy == Proxy.Twemproxy) throw new NotSupportedException("The pub/sub API is not available via twemproxy"); - return new RedisSubscriber(this, asyncState); - } - /// - /// Obtain an interactive connection to a database inside redis - /// - public IDatabase GetDatabase(int db = -1, object asyncState = null) - { - if (db == -1) - db = configuration.DefaultDatabase ?? 0; - - if (db < 0) throw new ArgumentOutOfRangeException(nameof(db)); - if (db != 0 && RawConfig.Proxy == Proxy.Twemproxy) throw new NotSupportedException("Twemproxy only supports database 0"); - - // if there's no async-state, and the DB is suitable, we can hand out a re-used instance - return (asyncState == null && db <= MaxCachedDatabaseInstance) - ? GetCachedDatabaseInstance(db) : new RedisDatabase(this, db, asyncState); - } - - // DB zero is stored separately, since 0-only is a massively common use-case - const int MaxCachedDatabaseInstance = 16; // 17 items - [0,16] - // side note: "databases 16" is the default in redis.conf; happy to store one extra to get nice alignment etc - private IDatabase dbCacheZero; - private IDatabase[] dbCacheLow; - private IDatabase GetCachedDatabaseInstance(int db) // note that we already trust db here; only caller checks range - { - // note we don't need to worry about *always* returning the same instance - // - if two threads ask for db 3 at the same time, it is OK for them to get - // different instances, one of which (arbitrarily) ends up cached for later use - if(db == 0) - { - return dbCacheZero ?? (dbCacheZero = new RedisDatabase(this, 0, null)); - } - var arr = dbCacheLow ?? (dbCacheLow = new IDatabase[MaxCachedDatabaseInstance]); - return arr[db - 1] ?? (arr[db - 1] = new RedisDatabase(this, db, null)); - } - - /// - /// Obtain a configuration API for an individual server - /// - public IServer GetServer(string host, int port, object asyncState = null) - { - return GetServer(Format.ParseEndPoint(host, port), asyncState); - } - /// - /// Obtain a configuration API for an individual server - /// - public IServer GetServer(string hostAndPort, object asyncState = null) - { - return GetServer(Format.TryParseEndPoint(hostAndPort), asyncState); - } - /// - /// Obtain a configuration API for an individual server - /// - public IServer GetServer(IPAddress host, int port) - { - return GetServer(new IPEndPoint(host, port)); - } - - /// - /// Obtain a configuration API for an individual server - /// - public IServer GetServer(EndPoint endpoint, object asyncState = null) - { - if (endpoint == null) throw new ArgumentNullException(nameof(endpoint)); - if (RawConfig.Proxy == Proxy.Twemproxy) throw new NotSupportedException("The server API is not available via twemproxy"); - var server = (ServerEndPoint)servers[endpoint]; - if (server == null) throw new ArgumentException("The specified endpoint is not defined", nameof(endpoint)); - return new RedisServer(this, server, asyncState); - } - - - [Conditional("VERBOSE")] - internal void Trace(string message, [System.Runtime.CompilerServices.CallerMemberName] string category = null) - { - OnTrace(message, category); - } - [Conditional("VERBOSE")] - internal void Trace(bool condition, string message, [System.Runtime.CompilerServices.CallerMemberName] string category = null) - { - if (condition) OnTrace(message, category); - } - - partial void OnTrace(string message, string category); - static partial void OnTraceWithoutContext(string message, string category); - - [Conditional("VERBOSE")] - internal static void TraceWithoutContext(string message, [System.Runtime.CompilerServices.CallerMemberName] string category = null) - { - OnTraceWithoutContext(message, category); - } - [Conditional("VERBOSE")] - internal static void TraceWithoutContext(bool condition, string message, [System.Runtime.CompilerServices.CallerMemberName] string category = null) - { - if(condition) OnTraceWithoutContext(message, category); - } - - private readonly CompletionManager unprocessableCompletionManager; - - /// - /// The number of operations that have been performed on all connections - /// - public long OperationCount { - get - { - long total = 0; - var snapshot = serverSnapshot; - for (int i = 0; i < snapshot.Length; i++) total += snapshot[i].OperationCount; - return total; - } - } - - string activeConfigCause; - - internal bool ReconfigureIfNeeded(EndPoint blame, bool fromBroadcast, string cause, bool publishReconfigure = false, CommandFlags flags = CommandFlags.None) - { - if (fromBroadcast) - { - OnConfigurationChangedBroadcast(blame); - } - string activeCause = Interlocked.CompareExchange(ref activeConfigCause, null, null); - if (activeCause == null) - { - bool reconfigureAll = fromBroadcast || publishReconfigure; - Trace("Configuration change detected; checking nodes", "Configuration"); - ReconfigureAsync(false, reconfigureAll, null, blame, cause, publishReconfigure, flags).ObserveErrors(); - return true; - } else - { - Trace("Configuration change skipped; already in progress via " + activeCause, "Configuration"); - return false; - } - } - - /// - /// Reconfigure the current connections based on the existing configuration - /// - public Task ConfigureAsync(TextWriter log = null) - { - return ReconfigureAsync(false, true, log, null, "configure").ObserveErrors(); - } - /// - /// Reconfigure the current connections based on the existing configuration - /// - public bool Configure(TextWriter log = null) - { - // note we expect ReconfigureAsync to internally allow [n] duration, - // so to avoid near misses, here we wait 2*[n] - var task = ReconfigureAsync(false, true, log, null, "configure"); - if (!task.Wait(SyncConnectTimeout(false))) - { - task.ObserveErrors(); - if (configuration.AbortOnConnectFail) - { - throw new TimeoutException(); - } - else - { - LastException = new TimeoutException("ConnectTimeout"); - } - return false; - } - return task.Result; - } - - internal int SyncConnectTimeout(bool forConnect) - { - int retryCount = forConnect ? RawConfig.ConnectRetry : 1; - if (retryCount <= 0) retryCount = 1; - - int timeout = configuration.ConnectTimeout; - if (timeout >= int.MaxValue / retryCount) return int.MaxValue; - - timeout *= retryCount; - if (timeout >= int.MaxValue - 500) return int.MaxValue; - return timeout + Math.Min(500, timeout); - } - /// - /// Provides a text overview of the status of all connections - /// - public string GetStatus() - { - using(var sw = new StringWriter()) - { - GetStatus(sw); - return sw.ToString(); - } - } - /// - /// Provides a text overview of the status of all connections - /// - public void GetStatus(TextWriter log) - { - if (log == null) return; - - var tmp = serverSnapshot; - foreach (var server in tmp) - { - LogLocked(log, server.Summary()); - LogLocked(log, server.GetCounters().ToString()); - LogLocked(log, server.GetProfile()); - } - LogLocked(log, "Sync timeouts: {0}; fire and forget: {1}; last heartbeat: {2}s ago", - Interlocked.Read(ref syncTimeouts), Interlocked.Read(ref fireAndForgets), LastHeartbeatSecondsAgo); - } - internal async Task ReconfigureAsync(bool first, bool reconfigureAll, TextWriter log, EndPoint blame, string cause, bool publishReconfigure = false, CommandFlags publishReconfigureFlags = CommandFlags.None) - { - if (isDisposed) throw new ObjectDisposedException(ToString()); - bool showStats = true; - - if (log == null) - { - log = TextWriter.Null; - showStats = false; - } - bool ranThisCall = false; - try - { // note that "activeReconfigs" starts at one; we don't need to set it the first time - ranThisCall = first || Interlocked.CompareExchange(ref activeConfigCause, cause, null) == null; - - if (!ranThisCall) - { - LogLocked(log, "Reconfiguration was already in progress"); - return false; - } - Trace("Starting reconfiguration..."); - Trace(blame != null, "Blaming: " + Format.ToString(blame)); - - LogLocked(log, configuration.ToString(includePassword: false)); - LogLocked(log, ""); - - - if (first) - { - if (configuration.ResolveDns && configuration.HasDnsEndPoints()) - { - var dns = configuration.ResolveEndPointsAsync(this, log).ObserveErrors(); -#if NET40 - var any = TaskEx.WhenAny(dns, TaskEx.Delay(timeoutMilliseconds)); -#else - var any = Task.WhenAny(dns, Task.Delay(timeoutMilliseconds)); -#endif - if ((await any.ForAwait()) != dns) - { - throw new TimeoutException("Timeout resolving endpoints"); - } - } - int index = 0; - lock (servers) - { - serverSnapshot = new ServerEndPoint[configuration.EndPoints.Count]; - foreach (var endpoint in configuration.EndPoints) - { - var server = (ServerEndPoint)servers[endpoint]; - if (server == null) - { - server = new ServerEndPoint(this, endpoint, log); - // ^^ this could indirectly cause servers to become changes, so treble-check! - if (!servers.ContainsKey(endpoint)) - { - servers.Add(endpoint, server); - } - } - serverSnapshot[index++] = server; - } - } - foreach (var server in serverSnapshot) - { - server.Activate(ConnectionType.Interactive, log); - if (CommandMap.IsAvailable(RedisCommand.SUBSCRIBE)) - { - server.Activate(ConnectionType.Subscription, null); // no need to log the SUB stuff - } - } - } - int attemptsLeft = first ? configuration.ConnectRetry : 1; - - bool healthy = false; - do - { - if (first) - { - attemptsLeft--; - } - int standaloneCount = 0, clusterCount = 0, sentinelCount = 0; - var endpoints = configuration.EndPoints; - LogLocked(log, "{0} unique nodes specified", endpoints.Count); - - if (endpoints.Count == 0) - { - throw new InvalidOperationException("No nodes to consider"); - } - - const CommandFlags flags = CommandFlags.NoRedirect | CommandFlags.HighPriority; - List masters = new List(endpoints.Count); - bool useTieBreakers = !string.IsNullOrWhiteSpace(configuration.TieBreaker); - - ServerEndPoint[] servers = null; - Task[] tieBreakers = null; - bool encounteredConnectedClusterServer = false; - Stopwatch watch = null; - - int iterCount = first ? 2 : 1; - // this is fix for https://github.com/StackExchange/StackExchange.Redis/issues/300 - // auto discoverability of cluster nodes is made synchronous. - // we try to connect to endpoints specified inside the user provided configuration - // and when we encounter one such endpoint to which we are able to successfully connect, - // we get the list of cluster nodes from this endpoint and try to proactively connect - // to these nodes instead of relying on auto configure - for (int iter = 0; iter < iterCount; ++iter) - { - if (endpoints == null) break; - - var available = new Task[endpoints.Count]; - tieBreakers = useTieBreakers ? new Task[endpoints.Count] : null; - servers = new ServerEndPoint[available.Length]; - - RedisKey tieBreakerKey = useTieBreakers ? (RedisKey)configuration.TieBreaker : default(RedisKey); - - for (int i = 0; i < available.Length; i++) - { - Trace("Testing: " + Format.ToString(endpoints[i])); - var server = GetServerEndPoint(endpoints[i]); - //server.ReportNextFailure(); - servers[i] = server; - if (reconfigureAll && server.IsConnected) - { - LogLocked(log, "Refreshing {0}...", Format.ToString(server.EndPoint)); - // note that these will be processed synchronously *BEFORE* the tracer is processed, - // so we know that the configuration will be up to date if we see the tracer - server.AutoConfigure(null); - } - available[i] = server.SendTracer(log); - if (useTieBreakers) - { - LogLocked(log, "Requesting tie-break from {0} > {1}...", Format.ToString(server.EndPoint), configuration.TieBreaker); - Message msg = Message.Create(0, flags, RedisCommand.GET, tieBreakerKey); - msg.SetInternalCall(); - msg = LoggingMessage.Create(log, msg); - tieBreakers[i] = server.QueueDirectAsync(msg, ResultProcessor.String); - } - } - - watch = watch ?? Stopwatch.StartNew(); - var remaining = configuration.ConnectTimeout - checked((int)watch.ElapsedMilliseconds); - LogLocked(log, "Allowing endpoints {0} to respond...", TimeSpan.FromMilliseconds(remaining)); - Trace("Allowing endpoints " + TimeSpan.FromMilliseconds(remaining) + " to respond..."); - await WaitAllIgnoreErrorsAsync(available, remaining, log).ForAwait(); - - EndPointCollection updatedClusterEndpointCollection = null; - for (int i = 0; i < available.Length; i++) - { - var task = available[i]; - Trace(Format.ToString(endpoints[i]) + ": " + task.Status); - if (task.IsFaulted) - { - servers[i].SetUnselectable(UnselectableFlags.DidNotRespond); - var aex = task.Exception; - foreach (var ex in aex.InnerExceptions) - { - LogLocked(log, "{0} faulted: {1}", Format.ToString(endpoints[i]), ex.Message); - failureMessage = ex.Message; - } - } - else if (task.IsCanceled) - { - servers[i].SetUnselectable(UnselectableFlags.DidNotRespond); - LogLocked(log, "{0} was canceled", Format.ToString(endpoints[i])); - } - else if (task.IsCompleted) - { - var server = servers[i]; - if (task.Result) - { - servers[i].ClearUnselectable(UnselectableFlags.DidNotRespond); - LogLocked(log, "{0} returned with success", Format.ToString(endpoints[i])); - - // count the server types - switch (server.ServerType) - { - case ServerType.Twemproxy: - case ServerType.Standalone: - standaloneCount++; - break; - case ServerType.Sentinel: - sentinelCount++; - break; - case ServerType.Cluster: - clusterCount++; - break; - } - - if (clusterCount > 0 && !encounteredConnectedClusterServer) - { - // we have encountered a connected server with clustertype for the first time. - // so we will get list of other nodes from this server using "CLUSTER NODES" command - // and try to connect to these other nodes in the next iteration - encounteredConnectedClusterServer = true; - updatedClusterEndpointCollection = await GetEndpointsFromClusterNodes(server, log).ForAwait(); - } - - // set the server UnselectableFlags and update masters list - switch (server.ServerType) - { - case ServerType.Twemproxy: - case ServerType.Sentinel: - case ServerType.Standalone: - case ServerType.Cluster: - servers[i].ClearUnselectable(UnselectableFlags.ServerType); - if (server.IsSlave) - { - servers[i].ClearUnselectable(UnselectableFlags.RedundantMaster); - } - else - { - masters.Add(server); - } - break; - default: - servers[i].SetUnselectable(UnselectableFlags.ServerType); - break; - } - } - else - { - servers[i].SetUnselectable(UnselectableFlags.DidNotRespond); - LogLocked(log, "{0} returned, but incorrectly", Format.ToString(endpoints[i])); - } - } - else - { - servers[i].SetUnselectable(UnselectableFlags.DidNotRespond); - LogLocked(log, "{0} did not respond", Format.ToString(endpoints[i])); - } - } - - if (encounteredConnectedClusterServer) - { - endpoints = updatedClusterEndpointCollection; - } - else - { - break; // we do not want to repeat the second iteration - } - } - - if (clusterCount == 0) - { - // set the serverSelectionStrategy - if (RawConfig.Proxy == Proxy.Twemproxy) - { - serverSelectionStrategy.ServerType = ServerType.Twemproxy; - } - else if (standaloneCount == 0 && sentinelCount > 0) - { - serverSelectionStrategy.ServerType = ServerType.Sentinel; - } - else - { - serverSelectionStrategy.ServerType = ServerType.Standalone; - } - var preferred = await NominatePreferredMaster(log, servers, useTieBreakers, tieBreakers, masters).ObserveErrors().ForAwait(); - foreach (var master in masters) - { - if (master == preferred) - { - master.ClearUnselectable(UnselectableFlags.RedundantMaster); - } - else - { - master.SetUnselectable(UnselectableFlags.RedundantMaster); - } - } - } - else - { - serverSelectionStrategy.ServerType = ServerType.Cluster; - long coveredSlots = serverSelectionStrategy.CountCoveredSlots(); - LogLocked(log, "Cluster: {0} of {1} slots covered", - coveredSlots, serverSelectionStrategy.TotalSlots); - - } - if (!first) - { - long subscriptionChanges = ValidateSubscriptions(); - if (subscriptionChanges == 0) - { - LogLocked(log, "No subscription changes necessary"); - } - else - { - LogLocked(log, "Subscriptions reconfigured: {0}", subscriptionChanges); - } - } - if (showStats) - { - GetStatus(log); - } - - string stormLog = GetStormLog(); - if (!string.IsNullOrWhiteSpace(stormLog)) - { - LogLocked(log, ""); - LogLocked(log, stormLog); - } - healthy = standaloneCount != 0 || clusterCount != 0 || sentinelCount != 0; - if (first && !healthy && attemptsLeft > 0) - { - LogLocked(log, "resetting failing connections to retry..."); - ResetAllNonConnected(); - LogLocked(log, "retrying; attempts left: " + attemptsLeft + "..."); - } - //WTF("?: " + attempts); - } while (first && !healthy && attemptsLeft > 0); - - if(first && configuration.AbortOnConnectFail && !healthy) - { - return false; - } - if (first) - { - LogLocked(log, "Starting heartbeat..."); - pulse = new Timer(heartbeat, this, MillisecondsPerHeartbeat, MillisecondsPerHeartbeat); - } - if(publishReconfigure) - { - try - { - LogLocked(log, "Broadcasting reconfigure..."); - PublishReconfigureImpl(publishReconfigureFlags); - } - catch - { } - } - return true; - - } catch (Exception ex) - { - Trace(ex.Message); - throw; - } - finally - { - Trace("Exiting reconfiguration..."); - OnTraceLog(log); - if (ranThisCall) Interlocked.Exchange(ref activeConfigCause, null); - if (!first) OnConfigurationChanged(blame); - Trace("Reconfiguration exited"); - } - } - - private async Task GetEndpointsFromClusterNodes(ServerEndPoint server, TextWriter log) - { - var message = Message.Create(-1, CommandFlags.None, RedisCommand.CLUSTER, RedisLiterals.NODES); - try - { - var clusterConfig = await ExecuteAsyncImpl(message, ResultProcessor.ClusterNodes, null, server).ForAwait(); - return new EndPointCollection(clusterConfig.Nodes.Select(node => node.EndPoint).ToList()); - } - catch (Exception ex) - { - LogLocked(log, "Encountered error while updating cluster config: " + ex.Message); - return null; - } - } - - - private void ResetAllNonConnected() - { - var snapshot = serverSnapshot; - foreach(var server in snapshot) - { - server.ResetNonConnected(); - } - } - - partial void OnTraceLog(TextWriter log, [System.Runtime.CompilerServices.CallerMemberName] string caller = null); - private async Task NominatePreferredMaster(TextWriter log, ServerEndPoint[] servers, bool useTieBreakers, Task[] tieBreakers, List masters) - { - Dictionary uniques = null; - if (useTieBreakers) - { // count the votes - uniques = new Dictionary(StringComparer.OrdinalIgnoreCase); - await WaitAllIgnoreErrorsAsync(tieBreakers, 50, log).ForAwait(); - for (int i = 0; i < tieBreakers.Length; i++) - { - var ep = servers[i].EndPoint; - var status = tieBreakers[i].Status; - switch (status) - { - case TaskStatus.RanToCompletion: - string s = tieBreakers[i].Result; - if (string.IsNullOrWhiteSpace(s)) - { - LogLocked(log, "{0} had no tiebreaker set", Format.ToString(ep)); - } - else - { - LogLocked(log, "{0} nominates: {1}", Format.ToString(ep), s); - int count; - if (!uniques.TryGetValue(s, out count)) count = 0; - uniques[s] = count + 1; - } - break; - case TaskStatus.Faulted: - LogLocked(log, "{0} failed to nominate ({1})", Format.ToString(ep), status); - foreach (var ex in tieBreakers[i].Exception.InnerExceptions) - { - if (ex.Message.StartsWith("MOVED ") || ex.Message.StartsWith("ASK ")) continue; - LogLocked(log, "> {0}", ex.Message); - } - break; - default: - LogLocked(log, "{0} failed to nominate ({1})", Format.ToString(ep), status); - break; - } - } - } - - - switch (masters.Count) - { - case 0: - LogLocked(log, "No masters detected"); - return null; - case 1: - LogLocked(log, "Single master detected: " + Format.ToString(masters[0].EndPoint)); - return masters[0]; - default: - LogLocked(log, "Multiple masters detected..."); - if (useTieBreakers && uniques != null) - { - switch (uniques.Count) - { - case 0: - LogLocked(log, "nobody nominated a tie-breaker"); - break; - case 1: - string unanimous = uniques.Keys.Single(); - LogLocked(log, "tie-break is unanimous at {0}", unanimous); - var found = SelectServerByElection(servers, unanimous, log); - if (found != null) - { - LogLocked(log, "Elected: {0}", Format.ToString(found.EndPoint)); - return found; - } - break; - default: - LogLocked(log, "tie-break is contested:"); - ServerEndPoint highest = null; - bool arbitrary = false; - foreach (var pair in uniques.OrderByDescending(x => x.Value)) - { - LogLocked(log, "{0} has {1} votes", pair.Key, pair.Value); - if (highest == null) - { - highest = SelectServerByElection(servers, pair.Key, log); - if (highest != null) - { - // any more with this vote? if so: arbitrary - arbitrary = uniques.Where(x => x.Value == pair.Value).Skip(1).Any(); - } - } - } - if (highest != null) - { - if (arbitrary) - { - LogLocked(log, "Choosing master arbitrarily: {0}", Format.ToString(highest.EndPoint)); - } - else - { - LogLocked(log, "Elected: {0}", Format.ToString(highest.EndPoint)); - } - return highest; - } - break; - - } - - } - break; - } - - LogLocked(log, "Choosing master arbitrarily: {0}", Format.ToString(masters[0].EndPoint)); - return masters[0]; - - } - - private ServerEndPoint SelectServerByElection(ServerEndPoint[] servers, string endpoint, TextWriter log) - { - if (servers == null || string.IsNullOrWhiteSpace(endpoint)) return null; - for (int i = 0; i < servers.Length; i++) - { - if (string.Equals(Format.ToString(servers[i].EndPoint), endpoint, StringComparison.OrdinalIgnoreCase)) - return servers[i]; - } - LogLocked(log, "...but we couldn't find that"); - var deDottedEndpoint = DeDotifyHost(endpoint); - for (int i = 0; i < servers.Length; i++) - { - if (string.Equals(DeDotifyHost(Format.ToString(servers[i].EndPoint)), deDottedEndpoint, StringComparison.OrdinalIgnoreCase)) - { - LogLocked(log, "...but we did find instead: {0}", deDottedEndpoint); - return servers[i]; - } - } - return null; - } - - static string DeDotifyHost(string input) - { - if (string.IsNullOrWhiteSpace(input)) return input; // GIGO - - if (!char.IsLetter(input[0])) return input; // need first char to be alpha for this to work - - int periodPosition = input.IndexOf('.'); - if (periodPosition <= 0) return input; // no period or starts with a period? nothing useful to split - - int colonPosition = input.IndexOf(':'); - if (colonPosition > 0) - { // has a port specifier - return input.Substring(0, periodPosition) + input.Substring(colonPosition); - } - else - { - return input.Substring(0, periodPosition); - } - } - - internal void UpdateClusterRange(ClusterConfiguration configuration) - { - if (configuration == null) return; - foreach (var node in configuration.Nodes) - { - if (node.IsSlave || node.Slots.Count == 0) continue; - foreach (var slot in node.Slots) - { - var server = GetServerEndPoint(node.EndPoint); - if (server != null) serverSelectionStrategy.UpdateClusterRange(slot.From, slot.To, server); - } - } - } - - private Timer pulse; - - private readonly ServerSelectionStrategy serverSelectionStrategy; - - internal ServerEndPoint[] GetServerSnapshot() - { - var tmp = serverSnapshot; - return tmp; - } - - internal ServerEndPoint SelectServer(Message message) - { - if (message == null) return null; - return serverSelectionStrategy.Select(message); - } - - internal ServerEndPoint SelectServer(int db, RedisCommand command, CommandFlags flags, RedisKey key) - { - return serverSelectionStrategy.Select(db, command, key, flags); - } - private bool TryPushMessageToBridge(Message message, ResultProcessor processor, ResultBox resultBox, ref ServerEndPoint server) - { - message.SetSource(processor, resultBox); - - if (server == null) - { // infer a server automatically - server = SelectServer(message); - } - else // a server was specified; do we trust their choice, though? - { - - if (message.IsMasterOnly() && server.IsSlave) - { - throw ExceptionFactory.MasterOnly(IncludeDetailInExceptions, message.Command, message, server); - } - - switch(server.ServerType) - { - case ServerType.Cluster: - case ServerType.Twemproxy: // strictly speaking twemproxy uses a different hashing algo, but the hash-tag behavior is - // the same, so this does a pretty good job of spotting illegal commands before sending them - if (message.GetHashSlot(ServerSelectionStrategy) == ServerSelectionStrategy.MultipleSlots) - { - throw ExceptionFactory.MultiSlot(IncludeDetailInExceptions, message); - } - break; - } - if (!server.IsConnected) - { - // well, that's no use! - server = null; - } - } - - if (server != null) - { - var profCtx = profiler?.GetContext(); - if (profCtx != null) - { - ConcurrentProfileStorageCollection inFlightForCtx; - if (profiledCommands.TryGetValue(profCtx, out inFlightForCtx)) - { - message.SetProfileStorage(ProfileStorage.NewWithContext(inFlightForCtx, server)); - } - } - - if (message.Db >= 0) - { - int availableDatabases = server.Databases; - if (availableDatabases > 0 && message.Db >= availableDatabases) throw ExceptionFactory.DatabaseOutfRange( - IncludeDetailInExceptions, message.Db, message, server); - } - - Trace("Queueing on server: " + message); - if (server.TryEnqueue(message)) return true; - } - Trace("No server or server unavailable - aborting: " + message); - return false; - } - - - /// - /// See Object.ToString() - /// - public override string ToString() - { - string s = ClientName; - if (string.IsNullOrWhiteSpace(s)) s = GetType().Name; - return s; - } - - internal readonly byte[] ConfigurationChangedChannel; // this gets accessed for every received event; let's make sure we can process it "raw" - internal readonly byte[] UniqueId = Guid.NewGuid().ToByteArray(); // unique identifier used when tracing - - - /// - /// Gets or sets whether asynchronous operations should be invoked in a way that guarantees their original delivery order - /// - public bool PreserveAsyncOrder { get; set; } - - /// - /// Indicates whether any servers are connected - /// - public bool IsConnected - { - get - { - var tmp = serverSnapshot; - for (int i = 0; i < tmp.Length; i++) - if (tmp[i].IsConnected) return true; - return false; - } - } - - internal ConfigurationOptions RawConfig => configuration; - - internal ServerSelectionStrategy ServerSelectionStrategy => serverSelectionStrategy; - - - /// - /// Close all connections and release all resources associated with this object - /// - public void Close(bool allowCommandsToComplete = true) - { - isDisposed = true; - using (var tmp = pulse) - { - pulse = null; - } - - if (allowCommandsToComplete) - { - var quits = QuitAllServers(); - WaitAllIgnoreErrors(quits); - } - DisposeAndClearServers(); - OnCloseReaderWriter(); - } - partial void OnCloseReaderWriter(); - - private void DisposeAndClearServers() - { - lock (servers) - { - var iter = servers.GetEnumerator(); - while (iter.MoveNext()) - { - var server = (ServerEndPoint)iter.Value; - server.Dispose(); - } - servers.Clear(); - } - } - - private Task[] QuitAllServers() - { - Task[] quits = new Task[servers.Count]; - lock (servers) - { - var iter = servers.GetEnumerator(); - int index = 0; - while (iter.MoveNext()) - { - var server = (ServerEndPoint)iter.Value; - quits[index++] = server.Close(); - } - } - return quits; - } - - /// - /// Close all connections and release all resources associated with this object - /// - public async Task CloseAsync(bool allowCommandsToComplete = true) - { - isDisposed = true; - using (var tmp = pulse) - { - pulse = null; - } - - if (allowCommandsToComplete) - { - var quits = QuitAllServers(); - await WaitAllIgnoreErrorsAsync(quits, configuration.SyncTimeout, null).ForAwait(); - } - - DisposeAndClearServers(); - } - - /// - /// Release all resources associated with this object - /// - public void Dispose() - { - Close(!isDisposed); - } - - - internal Task ExecuteAsyncImpl(Message message, ResultProcessor processor, object state, ServerEndPoint server) - { - if (isDisposed) throw new ObjectDisposedException(ToString()); - - if (message == null) - { - return CompletedTask.Default(state); - } - - if (message.IsFireAndForget) - { - TryPushMessageToBridge(message, processor, null, ref server); - return CompletedTask.Default(null); // F+F explicitly does not get async-state - } - else - { - var tcs = TaskSource.CreateDenyExecSync(state); - var source = ResultBox.Get(tcs); - if (!TryPushMessageToBridge(message, processor, source, ref server)) - { - ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, IncludePerformanceCountersInExceptions, message.Command, message, server, GetServerSnapshot())); - } - return tcs.Task; - } - } - - internal static void ThrowFailed(TaskCompletionSource source, Exception unthrownException) - { - try - { - throw unthrownException; - } catch (Exception ex) - { - source.TrySetException(ex); - GC.KeepAlive(source.Task.Exception); - GC.SuppressFinalize(source.Task); - } - } - internal T ExecuteSyncImpl(Message message, ResultProcessor processor, ServerEndPoint server) - { - if (isDisposed) throw new ObjectDisposedException(ToString()); - - if (message == null) // fire-and forget could involve a no-op, represented by null - for example Increment by 0 - { - return default(T); - } - - if (message.IsFireAndForget) - { - TryPushMessageToBridge(message, processor, null, ref server); - Interlocked.Increment(ref fireAndForgets); - return default(T); - } - else - { - var source = ResultBox.Get(null); - - lock (source) - { - if (!TryPushMessageToBridge(message, processor, source, ref server)) - { - throw ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, IncludePerformanceCountersInExceptions, message.Command, message, server, GetServerSnapshot()); - } - - if (Monitor.Wait(source, timeoutMilliseconds)) - { - Trace("Timeley response to " + message.ToString()); - } - else - { - Trace("Timeout performing " + message.ToString()); - Interlocked.Increment(ref syncTimeouts); - string errMessage; - List> data = null; - if (server == null || !IncludeDetailInExceptions) - { - errMessage = "Timeout performing " + message.Command.ToString(); - } - else - { - int inst, qu, qs, qc, wr, wq, @in, ar; -#if FEATURE_SOCKET_MODE_POLL - var mgrState = socketManager.State; - var lastError = socketManager.LastErrorTimeRelative(); - -#endif - var sb = new StringBuilder("Timeout performing ").Append(message.CommandAndKey); - data = new List> {Tuple.Create("Message", message.CommandAndKey)}; - Action add = (lk, sk, v) => - { - data.Add(Tuple.Create(lk, v)); - sb.Append(", " + sk + ": " + v); - }; - - int queue = server.GetOutstandingCount(message.Command, out inst, out qu, out qs, out qc, out wr, out wq, out @in, out ar); - add("Instantaneous", "inst", inst.ToString()); -#if FEATURE_SOCKET_MODE_POLL - add("Manager-State", "mgr", mgrState.ToString()); - add("Last-Error", "err", lastError); -#endif - add("Queue-Length", "queue", queue.ToString()); - add("Queue-Outstanding", "qu", qu.ToString()); - add("Queue-Awaiting-Response", "qs", qs.ToString()); - add("Queue-Completion-Outstanding", "qc", qc.ToString()); - add("Active-Writers", "wr", wr.ToString()); - add("Write-Queue", "wq", wq.ToString()); - add("Inbound-Bytes", "in", @in.ToString()); - add("Active-Readers", "ar", ar.ToString()); - - add("Client-Name", "clientName", ClientName); - add("Server-Endpoint", "serverEndpoint", server.EndPoint.ToString()); - var hashSlot = message.GetHashSlot(this.ServerSelectionStrategy); - // only add keyslot if its a valid cluster key slot - if (hashSlot != ServerSelectionStrategy.NoSlot) - { - add("Key-HashSlot", "keyHashSlot", message.GetHashSlot(this.ServerSelectionStrategy).ToString()); - } -#if !CORE_CLR - string iocp, worker; - int busyWorkerCount = GetThreadPoolStats(out iocp, out worker); - add("ThreadPool-IO-Completion", "IOCP", iocp); - add("ThreadPool-Workers", "WORKER", worker); - data.Add(Tuple.Create("Busy-Workers", busyWorkerCount.ToString())); - - if (IncludePerformanceCountersInExceptions) - { - add("Local-CPU", "Local-CPU", GetSystemCpuPercent()); - } -#endif - sb.Append(" (Please take a look at this article for some common client-side issues that can cause timeouts: "); - sb.Append(timeoutHelpLink); - sb.Append(")"); - errMessage = sb.ToString(); - if (stormLogThreshold >= 0 && queue >= stormLogThreshold && Interlocked.CompareExchange(ref haveStormLog, 1, 0) == 0) - { - var log = server.GetStormLog(message.Command); - if (string.IsNullOrWhiteSpace(log)) Interlocked.Exchange(ref haveStormLog, 0); - else Interlocked.Exchange(ref stormLogSnapshot, log); - } - } - var timeoutEx = ExceptionFactory.Timeout(IncludeDetailInExceptions, errMessage, message, server); - timeoutEx.HelpLink = timeoutHelpLink; - - if (data != null) - { - foreach (var kv in data) - { - timeoutEx.Data["Redis-" + kv.Item1] = kv.Item2; - } - } - throw timeoutEx; - // very important not to return "source" to the pool here - } - } - // snapshot these so that we can recycle the box - Exception ex; - T val; - ResultBox.UnwrapAndRecycle(source, true, out val, out ex); // now that we aren't locking it... - if (ex != null) throw ex; - Trace(message + " received " + val); - return val; - } - } - -#if !CORE_CLR - internal static string GetThreadPoolAndCPUSummary(bool includePerformanceCounters) - { - string iocp, worker; - GetThreadPoolStats(out iocp, out worker); - var cpu = includePerformanceCounters ? GetSystemCpuPercent() : "n/a"; - return $"IOCP: {iocp}, WORKER: {worker}, Local-CPU: {cpu}"; - } - - private static string GetSystemCpuPercent() - { - float systemCPU; - if (PerfCounterHelper.TryGetSystemCPU(out systemCPU)) - { - return Math.Round(systemCPU, 2) + "%"; - } - return "unavailable"; - } - - private static int GetThreadPoolStats(out string iocp, out string worker) - { - //BusyThreads = TP.GetMaxThreads() –TP.GetAVailable(); - //If BusyThreads >= TP.GetMinThreads(), then threadpool growth throttling is possible. - - int maxIoThreads, maxWorkerThreads; - ThreadPool.GetMaxThreads(out maxWorkerThreads, out maxIoThreads); - - int freeIoThreads, freeWorkerThreads; - ThreadPool.GetAvailableThreads(out freeWorkerThreads, out freeIoThreads); - - int minIoThreads, minWorkerThreads; - ThreadPool.GetMinThreads(out minWorkerThreads, out minIoThreads); - - int busyIoThreads = maxIoThreads - freeIoThreads; - int busyWorkerThreads = maxWorkerThreads - freeWorkerThreads; - - iocp = $"(Busy={busyIoThreads},Free={freeIoThreads},Min={minIoThreads},Max={maxIoThreads})"; - worker = $"(Busy={busyWorkerThreads},Free={freeWorkerThreads},Min={minWorkerThreads},Max={maxWorkerThreads})"; - return busyWorkerThreads; - } -#endif - - /// - /// Should exceptions include identifiable details? (key names, additional .Data annotations) - /// - public bool IncludeDetailInExceptions { get; set; } - - /// - /// Should exceptions include performance counter details? (CPU usage, etc - note that this can be problematic on some platforms) - /// - public bool IncludePerformanceCountersInExceptions { get; set; } - - int haveStormLog = 0, stormLogThreshold = 15; - string stormLogSnapshot; - /// - /// Limit at which to start recording unusual busy patterns (only one log will be retained at a time; - /// set to a negative value to disable this feature) - /// - public int StormLogThreshold { get { return stormLogThreshold; } set { stormLogThreshold = value; } } - /// - /// Obtains the log of unusual busy patterns - /// - public string GetStormLog() - { - var result = Interlocked.CompareExchange(ref stormLogSnapshot, null, null); - return result; - } - /// - /// Resets the log of unusual busy patterns - /// - public void ResetStormLog() - { - Interlocked.Exchange(ref stormLogSnapshot, null); - Interlocked.Exchange(ref haveStormLog, 0); - } - private long syncTimeouts, fireAndForgets; - - /// - /// Request all compatible clients to reconfigure or reconnect - /// - /// The number of instances known to have received the message (however, the actual number can be higher; returns -1 if the operation is pending) - public long PublishReconfigure(CommandFlags flags = CommandFlags.None) - { - byte[] channel = ConfigurationChangedChannel; - if (channel == null) return 0; - if (ReconfigureIfNeeded(null, false, "PublishReconfigure", true, flags)) - { - return -1; - } - else - { - return PublishReconfigureImpl(flags); - } - } - private long PublishReconfigureImpl(CommandFlags flags) - { - byte[] channel = ConfigurationChangedChannel; - if (channel == null) return 0; - return GetSubscriber().Publish(channel, RedisLiterals.Wildcard, flags); - } - - /// - /// Request all compatible clients to reconfigure or reconnect - /// - /// The number of instances known to have received the message (however, the actual number can be higher) - public Task PublishReconfigureAsync(CommandFlags flags = CommandFlags.None) - { - byte[] channel = ConfigurationChangedChannel; - if (channel == null) return CompletedTask.Default(null); - - return GetSubscriber().PublishAsync(channel, RedisLiterals.Wildcard, flags); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionType.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionType.cs deleted file mode 100644 index efba466..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ConnectionType.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// The type of a connection - /// - public enum ConnectionType - { - /// - /// Not connection-type related - /// - None = 0, - /// - /// An interactive connection handles request/response commands for accessing data on demand - /// - Interactive, - /// - /// A subscriber connection recieves unsolicted messages from the server as pub/sub events occur - /// - Subscription - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/DebuggingAids.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/DebuggingAids.cs deleted file mode 100644 index 19d3deb..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/DebuggingAids.cs +++ /dev/null @@ -1,458 +0,0 @@ -using System; -using System.Diagnostics; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ -#if DEBUG - - partial class ResultBox - { - internal static long allocations; - - public static long GetAllocationCount() - { - return Interlocked.Read(ref allocations); - } - static partial void OnAllocated() - { - Interlocked.Increment(ref allocations); - } - } - partial interface IServer - { - /// - /// Show what is in the pending (unsent) queue - /// - string ListPending(int maxCount); - /// - /// Get the value of key. If the key does not exist the special value nil is returned. An error is returned if the value stored at key is not a string, because GET only handles string values. - /// - /// the value of key, or nil when key does not exist. - /// http://redis.io/commands/get - RedisValue StringGet(int db, RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Get the value of key. If the key does not exist the special value nil is returned. An error is returned if the value stored at key is not a string, because GET only handles string values. - /// - /// the value of key, or nil when key does not exist. - /// http://redis.io/commands/get - Task StringGetAsync(int db, RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Break the connection without mercy or thought - /// - void SimulateConnectionFailure(); - - /// - /// DEBUG SEGFAULT performs an invalid memory access that crashes Redis. It is used to simulate bugs during the development. - /// - /// http://redis.io/commands/debug-segfault - void Crash(); - - /// - /// CLIENT PAUSE is a connections control command able to suspend all the Redis clients for the specified amount of time (in milliseconds). - /// - /// http://redis.io/commands/client-pause - void Hang(TimeSpan duration, CommandFlags flags = CommandFlags.None); - } - partial interface IRedis - { - /// - /// The CLIENT GETNAME returns the name of the current connection as set by CLIENT SETNAME. Since every new connection starts without an associated name, if no name was assigned a null string is returned. - /// - /// http://redis.io/commands/client-getname - /// The connection name, or a null string if no name is set. - string ClientGetName(CommandFlags flags = CommandFlags.None); - - /// - /// Ask the server to close the connection. The connection is closed as soon as all pending replies have been written to the client. - /// - /// http://redis.io/commands/quit - void Quit(CommandFlags flags = CommandFlags.None); - } - - partial interface IRedisAsync - { - /// - /// The CLIENT GETNAME returns the name of the current connection as set by CLIENT SETNAME. Since every new connection starts without an associated name, if no name was assigned a null string is returned. - /// - /// http://redis.io/commands/client-getname - /// The connection name, or a null string if no name is set. - Task ClientGetNameAsync(CommandFlags flags = CommandFlags.None); - } - partial class RedisBase - { - string IRedis.ClientGetName(CommandFlags flags) - { - var msg = Message.Create(-1, flags, RedisCommand.CLIENT, RedisLiterals.GETNAME); - return ExecuteSync(msg, ResultProcessor.String); - } - - Task IRedisAsync.ClientGetNameAsync(CommandFlags flags) - { - var msg = Message.Create(-1, flags, RedisCommand.CLIENT, RedisLiterals.GETNAME); - return ExecuteAsync(msg, ResultProcessor.String); - } - } - - partial class ServerEndPoint - { - - internal void SimulateConnectionFailure() - { - var tmp = interactive; - tmp?.SimulateConnectionFailure(); - tmp = subscription; - tmp?.SimulateConnectionFailure(); - } - internal string ListPending(int maxCount) - { - var sb = new StringBuilder(); - var tmp = interactive; - tmp?.ListPending(sb, maxCount); - tmp = subscription; - tmp?.ListPending(sb, maxCount); - return sb.ToString(); - } - } - - partial class RedisServer - { - void IServer.SimulateConnectionFailure() - { - server.SimulateConnectionFailure(); - } - string IServer.ListPending(int maxCount) - { - return server.ListPending(maxCount); - } - void IServer.Crash() - { - // using DB-0 because we also use "DEBUG OBJECT", which is db-centric - var msg = Message.Create(0, CommandFlags.FireAndForget, RedisCommand.DEBUG, RedisLiterals.SEGFAULT); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - void IServer.Hang(TimeSpan duration, CommandFlags flags) - { - var msg = Message.Create(-1, flags, RedisCommand.CLIENT, RedisLiterals.PAUSE, (long)duration.TotalMilliseconds); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - } - - partial class CompletionManager - { - private static long asyncCompletionWorkerCount; - - partial void OnCompletedAsync() - { - Interlocked.Increment(ref asyncCompletionWorkerCount); - } - internal static long GetAsyncCompletionWorkerCount() - { - return Interlocked.Read(ref asyncCompletionWorkerCount); - } - } - - partial class ConnectionMultiplexer - { - /// - /// Gets how many result-box instances were allocated - /// - public static long GetResultBoxAllocationCount() - { - return ResultBox.GetAllocationCount(); - } - /// - /// Gets how many async completion workers were queueud - /// - public static long GetAsyncCompletionWorkerCount() - { - return CompletionManager.GetAsyncCompletionWorkerCount(); - } - /// - /// For debugging; when not enabled, servers cannot connect - /// - public bool AllowConnect { get { return allowConnect; } set { allowConnect = value; } } - private volatile bool allowConnect = true, ignoreConnect = false; - - /// - /// For debugging; when not enabled, end-connect is silently ignored (to simulate a long-running connect) - /// - public bool IgnoreConnect { get { return ignoreConnect; } set { ignoreConnect = value; } } - } - - partial class SocketManager - { - partial void ShouldIgnoreConnect(ISocketCallback callback, ref bool ignore) - { - ignore = callback.IgnoreConnect; - } - - /// - /// Completion type for BeginConnect call - /// - public static CompletionType ConnectCompletionType { get; set; } - - partial void ShouldForceConnectCompletionType(ref CompletionType completionType) - { - completionType = SocketManager.ConnectCompletionType; - } - } - partial interface ISocketCallback - { - bool IgnoreConnect { get; } - } - - partial class MessageQueue - { - internal void ListPending(StringBuilder sb, int maxCount) - { - lock (regular) - { - foreach (var item in high) - { - if (--maxCount < 0) break; - if (sb.Length != 0) sb.Append(","); - item.AppendStormLog(sb); - } - foreach (var item in regular) - { - if (--maxCount < 0) break; - if (sb.Length != 0) sb.Append(","); - item.AppendStormLog(sb); - } - } - } - } - - partial class PhysicalBridge - { - internal void SimulateConnectionFailure() - { - if (!Multiplexer.RawConfig.AllowAdmin) - { - throw ExceptionFactory.AdminModeNotEnabled(Multiplexer.IncludeDetailInExceptions, RedisCommand.DEBUG, null, ServerEndPoint); // close enough - } - physical?.RecordConnectionFailed(ConnectionFailureType.SocketFailure); - } - internal void ListPending(StringBuilder sb, int maxCount) - { - queue.ListPending(sb, maxCount); - } - } - - partial class PhysicalConnection - { - partial void OnDebugAbort() - { - if (!Multiplexer.AllowConnect) - { - throw new RedisConnectionException(ConnectionFailureType.InternalFailure, "debugging"); - } - } - - bool ISocketCallback.IgnoreConnect => Multiplexer.IgnoreConnect; - - private static volatile bool emulateStaleConnection; - public static bool EmulateStaleConnection - { - get - { - return emulateStaleConnection; - } - set - { - emulateStaleConnection = value; - } - } - - partial void DebugEmulateStaleConnection(ref int firstUnansweredWrite) - { - if (emulateStaleConnection) - { - firstUnansweredWrite = Environment.TickCount - 100000; - } - } - } -#endif - - /// - /// Completion type for CompletionTypeHelper - /// - public enum CompletionType - { - /// - /// Retain original completion type (either sync or async) - /// - Any = 0, - /// - /// Force sync completion - /// - Sync = 1, - /// - /// Force async completion - /// - Async = 2 - } -#if !CORE_CLR - - internal static class PerfCounterHelper - { - static object staticLock = new object(); - static volatile PerformanceCounter _cpu; - static volatile bool _disabled; - - public static bool TryGetSystemCPU(out float value) - { - value = -1; - - try - { - if (!_disabled && _cpu == null) - { - lock (staticLock) - { - if (_cpu == null) - { - _cpu = new PerformanceCounter("Processor", "% Processor Time", "_Total"); - - // First call always returns 0, so get that out of the way. - _cpu.NextValue(); - } - } - } - } - catch (UnauthorizedAccessException) - { - // Some environments don't allow access to Performance Counters, so stop trying. - _disabled = true; - } - catch (Exception) - { - // this shouldn't happen, but just being safe... - } - - if (!_disabled && _cpu != null) - { - value = _cpu.NextValue(); - return true; - } - - return false; - } - } - - internal class CompletionTypeHelper - { - - public static void RunWithCompletionType(Func beginAsync, AsyncCallback callback, CompletionType completionType) - { - AsyncCallback proxyCallback; - if (completionType == CompletionType.Any) - { - proxyCallback = (ar) => - { - if (!ar.CompletedSynchronously) - { - callback(ar); - } - }; - } - else - { - proxyCallback = (ar) => { }; - } - - var result = beginAsync(proxyCallback); - - if (completionType == CompletionType.Any && !result.CompletedSynchronously) - { - return; - } - - result.AsyncWaitHandle.WaitOne(); - - switch (completionType) - { - case CompletionType.Async: - ThreadPool.QueueUserWorkItem((s) => { callback(result); }); - break; - case CompletionType.Any: - case CompletionType.Sync: - callback(result); - break; - } - - return; - } - } -#endif - -#if VERBOSE - - partial class ConnectionMultiplexer - { - private readonly int epoch = Environment.TickCount; - - partial void OnTrace(string message, string category) - { - Debug.WriteLine(message, - ((Environment.TickCount - epoch)).ToString().PadLeft(5, ' ') + "ms on " + - Environment.CurrentManagedThreadId + " ~ " + category); - } - static partial void OnTraceWithoutContext(string message, string category) - { - Debug.WriteLine(message, Environment.CurrentManagedThreadId + " ~ " + category); - } - - partial void OnTraceLog(TextWriter log, string caller) - { - lock (UniqueId) - { - Trace(log.ToString(), caller); // note that this won't always be useful, but we only do it in debug builds anyway - } - } - } -#endif - - -#if LOGOUTPUT - partial class ConnectionMultiplexer - { - /// - /// Dumps a copy of the stream - /// - public static string EchoPath { get; set; } - } - - partial class PhysicalConnection - { - private Stream echo; - partial void OnCreateEcho() - { - if (!string.IsNullOrEmpty(ConnectionMultiplexer.EchoPath)) - { - string fullPath = Path.Combine(ConnectionMultiplexer.EchoPath, - Regex.Replace(physicalName, @"[\-\.\@\#\:]", "_")); - echo = File.Open(Path.ChangeExtension(fullPath, "txt"), FileMode.Create, FileAccess.Write, FileShare.ReadWrite); - } - } - partial void OnCloseEcho() - { - if (echo != null) - { - try { echo.Close(); } catch { } - try { echo.Dispose(); } catch { } - echo = null; - } - } - partial void OnWrapForLogging(ref Stream stream, string name) - { - stream = new LoggingTextStream(stream, physicalName, echo); - } - } -#endif -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/EndPointCollection.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/EndPointCollection.cs deleted file mode 100644 index 46fde3e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/EndPointCollection.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Net; - -namespace StackExchange.Redis -{ - /// - /// A list of endpoints - /// - public sealed class EndPointCollection : Collection - { - /// - /// Create a new EndPointCollection - /// - public EndPointCollection() : base() - { - } - - /// - /// Create a new EndPointCollection - /// - public EndPointCollection(IList endpoints) : base(endpoints) - { - } - - /// - /// Format an endpoint - /// - public static string ToString(EndPoint endpoint) - { - return Format.ToString(endpoint); - } - - /// - /// Attempt to parse a string into an EndPoint - /// - public static EndPoint TryParse(string endpoint) - { - return Format.TryParseEndPoint(endpoint); - } - /// - /// Adds a new endpoint to the list - /// - public void Add(string hostAndPort) - { - var endpoint = Format.TryParseEndPoint(hostAndPort); - if (endpoint == null) throw new ArgumentException(); - Add(endpoint); - } - - /// - /// Adds a new endpoint to the list - /// - public void Add(string host, int port) - { - Add(Format.ParseEndPoint(host, port)); - } - - /// - /// Adds a new endpoint to the list - /// - public void Add(IPAddress host, int port) - { - Add(new IPEndPoint(host, port)); - } - - /// - /// See Collection<T>.InsertItem() - /// - protected override void InsertItem(int index, EndPoint item) - { - if (item == null) throw new ArgumentNullException(nameof(item)); - if (Contains(item)) throw new ArgumentException("EndPoints must be unique", nameof(item)); - base.InsertItem(index, item); - } - /// - /// See Collection<T>.SetItem() - /// - protected override void SetItem(int index, EndPoint item) - { - if (item == null) throw new ArgumentNullException(nameof(item)); - int existingIndex; - try - { - existingIndex = IndexOf(item); - } catch(NullReferenceException) - { - // mono has a nasty bug in DnsEndPoint.Equals; if they do bad things here: sorry, I can't help - existingIndex = -1; - } - if (existingIndex >= 0 && existingIndex != index) throw new ArgumentException("EndPoints must be unique", nameof(item)); - base.SetItem(index, item); - } - - internal void SetDefaultPorts(int defaultPort) - { - for (int i = 0; i < Count; i++) - { - var endpoint = this[i]; - var dns = endpoint as DnsEndPoint; - if (dns?.Port == 0) - { - this[i] = new DnsEndPoint(dns.Host, defaultPort, dns.AddressFamily); - continue; - } - var ip = endpoint as IPEndPoint; - if (ip?.Port == 0) - { - this[i] = new IPEndPoint(ip.Address, defaultPort); - continue; - } - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/EndPointEventArgs.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/EndPointEventArgs.cs deleted file mode 100644 index b57d11b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/EndPointEventArgs.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Net; -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Event information related to redis endpoints - /// - public class EndPointEventArgs : EventArgs, ICompletable - { - private readonly EventHandler handler; - private readonly object sender; - internal EndPointEventArgs(EventHandler handler, object sender, EndPoint endpoint) - { - this.handler = handler; - this.sender = sender; - EndPoint = endpoint; - } - - /// - /// The endpoint involved in this event (this can be null) - /// - public EndPoint EndPoint { get; } - - void ICompletable.AppendStormLog(StringBuilder sb) - { - sb.Append("event, endpoint: "); - if (EndPoint == null) sb.Append("n/a"); - else sb.Append(Format.ToString(EndPoint)); - } - - bool ICompletable.TryComplete(bool isAsync) - { - return ConnectionMultiplexer.TryCompleteHandler(handler, sender, this, isAsync); - } - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExceptionFactory.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExceptionFactory.cs deleted file mode 100644 index 7708055..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExceptionFactory.cs +++ /dev/null @@ -1,242 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Globalization; -using System.Text; - -namespace StackExchange.Redis -{ - internal static class ExceptionFactory - { - const string DataCommandKey = "redis-command", - DataServerKey = "redis-server", - DataServerEndpoint = "server-endpoint", - DataConnectionState = "connection-state", - DataLastFailure = "last-failure", - DataLastInnerException = "last-innerexception", - DataSentStatusKey = "request-sent-status"; - - - internal static Exception AdminModeNotEnabled(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server) - { - string s = GetLabel(includeDetail, command, message); - var ex = new RedisCommandException("This operation is not available unless admin mode is enabled: " + s); - if (includeDetail) AddDetail(ex, message, server, s); - return ex; - } - internal static Exception CommandDisabled(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server) - { - string s = GetLabel(includeDetail, command, message); - var ex = new RedisCommandException("This operation has been disabled in the command-map and cannot be used: " + s); - if (includeDetail) AddDetail(ex, message, server, s); - return ex; - } - internal static Exception TooManyArgs(bool includeDetail, string command, Message message, ServerEndPoint server, int required) - { - string s = GetLabel(includeDetail, command, message); - var ex = new RedisCommandException($"This operation would involve too many arguments ({required} vs the redis limit of {PhysicalConnection.REDIS_MAX_ARGS}): {s}"); - if (includeDetail) AddDetail(ex, message, server, s); - return ex; - } - internal static Exception CommandDisabled(bool includeDetail, string command, Message message, ServerEndPoint server) - { - string s = GetLabel(includeDetail, command, message); - var ex = new RedisCommandException("This operation has been disabled in the command-map and cannot be used: " + s); - if (includeDetail) AddDetail(ex, message, server, s); - return ex; - } - - internal static Exception ConnectionFailure(bool includeDetail, ConnectionFailureType failureType, string message, ServerEndPoint server) - { - var ex = new RedisConnectionException(failureType, message); - if (includeDetail) AddDetail(ex, null, server, null); - return ex; - } - - internal static Exception DatabaseNotRequired(bool includeDetail, RedisCommand command) - { - string s = command.ToString(); - var ex = new RedisCommandException("A target database is not required for " + s); - if (includeDetail) AddDetail(ex, null, null, s); - return ex; - } - - internal static Exception DatabaseOutfRange(bool includeDetail, int targetDatabase, Message message, ServerEndPoint server) - { - var ex = new RedisCommandException("The database does not exist on the server: " + targetDatabase); - if (includeDetail) AddDetail(ex, message, server, null); - return ex; - } - - internal static Exception DatabaseRequired(bool includeDetail, RedisCommand command) - { - string s = command.ToString(); - var ex = new RedisCommandException("A target database is required for " + s); - if (includeDetail) AddDetail(ex, null, null, s); - return ex; - } - - internal static Exception MasterOnly(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server) - { - string s = GetLabel(includeDetail, command, message); - var ex = new RedisCommandException("Command cannot be issued to a slave: " + s); - if (includeDetail) AddDetail(ex, message, server, s); - return ex; - } - - internal static Exception MultiSlot(bool includeDetail, Message message) - { - var ex = new RedisCommandException("Multi-key operations must involve a single slot; keys can use 'hash tags' to help this, i.e. '{/users/12345}/account' and '{/users/12345}/contacts' will always be in the same slot"); - if (includeDetail) AddDetail(ex, message, null, null); - return ex; - } - - internal static string GetInnerMostExceptionMessage(Exception e) - { - if (e == null) - { - return ""; - } - else - { - while (e.InnerException != null) - { - e = e.InnerException; - } - return e.Message; - } - } - - internal static Exception NoConnectionAvailable(bool includeDetail, bool includePerformanceCounters, RedisCommand command, Message message, ServerEndPoint server, ServerEndPoint[] serverSnapshot) - { - string commandLabel = GetLabel(includeDetail, command, message); - - if (server != null) - { - //if we already have the serverEndpoint for connection failure use that - //otherwise it would output state of all the endpoints - serverSnapshot = new ServerEndPoint[] { server }; - } - - var innerException = PopulateInnerExceptions(serverSnapshot); - - StringBuilder exceptionmessage = new StringBuilder("No connection is available to service this operation: ").Append(commandLabel); - string innermostExceptionstring = GetInnerMostExceptionMessage(innerException); - if (!string.IsNullOrEmpty(innermostExceptionstring)) - { - exceptionmessage.Append("; ").Append(innermostExceptionstring); - } - -#if !CORE_CLR - if (includeDetail) - { - exceptionmessage.Append("; ").Append(ConnectionMultiplexer.GetThreadPoolAndCPUSummary(includePerformanceCounters)); - } -#endif - - var ex = new RedisConnectionException(ConnectionFailureType.UnableToResolvePhysicalConnection, exceptionmessage.ToString(), innerException, message?.Status ?? CommandStatus.Unknown); - - if (includeDetail) - { - AddDetail(ex, message, server, commandLabel); - } - return ex; - } - - internal static Exception PopulateInnerExceptions(ServerEndPoint[] serverSnapshot) - { - List innerExceptions = new List(); - if (serverSnapshot != null) - { - if (serverSnapshot.Length > 0 && serverSnapshot[0].Multiplexer.LastException != null) - { - innerExceptions.Add(serverSnapshot[0].Multiplexer.LastException); - } - - for (int i = 0; i < serverSnapshot.Length; i++) - { - if (serverSnapshot[i].LastException != null) - { - var lastException = serverSnapshot[i].LastException; - innerExceptions.Add(lastException); - } - } - } - if (innerExceptions.Count == 1) - { - return innerExceptions[0]; - } - else if(innerExceptions.Count > 1) - { - return new AggregateException(innerExceptions); - } - return null; - } - - internal static Exception NotSupported(bool includeDetail, RedisCommand command) - { - string s = GetLabel(includeDetail, command, null); - var ex = new RedisCommandException("Command is not available on your server: " + s); - if (includeDetail) AddDetail(ex, null, null, s); - return ex; - } - internal static Exception NoCursor(RedisCommand command) - { - string s = GetLabel(false, command, null); - var ex = new RedisCommandException("Command cannot be used with a cursor: " + s); - return ex; - } - - internal static Exception Timeout(bool includeDetail, string errorMessage, Message message, ServerEndPoint server) - { - var ex = new RedisTimeoutException(errorMessage, message?.Status ?? CommandStatus.Unknown); - if (includeDetail) AddDetail(ex, message, server, null); - return ex; - } - - private static void AddDetail(Exception exception, Message message, ServerEndPoint server, string label) - { - if (exception != null) - { - if (message != null) - { - exception.Data.Add(DataCommandKey, message.CommandAndKey); - exception.Data.Add(DataSentStatusKey, message.Status); - } - else if (label != null) exception.Data.Add(DataCommandKey, label); - - if (server != null) exception.Data.Add(DataServerKey, Format.ToString(server.EndPoint)); - } - } - - static string GetLabel(bool includeDetail, RedisCommand command, Message message) - { - return message == null ? command.ToString() : (includeDetail ? message.CommandAndKey : message.Command.ToString()); - } - static string GetLabel(bool includeDetail, string command, Message message) - { - return message == null ? command : (includeDetail ? message.CommandAndKey : message.Command.ToString()); - } - - internal static Exception UnableToConnect(bool abortOnConnect, string failureMessage=null) - { - var abortOnConnectionFailure = abortOnConnect ? "to create a disconnected multiplexer, disable AbortOnConnectFail. " : ""; - return new RedisConnectionException(ConnectionFailureType.UnableToConnect, - string.Format("It was not possible to connect to the redis server(s); {0}{1}", abortOnConnectionFailure, failureMessage)); - } - - internal static Exception BeganProfilingWithDuplicateContext(object forContext) - { - var exc = new InvalidOperationException("Attempted to begin profiling for the same context twice"); - exc.Data["forContext"] = forContext; - return exc; - } - - internal static Exception FinishedProfilingWithInvalidContext(object forContext) - { - var exc = new InvalidOperationException("Attempted to finish profiling for a context which is no longer valid, or was never begun"); - exc.Data["forContext"] = forContext; - return exc; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Exclude.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Exclude.cs deleted file mode 100644 index b8a9db0..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Exclude.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - /// - /// When performing a range query, by default the start / stop limits are inclusive; - /// however, both can also be specified separately as exclusive - /// - [Flags] - public enum Exclude - { - /// - /// Both start and stop are inclusive - /// - None = 0, - /// - /// Start is exclusive, stop is inclusive - /// - Start = 1, - /// - /// Start is inclusive, stop is exclusive - /// - Stop = 2, - /// - /// Both start and stop are exclusive - /// - Both = Start | Stop - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExponentialRetry.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExponentialRetry.cs deleted file mode 100644 index ab954da..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExponentialRetry.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - /// - /// Represents a retry policy that performs retries, using a randomized exponential back off scheme to determine the interval between retries. - /// - public class ExponentialRetry : IReconnectRetryPolicy - { - private int deltaBackOffMilliseconds; - private int maxDeltaBackOffMilliseconds = (int)TimeSpan.FromSeconds(10).TotalMilliseconds; - [ThreadStatic] - private static Random r; - - /// - /// Initializes a new instance using the specified back off interval with default maxDeltaBackOffMilliseconds of 10 seconds - /// - /// time in milliseconds for the back-off interval between retries - public ExponentialRetry(int deltaBackOffMilliseconds) : this(deltaBackOffMilliseconds, (int)TimeSpan.FromSeconds(10).TotalMilliseconds) - { - } - - /// - /// Initializes a new instance using the specified back off interval. - /// - /// time in milliseconds for the back-off interval between retries - /// time in milliseconds for the maximum value that the back-off interval can exponentailly grow upto - public ExponentialRetry(int deltaBackOffMilliseconds, int maxDeltaBackOffMilliseconds) - { - this.deltaBackOffMilliseconds = deltaBackOffMilliseconds; - this.maxDeltaBackOffMilliseconds = maxDeltaBackOffMilliseconds; - } - - /// - /// This method is called by the ConnectionMultiplexer to determine if a reconnect operation can be retried now. - /// - /// The number of times reconnect retries have already been made by the ConnectionMultiplexer while it was in the connecting state - /// Total elapsed time in milliseconds since the last reconnect retry was made - public bool ShouldRetry(long currentRetryCount, int timeElapsedMillisecondsSinceLastRetry) - { - var exponential = (int)Math.Min(maxDeltaBackOffMilliseconds, deltaBackOffMilliseconds * Math.Pow(1.1, currentRetryCount)); - int random; - r = r ?? new Random(); - random = r.Next((int)deltaBackOffMilliseconds, exponential); - return timeElapsedMillisecondsSinceLastRetry >= random; - //exponential backoff with deltaBackOff of 5000ms - //deltabackoff exponential - //5000 5500 - //5000 6050 - //5000 6655 - //5000 8053 - //5000 10718 - //5000 17261 - //5000 37001 - //5000 127738 - } - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExportOptions.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExportOptions.cs deleted file mode 100644 index c6891b5..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExportOptions.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - /// - /// Which settings to export - /// - [Flags] - public enum ExportOptions - { - /// - /// No options - /// - None = 0, - /// - /// The output of INFO - /// - Info = 1, - /// - /// The output of CONFIG GET * - /// - Config = 2, - /// - /// The output of CLIENT LIST - /// - Client = 4, - /// - /// The output of CLUSTER NODES - /// - Cluster = 8, - /// - /// Everything available - /// - All = -1 - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExtensionMethods.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExtensionMethods.cs deleted file mode 100644 index 67bbafc..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ExtensionMethods.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Security; -using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; - -namespace StackExchange.Redis -{ - /// - /// Utility methods - /// - public static class ExtensionMethods - { - /// - /// Create a dictionary from an array of HashEntry values - /// - public static Dictionary ToStringDictionary(this HashEntry[] hash) - { - if (hash == null) return null; - - var result = new Dictionary(hash.Length, StringComparer.Ordinal); - for(int i = 0; i < hash.Length; i++) - { - result.Add(hash[i].name, hash[i].value); - } - return result; - } - /// - /// Create a dictionary from an array of HashEntry values - /// - public static Dictionary ToDictionary(this HashEntry[] hash) - { - if (hash == null) return null; - - var result = new Dictionary(hash.Length); - for (int i = 0; i < hash.Length; i++) - { - result.Add(hash[i].name, hash[i].value); - } - return result; - } - - /// - /// Create a dictionary from an array of SortedSetEntry values - /// - public static Dictionary ToStringDictionary(this SortedSetEntry[] sortedSet) - { - if (sortedSet == null) return null; - - var result = new Dictionary(sortedSet.Length, StringComparer.Ordinal); - for (int i = 0; i < sortedSet.Length; i++) - { - result.Add(sortedSet[i].element, sortedSet[i].score); - } - return result; - } - - /// - /// Create a dictionary from an array of SortedSetEntry values - /// - public static Dictionary ToDictionary(this SortedSetEntry[] sortedSet) - { - if (sortedSet == null) return null; - - var result = new Dictionary(sortedSet.Length); - for (int i = 0; i < sortedSet.Length; i++) - { - result.Add(sortedSet[i].element, sortedSet[i].score); - } - return result; - } - - /// - /// Create a dictionary from an array of key/value pairs - /// - public static Dictionary ToStringDictionary(this KeyValuePair[] pairs) - { - if (pairs == null) return null; - - var result = new Dictionary(pairs.Length, StringComparer.Ordinal); - for (int i = 0; i < pairs.Length; i++) - { - result.Add(pairs[i].Key, pairs[i].Value); - } - return result; - } - - /// - /// Create a dictionary from an array of key/value pairs - /// - public static Dictionary ToDictionary(this KeyValuePair[] pairs) - { - if (pairs == null) return null; - - var result = new Dictionary(pairs.Length); - for (int i = 0; i < pairs.Length; i++) - { - result.Add(pairs[i].Key, pairs[i].Value); - } - return result; - } - - /// - /// Create a dictionary from an array of string pairs - /// - public static Dictionary ToDictionary(this KeyValuePair[] pairs) - { - if (pairs == null) return null; - - var result = new Dictionary(pairs.Length, StringComparer.Ordinal); - for (int i = 0; i < pairs.Length; i++) - { - result.Add(pairs[i].Key, pairs[i].Value); - } - return result; - } - - static readonly string[] nix = new string[0]; - /// - /// Create an array of strings from an array of values - /// - public static string[] ToStringArray(this RedisValue[] values) - { - if (values == null) return null; - if (values.Length == 0) return nix; - return ConvertHelper.ConvertAll(values, x => (string)x); - } - - internal static void AuthenticateAsClient(this SslStream ssl, string host, SslProtocols? allowedProtocols) - { - if (!allowedProtocols.HasValue) - { - //Default to the sslProtocols defined by the .NET Framework - AuthenticateAsClientUsingDefaultProtocols(ssl, host); - return; - } - - var certificateCollection = new X509CertificateCollection(); - const bool checkCertRevocation = true; -#if CORE_CLR - ssl.AuthenticateAsClientAsync(host, certificateCollection, allowedProtocols.Value, checkCertRevocation) - .GetAwaiter().GetResult(); -#else - ssl.AuthenticateAsClient(host, certificateCollection, allowedProtocols.Value, checkCertRevocation); -#endif - } - - private static void AuthenticateAsClientUsingDefaultProtocols(SslStream ssl, string host) - { -#if CORE_CLR - ssl.AuthenticateAsClientAsync(host).GetAwaiter().GetResult(); -#else - ssl.AuthenticateAsClient(host); -#endif - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Format.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Format.cs deleted file mode 100644 index 3c8a3c6..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Format.cs +++ /dev/null @@ -1,182 +0,0 @@ -using System; -using System.Globalization; -using System.Net; - -namespace StackExchange.Redis -{ - internal static class Format - { - public static int ParseInt32(string s) - { - return int.Parse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo); - } - - public static long ParseInt64(string s) - { - return long.Parse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo); - } - - public static string ToString(int value) - { - return value.ToString(NumberFormatInfo.InvariantInfo); - } - - public static bool TryParseBoolean(string s, out bool value) - { - if (bool.TryParse(s, out value)) return true; - - if (s == "1" || string.Equals(s, "yes", StringComparison.OrdinalIgnoreCase) || string.Equals(s, "on", StringComparison.OrdinalIgnoreCase)) - { - value = true; - return true; - } - if (s == "0" || string.Equals(s, "no", StringComparison.OrdinalIgnoreCase) || string.Equals(s, "off", StringComparison.OrdinalIgnoreCase)) - { - value = false; - return true; - } - value = false; - return false; - } - - public static bool TryParseInt32(string s, out int value) - { - return int.TryParse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out value); - } - internal static EndPoint ParseEndPoint(string host, int port) - { - IPAddress ip; - if (IPAddress.TryParse(host, out ip)) return new IPEndPoint(ip, port); - return new DnsEndPoint(host, port); - } - internal static EndPoint TryParseEndPoint(string host, string port) - { - if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(port)) return null; - int i; - return TryParseInt32(port, out i) ? ParseEndPoint(host, i) : null; - } - - internal static string ToString(long value) - { - return value.ToString(NumberFormatInfo.InvariantInfo); - } - - internal static string ToString(double value) - { - if (double.IsInfinity(value)) - { - if (double.IsPositiveInfinity(value)) return "+inf"; - if (double.IsNegativeInfinity(value)) return "-inf"; - } - return value.ToString("G17", NumberFormatInfo.InvariantInfo); - } - - internal static string ToString(object value) - { - return Convert.ToString(value, CultureInfo.InvariantCulture); - } - - internal static string ToString(EndPoint endpoint) - { - var dns = endpoint as DnsEndPoint; - if (dns != null) - { - if (dns.Port == 0) return dns.Host; - return dns.Host + ":" + Format.ToString(dns.Port); - } - var ip = endpoint as IPEndPoint; - if (ip != null) - { - if (ip.Port == 0) return ip.Address.ToString(); - return ip.Address.ToString() + ":" + Format.ToString(ip.Port); - } - return endpoint?.ToString() ?? ""; - } - internal static string ToStringHostOnly(EndPoint endpoint) - { - var dns = endpoint as DnsEndPoint; - if (dns != null) - { - return dns.Host; - } - var ip = endpoint as IPEndPoint; - if(ip != null) - { - return ip.Address.ToString(); - } - return ""; - } - - internal static bool TryGetHostPort(EndPoint endpoint, out string host, out int port) - { - if (endpoint != null) - { - if (endpoint is IPEndPoint) - { - IPEndPoint ip = (IPEndPoint)endpoint; - host = ip.Address.ToString(); - port = ip.Port; - return true; - } - if (endpoint is DnsEndPoint) - { - DnsEndPoint dns = (DnsEndPoint)endpoint; - host = dns.Host; - port = dns.Port; - return true; - } - } - host = null; - port = 0; - return false; - } - - internal static bool TryParseDouble(string s, out double value) - { - if(string.IsNullOrEmpty(s)) - { - value = 0; - return false; - } - if(s.Length==1 && s[0] >= '0' && s[0] <= '9') - { - value = (int)(s[0] - '0'); - return true; - } - // need to handle these - if(string.Equals("+inf", s, StringComparison.OrdinalIgnoreCase) || string.Equals("inf", s, StringComparison.OrdinalIgnoreCase)) - { - value = double.PositiveInfinity; - return true; - } - if(string.Equals("-inf", s, StringComparison.OrdinalIgnoreCase)) - { - value = double.NegativeInfinity; - return true; - } - return double.TryParse(s, NumberStyles.Any, NumberFormatInfo.InvariantInfo, out value); - } - internal static EndPoint TryParseEndPoint(string endpoint) - { - if (string.IsNullOrWhiteSpace(endpoint)) return null; - string host; - int port; - int i = endpoint.IndexOf(':'); - if (i < 0) - { - host = endpoint; - port = 0; - } - else - { - host = endpoint.Substring(0, i); - var portAsString = endpoint.Substring(i + 1); - if (string.IsNullOrEmpty(portAsString)) return null; - if (!Format.TryParseInt32(portAsString, out port)) return null; - } - if (string.IsNullOrWhiteSpace(host)) return null; - - return Format.ParseEndPoint(host, port); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/GeoEntry.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/GeoEntry.cs deleted file mode 100644 index dd56090..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/GeoEntry.cs +++ /dev/null @@ -1,242 +0,0 @@ - -using System; - -namespace StackExchange.Redis -{ - /// - /// GeoRadius command options. - /// - [Flags] - public enum GeoRadiusOptions - { - /// - /// No Options - /// - None = 0, - /// - /// Redis will return the coordinates of any results. - /// - WithCoordinates = 1, - /// - /// Redis will return the distance from center for all results. - /// - WithDistance = 2, - /// - /// Redis will return the geo hash value as an integer. (This is the score in the sorted set) - /// - WithGeoHash = 4, - /// - /// Populates the commonly used values from the entry (the integer hash is not returned as it is not commonly useful) - /// - Default = WithCoordinates | GeoRadiusOptions.WithDistance - } - - /// - /// The result of a GeoRadius command. - /// - public struct GeoRadiusResult - { - /// - /// Indicate the member being represented - /// - public override string ToString() => Member.ToString(); - /// - /// The matched member. - /// - public RedisValue Member { get; } - - - /// - /// The distance of the matched member from the center of the geo radius command. - /// - public double? Distance { get; } - - /// - /// The hash value of the matched member as an integer. (The key in the sorted set) - /// - /// Note that this is not the same as the hash returned from GeoHash - public long? Hash { get; } - - /// - /// The coordinates of the matched member. - /// - public GeoPosition? Position { get; } - - /// - /// Returns a new GeoRadiusResult - /// - internal GeoRadiusResult(RedisValue member, double? distance, long? hash, GeoPosition? position) - { - Member = member; - Distance = distance; - Hash = hash; - Position = position; - } - } - - /// - /// Describes the longitude and latitude of a GeoEntry - /// - public struct GeoPosition : IEquatable - { - internal static string GetRedisUnit(GeoUnit unit) - { - switch (unit) - { - case GeoUnit.Meters: return "m"; - case GeoUnit.Kilometers: return "km"; - case GeoUnit.Miles: return "mi"; - case GeoUnit.Feet: return "ft"; - default: - throw new ArgumentOutOfRangeException(nameof(unit)); - } - } - - /// - /// The Latitude of the GeoPosition - /// - public double Latitude { get; } - - /// - /// The Logitude of the GeoPosition - /// - public double Longitude { get; } - - /// - /// Creates a new GeoPosition - /// - /// - /// - public GeoPosition(double longitude, double latitude) - { - Longitude = longitude; - Latitude = latitude; - } - - /// - /// See Object.ToString() - /// - public override string ToString() - { - return string.Format("{0} {1}", Longitude, Latitude); - } - /// - /// See Object.GetHashCode() - /// Diagonals not an issue in the case of lat/long - /// - public override int GetHashCode() - { - // diagonals not an issue in the case of lat/long - return Longitude.GetHashCode() ^ Latitude.GetHashCode(); - } - /// - /// Compares two values for equality - /// - public override bool Equals(object obj) - { - return obj is GeoPosition && Equals((GeoPosition)obj); - } - /// - /// Compares two values for equality - /// - public bool Equals(GeoPosition value) - { - return this == value; - } - /// - /// Compares two values for equality - /// - public static bool operator ==(GeoPosition x, GeoPosition y) - { - return x.Longitude == y.Longitude && x.Latitude == y.Latitude; - } - /// - /// Compares two values for non-equality - /// - public static bool operator !=(GeoPosition x, GeoPosition y) - { - return x.Longitude != y.Longitude || x.Latitude != y.Latitude; - } - } - - /// - /// Describes a GeoEntry element with the corresponding value - /// GeoEntries are stored in redis as SortedSetEntries - /// - public struct GeoEntry : IEquatable - { - /// - /// The name of the geo entry - /// - public RedisValue Member { get; } - - /// - /// Describes the longitude and latitude of a GeoEntry - /// - public GeoPosition Position { get; } - - /// - /// Initializes a GeoEntry value - /// - public GeoEntry(double longitude, double latitude, RedisValue member) - { - Member = member; - Position = new GeoPosition(longitude, latitude); - } - - - - /// - /// The longitude of the geo entry - /// - public double Longitude => Position.Longitude; - - /// - /// The latitude of the geo entry - /// - public double Latitude => Position.Latitude; - - /// - /// See Object.ToString() - /// - public override string ToString() - { - return $"({Longitude},{Latitude})={Member}"; - } - /// - /// See Object.GetHashCode() - /// - public override int GetHashCode() - { - return Position.GetHashCode() ^ Member.GetHashCode(); - } - /// - /// Compares two values for equality - /// - public override bool Equals(object obj) - { - return obj is GeoEntry && Equals((GeoEntry)obj); - } - /// - /// Compares two values for equality - /// - public bool Equals(GeoEntry value) - { - return this == value; - } - /// - /// Compares two values for equality - /// - public static bool operator ==(GeoEntry x, GeoEntry y) - { - return x.Position == y.Position && x.Member == y.Member; - } - /// - /// Compares two values for non-equality - /// - public static bool operator !=(GeoEntry x, GeoEntry y) - { - return x.Position != y.Position || x.Member != y.Member; - } - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/GeoUnit.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/GeoUnit.cs deleted file mode 100644 index a88e2de..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/GeoUnit.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.ComponentModel; - -namespace StackExchange.Redis -{ - /// - /// Units associated with Geo Commands - /// - public enum GeoUnit - { - /// - /// Meters - /// - Meters, - /// - /// Kilometers - /// - Kilometers, - /// - /// Miles - /// - Miles, - /// - /// Feet - /// - Feet - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/HashEntry.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/HashEntry.cs deleted file mode 100644 index 0446a4e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/HashEntry.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; - -namespace StackExchange.Redis -{ - /// - /// Describes a hash-field (a name/value pair) - /// - public struct HashEntry : IEquatable - { - internal readonly RedisValue name, value; - - /// - /// Initializes a HashEntry value - /// - public HashEntry(RedisValue name, RedisValue value) - { - this.name = name; - this.value = value; - } - /// - /// The name of the hash field - /// - public RedisValue Name => name; - - /// - /// The value of the hash field - /// - public RedisValue Value => value; - - /// - /// The name of the hash field - /// -#if !CORE_CLR - [Browsable(false)] -#endif - [EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Name", false)] - public RedisValue Key { get { return name; } } - - /// - /// Converts to a key/value pair - /// - public static implicit operator KeyValuePair(HashEntry value) - { - return new KeyValuePair(value.name, value.value); - } - /// - /// Converts from a key/value pair - /// - public static implicit operator HashEntry(KeyValuePair value) - { - return new HashEntry(value.Key, value.Value); - } - - /// - /// See Object.ToString() - /// - public override string ToString() - { - return name + ": " + value; - } - /// - /// See Object.GetHashCode() - /// - public override int GetHashCode() - { - return name.GetHashCode() ^ value.GetHashCode(); - } - /// - /// Compares two values for equality - /// - public override bool Equals(object obj) - { - return obj is HashEntry && Equals((HashEntry)obj); - } - - /// - /// Compares two values for equality - /// - public bool Equals(HashEntry value) - { - return name == value.name && this.value == value.value; - } - /// - /// Compares two values for equality - /// - public static bool operator ==(HashEntry x, HashEntry y) - { - return x.name == y.name && x.value == y.value; - } - /// - /// Compares two values for non-equality - /// - public static bool operator !=(HashEntry x, HashEntry y) - { - return x.name != y.name || x.value != y.value; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/HashSlotMovedEventArgs.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/HashSlotMovedEventArgs.cs deleted file mode 100644 index d518962..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/HashSlotMovedEventArgs.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Net; -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Contains information about individual hash-slot relocations - /// - public sealed class HashSlotMovedEventArgs : EventArgs, ICompletable - { - private readonly object sender; - private readonly EventHandler handler; - /// - /// The hash-slot that was relocated - /// - public int HashSlot { get; } - - /// - /// The old endpoint for this hash-slot (if known) - /// - public EndPoint OldEndPoint { get; } - - /// - /// The new endpoint for this hash-slot (if known) - /// - public EndPoint NewEndPoint { get; } - - internal HashSlotMovedEventArgs(EventHandler handler, object sender, - int hashSlot, EndPoint old, EndPoint @new) - { - this.handler = handler; - this.sender = sender; - HashSlot = hashSlot; - OldEndPoint = old; - NewEndPoint = @new; - } - - bool ICompletable.TryComplete(bool isAsync) - { - return ConnectionMultiplexer.TryCompleteHandler(handler, sender, this, isAsync); - } - - void ICompletable.AppendStormLog(StringBuilder sb) - { - sb.Append("event, slot-moved: ").Append(HashSlot); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IBatch.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IBatch.cs deleted file mode 100644 index c98e901..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IBatch.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// Represents a block of operations that will be sent to the server together; - /// this can be useful to reduce packet fragmentation on slow connections - it - /// can improve the time to get *all* the operations processed, with the trade-off - /// of a slower time to get the *first* operation processed; this is usually - /// a good thing. Unless this batch is a transaction, there is no guarantee - /// that these operations will be processed either contiguously or atomically by the server. - /// - public interface IBatch : IDatabaseAsync - { - /// - /// Execute the batch operation, sending all queued commands to the server. - /// Note that this operation is neither synchronous nor truly asyncronous - it - /// simply enqueues the buffered messages. To check on completion, you should - /// check the individual responses. - /// - void Execute(); - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ICompletable.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ICompletable.cs deleted file mode 100644 index d469fb5..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ICompletable.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text; - -namespace StackExchange.Redis -{ - interface ICompletable - { - void AppendStormLog(StringBuilder sb); - - bool TryComplete(bool isAsync); - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IConnectionMultiplexer.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IConnectionMultiplexer.cs deleted file mode 100644 index 52d2777..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IConnectionMultiplexer.cs +++ /dev/null @@ -1,253 +0,0 @@ -using System; -using System.IO; -using System.Net; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - /// - /// Represents the abstract multiplexer API - /// - public interface IConnectionMultiplexer - { - -#if DEBUG - /// - /// For debugging; when not enabled, servers cannot connect - /// - bool AllowConnect { get; set; } - - /// - /// For debugging; when not enabled, end-connect is silently ignored (to simulate a long-running connect) - /// - bool IgnoreConnect { get; set; } -#endif - /// - /// Gets the client-name that will be used on all new connections - /// - string ClientName { get; } - - /// - /// Gets the configuration of the connection - /// - string Configuration { get; } - - /// - /// Gets the timeout associated with the connections - /// - int TimeoutMilliseconds { get; } - - /// - /// The number of operations that have been performed on all connections - /// - long OperationCount { get; } - - /// - /// Gets or sets whether asynchronous operations should be invoked in a way that guarantees their original delivery order - /// - bool PreserveAsyncOrder { get; set; } - - /// - /// Indicates whether any servers are connected - /// - bool IsConnected { get; } - - /// - /// Should exceptions include identifiable details? (key names, additional .Data annotations) - /// - bool IncludeDetailInExceptions { get; set; } - - /// - /// Limit at which to start recording unusual busy patterns (only one log will be retained at a time; - /// set to a negative value to disable this feature) - /// - int StormLogThreshold { get; set; } - - /// - /// Sets an IProfiler instance for this ConnectionMultiplexer. - /// - /// An IProfiler instances is used to determine which context to associate an - /// IProfiledCommand with. See BeginProfiling(object) and FinishProfiling(object) - /// for more details. - /// - void RegisterProfiler(IProfiler profiler); - - /// - /// Begins profiling for the given context. - /// - /// If the same context object is returned by the registered IProfiler, the IProfiledCommands - /// will be associated with each other. - /// - /// Call FinishProfiling with the same context to get the assocated commands. - /// - /// Note that forContext cannot be a WeakReference or a WeakReference<T> - /// - void BeginProfiling(object forContext); - - /// - /// Stops profiling for the given context, returns all IProfiledCommands associated. - /// - /// By default this may do a sweep for dead profiling contexts, you can disable this by passing "allowCleanupSweep: false". - /// - ProfiledCommandEnumerable FinishProfiling(object forContext, bool allowCleanupSweep = true); - - /// - /// Get summary statistics associates with this server - /// - ServerCounters GetCounters(); - - /// - /// A server replied with an error message; - /// - event EventHandler ErrorMessage; - - /// - /// Raised whenever a physical connection fails - /// - event EventHandler ConnectionFailed; - - /// - /// Raised whenever an internal error occurs (this is primarily for debugging) - /// - event EventHandler InternalError; - - /// - /// Raised whenever a physical connection is established - /// - event EventHandler ConnectionRestored; - - /// - /// Raised when configuration changes are detected - /// - event EventHandler ConfigurationChanged; - - /// - /// Raised when nodes are explicitly requested to reconfigure via broadcast; - /// this usually means master/slave changes - /// - event EventHandler ConfigurationChangedBroadcast; - - /// - /// Gets all endpoints defined on the server - /// - /// - EndPoint[] GetEndPoints(bool configuredOnly = false); - - /// - /// Wait for a given asynchronous operation to complete (or timeout) - /// - void Wait(Task task); - - /// - /// Wait for a given asynchronous operation to complete (or timeout) - /// - T Wait(Task task); - - /// - /// Wait for the given asynchronous operations to complete (or timeout) - /// - void WaitAll(params Task[] tasks); - - /// - /// Raised when a hash-slot has been relocated - /// - event EventHandler HashSlotMoved; - - /// - /// Compute the hash-slot of a specified key - /// - int HashSlot(RedisKey key); - - /// - /// Obtain a pub/sub subscriber connection to the specified server - /// - ISubscriber GetSubscriber(object asyncState = null); - - /// - /// Obtain an interactive connection to a database inside redis - /// - IDatabase GetDatabase(int db = -1, object asyncState = null); - - /// - /// Obtain a configuration API for an individual server - /// - IServer GetServer(string host, int port, object asyncState = null); - - /// - /// Obtain a configuration API for an individual server - /// - IServer GetServer(string hostAndPort, object asyncState = null); - - /// - /// Obtain a configuration API for an individual server - /// - IServer GetServer(IPAddress host, int port); - - /// - /// Obtain a configuration API for an individual server - /// - IServer GetServer(EndPoint endpoint, object asyncState = null); - - /// - /// Reconfigure the current connections based on the existing configuration - /// - Task ConfigureAsync(TextWriter log = null); - - /// - /// Reconfigure the current connections based on the existing configuration - /// - bool Configure(TextWriter log = null); - - /// - /// Provides a text overview of the status of all connections - /// - string GetStatus(); - - /// - /// Provides a text overview of the status of all connections - /// - void GetStatus(TextWriter log); - - /// - /// See Object.ToString() - /// - string ToString(); - - /// - /// Close all connections and release all resources associated with this object - /// - void Close(bool allowCommandsToComplete = true); - - /// - /// Close all connections and release all resources associated with this object - /// - Task CloseAsync(bool allowCommandsToComplete = true); - - /// - /// Release all resources associated with this object - /// - void Dispose(); - - /// - /// Obtains the log of unusual busy patterns - /// - string GetStormLog(); - - /// - /// Resets the log of unusual busy patterns - /// - void ResetStormLog(); - - /// - /// Request all compatible clients to reconfigure or reconnect - /// - /// The number of instances known to have received the message (however, the actual number can be higher; returns -1 if the operation is pending) - long PublishReconfigure(CommandFlags flags = CommandFlags.None); - - /// - /// Request all compatible clients to reconfigure or reconnect - /// - /// The number of instances known to have received the message (however, the actual number can be higher) - Task PublishReconfigureAsync(CommandFlags flags = CommandFlags.None); - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IDatabase.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IDatabase.cs deleted file mode 100644 index 5d9addf..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IDatabase.cs +++ /dev/null @@ -1,1078 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; - -namespace StackExchange.Redis -{ - - /// - /// Describes functionality that is common to both standalone redis servers and redis clusters - /// - public interface IDatabase : IRedis, IDatabaseAsync - { - - /// - /// The numeric identifier of this database - /// - int Database { get; } - - /// - /// Allows creation of a group of operations that will be sent to the server as a single unit, - /// but which may or may not be processed on the server contiguously. - /// - [IgnoreNamePrefix] - IBatch CreateBatch(object asyncState = null); - - - /// - /// Atomically transfer a key from a source Redis instance to a destination Redis instance. On success the key is deleted from the original instance by default, and is guaranteed to exist in the target instance. - /// - /// http://redis.io/commands/MIGRATE - void KeyMigrate(RedisKey key, EndPoint toServer, int toDatabase = 0, int timeoutMilliseconds = 0, MigrateOptions migrateOptions = MigrateOptions.None, CommandFlags flags = CommandFlags.None); - - - /// - /// Allows creation of a group of operations that will be sent to the server as a single unit, - /// and processed on the server as a single unit. - /// - [IgnoreNamePrefix] - ITransaction CreateTransaction(object asyncState = null); - - /// - /// Returns the raw DEBUG OBJECT output for a key; this command is not fully documented and should be avoided unless you have good reason, and then avoided anyway. - /// - /// http://redis.io/commands/debug-object - RedisValue DebugObject(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Add the specified member to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members. - /// - /// True if the specified member was not already present in the set, else False - /// http://redis.io/commands/geoadd - bool GeoAdd(RedisKey key, double longitude, double latitude, RedisValue member, CommandFlags flags = CommandFlags.None); - - - /// - /// Add the specified member to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members. - /// - /// True if the specified member was not already present in the set, else False - /// http://redis.io/commands/geoadd - bool GeoAdd(RedisKey key, StackExchange.Redis.GeoEntry value, CommandFlags flags = CommandFlags.None); - - - /// - /// Add the specified members to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members. - /// - /// the number of elements that were added to the set, not including all the elements already present into the set. - /// http://redis.io/commands/geoadd - long GeoAdd(RedisKey key, GeoEntry[] values, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified member from the geo sorted set stored at key. Non existing members are ignored. - /// - /// True if the member existed in the sorted set and was removed; False otherwise. - /// http://redis.io/commands/zrem - bool GeoRemove(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None); - - /// - /// Return the distance between two members in the geospatial index represented by the sorted set. - /// - /// The command returns the distance as a double (represented as a string) in the specified unit, or NULL if one or both the elements are missing. - /// http://redis.io/commands/geodist - double? GeoDistance(RedisKey key, RedisValue member1, RedisValue member2, GeoUnit unit = GeoUnit.Meters, CommandFlags flags = CommandFlags.None); - - /// - /// Return valid Geohash strings representing the position of one or more elements in a sorted set value representing a geospatial index (where elements were added using GEOADD). - /// - /// The command returns an array where each element is the Geohash corresponding to each member name passed as argument to the command. - /// http://redis.io/commands/geohash - string[] GeoHash(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None); - - /// - /// Return valid Geohash strings representing the position of one or more elements in a sorted set value representing a geospatial index (where elements were added using GEOADD). - /// - /// The command returns an array where each element is the Geohash corresponding to each member name passed as argument to the command. - /// http://redis.io/commands/geohash - string GeoHash(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None); - - - /// - /// Return the positions (longitude,latitude) of all the specified members of the geospatial index represented by the sorted set at key. - /// - /// The command returns an array where each element is a two elements array representing longitude and latitude (x,y) of each member name passed as argument to the command.Non existing elements are reported as NULL elements of the array. - /// http://redis.io/commands/geopos - GeoPosition?[] GeoPosition(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None); - - /// - /// Return the positions (longitude,latitude) of all the specified members of the geospatial index represented by the sorted set at key. - /// - /// The command returns an array where each element is a two elements array representing longitude and latitude (x,y) of each member name passed as argument to the command.Non existing elements are reported as NULL elements of the array. - /// http://redis.io/commands/geopos - GeoPosition? GeoPosition(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None); - - /// - /// Return the members of a sorted set populated with geospatial information using GEOADD, which are within the borders of the area specified with the center location and the maximum distance from the center (the radius). - /// - /// GeoRadiusResult[] - /// http://redis.io/commands/georadius - GeoRadiusResult[] GeoRadius(RedisKey key, RedisValue member, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None); - - /// - /// Return the members of a sorted set populated with geospatial information using GEOADD, which are within the borders of the area specified with the center location and the maximum distance from the center (the radius). - /// - /// GeoRadiusResult[] - /// http://redis.io/commands/georadius - GeoRadiusResult[] GeoRadius(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None); - - /// - /// Decrements the number stored at field in the hash stored at key by decrement. If key does not exist, a new key holding a hash is created. If field does not exist or holds a string that cannot be interpreted as integer, the value is set to 0 before the operation is performed. - /// - /// The range of values supported by HINCRBY is limited to 64 bit signed integers. - /// the value at field after the decrement operation. - /// http://redis.io/commands/hincrby - long HashDecrement(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None); - - /// - /// Decrement the specified field of an hash stored at key, and representing a floating point number, by the specified decrement. If the field does not exist, it is set to 0 before performing the operation. - /// - /// The precision of the output is fixed at 17 digits after the decimal point regardless of the actual internal precision of the computation. - /// the value at field after the decrement operation. - /// http://redis.io/commands/hincrbyfloat - double HashDecrement(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified fields from the hash stored at key. Non-existing fields are ignored. Non-existing keys are treated as empty hashes and this command returns 0. - /// - /// http://redis.io/commands/hdel - /// The number of fields that were removed. - bool HashDelete(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified fields from the hash stored at key. Non-existing fields are ignored. Non-existing keys are treated as empty hashes and this command returns 0. - /// - /// http://redis.io/commands/hdel - /// The number of fields that were removed. - long HashDelete(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None); - - /// - /// Returns if field is an existing field in the hash stored at key. - /// - /// 1 if the hash contains field. 0 if the hash does not contain field, or key does not exist. - /// http://redis.io/commands/hexists - bool HashExists(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the value associated with field in the hash stored at key. - /// - /// the value associated with field, or nil when field is not present in the hash or key does not exist. - /// http://redis.io/commands/hget - RedisValue HashGet(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the values associated with the specified fields in the hash stored at key. - /// For every field that does not exist in the hash, a nil value is returned.Because a non-existing keys are treated as empty hashes, running HMGET against a non-existing key will return a list of nil values. - /// - /// list of values associated with the given fields, in the same order as they are requested. - /// http://redis.io/commands/hmget - RedisValue[] HashGet(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None); - - /// - /// Returns all fields and values of the hash stored at key. - /// - /// list of fields and their values stored in the hash, or an empty list when key does not exist. - /// http://redis.io/commands/hgetall - HashEntry[] HashGetAll(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Increments the number stored at field in the hash stored at key by increment. If key does not exist, a new key holding a hash is created. If field does not exist or holds a string that cannot be interpreted as integer, the value is set to 0 before the operation is performed. - /// - /// The range of values supported by HINCRBY is limited to 64 bit signed integers. - /// the value at field after the increment operation. - /// http://redis.io/commands/hincrby - long HashIncrement(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None); - - /// - /// Increment the specified field of an hash stored at key, and representing a floating point number, by the specified increment. If the field does not exist, it is set to 0 before performing the operation. - /// - /// The precision of the output is fixed at 17 digits after the decimal point regardless of the actual internal precision of the computation. - /// the value at field after the increment operation. - /// http://redis.io/commands/hincrbyfloat - double HashIncrement(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None); - - /// - /// Returns all field names in the hash stored at key. - /// - /// list of fields in the hash, or an empty list when key does not exist. - /// http://redis.io/commands/hkeys - RedisValue[] HashKeys(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the number of fields contained in the hash stored at key. - /// - /// number of fields in the hash, or 0 when key does not exist. - /// http://redis.io/commands/hlen - long HashLength(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// The HSCAN command is used to incrementally iterate over a hash - /// - /// yields all elements of the hash. - /// http://redis.io/commands/hscan - IEnumerable HashScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags); - - /// - /// The HSCAN command is used to incrementally iterate over a hash; note: to resume an iteration via cursor, cast the original enumerable or enumerator to IScanningCursor. - /// - /// yields all elements of the hash. - /// http://redis.io/commands/hscan - IEnumerable HashScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisBase.CursorUtils.DefaultPageSize, long cursor = RedisBase.CursorUtils.Origin, int pageOffset = 0, CommandFlags flags = CommandFlags.None); - - /// - /// Sets the specified fields to their respective values in the hash stored at key. This command overwrites any existing fields in the hash. If key does not exist, a new key holding a hash is created. - /// - /// http://redis.io/commands/hmset - void HashSet(RedisKey key, HashEntry[] hashFields, CommandFlags flags = CommandFlags.None); - - /// - /// Sets field in the hash stored at key to value. If key does not exist, a new key holding a hash is created. If field already exists in the hash, it is overwritten. - /// - /// 1 if field is a new field in the hash and value was set. 0 if field already exists in the hash and the value was updated. - /// http://redis.io/commands/hset - /// http://redis.io/commands/hsetnx - bool HashSet(RedisKey key, RedisValue hashField, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Returns all values in the hash stored at key. - /// - /// list of values in the hash, or an empty list when key does not exist. - /// http://redis.io/commands/hvals - RedisValue[] HashValues(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Adds the element to the HyperLogLog data structure stored at the variable name specified as first argument. - /// - /// true if at least 1 HyperLogLog internal register was altered. false otherwise. - /// http://redis.io/commands/pfadd - bool HyperLogLogAdd(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Adds all the element arguments to the HyperLogLog data structure stored at the variable name specified as first argument. - /// - /// true if at least 1 HyperLogLog internal register was altered. false otherwise. - /// http://redis.io/commands/pfadd - bool HyperLogLogAdd(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the approximated cardinality computed by the HyperLogLog data structure stored at the specified variable, or 0 if the variable does not exist. - /// - /// The approximated number of unique elements observed via HyperLogLogAdd. - /// http://redis.io/commands/pfcount - long HyperLogLogLength(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the approximated cardinality of the union of the HyperLogLogs passed, by internally merging the HyperLogLogs stored at the provided keys into a temporary hyperLogLog, or 0 if the variable does not exist. - /// - /// The approximated number of unique elements observed via HyperLogLogAdd. - /// http://redis.io/commands/pfcount - long HyperLogLogLength(RedisKey[] keys, CommandFlags flags = CommandFlags.None); - - /// - /// Merge multiple HyperLogLog values into an unique value that will approximate the cardinality of the union of the observed Sets of the source HyperLogLog structures. - /// - /// http://redis.io/commands/pfmerge - void HyperLogLogMerge(RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None); - - /// - /// Merge multiple HyperLogLog values into an unique value that will approximate the cardinality of the union of the observed Sets of the source HyperLogLog structures. - /// - /// http://redis.io/commands/pfmerge - void HyperLogLogMerge(RedisKey destination, RedisKey[] sourceKeys, CommandFlags flags = CommandFlags.None); - - /// - /// Inidicate exactly which redis server we are talking to - /// - [IgnoreNamePrefix] - EndPoint IdentifyEndpoint(RedisKey key = default(RedisKey), CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified key. A key is ignored if it does not exist. - /// - /// True if the key was removed. - /// http://redis.io/commands/del - bool KeyDelete(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified keys. A key is ignored if it does not exist. - /// - /// The number of keys that were removed. - /// http://redis.io/commands/del - long KeyDelete(RedisKey[] keys, CommandFlags flags = CommandFlags.None); - - /// - /// Serialize the value stored at key in a Redis-specific format and return it to the user. The returned value can be synthesized back into a Redis key using the RESTORE command. - /// - /// the serialized value. - /// http://redis.io/commands/dump - byte[] KeyDump(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns if key exists. - /// - /// 1 if the key exists. 0 if the key does not exist. - /// http://redis.io/commands/exists - bool KeyExists(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Set a timeout on key. After the timeout has expired, the key will automatically be deleted. A key with an associated timeout is said to be volatile in Redis terminology. - /// - /// If key is updated before the timeout has expired, then the timeout is removed as if the PERSIST command was invoked on key. - /// For Redis versions < 2.1.3, existing timeouts cannot be overwritten. So, if key already has an associated timeout, it will do nothing and return 0. Since Redis 2.1.3, you can update the timeout of a key. It is also possible to remove the timeout using the PERSIST command. See the page on key expiry for more information. - /// 1 if the timeout was set. 0 if key does not exist or the timeout could not be set. - /// http://redis.io/commands/expire - /// http://redis.io/commands/pexpire - /// http://redis.io/commands/persist - bool KeyExpire(RedisKey key, TimeSpan? expiry, CommandFlags flags = CommandFlags.None); - - /// - /// Set a timeout on key. After the timeout has expired, the key will automatically be deleted. A key with an associated timeout is said to be volatile in Redis terminology. - /// - /// If key is updated before the timeout has expired, then the timeout is removed as if the PERSIST command was invoked on key. - /// For Redis versions < 2.1.3, existing timeouts cannot be overwritten. So, if key already has an associated timeout, it will do nothing and return 0. Since Redis 2.1.3, you can update the timeout of a key. It is also possible to remove the timeout using the PERSIST command. See the page on key expiry for more information. - /// 1 if the timeout was set. 0 if key does not exist or the timeout could not be set. - /// http://redis.io/commands/expireat - /// http://redis.io/commands/pexpireat - /// http://redis.io/commands/persist - bool KeyExpire(RedisKey key, DateTime? expiry, CommandFlags flags = CommandFlags.None); - - /// - /// Move key from the currently selected database (see SELECT) to the specified destination database. When key already exists in the destination database, or it does not exist in the source database, it does nothing. It is possible to use MOVE as a locking primitive because of this. - /// - /// 1 if key was moved; 0 if key was not moved. - /// http://redis.io/commands/move - bool KeyMove(RedisKey key, int database, CommandFlags flags = CommandFlags.None); - - /// Remove the existing timeout on key, turning the key from volatile (a key with an expire set) to persistent (a key that will never expire as no timeout is associated). - /// 1 if the timeout was removed. 0 if key does not exist or does not have an associated timeout. - /// http://redis.io/commands/persist - bool KeyPersist(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Return a random key from the currently selected database. - /// - /// the random key, or nil when the database is empty. - /// http://redis.io/commands/randomkey - RedisKey KeyRandom(CommandFlags flags = CommandFlags.None); - - /// - /// Renames key to newkey. It returns an error when the source and destination names are the same, or when key does not exist. - /// - /// http://redis.io/commands/rename - /// http://redis.io/commands/renamenx - bool KeyRename(RedisKey key, RedisKey newKey, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Create a key associated with a value that is obtained by deserializing the provided serialized value (obtained via DUMP). - /// If ttl is 0 the key is created without any expire, otherwise the specified expire time(in milliseconds) is set. - /// - /// http://redis.io/commands/restore - void KeyRestore(RedisKey key, byte[] value, TimeSpan? expiry = null, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the remaining time to live of a key that has a timeout. This introspection capability allows a Redis client to check how many seconds a given key will continue to be part of the dataset. - /// - /// TTL, or nil when key does not exist or does not have a timeout. - /// http://redis.io/commands/ttl - TimeSpan? KeyTimeToLive(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the string representation of the type of the value stored at key. The different types that can be returned are: string, list, set, zset and hash. - /// - /// type of key, or none when key does not exist. - /// http://redis.io/commands/type - RedisType KeyType(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the element at index index in the list stored at key. The index is zero-based, so 0 means the first element, 1 the second element and so on. Negative indices can be used to designate elements starting at the tail of the list. Here, -1 means the last element, -2 means the penultimate and so forth. - /// - /// the requested element, or nil when index is out of range. - /// http://redis.io/commands/lindex - RedisValue ListGetByIndex(RedisKey key, long index, CommandFlags flags = CommandFlags.None); - - /// - /// Inserts value in the list stored at key either before or after the reference value pivot. - /// When key does not exist, it is considered an empty list and no operation is performed. - /// - /// the length of the list after the insert operation, or -1 when the value pivot was not found. - /// http://redis.io/commands/linsert - long ListInsertAfter(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Inserts value in the list stored at key either before or after the reference value pivot. - /// When key does not exist, it is considered an empty list and no operation is performed. - /// - /// the length of the list after the insert operation, or -1 when the value pivot was not found. - /// http://redis.io/commands/linsert - long ListInsertBefore(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Removes and returns the first element of the list stored at key. - /// - /// the value of the first element, or nil when key does not exist. - /// http://redis.io/commands/lpop - RedisValue ListLeftPop(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Insert the specified value at the head of the list stored at key. If key does not exist, it is created as empty list before performing the push operations. - /// - /// the length of the list after the push operations. - /// http://redis.io/commands/lpush - /// http://redis.io/commands/lpushx - long ListLeftPush(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Insert all the specified values at the head of the list stored at key. If key does not exist, it is created as empty list before performing the push operations. - /// Elements are inserted one after the other to the head of the list, from the leftmost element to the rightmost element. So for instance the command LPUSH mylist a b c will result into a list containing c as first element, b as second element and a as third element. - /// - /// the length of the list after the push operations. - /// http://redis.io/commands/lpush - long ListLeftPush(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the length of the list stored at key. If key does not exist, it is interpreted as an empty list and 0 is returned. - /// - /// the length of the list at key. - /// http://redis.io/commands/llen - long ListLength(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the specified elements of the list stored at key. The offsets start and stop are zero-based indexes, with 0 being the first element of the list (the head of the list), 1 being the next element and so on. - /// These offsets can also be negative numbers indicating offsets starting at the end of the list.For example, -1 is the last element of the list, -2 the penultimate, and so on. - /// Note that if you have a list of numbers from 0 to 100, LRANGE list 0 10 will return 11 elements, that is, the rightmost item is included. - /// - /// list of elements in the specified range. - /// http://redis.io/commands/lrange - RedisValue[] ListRange(RedisKey key, long start = 0, long stop = -1, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the first count occurrences of elements equal to value from the list stored at key. The count argument influences the operation in the following ways: - /// count > 0: Remove elements equal to value moving from head to tail. - /// count < 0: Remove elements equal to value moving from tail to head. - /// count = 0: Remove all elements equal to value. - /// - /// the number of removed elements. - /// http://redis.io/commands/lrem - long ListRemove(RedisKey key, RedisValue value, long count = 0, CommandFlags flags = CommandFlags.None); - - /// - /// Removes and returns the last element of the list stored at key. - /// - /// http://redis.io/commands/rpop - RedisValue ListRightPop(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Atomically returns and removes the last element (tail) of the list stored at source, and pushes the element at the first element (head) of the list stored at destination. - /// - /// the element being popped and pushed. - /// http://redis.io/commands/rpoplpush - RedisValue ListRightPopLeftPush(RedisKey source, RedisKey destination, CommandFlags flags = CommandFlags.None); - - /// - /// Insert the specified value at the tail of the list stored at key. If key does not exist, it is created as empty list before performing the push operation. - /// - /// the length of the list after the push operation. - /// http://redis.io/commands/rpush - /// http://redis.io/commands/rpushx - long ListRightPush(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Insert all the specified values at the tail of the list stored at key. If key does not exist, it is created as empty list before performing the push operation. - /// Elements are inserted one after the other to the tail of the list, from the leftmost element to the rightmost element. So for instance the command RPUSH mylist a b c will result into a list containing a as first element, b as second element and c as third element. - /// - /// the length of the list after the push operation. - /// http://redis.io/commands/rpush - long ListRightPush(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None); - - /// - /// Sets the list element at index to value. For more information on the index argument, see ListGetByIndex. An error is returned for out of range indexes. - /// - /// http://redis.io/commands/lset - void ListSetByIndex(RedisKey key, long index, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Trim an existing list so that it will contain only the specified range of elements specified. Both start and stop are zero-based indexes, where 0 is the first element of the list (the head), 1 the next element and so on. - /// For example: LTRIM foobar 0 2 will modify the list stored at foobar so that only the first three elements of the list will remain. - /// start and end can also be negative numbers indicating offsets from the end of the list, where -1 is the last element of the list, -2 the penultimate element and so on. - /// - /// http://redis.io/commands/ltrim - void ListTrim(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None); - - /// - /// Extends a lock, if the token value is correct - /// - bool LockExtend(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None); - - /// - /// Queries the token held against a lock - /// - RedisValue LockQuery(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Releases a lock, if the token value is correct - /// - bool LockRelease(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Takes a lock (specifying a token value) if it is not already taken - /// - bool LockTake(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None); - - /// - /// Posts a message to the given channel. - /// - /// the number of clients that received the message. - /// http://redis.io/commands/publish - long Publish(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None); - - /// - /// Execute an arbitrary command against the server; this is primarily intended for - /// executing modules, but may also be used to provide access to new features that lack - /// a direct API - /// - /// A dynamic representation of the command's result - RedisResult Execute(string command, params object[] args); - - /// - /// Execute an arbitrary command against the server; this is primarily intended for - /// executing modules, but may also be used to provide access to new features that lack - /// a direct API - /// - /// A dynamic representation of the command's result - RedisResult Execute(string command, ICollection args, CommandFlags flags = CommandFlags.None); - - - /// - /// Execute a Lua script against the server - /// - /// http://redis.io/commands/eval, http://redis.io/commands/evalsha - /// A dynamic representation of the script's result - RedisResult ScriptEvaluate(string script, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None); - - /// - /// Execute a Lua script against the server using just the SHA1 hash - /// - /// http://redis.io/commands/evalsha - /// A dynamic representation of the script's result - RedisResult ScriptEvaluate(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None); - - /// - /// Execute a lua script against the server, using previously prepared script. - /// Named parameters, if any, are provided by the `parameters` object. - /// - RedisResult ScriptEvaluate(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None); - - /// - /// Execute a lua script against the server, using previously prepared and loaded script. - /// This method sends only the SHA1 hash of the lua script to Redis. - /// Named parameters, if any, are provided by the `parameters` object. - /// - RedisResult ScriptEvaluate(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None); - - /// - /// Add the specified member to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members. - /// - /// True if the specified member was not already present in the set, else False - /// http://redis.io/commands/sadd - bool SetAdd(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Add the specified members to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members. - /// - /// the number of elements that were added to the set, not including all the elements already present into the set. - /// http://redis.io/commands/sadd - long SetAdd(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the members of the set resulting from the specified operation against the given sets. - /// - /// list with members of the resulting set. - /// http://redis.io/commands/sunion - /// http://redis.io/commands/sinter - /// http://redis.io/commands/sdiff - RedisValue[] SetCombine(SetOperation operation, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the members of the set resulting from the specified operation against the given sets. - /// - /// list with members of the resulting set. - /// http://redis.io/commands/sunion - /// http://redis.io/commands/sinter - /// http://redis.io/commands/sdiff - RedisValue[] SetCombine(SetOperation operation, RedisKey[] keys, CommandFlags flags = CommandFlags.None); - - /// - /// This command is equal to SetCombine, but instead of returning the resulting set, it is stored in destination. If destination already exists, it is overwritten. - /// - /// the number of elements in the resulting set. - /// http://redis.io/commands/sunionstore - /// http://redis.io/commands/sinterstore - /// http://redis.io/commands/sdiffstore - long SetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None); - - /// - /// This command is equal to SetCombine, but instead of returning the resulting set, it is stored in destination. If destination already exists, it is overwritten. - /// - /// the number of elements in the resulting set. - /// http://redis.io/commands/sunionstore - /// http://redis.io/commands/sinterstore - /// http://redis.io/commands/sdiffstore - long SetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None); - - /// - /// Returns if member is a member of the set stored at key. - /// - /// 1 if the element is a member of the set. 0 if the element is not a member of the set, or if key does not exist. - /// http://redis.io/commands/sismember - bool SetContains(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the set cardinality (number of elements) of the set stored at key. - /// - /// the cardinality (number of elements) of the set, or 0 if key does not exist. - /// http://redis.io/commands/scard - long SetLength(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns all the members of the set value stored at key. - /// - /// all elements of the set. - /// http://redis.io/commands/smembers - RedisValue[] SetMembers(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Move member from the set at source to the set at destination. This operation is atomic. In every given moment the element will appear to be a member of source or destination for other clients. - /// When the specified element already exists in the destination set, it is only removed from the source set. - /// - /// 1 if the element is moved. 0 if the element is not a member of source and no operation was performed. - /// http://redis.io/commands/smove - bool SetMove(RedisKey source, RedisKey destination, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Removes and returns a random element from the set value stored at key. - /// - /// the removed element, or nil when key does not exist. - /// http://redis.io/commands/spop - RedisValue SetPop(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Return a random element from the set value stored at key. - /// - /// the randomly selected element, or nil when key does not exist - /// http://redis.io/commands/srandmember - RedisValue SetRandomMember(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Return an array of count distinct elements if count is positive. If called with a negative count the behavior changes and the command is allowed to return the same element multiple times. - /// In this case the numer of returned elements is the absolute value of the specified count. - /// - /// an array of elements, or an empty array when key does not exist - /// http://redis.io/commands/srandmember - RedisValue[] SetRandomMembers(RedisKey key, long count, CommandFlags flags = CommandFlags.None); - - /// - /// Remove the specified member from the set stored at key. Specified members that are not a member of this set are ignored. - /// - /// True if the specified member was already present in the set, else False - /// http://redis.io/commands/srem - bool SetRemove(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Remove the specified members from the set stored at key. Specified members that are not a member of this set are ignored. - /// - /// the number of members that were removed from the set, not including non existing members. - /// http://redis.io/commands/srem - long SetRemove(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None); - - /// - /// The SSCAN command is used to incrementally iterate over set - /// - /// yields all elements of the set. - /// http://redis.io/commands/sscan - IEnumerable SetScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags); - - /// - /// The SSCAN command is used to incrementally iterate over set; note: to resume an iteration via cursor, cast the original enumerable or enumerator to IScanningCursor. - /// - /// yields all elements of the set. - /// http://redis.io/commands/sscan - IEnumerable SetScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisBase.CursorUtils.DefaultPageSize, long cursor = RedisBase.CursorUtils.Origin, int pageOffset = 0, CommandFlags flags = CommandFlags.None); - - /// - /// Sorts a list, set or sorted set (numerically or alphabetically, ascending by default); By default, the elements themselves are compared, but the values can also be - /// used to perform external key-lookups using the by parameter. By default, the elements themselves are returned, but external key-lookups (one or many) can - /// be performed instead by specifying the get parameter (note that # specifies the element itself, when used in get). - /// Referring to the redis SORT documentation for examples is recommended. When used in hashes, by and get - /// can be used to specify fields using -> notation (again, refer to redis documentation). - /// - /// http://redis.io/commands/sort - /// Returns the sorted elements, or the external values if get is specified - [IgnoreNamePrefix] - RedisValue[] Sort(RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None); - - /// - /// Sorts a list, set or sorted set (numerically or alphabetically, ascending by default); By default, the elements themselves are compared, but the values can also be - /// used to perform external key-lookups using the by parameter. By default, the elements themselves are returned, but external key-lookups (one or many) can - /// be performed instead by specifying the get parameter (note that # specifies the element itself, when used in get). - /// Referring to the redis SORT documentation for examples is recommended. When used in hashes, by and get - /// can be used to specify fields using -> notation (again, refer to redis documentation). - /// - /// http://redis.io/commands/sort - /// Returns the number of elements stored in the new list - [IgnoreNamePrefix] - long SortAndStore(RedisKey destination, RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None); - - /// - /// Adds the specified member with the specified score to the sorted set stored at key. If the specified member is already a member of the sorted set, the score is updated and the element reinserted at the right position to ensure the correct ordering. - /// - /// True if the value was added, False if it already existed (the score is still updated) - /// http://redis.io/commands/zadd - bool SortedSetAdd(RedisKey key, RedisValue member, double score, CommandFlags flags); - - /// - /// Adds the specified member with the specified score to the sorted set stored at key. If the specified member is already a member of the sorted set, the score is updated and the element reinserted at the right position to ensure the correct ordering. - /// - /// True if the value was added, False if it already existed (the score is still updated) - /// http://redis.io/commands/zadd - bool SortedSetAdd(RedisKey key, RedisValue member, double score, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Adds all the specified members with the specified scores to the sorted set stored at key. If a specified member is already a member of the sorted set, the score is updated and the element reinserted at the right position to ensure the correct ordering. - /// - /// The number of elements added to the sorted sets, not including elements already existing for which the score was updated. - /// http://redis.io/commands/zadd - long SortedSetAdd(RedisKey key, SortedSetEntry[] values, CommandFlags flags); - - /// - /// Adds all the specified members with the specified scores to the sorted set stored at key. If a specified member is already a member of the sorted set, the score is updated and the element reinserted at the right position to ensure the correct ordering. - /// - /// The number of elements added to the sorted sets, not including elements already existing for which the score was updated. - /// http://redis.io/commands/zadd - long SortedSetAdd(RedisKey key, SortedSetEntry[] values, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Computes a set operation over two sorted sets, and stores the result in destination, optionally performing - /// a specific aggregation (defaults to sum) - /// - /// http://redis.io/commands/zunionstore - /// http://redis.io/commands/zinterstore - /// the number of elements in the resulting sorted set at destination - long SortedSetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None); - - /// - /// Computes a set operation over multiple sorted sets (optionally using per-set weights), and stores the result in destination, optionally performing - /// a specific aggregation (defaults to sum) - /// - /// http://redis.io/commands/zunionstore - /// http://redis.io/commands/zinterstore - /// the number of elements in the resulting sorted set at destination - long SortedSetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey[] keys, double[] weights = null, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None); - - /// - /// Decrements the score of member in the sorted set stored at key by decrement. If member does not exist in the sorted set, it is added with -decrement as its score (as if its previous score was 0.0). - /// - /// the new score of member - /// http://redis.io/commands/zincrby - double SortedSetDecrement(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None); - - /// - /// Increments the score of member in the sorted set stored at key by increment. If member does not exist in the sorted set, it is added with increment as its score (as if its previous score was 0.0). - /// - /// the new score of member - /// http://redis.io/commands/zincrby - double SortedSetIncrement(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the sorted set cardinality (number of elements) of the sorted set stored at key. - /// - /// the cardinality (number of elements) of the sorted set, or 0 if key does not exist. - /// http://redis.io/commands/zcard - long SortedSetLength(RedisKey key, double min = double.NegativeInfinity, double max = double.PositiveInfinity, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None); - - /// - /// When all the elements in a sorted set are inserted with the same score, in order to force lexicographical ordering, this command returns the number of elements in the sorted set at key with a value between min and max. - /// - /// the number of elements in the specified score range. - /// When all the elements in a sorted set are inserted with the same score, in order to force lexicographical ordering, this command returns all the elements in the sorted set at key with a value between min and max. - long SortedSetLengthByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the specified range of elements in the sorted set stored at key. By default the elements are considered to be ordered from the lowest to the highest score. Lexicographical order is used for elements with equal score. - /// Both start and stop are zero-based indexes, where 0 is the first element, 1 is the next element and so on. They can also be negative numbers indicating offsets from the end of the sorted set, with -1 being the last element of the sorted set, -2 the penultimate element and so on. - /// - /// list of elements in the specified range - /// http://redis.io/commands/zrange - /// http://redis.io/commands/zrevrange - RedisValue[] SortedSetRangeByRank(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the specified range of elements in the sorted set stored at key. By default the elements are considered to be ordered from the lowest to the highest score. Lexicographical order is used for elements with equal score. - /// Both start and stop are zero-based indexes, where 0 is the first element, 1 is the next element and so on. They can also be negative numbers indicating offsets from the end of the sorted set, with -1 being the last element of the sorted set, -2 the penultimate element and so on. - /// - /// list of elements in the specified range - /// http://redis.io/commands/zrange - /// http://redis.io/commands/zrevrange - SortedSetEntry[] SortedSetRangeByRankWithScores(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None); - - - - /// - /// Returns the specified range of elements in the sorted set stored at key. By default the elements are considered to be ordered from the lowest to the highest score. Lexicographical order is used for elements with equal score. - /// Start and stop are used to specify the min and max range for score values. Similar to other range methods the values are inclusive. - /// - /// list of elements in the specified score range - /// http://redis.io/commands/zrangebyscore - /// http://redis.io/commands/zrevrangebyscore - RedisValue[] SortedSetRangeByScore(RedisKey key, - double start = double.NegativeInfinity, double stop = double.PositiveInfinity, - Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, - CommandFlags flags = CommandFlags.None); - - /// - /// Returns the specified range of elements in the sorted set stored at key. By default the elements are considered to be ordered from the lowest to the highest score. Lexicographical order is used for elements with equal score. - /// Start and stop are used to specify the min and max range for score values. Similar to other range methods the values are inclusive. - /// - /// list of elements in the specified score range - /// http://redis.io/commands/zrangebyscore - /// http://redis.io/commands/zrevrangebyscore - SortedSetEntry[] SortedSetRangeByScoreWithScores(RedisKey key, - double start = double.NegativeInfinity, double stop = double.PositiveInfinity, - Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, - CommandFlags flags = CommandFlags.None); - - /// - /// When all the elements in a sorted set are inserted with the same score, in order to force lexicographical ordering, this command returns all the elements in the sorted set at key with a value between min and max. - /// - /// http://redis.io/commands/zrangebylex - /// list of elements in the specified score range. - RedisValue[] SortedSetRangeByValue(RedisKey key, RedisValue min = default(RedisValue), RedisValue max = default(RedisValue), - Exclude exclude = Exclude.None, long skip = 0, long take = -1, - CommandFlags flags = CommandFlags.None); - - /// - /// Returns the rank of member in the sorted set stored at key, by default with the scores ordered from low to high. The rank (or index) is 0-based, which means that the member with the lowest score has rank 0. - /// - /// If member exists in the sorted set, the rank of member; If member does not exist in the sorted set or key does not exist, null - /// http://redis.io/commands/zrank - /// http://redis.io/commands/zrevrank - long? SortedSetRank(RedisKey key, RedisValue member, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified member from the sorted set stored at key. Non existing members are ignored. - /// - /// True if the member existed in the sorted set and was removed; False otherwise. - /// http://redis.io/commands/zrem - bool SortedSetRemove(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified members from the sorted set stored at key. Non existing members are ignored. - /// - /// The number of members removed from the sorted set, not including non existing members. - /// http://redis.io/commands/zrem - long SortedSetRemove(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None); - - /// - /// Removes all elements in the sorted set stored at key with rank between start and stop. Both start and stop are 0 -based indexes with 0 being the element with the lowest score. These indexes can be negative numbers, where they indicate offsets starting at the element with the highest score. For example: -1 is the element with the highest score, -2 the element with the second highest score and so forth. - /// - /// the number of elements removed. - /// http://redis.io/commands/zremrangebyrank - long SortedSetRemoveRangeByRank(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None); - - /// - /// Removes all elements in the sorted set stored at key with a score between min and max (inclusive by default). - /// - /// the number of elements removed. - /// http://redis.io/commands/zremrangebyscore - long SortedSetRemoveRangeByScore(RedisKey key, double start, double stop, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None); - - /// - /// When all the elements in a sorted set are inserted with the same score, in order to force lexicographical ordering, this command removes all elements in the sorted set stored at key between the lexicographical range specified by min and max. - /// - /// http://redis.io/commands/zremrangebylex - /// the number of elements removed. - long SortedSetRemoveRangeByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None); - /// - /// The ZSCAN command is used to incrementally iterate over a sorted set - /// - /// yields all elements of the sorted set. - /// http://redis.io/commands/zscan - IEnumerable SortedSetScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags); - - /// - /// The ZSCAN command is used to incrementally iterate over a sorted set; note: to resume an iteration via cursor, cast the original enumerable or enumerator to IScanningCursor. - /// - /// yields all elements of the sorted set. - /// http://redis.io/commands/zscan - IEnumerable SortedSetScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisBase.CursorUtils.DefaultPageSize, long cursor = RedisBase.CursorUtils.Origin, int pageOffset = 0, CommandFlags flags = CommandFlags.None); - /// - /// Returns the score of member in the sorted set at key; If member does not exist in the sorted set, or key does not exist, nil is returned. - /// - /// the score of member - /// http://redis.io/commands/zscore - double? SortedSetScore(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None); - - - - - - /// - /// If key already exists and is a string, this command appends the value at the end of the string. If key does not exist it is created and set as an empty string, - /// so APPEND will be similar to SET in this special case. - /// - /// the length of the string after the append operation. - /// http://redis.io/commands/append - long StringAppend(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Count the number of set bits (population counting) in a string. - /// By default all the bytes contained in the string are examined.It is possible to specify the counting operation only in an interval passing the additional arguments start and end. - /// Like for the GETRANGE command start and end can contain negative values in order to index bytes starting from the end of the string, where -1 is the last byte, -2 is the penultimate, and so forth. - /// - /// The number of bits set to 1 - /// http://redis.io/commands/bitcount - long StringBitCount(RedisKey key, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None); - - /// - /// Perform a bitwise operation between multiple keys (containing string values) and store the result in the destination key. - /// The BITOP command supports four bitwise operations; note that NOT is a unary operator: the second key should be omitted in this case - /// and only the first key will be considered. - /// The result of the operation is always stored at destkey. - /// - /// The size of the string stored in the destination key, that is equal to the size of the longest input string. - /// http://redis.io/commands/bitop - long StringBitOperation(Bitwise operation, RedisKey destination, RedisKey first, RedisKey second = default(RedisKey), CommandFlags flags = CommandFlags.None); - - /// - /// Perform a bitwise operation between multiple keys (containing string values) and store the result in the destination key. - /// The BITOP command supports four bitwise operations; note that NOT is a unary operator. - /// The result of the operation is always stored at destkey. - /// - /// The size of the string stored in the destination key, that is equal to the size of the longest input string. - /// http://redis.io/commands/bitop - long StringBitOperation(Bitwise operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None); - - /// - /// Return the position of the first bit set to 1 or 0 in a string. - /// The position is returned thinking at the string as an array of bits from left to right where the first byte most significant bit is at position 0, the second byte most significant bit is at position 8 and so forth. - /// An start and end may be specified; these are in bytes, not bits; start and end can contain negative values in order to index bytes starting from the end of the string, where -1 is the last byte, -2 is the penultimate, and so forth. - /// - /// The command returns the position of the first bit set to 1 or 0 according to the request. - /// If we look for set bits(the bit argument is 1) and the string is empty or composed of just zero bytes, -1 is returned. - /// http://redis.io/commands/bitpos - long StringBitPosition(RedisKey key, bool bit, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None); - - /// - /// Decrements the number stored at key by decrement. If the key does not exist, it is set to 0 before performing the operation. - /// An error is returned if the key contains a value of the wrong type or contains a string that is not representable as integer. This operation is limited to 64 bit signed integers. - /// - /// the value of key after the decrement - /// http://redis.io/commands/decrby - /// http://redis.io/commands/decr - long StringDecrement(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None); - - /// - /// Decrements the string representing a floating point number stored at key by the specified decrement. If the key does not exist, it is set to 0 before performing the operation. The precision of the output is fixed at 17 digits after the decimal point regardless of the actual internal precision of the computation. - /// - /// the value of key after the decrement - /// http://redis.io/commands/incrbyfloat - double StringDecrement(RedisKey key, double value, CommandFlags flags = CommandFlags.None); - - /// - /// Get the value of key. If the key does not exist the special value nil is returned. An error is returned if the value stored at key is not a string, because GET only handles string values. - /// - /// the value of key, or nil when key does not exist. - /// http://redis.io/commands/get - RedisValue StringGet(RedisKey key, CommandFlags flags = CommandFlags.None); - /// - /// Returns the values of all specified keys. For every key that does not hold a string value or does not exist, the special value nil is returned. - /// - /// http://redis.io/commands/mget - RedisValue[] StringGet(RedisKey[] keys, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the bit value at offset in the string value stored at key. - /// When offset is beyond the string length, the string is assumed to be a contiguous space with 0 bits. - /// - /// the bit value stored at offset. - /// http://redis.io/commands/getbit - bool StringGetBit(RedisKey key, long offset, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the substring of the string value stored at key, determined by the offsets start and end (both are inclusive). Negative offsets can be used in order to provide an offset starting from the end of the string. So -1 means the last character, -2 the penultimate and so forth. - /// - /// the substring of the string value stored at key - /// http://redis.io/commands/getrange - RedisValue StringGetRange(RedisKey key, long start, long end, CommandFlags flags = CommandFlags.None); - - /// - /// Atomically sets key to value and returns the old value stored at key. - /// - /// http://redis.io/commands/getset - /// the old value stored at key, or nil when key did not exist. - RedisValue StringGetSet(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Get the value of key. If the key does not exist the special value nil is returned. An error is returned if the value stored at key is not a string, because GET only handles string values. - /// - /// the value of key, or nil when key does not exist. - /// http://redis.io/commands/get - RedisValueWithExpiry StringGetWithExpiry(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Increments the number stored at key by increment. If the key does not exist, it is set to 0 before performing the operation. An error is returned if the key contains a value of the wrong type or contains a string that is not representable as integer. This operation is limited to 64 bit signed integers. - /// - /// the value of key after the increment - /// http://redis.io/commands/incrby - /// http://redis.io/commands/incr - long StringIncrement(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None); - - /// - /// Increments the string representing a floating point number stored at key by the specified increment. If the key does not exist, it is set to 0 before performing the operation. The precision of the output is fixed at 17 digits after the decimal point regardless of the actual internal precision of the computation. - /// - /// the value of key after the increment - /// http://redis.io/commands/incrbyfloat - double StringIncrement(RedisKey key, double value, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the length of the string value stored at key. - /// - /// the length of the string at key, or 0 when key does not exist. - /// http://redis.io/commands/strlen - long StringLength(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Set key to hold the string value. If key already holds a value, it is overwritten, regardless of its type. - /// - /// http://redis.io/commands/set - bool StringSet(RedisKey key, RedisValue value, TimeSpan? expiry = null, When when = When.Always, CommandFlags flags = CommandFlags.None); - /// - /// Sets the given keys to their respective values. If "not exists" is specified, this will not perform any operation at all even if just a single key already exists. - /// - /// True if the keys were set, else False - /// http://redis.io/commands/mset - /// http://redis.io/commands/msetnx - bool StringSet(KeyValuePair[] values, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Sets or clears the bit at offset in the string value stored at key. - /// The bit is either set or cleared depending on value, which can be either 0 or 1. When key does not exist, a new string value is created.The string is grown to make sure it can hold a bit at offset. - /// - /// the original bit value stored at offset. - /// http://redis.io/commands/setbit - bool StringSetBit(RedisKey key, long offset, bool bit, CommandFlags flags = CommandFlags.None); - /// - /// Overwrites part of the string stored at key, starting at the specified offset, for the entire length of value. If the offset is larger than the current length of the string at key, the string is padded with zero-bytes to make offset fit. Non-existing keys are considered as empty strings, so this command will make sure it holds a string large enough to be able to set value at offset. - /// - /// the length of the string after it was modified by the command. - /// http://redis.io/commands/setrange - RedisValue StringSetRange(RedisKey key, long offset, RedisValue value, CommandFlags flags = CommandFlags.None); - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IDatabaseAsync.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IDatabaseAsync.cs deleted file mode 100644 index 5553966..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IDatabaseAsync.cs +++ /dev/null @@ -1,1040 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - /// - /// Describes functionality that is common to both standalone redis servers and redis clusters - /// - public interface IDatabaseAsync : IRedisAsync - { - /// - /// Returns the raw DEBUG OBJECT output for a key; this command is not fully documented and should be avoided unless you have good reason, and then avoided anyway. - /// - /// http://redis.io/commands/debug-object - Task DebugObjectAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Add the specified member to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members. - /// - /// True if the specified member was not already present in the set, else False - /// http://redis.io/commands/geoadd - Task GeoAddAsync(RedisKey key, double longitude, double latitude, RedisValue member, CommandFlags flags = CommandFlags.None); - - - /// - /// Add the specified member to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members. - /// - /// True if the specified member was not already present in the set, else False - /// http://redis.io/commands/geoadd - Task GeoAddAsync(RedisKey key, StackExchange.Redis.GeoEntry value, CommandFlags flags = CommandFlags.None); - - - /// - /// Add the specified members to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members. - /// - /// the number of elements that were added to the set, not including all the elements already present into the set. - /// http://redis.io/commands/geoadd - Task GeoAddAsync(RedisKey key, GeoEntry[] values, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified member from the geo sorted set stored at key. Non existing members are ignored. - /// - /// True if the member existed in the sorted set and was removed; False otherwise. - /// http://redis.io/commands/zrem - Task GeoRemoveAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None); - - /// - /// Return the distance between two members in the geospatial index represented by the sorted set. - /// - /// The command returns the distance as a double (represented as a string) in the specified unit, or NULL if one or both the elements are missing. - /// http://redis.io/commands/geodist - Task GeoDistanceAsync(RedisKey key, RedisValue member1, RedisValue member2, GeoUnit unit = GeoUnit.Meters, CommandFlags flags = CommandFlags.None); - - /// - /// Return valid Geohash strings representing the position of one or more elements in a sorted set value representing a geospatial index (where elements were added using GEOADD). - /// - /// The command returns an array where each element is the Geohash corresponding to each member name passed as argument to the command. - /// http://redis.io/commands/geohash - Task GeoHashAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None); - - /// - /// Return valid Geohash strings representing the position of one or more elements in a sorted set value representing a geospatial index (where elements were added using GEOADD). - /// - /// The command returns an array where each element is the Geohash corresponding to each member name passed as argument to the command. - /// http://redis.io/commands/geohash - Task GeoHashAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None); - - - /// - /// Return the positions (longitude,latitude) of all the specified members of the geospatial index represented by the sorted set at key. - /// - /// The command returns an array where each element is a two elements array representing longitude and latitude (x,y) of each member name passed as argument to the command.Non existing elements are reported as NULL elements of the array. - /// http://redis.io/commands/geopos - Task GeoPositionAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None); - - /// - /// Return the positions (longitude,latitude) of all the specified members of the geospatial index represented by the sorted set at key. - /// - /// The command returns an array where each element is a two elements array representing longitude and latitude (x,y) of each member name passed as argument to the command.Non existing elements are reported as NULL elements of the array. - /// http://redis.io/commands/geopos - Task GeoPositionAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None); - - /// - /// Return the members of a sorted set populated with geospatial information using GEOADD, which are within the borders of the area specified with the center location and the maximum distance from the center (the radius). - /// - /// GeoRadiusResult[] - /// http://redis.io/commands/georadius - Task GeoRadiusAsync(RedisKey key, RedisValue member, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None); - - /// - /// Return the members of a sorted set populated with geospatial information using GEOADD, which are within the borders of the area specified with the center location and the maximum distance from the center (the radius). - /// - /// GeoRadiusResult[] - /// http://redis.io/commands/georadius - Task GeoRadiusAsync(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None); - - - /// - /// Increments the number stored at field in the hash stored at key by increment. If key does not exist, a new key holding a hash is created. If field does not exist or holds a string that cannot be interpreted as integer, the value is set to 0 before the operation is performed. - /// - /// The range of values supported by HINCRBY is limited to 64 bit signed integers. - /// the value at field after the increment operation. - /// http://redis.io/commands/hincrby - Task HashDecrementAsync(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None); - - /// - /// Decrement the specified field of an hash stored at key, and representing a floating point number, by the specified decrement. If the field does not exist, it is set to 0 before performing the operation. - /// - /// The precision of the output is fixed at 17 digits after the decimal point regardless of the actual internal precision of the computation. - /// the value at field after the decrement operation. - /// http://redis.io/commands/hincrbyfloat - Task HashDecrementAsync(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified fields from the hash stored at key. Non-existing fields are ignored. Non-existing keys are treated as empty hashes and this command returns 0. - /// - /// http://redis.io/commands/hdel - /// The number of fields that were removed. - Task HashDeleteAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified fields from the hash stored at key. Non-existing fields are ignored. Non-existing keys are treated as empty hashes and this command returns 0. - /// - /// http://redis.io/commands/hdel - /// The number of fields that were removed. - Task HashDeleteAsync(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None); - - /// - /// Returns if field is an existing field in the hash stored at key. - /// - /// 1 if the hash contains field. 0 if the hash does not contain field, or key does not exist. - /// http://redis.io/commands/hexists - Task HashExistsAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None); - - /// - /// Returns all fields and values of the hash stored at key. - /// - /// list of fields and their values stored in the hash, or an empty list when key does not exist. - /// http://redis.io/commands/hgetall - Task HashGetAllAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the value associated with field in the hash stored at key. - /// - /// the value associated with field, or nil when field is not present in the hash or key does not exist. - /// http://redis.io/commands/hget - Task HashGetAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the values associated with the specified fields in the hash stored at key. - /// For every field that does not exist in the hash, a nil value is returned.Because a non-existing keys are treated as empty hashes, running HMGET against a non-existing key will return a list of nil values. - /// - /// list of values associated with the given fields, in the same order as they are requested. - /// http://redis.io/commands/hmget - Task HashGetAsync(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None); - - /// - /// Increments the number stored at field in the hash stored at key by increment. If key does not exist, a new key holding a hash is created. If field does not exist or holds a string that cannot be interpreted as integer, the value is set to 0 before the operation is performed. - /// - /// The range of values supported by HINCRBY is limited to 64 bit signed integers. - /// the value at field after the increment operation. - /// http://redis.io/commands/hincrby - Task HashIncrementAsync(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None); - - /// - /// Increment the specified field of an hash stored at key, and representing a floating point number, by the specified increment. If the field does not exist, it is set to 0 before performing the operation. - /// - /// The precision of the output is fixed at 17 digits after the decimal point regardless of the actual internal precision of the computation. - /// the value at field after the increment operation. - /// http://redis.io/commands/hincrbyfloat - Task HashIncrementAsync(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None); - - /// - /// Returns all field names in the hash stored at key. - /// - /// list of fields in the hash, or an empty list when key does not exist. - /// http://redis.io/commands/hkeys - Task HashKeysAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the number of fields contained in the hash stored at key. - /// - /// number of fields in the hash, or 0 when key does not exist. - /// http://redis.io/commands/hlen - Task HashLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Sets the specified fields to their respective values in the hash stored at key. This command overwrites any existing fields in the hash. If key does not exist, a new key holding a hash is created. - /// - /// http://redis.io/commands/hmset - Task HashSetAsync(RedisKey key, HashEntry[] hashFields, CommandFlags flags = CommandFlags.None); - - /// - /// Sets field in the hash stored at key to value. If key does not exist, a new key holding a hash is created. If field already exists in the hash, it is overwritten. - /// - /// 1 if field is a new field in the hash and value was set. 0 if field already exists in the hash and the value was updated. - /// http://redis.io/commands/hset - /// http://redis.io/commands/hsetnx - Task HashSetAsync(RedisKey key, RedisValue hashField, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Returns all values in the hash stored at key. - /// - /// list of values in the hash, or an empty list when key does not exist. - /// http://redis.io/commands/hvals - Task HashValuesAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Adds the element to the HyperLogLog data structure stored at the variable name specified as first argument. - /// - /// true if at least 1 HyperLogLog internal register was altered. false otherwise. - /// http://redis.io/commands/pfadd - Task HyperLogLogAddAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Adds all the element arguments to the HyperLogLog data structure stored at the variable name specified as first argument. - /// - /// true if at least 1 HyperLogLog internal register was altered. false otherwise. - /// http://redis.io/commands/pfadd - Task HyperLogLogAddAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the approximated cardinality computed by the HyperLogLog data structure stored at the specified variable, or 0 if the variable does not exist. - /// - /// The approximated number of unique elements observed via HyperLogLogAdd. - /// http://redis.io/commands/pfcount - Task HyperLogLogLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the approximated cardinality of the union of the HyperLogLogs passed, by internally merging the HyperLogLogs stored at the provided keys into a temporary hyperLogLog, or 0 if the variable does not exist. - /// - /// The approximated number of unique elements observed via HyperLogLogAdd. - /// http://redis.io/commands/pfcount - Task HyperLogLogLengthAsync(RedisKey[] keys, CommandFlags flags = CommandFlags.None); - - /// - /// Merge multiple HyperLogLog values into an unique value that will approximate the cardinality of the union of the observed Sets of the source HyperLogLog structures. - /// - /// http://redis.io/commands/pfmerge - Task HyperLogLogMergeAsync(RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None); - - /// - /// Merge multiple HyperLogLog values into an unique value that will approximate the cardinality of the union of the observed Sets of the source HyperLogLog structures. - /// - /// http://redis.io/commands/pfmerge - Task HyperLogLogMergeAsync(RedisKey destination, RedisKey[] sourceKeys, CommandFlags flags = CommandFlags.None); - - /// - /// Inidicate exactly which redis server we are talking to - /// - [IgnoreNamePrefix] - Task IdentifyEndpointAsync(RedisKey key = default(RedisKey), CommandFlags flags = CommandFlags.None); - - /// - /// Indicates whether the instance can communicate with the server (resolved - /// using the supplied key and optional flags) - /// - [IgnoreNamePrefix(true)] - bool IsConnected(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified key. A key is ignored if it does not exist. - /// - /// True if the key was removed. - /// http://redis.io/commands/del - Task KeyDeleteAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified keys. A key is ignored if it does not exist. - /// - /// The number of keys that were removed. - /// http://redis.io/commands/del - Task KeyDeleteAsync(RedisKey[] keys, CommandFlags flags = CommandFlags.None); - - /// - /// Serialize the value stored at key in a Redis-specific format and return it to the user. The returned value can be synthesized back into a Redis key using the RESTORE command. - /// - /// the serialized value. - /// http://redis.io/commands/dump - Task KeyDumpAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns if key exists. - /// - /// 1 if the key exists. 0 if the key does not exist. - /// http://redis.io/commands/exists - Task KeyExistsAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Set a timeout on key. After the timeout has expired, the key will automatically be deleted. A key with an associated timeout is said to be volatile in Redis terminology. - /// - /// If key is updated before the timeout has expired, then the timeout is removed as if the PERSIST command was invoked on key. - /// For Redis versions < 2.1.3, existing timeouts cannot be overwritten. So, if key already has an associated timeout, it will do nothing and return 0. Since Redis 2.1.3, you can update the timeout of a key. It is also possible to remove the timeout using the PERSIST command. See the page on key expiry for more information. - /// 1 if the timeout was set. 0 if key does not exist or the timeout could not be set. - /// http://redis.io/commands/expire - /// http://redis.io/commands/pexpire - /// http://redis.io/commands/persist - Task KeyExpireAsync(RedisKey key, TimeSpan? expiry, CommandFlags flags = CommandFlags.None); - - /// - /// Set a timeout on key. After the timeout has expired, the key will automatically be deleted. A key with an associated timeout is said to be volatile in Redis terminology. - /// - /// If key is updated before the timeout has expired, then the timeout is removed as if the PERSIST command was invoked on key. - /// For Redis versions < 2.1.3, existing timeouts cannot be overwritten. So, if key already has an associated timeout, it will do nothing and return 0. Since Redis 2.1.3, you can update the timeout of a key. It is also possible to remove the timeout using the PERSIST command. See the page on key expiry for more information. - /// 1 if the timeout was set. 0 if key does not exist or the timeout could not be set. - /// http://redis.io/commands/expireat - /// http://redis.io/commands/pexpireat - /// http://redis.io/commands/persist - Task KeyExpireAsync(RedisKey key, DateTime? expiry, CommandFlags flags = CommandFlags.None); - - - /// - /// Atomically transfer a key from a source Redis instance to a destination Redis instance. On success the key is deleted from the original instance by default, and is guaranteed to exist in the target instance. - /// - /// http://redis.io/commands/MIGRATE - Task KeyMigrateAsync(RedisKey key, EndPoint toServer, int toDatabase = 0, int timeoutMilliseconds = 0, MigrateOptions migrateOptions = MigrateOptions.None, CommandFlags flags = CommandFlags.None); - - /// - /// Move key from the currently selected database (see SELECT) to the specified destination database. When key already exists in the destination database, or it does not exist in the source database, it does nothing. It is possible to use MOVE as a locking primitive because of this. - /// - /// 1 if key was moved; 0 if key was not moved. - /// http://redis.io/commands/move - Task KeyMoveAsync(RedisKey key, int database, CommandFlags flags = CommandFlags.None); - - /// Remove the existing timeout on key, turning the key from volatile (a key with an expire set) to persistent (a key that will never expire as no timeout is associated). - /// 1 if the timeout was removed. 0 if key does not exist or does not have an associated timeout. - /// http://redis.io/commands/persist - Task KeyPersistAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Return a random key from the currently selected database. - /// - /// the random key, or nil when the database is empty. - /// http://redis.io/commands/randomkey - Task KeyRandomAsync(CommandFlags flags = CommandFlags.None); - - /// - /// Renames key to newkey. It returns an error when the source and destination names are the same, or when key does not exist. - /// - /// http://redis.io/commands/rename - /// http://redis.io/commands/renamenx - Task KeyRenameAsync(RedisKey key, RedisKey newKey, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Create a key associated with a value that is obtained by deserializing the provided serialized value (obtained via DUMP). - /// If ttl is 0 the key is created without any expire, otherwise the specified expire time(in milliseconds) is set. - /// - /// http://redis.io/commands/restore - Task KeyRestoreAsync(RedisKey key, byte[] value, TimeSpan? expiry = null, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the remaining time to live of a key that has a timeout. This introspection capability allows a Redis client to check how many seconds a given key will continue to be part of the dataset. - /// - /// TTL, or nil when key does not exist or does not have a timeout. - /// http://redis.io/commands/ttl - Task KeyTimeToLiveAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the string representation of the type of the value stored at key. The different types that can be returned are: string, list, set, zset and hash. - /// - /// type of key, or none when key does not exist. - /// http://redis.io/commands/type - Task KeyTypeAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the element at index index in the list stored at key. The index is zero-based, so 0 means the first element, 1 the second element and so on. Negative indices can be used to designate elements starting at the tail of the list. Here, -1 means the last element, -2 means the penultimate and so forth. - /// - /// the requested element, or nil when index is out of range. - /// http://redis.io/commands/lindex - Task ListGetByIndexAsync(RedisKey key, long index, CommandFlags flags = CommandFlags.None); - - /// - /// Inserts value in the list stored at key either before or after the reference value pivot. - /// When key does not exist, it is considered an empty list and no operation is performed. - /// - /// the length of the list after the insert operation, or -1 when the value pivot was not found. - /// http://redis.io/commands/linsert - Task ListInsertAfterAsync(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Inserts value in the list stored at key either before or after the reference value pivot. - /// When key does not exist, it is considered an empty list and no operation is performed. - /// - /// the length of the list after the insert operation, or -1 when the value pivot was not found. - /// http://redis.io/commands/linsert - Task ListInsertBeforeAsync(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Removes and returns the first element of the list stored at key. - /// - /// the value of the first element, or nil when key does not exist. - /// http://redis.io/commands/lpop - Task ListLeftPopAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Insert the specified value at the head of the list stored at key. If key does not exist, it is created as empty list before performing the push operations. - /// - /// the length of the list after the push operations. - /// http://redis.io/commands/lpush - /// http://redis.io/commands/lpushx - Task ListLeftPushAsync(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Insert all the specified values at the head of the list stored at key. If key does not exist, it is created as empty list before performing the push operations. - /// Elements are inserted one after the other to the head of the list, from the leftmost element to the rightmost element. So for instance the command LPUSH mylist a b c will result into a list containing c as first element, b as second element and a as third element. - /// - /// the length of the list after the push operations. - /// http://redis.io/commands/lpush - Task ListLeftPushAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the length of the list stored at key. If key does not exist, it is interpreted as an empty list and 0 is returned. - /// - /// the length of the list at key. - /// http://redis.io/commands/llen - Task ListLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the specified elements of the list stored at key. The offsets start and stop are zero-based indexes, with 0 being the first element of the list (the head of the list), 1 being the next element and so on. - /// These offsets can also be negative numbers indicating offsets starting at the end of the list.For example, -1 is the last element of the list, -2 the penultimate, and so on. - /// Note that if you have a list of numbers from 0 to 100, LRANGE list 0 10 will return 11 elements, that is, the rightmost item is included. - /// - /// list of elements in the specified range. - /// http://redis.io/commands/lrange - Task ListRangeAsync(RedisKey key, long start = 0, long stop = -1, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the first count occurrences of elements equal to value from the list stored at key. The count argument influences the operation in the following ways: - /// count > 0: Remove elements equal to value moving from head to tail. - /// count < 0: Remove elements equal to value moving from tail to head. - /// count = 0: Remove all elements equal to value. - /// - /// the number of removed elements. - /// http://redis.io/commands/lrem - Task ListRemoveAsync(RedisKey key, RedisValue value, long count = 0, CommandFlags flags = CommandFlags.None); - - /// - /// Removes and returns the last element of the list stored at key. - /// - /// http://redis.io/commands/rpop - Task ListRightPopAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Atomically returns and removes the last element (tail) of the list stored at source, and pushes the element at the first element (head) of the list stored at destination. - /// - /// the element being popped and pushed. - /// http://redis.io/commands/rpoplpush - Task ListRightPopLeftPushAsync(RedisKey source, RedisKey destination, CommandFlags flags = CommandFlags.None); - - /// - /// Insert the specified value at the tail of the list stored at key. If key does not exist, it is created as empty list before performing the push operation. - /// - /// the length of the list after the push operation. - /// http://redis.io/commands/rpush - /// http://redis.io/commands/rpushx - Task ListRightPushAsync(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Insert all the specified values at the tail of the list stored at key. If key does not exist, it is created as empty list before performing the push operation. - /// Elements are inserted one after the other to the tail of the list, from the leftmost element to the rightmost element. So for instance the command RPUSH mylist a b c will result into a list containing a as first element, b as second element and c as third element. - /// - /// the length of the list after the push operation. - /// http://redis.io/commands/rpush - Task ListRightPushAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None); - - /// - /// Sets the list element at index to value. For more information on the index argument, see ListGetByIndex. An error is returned for out of range indexes. - /// - /// http://redis.io/commands/lset - Task ListSetByIndexAsync(RedisKey key, long index, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Trim an existing list so that it will contain only the specified range of elements specified. Both start and stop are zero-based indexes, where 0 is the first element of the list (the head), 1 the next element and so on. - /// For example: LTRIM foobar 0 2 will modify the list stored at foobar so that only the first three elements of the list will remain. - /// start and end can also be negative numbers indicating offsets from the end of the list, where -1 is the last element of the list, -2 the penultimate element and so on. - /// - /// http://redis.io/commands/ltrim - Task ListTrimAsync(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None); - - /// - /// Extends a lock, if the token value is correct - /// - Task LockExtendAsync(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None); - - /// - /// Queries the token held against a lock - /// - Task LockQueryAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Releases a lock, if the token value is correct - /// - Task LockReleaseAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Takes a lock (specifying a token value) if it is not already taken - /// - Task LockTakeAsync(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None); - - /// - /// Posts a message to the given channel. - /// - /// the number of clients that received the message. - /// http://redis.io/commands/publish - Task PublishAsync(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None); - - /// - /// Execute a Lua script against the server - /// - /// http://redis.io/commands/eval, http://redis.io/commands/evalsha - /// A dynamic representation of the script's result - Task ScriptEvaluateAsync(string script, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None); - - /// - /// Execute an arbitrary command against the server; this is primarily intended for - /// executing modules, but may also be used to provide access to new features that lack - /// a direct API - /// - /// A dynamic representation of the command's result - Task ExecuteAsync(string command, params object[] args); - - - /// - /// Execute an arbitrary command against the server; this is primarily intended for - /// executing modules, but may also be used to provide access to new features that lack - /// a direct API - /// - /// A dynamic representation of the command's result - Task ExecuteAsync(string command, ICollection args, CommandFlags flags = CommandFlags.None); - - /// - /// Execute a Lua script against the server using just the SHA1 hash - /// - /// http://redis.io/commands/evalsha - /// A dynamic representation of the script's result - Task ScriptEvaluateAsync(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None); - - /// - /// Execute a lua script against the server, using previously prepared script. - /// Named parameters, if any, are provided by the `parameters` object. - /// - Task ScriptEvaluateAsync(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None); - - /// - /// Execute a lua script against the server, using previously prepared and loaded script. - /// This method sends only the SHA1 hash of the lua script to Redis. - /// Named parameters, if any, are provided by the `parameters` object. - /// - Task ScriptEvaluateAsync(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None); - - /// - /// Add the specified member to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members. - /// - /// True if the specified member was not already present in the set, else False - /// http://redis.io/commands/sadd - Task SetAddAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Add the specified members to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members. - /// - /// the number of elements that were added to the set, not including all the elements already present into the set. - /// http://redis.io/commands/sadd - Task SetAddAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None); - - /// - /// This command is equal to SetCombine, but instead of returning the resulting set, it is stored in destination. If destination already exists, it is overwritten. - /// - /// the number of elements in the resulting set. - /// http://redis.io/commands/sunionstore - /// http://redis.io/commands/sinterstore - /// http://redis.io/commands/sdiffstore - Task SetCombineAndStoreAsync(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None); - - /// - /// This command is equal to SetCombine, but instead of returning the resulting set, it is stored in destination. If destination already exists, it is overwritten. - /// - /// the number of elements in the resulting set. - /// http://redis.io/commands/sunionstore - /// http://redis.io/commands/sinterstore - /// http://redis.io/commands/sdiffstore - Task SetCombineAndStoreAsync(SetOperation operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the members of the set resulting from the specified operation against the given sets. - /// - /// list with members of the resulting set. - /// http://redis.io/commands/sunion - /// http://redis.io/commands/sinter - /// http://redis.io/commands/sdiff - Task SetCombineAsync(SetOperation operation, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the members of the set resulting from the specified operation against the given sets. - /// - /// list with members of the resulting set. - /// http://redis.io/commands/sunion - /// http://redis.io/commands/sinter - /// http://redis.io/commands/sdiff - Task SetCombineAsync(SetOperation operation, RedisKey[] keys, CommandFlags flags = CommandFlags.None); - - /// - /// Returns if member is a member of the set stored at key. - /// - /// 1 if the element is a member of the set. 0 if the element is not a member of the set, or if key does not exist. - /// http://redis.io/commands/sismember - Task SetContainsAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the set cardinality (number of elements) of the set stored at key. - /// - /// the cardinality (number of elements) of the set, or 0 if key does not exist. - /// http://redis.io/commands/scard - Task SetLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Returns all the members of the set value stored at key. - /// - /// all elements of the set. - /// http://redis.io/commands/smembers - Task SetMembersAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Move member from the set at source to the set at destination. This operation is atomic. In every given moment the element will appear to be a member of source or destination for other clients. - /// When the specified element already exists in the destination set, it is only removed from the source set. - /// - /// 1 if the element is moved. 0 if the element is not a member of source and no operation was performed. - /// http://redis.io/commands/smove - Task SetMoveAsync(RedisKey source, RedisKey destination, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Removes and returns a random element from the set value stored at key. - /// - /// the removed element, or nil when key does not exist. - /// http://redis.io/commands/spop - Task SetPopAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Return a random element from the set value stored at key. - /// - /// the randomly selected element, or nil when key does not exist - /// http://redis.io/commands/srandmember - Task SetRandomMemberAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Return an array of count distinct elements if count is positive. If called with a negative count the behavior changes and the command is allowed to return the same element multiple times. - /// In this case the numer of returned elements is the absolute value of the specified count. - /// - /// an array of elements, or an empty array when key does not exist - /// http://redis.io/commands/srandmember - Task SetRandomMembersAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None); - - /// - /// Remove the specified member from the set stored at key. Specified members that are not a member of this set are ignored. - /// - /// True if the specified member was already present in the set, else False - /// http://redis.io/commands/srem - Task SetRemoveAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Remove the specified members from the set stored at key. Specified members that are not a member of this set are ignored. - /// - /// the number of members that were removed from the set, not including non existing members. - /// http://redis.io/commands/srem - Task SetRemoveAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None); - - /// - /// Sorts a list, set or sorted set (numerically or alphabetically, ascending by default); By default, the elements themselves are compared, but the values can also be - /// used to perform external key-lookups using the by parameter. By default, the elements themselves are returned, but external key-lookups (one or many) can - /// be performed instead by specifying the get parameter (note that # specifies the element itself, when used in get). - /// Referring to the redis SORT documentation for examples is recommended. When used in hashes, by and get - /// can be used to specify fields using -> notation (again, refer to redis documentation). - /// - /// http://redis.io/commands/sort - /// Returns the number of elements stored in the new list - [IgnoreNamePrefix] - Task SortAndStoreAsync(RedisKey destination, RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None); - - /// - /// Sorts a list, set or sorted set (numerically or alphabetically, ascending by default); By default, the elements themselves are compared, but the values can also be - /// used to perform external key-lookups using the by parameter. By default, the elements themselves are returned, but external key-lookups (one or many) can - /// be performed instead by specifying the get parameter (note that # specifies the element itself, when used in get). - /// Referring to the redis SORT documentation for examples is recommended. When used in hashes, by and get - /// can be used to specify fields using -> notation (again, refer to redis documentation). - /// - /// http://redis.io/commands/sort - /// Returns the sorted elements, or the external values if get is specified - [IgnoreNamePrefix] - Task SortAsync(RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None); - - /// - /// Adds the specified member with the specified score to the sorted set stored at key. If the specified member is already a member of the sorted set, the score is updated and the element reinserted at the right position to ensure the correct ordering. - /// - /// True if the value was added, False if it already existed (the score is still updated) - /// http://redis.io/commands/zadd - Task SortedSetAddAsync(RedisKey key, RedisValue member, double score, CommandFlags flags); - - /// - /// Adds the specified member with the specified score to the sorted set stored at key. If the specified member is already a member of the sorted set, the score is updated and the element reinserted at the right position to ensure the correct ordering. - /// - /// True if the value was added, False if it already existed (the score is still updated) - /// http://redis.io/commands/zadd - Task SortedSetAddAsync(RedisKey key, RedisValue member, double score, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Adds all the specified members with the specified scores to the sorted set stored at key. If a specified member is already a member of the sorted set, the score is updated and the element reinserted at the right position to ensure the correct ordering. - /// - /// The number of elements added to the sorted sets, not including elements already existing for which the score was updated. - /// http://redis.io/commands/zadd - Task SortedSetAddAsync(RedisKey key, SortedSetEntry[] values, CommandFlags flags); - - /// - /// Adds all the specified members with the specified scores to the sorted set stored at key. If a specified member is already a member of the sorted set, the score is updated and the element reinserted at the right position to ensure the correct ordering. - /// - /// The number of elements added to the sorted sets, not including elements already existing for which the score was updated. - /// http://redis.io/commands/zadd - Task SortedSetAddAsync(RedisKey key, SortedSetEntry[] values, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Computes a set operation over two sorted sets, and stores the result in destination, optionally performing - /// a specific aggregation (defaults to sum) - /// - /// http://redis.io/commands/zunionstore - /// http://redis.io/commands/zinterstore - /// the number of elements in the resulting sorted set at destination - Task SortedSetCombineAndStoreAsync(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None); - - /// - /// Computes a set operation over multiple sorted sets (optionally using per-set weights), and stores the result in destination, optionally performing - /// a specific aggregation (defaults to sum) - /// - /// http://redis.io/commands/zunionstore - /// http://redis.io/commands/zinterstore - /// the number of elements in the resulting sorted set at destination - Task SortedSetCombineAndStoreAsync(SetOperation operation, RedisKey destination, RedisKey[] keys, double[] weights = null, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None); - - /// - /// Decrements the score of member in the sorted set stored at key by decrement. If member does not exist in the sorted set, it is added with -decrement as its score (as if its previous score was 0.0). - /// - /// the new score of member - /// http://redis.io/commands/zincrby - Task SortedSetDecrementAsync(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None); - - /// - /// Increments the score of member in the sorted set stored at key by increment. If member does not exist in the sorted set, it is added with increment as its score (as if its previous score was 0.0). - /// - /// the new score of member - /// http://redis.io/commands/zincrby - Task SortedSetIncrementAsync(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the sorted set cardinality (number of elements) of the sorted set stored at key. - /// - /// the cardinality (number of elements) of the sorted set, or 0 if key does not exist. - /// http://redis.io/commands/zcard - Task SortedSetLengthAsync(RedisKey key, double min = double.NegativeInfinity, double max = double.PositiveInfinity, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None); - - /// - /// When all the elements in a sorted set are inserted with the same score, in order to force lexicographical ordering, this command returns the number of elements in the sorted set at key with a value between min and max. - /// - /// the number of elements in the specified score range. - /// When all the elements in a sorted set are inserted with the same score, in order to force lexicographical ordering, this command returns all the elements in the sorted set at key with a value between min and max. - Task SortedSetLengthByValueAsync(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the specified range of elements in the sorted set stored at key. By default the elements are considered to be ordered from the lowest to the highest score. Lexicographical order is used for elements with equal score. - /// Both start and stop are zero-based indexes, where 0 is the first element, 1 is the next element and so on. They can also be negative numbers indicating offsets from the end of the sorted set, with -1 being the last element of the sorted set, -2 the penultimate element and so on. - /// - /// list of elements in the specified range - /// http://redis.io/commands/zrange - /// http://redis.io/commands/zrevrange - Task SortedSetRangeByRankAsync(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the specified range of elements in the sorted set stored at key. By default the elements are considered to be ordered from the lowest to the highest score. Lexicographical order is used for elements with equal score. - /// Both start and stop are zero-based indexes, where 0 is the first element, 1 is the next element and so on. They can also be negative numbers indicating offsets from the end of the sorted set, with -1 being the last element of the sorted set, -2 the penultimate element and so on. - /// - /// list of elements in the specified range - /// http://redis.io/commands/zrange - /// http://redis.io/commands/zrevrange - Task SortedSetRangeByRankWithScoresAsync(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the specified range of elements in the sorted set stored at key. By default the elements are considered to be ordered from the lowest to the highest score. Lexicographical order is used for elements with equal score. - /// Start and stop are used to specify the min and max range for score values. Similar to other range methods the values are inclusive. - /// - /// list of elements in the specified score range - /// http://redis.io/commands/zrangebyscore - /// http://redis.io/commands/zrevrangebyscore - Task SortedSetRangeByScoreAsync(RedisKey key, - double start = double.NegativeInfinity, double stop = double.PositiveInfinity, - Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, - CommandFlags flags = CommandFlags.None); - - /// - /// Returns the specified range of elements in the sorted set stored at key. By default the elements are considered to be ordered from the lowest to the highest score. Lexicographical order is used for elements with equal score. - /// Start and stop are used to specify the min and max range for score values. Similar to other range methods the values are inclusive. - /// - /// list of elements in the specified score range - /// http://redis.io/commands/zrangebyscore - /// http://redis.io/commands/zrevrangebyscore - Task SortedSetRangeByScoreWithScoresAsync(RedisKey key, - double start = double.NegativeInfinity, double stop = double.PositiveInfinity, - Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, - CommandFlags flags = CommandFlags.None); - - /// - /// When all the elements in a sorted set are inserted with the same score, in order to force lexicographical ordering, this command returns all the elements in the sorted set at key with a value between min and max. - /// - /// http://redis.io/commands/zrangebylex - /// list of elements in the specified score range. - Task SortedSetRangeByValueAsync(RedisKey key, RedisValue min = default(RedisValue), RedisValue max = default(RedisValue), - Exclude exclude = Exclude.None, long skip = 0, long take = -1, - CommandFlags flags = CommandFlags.None); - - /// - /// Returns the rank of member in the sorted set stored at key, by default with the scores ordered from low to high. The rank (or index) is 0-based, which means that the member with the lowest score has rank 0. - /// - /// If member exists in the sorted set, the rank of member; If member does not exist in the sorted set or key does not exist, null - /// http://redis.io/commands/zrank - /// http://redis.io/commands/zrevrank - Task SortedSetRankAsync(RedisKey key, RedisValue member, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified member from the sorted set stored at key. Non existing members are ignored. - /// - /// True if the member existed in the sorted set and was removed; False otherwise. - /// http://redis.io/commands/zrem - Task SortedSetRemoveAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None); - - /// - /// Removes the specified members from the sorted set stored at key. Non existing members are ignored. - /// - /// The number of members removed from the sorted set, not including non existing members. - /// http://redis.io/commands/zrem - Task SortedSetRemoveAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None); - - /// - /// Removes all elements in the sorted set stored at key with rank between start and stop. Both start and stop are 0 -based indexes with 0 being the element with the lowest score. These indexes can be negative numbers, where they indicate offsets starting at the element with the highest score. For example: -1 is the element with the highest score, -2 the element with the second highest score and so forth. - /// - /// the number of elements removed. - /// http://redis.io/commands/zremrangebyrank - Task SortedSetRemoveRangeByRankAsync(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None); - - /// - /// Removes all elements in the sorted set stored at key with a score between min and max (inclusive by default). - /// - /// the number of elements removed. - /// http://redis.io/commands/zremrangebyscore - Task SortedSetRemoveRangeByScoreAsync(RedisKey key, double start, double stop, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None); - - /// - /// When all the elements in a sorted set are inserted with the same score, in order to force lexicographical ordering, this command removes all elements in the sorted set stored at key between the lexicographical range specified by min and max. - /// - /// http://redis.io/commands/zremrangebylex - /// the number of elements removed. - Task SortedSetRemoveRangeByValueAsync(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None); - /// - /// Returns the score of member in the sorted set at key; If member does not exist in the sorted set, or key does not exist, nil is returned. - /// - /// the score of member - /// http://redis.io/commands/zscore - Task SortedSetScoreAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None); - - - /// - /// If key already exists and is a string, this command appends the value at the end of the string. If key does not exist it is created and set as an empty string, - /// so APPEND will be similar to SET in this special case. - /// - /// the length of the string after the append operation. - /// http://redis.io/commands/append - Task StringAppendAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Count the number of set bits (population counting) in a string. - /// By default all the bytes contained in the string are examined.It is possible to specify the counting operation only in an interval passing the additional arguments start and end. - /// Like for the GETRANGE command start and end can contain negative values in order to index bytes starting from the end of the string, where -1 is the last byte, -2 is the penultimate, and so forth. - /// - /// The number of bits set to 1 - /// http://redis.io/commands/bitcount - Task StringBitCountAsync(RedisKey key, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None); - - /// - /// Perform a bitwise operation between multiple keys (containing string values) and store the result in the destination key. - /// The BITOP command supports four bitwise operations; note that NOT is a unary operator: the second key should be omitted in this case - /// and only the first key will be considered. - /// The result of the operation is always stored at destkey. - /// - /// The size of the string stored in the destination key, that is equal to the size of the longest input string. - /// http://redis.io/commands/bitop - Task StringBitOperationAsync(Bitwise operation, RedisKey destination, RedisKey first, RedisKey second = default(RedisKey), CommandFlags flags = CommandFlags.None); - - /// - /// Perform a bitwise operation between multiple keys (containing string values) and store the result in the destination key. - /// The BITOP command supports four bitwise operations; note that NOT is a unary operator. - /// The result of the operation is always stored at destkey. - /// - /// The size of the string stored in the destination key, that is equal to the size of the longest input string. - /// http://redis.io/commands/bitop - Task StringBitOperationAsync(Bitwise operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None); - - /// - /// Return the position of the first bit set to 1 or 0 in a string. - /// The position is returned thinking at the string as an array of bits from left to right where the first byte most significant bit is at position 0, the second byte most significant big is at position 8 and so forth. - /// An start and end may be specified; these are in bytes, not bits; start and end can contain negative values in order to index bytes starting from the end of the string, where -1 is the last byte, -2 is the penultimate, and so forth. - /// - /// The command returns the position of the first bit set to 1 or 0 according to the request. - /// If we look for set bits(the bit argument is 1) and the string is empty or composed of just zero bytes, -1 is returned. - /// http://redis.io/commands/bitpos - Task StringBitPositionAsync(RedisKey key, bool bit, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None); - - /// - /// Decrements the number stored at key by decrement. If the key does not exist, it is set to 0 before performing the operation. An error is returned if the key contains a value of the wrong type or contains a string that is not representable as integer. This operation is limited to 64 bit signed integers. - /// - /// the value of key after the increment - /// http://redis.io/commands/decrby - /// http://redis.io/commands/decr - Task StringDecrementAsync(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None); - - /// - /// Decrements the string representing a floating point number stored at key by the specified increment. If the key does not exist, it is set to 0 before performing the operation. The precision of the output is fixed at 17 digits after the decimal point regardless of the actual internal precision of the computation. - /// - /// the value of key after the increment - /// http://redis.io/commands/incrbyfloat - Task StringDecrementAsync(RedisKey key, double value, CommandFlags flags = CommandFlags.None); - - /// - /// Get the value of key. If the key does not exist the special value nil is returned. An error is returned if the value stored at key is not a string, because GET only handles string values. - /// - /// the value of key, or nil when key does not exist. - /// http://redis.io/commands/get - Task StringGetAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - /// - /// Returns the values of all specified keys. For every key that does not hold a string value or does not exist, the special value nil is returned. - /// - /// http://redis.io/commands/mget - Task StringGetAsync(RedisKey[] keys, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the bit value at offset in the string value stored at key. - /// When offset is beyond the string length, the string is assumed to be a contiguous space with 0 bits. - /// - /// the bit value stored at offset. - /// http://redis.io/commands/getbit - Task StringGetBitAsync(RedisKey key, long offset, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the substring of the string value stored at key, determined by the offsets start and end (both are inclusive). Negative offsets can be used in order to provide an offset starting from the end of the string. So -1 means the last character, -2 the penultimate and so forth. - /// - /// the substring of the string value stored at key - /// http://redis.io/commands/getrange - Task StringGetRangeAsync(RedisKey key, long start, long end, CommandFlags flags = CommandFlags.None); - - /// - /// Atomically sets key to value and returns the old value stored at key. - /// - /// http://redis.io/commands/getset - /// the old value stored at key, or nil when key did not exist. - Task StringGetSetAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Get the value of key. If the key does not exist the special value nil is returned. An error is returned if the value stored at key is not a string, because GET only handles string values. - /// - /// the value of key, or nil when key does not exist. - /// http://redis.io/commands/get - Task StringGetWithExpiryAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Increments the number stored at key by increment. If the key does not exist, it is set to 0 before performing the operation. An error is returned if the key contains a value of the wrong type or contains a string that is not representable as integer. This operation is limited to 64 bit signed integers. - /// - /// the value of key after the increment - /// http://redis.io/commands/incrby - /// http://redis.io/commands/incr - Task StringIncrementAsync(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None); - - /// - /// Increment the string representing a floating point number stored at key by the specified increment. If the key does not exist, it is set to 0 before performing the operation. The precision of the output is fixed at 17 digits after the decimal point regardless of the actual internal precision of the computation. - /// - /// the value of key after the increment - /// http://redis.io/commands/incrbyfloat - Task StringIncrementAsync(RedisKey key, double value, CommandFlags flags = CommandFlags.None); - /// - /// Returns the length of the string value stored at key. - /// - /// the length of the string at key, or 0 when key does not exist. - /// http://redis.io/commands/strlen - Task StringLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None); - - /// - /// Set key to hold the string value. If key already holds a value, it is overwritten, regardless of its type. - /// - /// http://redis.io/commands/set - Task StringSetAsync(RedisKey key, RedisValue value, TimeSpan? expiry = null, When when = When.Always, CommandFlags flags = CommandFlags.None); - /// - /// Sets the given keys to their respective values. If "not exists" is specified, this will not perform any operation at all even if just a single key already exists. - /// - /// True if the keys were set, else False - /// http://redis.io/commands/mset - /// http://redis.io/commands/msetnx - Task StringSetAsync(KeyValuePair[] values, When when = When.Always, CommandFlags flags = CommandFlags.None); - - /// - /// Sets or clears the bit at offset in the string value stored at key. - /// The bit is either set or cleared depending on value, which can be either 0 or 1. When key does not exist, a new string value is created.The string is grown to make sure it can hold a bit at offset. - /// - /// the original bit value stored at offset. - /// http://redis.io/commands/setbit - Task StringSetBitAsync(RedisKey key, long offset, bool bit, CommandFlags flags = CommandFlags.None); - /// - /// Overwrites part of the string stored at key, starting at the specified offset, for the entire length of value. If the offset is larger than the current length of the string at key, the string is padded with zero-bytes to make offset fit. Non-existing keys are considered as empty strings, so this command will make sure it holds a string large enough to be able to set value at offset. - /// - /// the length of the string after it was modified by the command. - /// http://redis.io/commands/setrange - Task StringSetRangeAsync(RedisKey key, long offset, RedisValue value, CommandFlags flags = CommandFlags.None); - } - - - /// - /// Describes a value/expiry pair - /// - public struct RedisValueWithExpiry - { - internal RedisValueWithExpiry(RedisValue value, TimeSpan? expiry) - { - Value = value; - Expiry = expiry; - } - - /// - /// The expiry of this record - /// - public TimeSpan? Expiry { get; } - - /// - /// The value of this record - /// - public RedisValue Value { get; } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IMultiMessage.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IMultiMessage.cs deleted file mode 100644 index e547dde..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IMultiMessage.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; - -namespace StackExchange.Redis -{ - internal interface IMultiMessage - { - IEnumerable GetMessages(PhysicalConnection connection); - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IProfiler.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IProfiler.cs deleted file mode 100644 index 8e93b15..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IProfiler.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.Net; - -namespace StackExchange.Redis -{ - /// - /// If an IProfiledCommand is a retransmission of a previous command, this enum - /// is used to indicate what prompted the retransmission. - /// - /// This can be used to distinguish between transient causes (moving hashslots, joining nodes, etc.) - /// and incorrect routing. - /// - public enum RetransmissionReasonType - { - /// - /// No stated reason - /// - None = 0, - /// - /// Issued to investigate which node owns a key - /// - Ask, - /// - /// A node has indicated that it does *not* own the given key - /// - Moved - } - - /// - /// A profiled command against a redis instance. - /// - /// TimeSpans returned by this interface use a high precision timer if possible. - /// DateTimes returned by this interface are no more precise than DateTime.UtcNow. - /// - public interface IProfiledCommand - { - /// - /// The endpoint this command was sent to. - /// - EndPoint EndPoint { get; } - - /// - /// The Db this command was sent to. - /// - int Db { get; } - - /// - /// The name of this command. - /// - string Command { get; } - - /// - /// The CommandFlags the command was submitted with. - /// - CommandFlags Flags { get; } - - /// - /// When this command was *created*, will be approximately - /// when the paired method of StackExchange.Redis was called but - /// before that method returned. - /// - /// Note that the resolution of the returned DateTime is limited by DateTime.UtcNow. - /// - DateTime CommandCreated { get; } - - /// - /// How long this command waited to be added to the queue of pending - /// redis commands. A large TimeSpan indicates serious contention for - /// the pending queue. - /// - TimeSpan CreationToEnqueued { get; } - - /// - /// How long this command spent in the pending queue before being sent to redis. - /// A large TimeSpan can indicate a large number of pending events, large pending events, - /// or network issues. - /// - TimeSpan EnqueuedToSending { get; } - - /// - /// How long before Redis responded to this command and it's response could be handled after it was sent. - /// A large TimeSpan can indicate a large response body, an overtaxed redis instance, or network issues. - /// - TimeSpan SentToResponse { get; } - - /// - /// How long between Redis responding to this command and awaiting consumers being notified. - /// - TimeSpan ResponseToCompletion { get; } - - /// - /// How long it took this redis command to be processed, from creation to deserializing the final response. - /// - /// Note that this TimeSpan *does not* include time spent awaiting a Task in consumer code. - /// - TimeSpan ElapsedTime { get; } - - /// - /// If a command has to be resent due to an ASK or MOVED response from redis (in a cluster configuration), - /// the second sending of the command will have this property set to the original IProfiledCommand. - /// - /// This can only be set if redis is configured as a cluster. - /// - IProfiledCommand RetransmissionOf { get; } - - /// - /// If RetransmissionOf is not null, this property will be set to either Ask or Moved to indicate - /// what sort of response triggered the retransmission. - /// - /// This can be useful for determining the root cause of extra commands. - /// - RetransmissionReasonType? RetransmissionReason { get; } - } - - /// - /// Interface for profiling individual commands against an Redis ConnectionMulitplexer. - /// - public interface IProfiler - { - /// - /// Called to provide a context object. - /// - /// This method is called before the method which triggers work against redis (such as StringSet(Async)) returns, - /// and will always be called on the same thread as that method. - /// - /// Note that GetContext() may be called even if ConnectionMultiplexer.BeginProfiling() has not been called. - /// You may return `null` to prevent any tracking of commands. - /// - object GetContext(); - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IReconnectRetryPolicy.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IReconnectRetryPolicy.cs deleted file mode 100644 index c368b0e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IReconnectRetryPolicy.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - /// - /// Describes retry policy functionality that can be provided to the multiplexer to be used for connection reconnects - /// - public interface IReconnectRetryPolicy - { - /// - /// This method is called by the multiplexer to determine if a reconnect operation can be retried now. - /// - /// The number of times reconnect retries have already been made by the multiplexer while it was in connecting state - /// Total time elapsed in milliseconds since the last reconnect retry was made - bool ShouldRetry(long currentRetryCount, int timeElapsedMillisecondsSinceLastRetry); - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IRedis.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IRedis.cs deleted file mode 100644 index 37cbdf0..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IRedis.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Diagnostics; - -namespace StackExchange.Redis -{ - /// - /// Common operations available to all redis connections - /// - public partial interface IRedis : IRedisAsync - { - /// - /// This command is often used to test if a connection is still alive, or to measure latency. - /// - /// The observed latency. - /// http://redis.io/commands/ping - TimeSpan Ping(CommandFlags flags = CommandFlags.None); - } - - /// - /// Represents a resumable, cursor-based scanning operation - /// - public interface IScanningCursor - { - /// - /// Returns the cursor that represents the *active* page of results (not the pending/next page of results as returned by SCAN/HSCAN/ZSCAN/SSCAN) - /// - long Cursor { get; } - - /// - /// The page size of the current operation - /// - int PageSize { get; } - - /// - /// The offset into the current page - /// - int PageOffset { get; } - } - - [Conditional("DEBUG")] - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] - internal class IgnoreNamePrefixAttribute : Attribute - { - public IgnoreNamePrefixAttribute(bool ignoreEntireMethod = false) - { - IgnoreEntireMethod = ignoreEntireMethod; - } - - public bool IgnoreEntireMethod { get; private set; } - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IRedisAsync.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IRedisAsync.cs deleted file mode 100644 index 840844a..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IRedisAsync.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - /// - /// Common operations available to all redis connections - /// - public partial interface IRedisAsync - { - /// - /// Gets the multiplexer that created this instance - /// - ConnectionMultiplexer Multiplexer { get; } - - /// - /// This command is often used to test if a connection is still alive, or to measure latency. - /// - /// The observed latency. - /// http://redis.io/commands/ping - Task PingAsync(CommandFlags flags = CommandFlags.None); - /// - /// Wait for a given asynchronous operation to complete (or timeout), reporting which - /// - bool TryWait(Task task); - - /// - /// Wait for a given asynchronous operation to complete (or timeout) - /// - void Wait(Task task); - /// - /// Wait for a given asynchronous operation to complete (or timeout) - /// - T Wait(Task task); - /// - /// Wait for the given asynchronous operations to complete (or timeout) - /// - - void WaitAll(params Task[] tasks); - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IServer.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IServer.cs deleted file mode 100644 index 7cc2240..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/IServer.cs +++ /dev/null @@ -1,529 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - /// - /// Provides configuration controls of a redis server - /// - public partial interface IServer : IRedis - { - /// - /// Gets the cluster configuration associated with this server, if known - /// - ClusterConfiguration ClusterConfiguration { get; } - - /// - /// Gets the address of the connected server - /// - EndPoint EndPoint { get; } - - /// - /// Gets the features available to the connected server - /// - RedisFeatures Features { get; } - - /// - /// Gets whether the connection to the server is active and usable - /// - bool IsConnected { get; } - - /// - /// Gets whether the connected server is a replica / slave - /// - bool IsSlave { get; } - - /// - /// Explicitly opt in for slave writes on writable slaves - /// - bool AllowSlaveWrites { get; set; } - - /// - /// Gets the operating mode of the connected server - /// - ServerType ServerType { get; } - - /// - /// Gets the version of the connected server - /// - Version Version { get; } - - /// - /// The CLIENT KILL command closes a given client connection identified by ip:port. - /// The ip:port should match a line returned by the CLIENT LIST command. - /// Due to the single-treaded nature of Redis, it is not possible to kill a client connection while it is executing a command.From the client point of view, the connection can never be closed in the middle of the execution of a command.However, the client will notice the connection has been closed only when the next command is sent (and results in network error). - /// - /// http://redis.io/commands/client-kill - void ClientKill(EndPoint endpoint, CommandFlags flags = CommandFlags.None); - - /// - /// The CLIENT KILL command closes a given client connection identified by ip:port. - /// The ip:port should match a line returned by the CLIENT LIST command. - /// Due to the single-treaded nature of Redis, it is not possible to kill a client connection while it is executing a command.From the client point of view, the connection can never be closed in the middle of the execution of a command.However, the client will notice the connection has been closed only when the next command is sent (and results in network error). - /// - /// http://redis.io/commands/client-kill - Task ClientKillAsync(EndPoint endpoint, CommandFlags flags = CommandFlags.None); - - /// - /// The CLIENT KILL command closes multiple connections that match the specified filters - /// - /// the number of clients killed. - /// http://redis.io/commands/client-kill - long ClientKill(long? id = null, ClientType? clientType = null, EndPoint endpoint = null, bool skipMe = true, CommandFlags flags = CommandFlags.None); - /// - /// The CLIENT KILL command closes multiple connections that match the specified filters - /// - /// the number of clients killed. - /// http://redis.io/commands/client-kill - Task ClientKillAsync(long? id = null, ClientType? clientType = null, EndPoint endpoint = null, bool skipMe = true, CommandFlags flags = CommandFlags.None); - - /// - /// The CLIENT LIST command returns information and statistics about the client connections server in a mostly human readable format. - /// - /// http://redis.io/commands/client-list - ClientInfo[] ClientList(CommandFlags flags = CommandFlags.None); - - /// - /// The CLIENT LIST command returns information and statistics about the client connections server in a mostly human readable format. - /// - /// http://redis.io/commands/client-list - Task ClientListAsync(CommandFlags flags = CommandFlags.None); - - /// - /// Obtains the current CLUSTER NODES output from a cluster server - /// - ClusterConfiguration ClusterNodes(CommandFlags flags = CommandFlags.None); - - /// - /// Obtains the current CLUSTER NODES output from a cluster server - /// - Task ClusterNodesAsync(CommandFlags flags = CommandFlags.None); - - /// - /// Obtains the current raw CLUSTER NODES output from a cluster server - /// - string ClusterNodesRaw(CommandFlags flags = CommandFlags.None); - - /// - /// Obtains the current raw CLUSTER NODES output from a cluster server - /// - Task ClusterNodesRawAsync(CommandFlags flags = CommandFlags.None); - - /// - /// Get all configuration parameters matching the specified pattern. - /// - /// All matching configuration parameters. - /// http://redis.io/commands/config-get - KeyValuePair[] ConfigGet(RedisValue pattern = default(RedisValue), CommandFlags flags = CommandFlags.None); - - /// - /// Get all configuration parameters matching the specified pattern. - /// - /// All matching configuration parameters. - /// http://redis.io/commands/config-get - Task[]> ConfigGetAsync(RedisValue pattern = default(RedisValue), CommandFlags flags = CommandFlags.None); - - /// - /// Resets the statistics reported by Redis using the INFO command. - /// - /// http://redis.io/commands/config-resetstat - void ConfigResetStatistics(CommandFlags flags = CommandFlags.None); - - /// - /// Resets the statistics reported by Redis using the INFO command. - /// - /// http://redis.io/commands/config-resetstat - Task ConfigResetStatisticsAsync(CommandFlags flags = CommandFlags.None); - - /// - /// The CONFIG REWRITE command rewrites the redis.conf file the server was started with, applying the minimal changes needed to make it reflecting the configuration currently used by the server, that may be different compared to the original one because of the use of the CONFIG SET command. - /// - /// http://redis.io/commands/config-rewrite - void ConfigRewrite(CommandFlags flags = CommandFlags.None); - - /// - /// The CONFIG REWRITE command rewrites the redis.conf file the server was started with, applying the minimal changes needed to make it reflecting the configuration currently used by the server, that may be different compared to the original one because of the use of the CONFIG SET command. - /// - /// http://redis.io/commands/config-rewrite - Task ConfigRewriteAsync(CommandFlags flags = CommandFlags.None); - - /// - /// The CONFIG SET command is used in order to reconfigure the server at runtime without the need to restart Redis. You can change both trivial parameters or switch from one to another persistence option using this command. - /// - /// http://redis.io/commands/config-set - void ConfigSet(RedisValue setting, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// The CONFIG SET command is used in order to reconfigure the server at runtime without the need to restart Redis. You can change both trivial parameters or switch from one to another persistence option using this command. - /// - /// http://redis.io/commands/config-set - Task ConfigSetAsync(RedisValue setting, RedisValue value, CommandFlags flags = CommandFlags.None); - - /// - /// Return the number of keys in the database. - /// - /// http://redis.io/commands/dbsize - long DatabaseSize(int database = 0, CommandFlags flags = CommandFlags.None); - - /// - /// Return the number of keys in the database. - /// - /// http://redis.io/commands/dbsize - Task DatabaseSizeAsync(int database = 0, CommandFlags flags = CommandFlags.None); - - /// - /// Return the same message passed in - /// - /// http://redis.io/commands/echo - RedisValue Echo(RedisValue message, CommandFlags flags = CommandFlags.None); - - /// - /// Return the same message passed in - /// - /// http://redis.io/commands/echo - Task EchoAsync(RedisValue message, CommandFlags flags = CommandFlags.None); - - /// - /// Delete all the keys of all databases on the server. - /// - /// http://redis.io/commands/flushall - void FlushAllDatabases(CommandFlags flags = CommandFlags.None); - - /// - /// Delete all the keys of all databases on the server. - /// - /// http://redis.io/commands/flushall - Task FlushAllDatabasesAsync(CommandFlags flags = CommandFlags.None); - - /// - /// Delete all the keys of the database. - /// - /// http://redis.io/commands/flushdb - void FlushDatabase(int database = 0, CommandFlags flags = CommandFlags.None); - - /// - /// Delete all the keys of the database. - /// - /// http://redis.io/commands/flushdb - Task FlushDatabaseAsync(int database = 0, CommandFlags flags = CommandFlags.None); - - /// - /// Get summary statistics associates with this server - /// - ServerCounters GetCounters(); - /// - /// The INFO command returns information and statistics about the server in a format that is simple to parse by computers and easy to read by humans. - /// - /// http://redis.io/commands/info - IGrouping>[] Info(RedisValue section = default(RedisValue), CommandFlags flags = CommandFlags.None); - - /// - /// The INFO command returns information and statistics about the server in a format that is simple to parse by computers and easy to read by humans. - /// - /// http://redis.io/commands/info - Task>[]> InfoAsync(RedisValue section = default(RedisValue), CommandFlags flags = CommandFlags.None); - - /// - /// The INFO command returns information and statistics about the server in a format that is simple to parse by computers and easy to read by humans. - /// - /// http://redis.io/commands/info - string InfoRaw(RedisValue section = default(RedisValue), CommandFlags flags = CommandFlags.None); - - /// - /// The INFO command returns information and statistics about the server in a format that is simple to parse by computers and easy to read by humans. - /// - /// http://redis.io/commands/info - Task InfoRawAsync(RedisValue section = default(RedisValue), CommandFlags flags = CommandFlags.None); - - /// - /// Returns all keys matching pattern; the KEYS or SCAN commands will be used based on the server capabilities. - /// - /// Warning: consider KEYS as a command that should only be used in production environments with extreme care. - /// http://redis.io/commands/keys - /// http://redis.io/commands/scan - IEnumerable Keys(int database, RedisValue pattern, int pageSize, CommandFlags flags); - - /// - /// Returns all keys matching pattern; the KEYS or SCAN commands will be used based on the server capabilities; note: to resume an iteration via cursor, cast the original enumerable or enumerator to IScanningCursor. - /// - /// Warning: consider KEYS as a command that should only be used in production environments with extreme care. - /// http://redis.io/commands/keys - /// http://redis.io/commands/scan - IEnumerable Keys(int database = 0, RedisValue pattern = default(RedisValue), int pageSize = RedisBase.CursorUtils.DefaultPageSize, long cursor = RedisBase.CursorUtils.Origin, int pageOffset = 0, CommandFlags flags = CommandFlags.None); - - /// - /// Return the time of the last DB save executed with success. A client may check if a BGSAVE command succeeded reading the LASTSAVE value, then issuing a BGSAVE command and checking at regular intervals every N seconds if LASTSAVE changed. - /// - /// http://redis.io/commands/lastsave - DateTime LastSave(CommandFlags flags = CommandFlags.None); - - /// - /// Return the time of the last DB save executed with success. A client may check if a BGSAVE command succeeded reading the LASTSAVE value, then issuing a BGSAVE command and checking at regular intervals every N seconds if LASTSAVE changed. - /// - /// http://redis.io/commands/lastsave - Task LastSaveAsync(CommandFlags flags = CommandFlags.None); - - /// - /// Promote the selected node to be master - /// - void MakeMaster(ReplicationChangeOptions options, TextWriter log = null); - - /// - /// Explicitly request the database to persist the current state to disk - /// - /// http://redis.io/commands/bgrewriteaof - /// http://redis.io/commands/bgsave - /// http://redis.io/commands/save - /// http://redis.io/topics/persistence - void Save(SaveType type, CommandFlags flags = CommandFlags.None); - - /// - /// Explicitly request the database to persist the current state to disk - /// - /// http://redis.io/commands/bgrewriteaof - /// http://redis.io/commands/bgsave - /// http://redis.io/commands/save - /// http://redis.io/topics/persistence - Task SaveAsync(SaveType type, CommandFlags flags = CommandFlags.None); - - /// - /// Inidicates whether the specified script is defined on the server - /// - bool ScriptExists(string script, CommandFlags flags = CommandFlags.None); - - /// - /// Inidicates whether the specified script hash is defined on the server - /// - bool ScriptExists(byte[] sha1, CommandFlags flags = CommandFlags.None); - - /// - /// Inidicates whether the specified script is defined on the server - /// - Task ScriptExistsAsync(string script, CommandFlags flags = CommandFlags.None); - - /// - /// Inidicates whether the specified script hash is defined on the server - /// - Task ScriptExistsAsync(byte[] sha1, CommandFlags flags = CommandFlags.None); - - /// - /// Removes all cached scripts on this server - /// - void ScriptFlush(CommandFlags flags = CommandFlags.None); - - /// - /// Removes all cached scripts on this server - /// - Task ScriptFlushAsync(CommandFlags flags = CommandFlags.None); - - /// - /// Explicitly defines a script on the server - /// - byte[] ScriptLoad(string script, CommandFlags flags = CommandFlags.None); - - /// - /// Explicitly defines a script on the server - /// - LoadedLuaScript ScriptLoad(LuaScript script, CommandFlags flags = CommandFlags.None); - - /// - /// Explicitly defines a script on the server - /// - Task ScriptLoadAsync(string script, CommandFlags flags = CommandFlags.None); - - /// - /// Explicitly defines a script on the server - /// - Task ScriptLoadAsync(LuaScript script, CommandFlags flags = CommandFlags.None); - - /// Asks the redis server to shutdown, killing all connections. Please FULLY read the notes on the SHUTDOWN command. - /// http://redis.io/commands/shutdown - void Shutdown(ShutdownMode shutdownMode = ShutdownMode.Default, CommandFlags flags = CommandFlags.None); - - /// - /// The SLAVEOF command can change the replication settings of a slave on the fly. If a Redis server is already acting as slave, specifying a null master will turn off the replication, turning the Redis server into a MASTER. Specifying a non-null master will make the server a slave of another server listening at the specified hostname and port. - /// - /// http://redis.io/commands/slaveof - void SlaveOf(EndPoint master, CommandFlags flags = CommandFlags.None); - /// - /// The SLAVEOF command can change the replication settings of a slave on the fly. If a Redis server is already acting as slave, specifying a null master will turn off the replication, turning the Redis server into a MASTER. Specifying a non-null master will make the server a slave of another server listening at the specified hostname and port. - /// - /// http://redis.io/commands/slaveof - Task SlaveOfAsync(EndPoint master, CommandFlags flags = CommandFlags.None); - - /// - /// To read the slow log the SLOWLOG GET command is used, that returns every entry in the slow log. It is possible to return only the N most recent entries passing an additional argument to the command (for instance SLOWLOG GET 10). - /// - /// http://redis.io/commands/slowlog - CommandTrace[] SlowlogGet(int count = 0, CommandFlags flags = CommandFlags.None); - /// - /// To read the slow log the SLOWLOG GET command is used, that returns every entry in the slow log. It is possible to return only the N most recent entries passing an additional argument to the command (for instance SLOWLOG GET 10). - /// - /// http://redis.io/commands/slowlog - Task SlowlogGetAsync(int count = 0, CommandFlags flags = CommandFlags.None); - /// - /// You can reset the slow log using the SLOWLOG RESET command. Once deleted the information is lost forever. - /// - /// http://redis.io/commands/slowlog - void SlowlogReset(CommandFlags flags = CommandFlags.None); - /// - /// You can reset the slow log using the SLOWLOG RESET command. Once deleted the information is lost forever. - /// - /// http://redis.io/commands/slowlog - Task SlowlogResetAsync(CommandFlags flags = CommandFlags.None); - /// - /// Lists the currently active channels. An active channel is a Pub/Sub channel with one ore more subscribers (not including clients subscribed to patterns). - /// - /// a list of active channels, optionally matching the specified pattern. - /// http://redis.io/commands/pubsub - RedisChannel[] SubscriptionChannels(RedisChannel pattern = default(RedisChannel), CommandFlags flags = CommandFlags.None); - - /// - /// Lists the currently active channels. An active channel is a Pub/Sub channel with one ore more subscribers (not including clients subscribed to patterns). - /// - /// a list of active channels, optionally matching the specified pattern. - /// http://redis.io/commands/pubsub - Task SubscriptionChannelsAsync(RedisChannel pattern = default(RedisChannel), CommandFlags flags = CommandFlags.None); - - /// - /// Returns the number of subscriptions to patterns (that are performed using the PSUBSCRIBE command). Note that this is not just the count of clients subscribed to patterns but the total number of patterns all the clients are subscribed to. - /// - /// the number of patterns all the clients are subscribed to. - /// http://redis.io/commands/pubsub - long SubscriptionPatternCount(CommandFlags flags = CommandFlags.None); - - /// - /// Returns the number of subscriptions to patterns (that are performed using the PSUBSCRIBE command). Note that this is not just the count of clients subscribed to patterns but the total number of patterns all the clients are subscribed to. - /// - /// the number of patterns all the clients are subscribed to. - /// http://redis.io/commands/pubsub - Task SubscriptionPatternCountAsync(CommandFlags flags = CommandFlags.None); - - /// - /// Returns the number of subscribers (not counting clients subscribed to patterns) for the specified channel. - /// - /// http://redis.io/commands/pubsub - long SubscriptionSubscriberCount(RedisChannel channel, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the number of subscribers (not counting clients subscribed to patterns) for the specified channel. - /// - /// http://redis.io/commands/pubsub - Task SubscriptionSubscriberCountAsync(RedisChannel channel, CommandFlags flags = CommandFlags.None); - - /// - /// The TIME command returns the current server time. - /// - /// The server's current time. - /// http://redis.io/commands/time - DateTime Time(CommandFlags flags = CommandFlags.None); - /// - /// The TIME command returns the current server time. - /// - /// The server's current time. - /// http://redis.io/commands/time - Task TimeAsync(CommandFlags flags = CommandFlags.None); - - #region Sentinel - - /// - /// Returns the ip and port number of the master with that name. - /// If a failover is in progress or terminated successfully for this master it returns the address and port of the promoted slave. - /// - /// the sentinel service name - /// - /// the master ip and port - /// http://redis.io/topics/sentinel - EndPoint SentinelGetMasterAddressByName(string serviceName, CommandFlags flags = CommandFlags.None); - - /// - /// Returns the ip and port number of the master with that name. - /// If a failover is in progress or terminated successfully for this master it returns the address and port of the promoted slave. - /// - /// the sentinel service name - /// - /// the master ip and port - /// http://redis.io/topics/sentinel - Task SentinelGetMasterAddressByNameAsync(string serviceName, CommandFlags flags = CommandFlags.None); - - /// - /// Show the state and info of the specified master. - /// - /// the sentinel service name - /// - /// the master state as KeyValuePairs - /// http://redis.io/topics/sentinel - KeyValuePair[] SentinelMaster(string serviceName, CommandFlags flags = CommandFlags.None); - - /// - /// Force a failover as if the master was not reachable, and without asking for agreement to other Sentinels - /// (however a new version of the configuration will be published so that the other Sentinels will update their configurations). - /// - /// the sentinel service name - /// - /// the master state as KeyValuePairs - /// http://redis.io/topics/sentinel - Task[]> SentinelMasterAsync(string serviceName, CommandFlags flags = CommandFlags.None); - - /// - /// Show a list of monitored masters and their state. - /// - /// - /// an array of master state KeyValuePair arrays - /// http://redis.io/topics/sentinel - KeyValuePair[][] SentinelMasters(CommandFlags flags = CommandFlags.None); - - /// - /// Show a list of monitored masters and their state. - /// - /// - /// an array of master state KeyValuePair arrays - /// http://redis.io/topics/sentinel - Task[][]> SentinelMastersAsync(CommandFlags flags = CommandFlags.None); - - /// - /// Show a list of slaves for this master, and their state. - /// - /// the sentinel service name - /// - /// an array of slave state KeyValuePair arrays - /// http://redis.io/topics/sentinel - KeyValuePair[][] SentinelSlaves(string serviceName, CommandFlags flags = CommandFlags.None); - - /// - /// Show a list of slaves for this master, and their state. - /// - /// the sentinel service name - /// - /// an array of slave state KeyValuePair arrays - /// http://redis.io/topics/sentinel - Task[][]> SentinelSlavesAsync(string serviceName, CommandFlags flags = CommandFlags.None); - - /// - /// Force a failover as if the master was not reachable, and without asking for agreement to other Sentinels - /// (however a new version of the configuration will be published so that the other Sentinels will update their configurations). - /// - /// the sentinel service name - /// - /// http://redis.io/topics/sentinel - void SentinelFailover(string serviceName, CommandFlags flags = CommandFlags.None); - - /// - /// Force a failover as if the master was not reachable, and without asking for agreement to other Sentinels - /// (however a new version of the configuration will be published so that the other Sentinels will update their configurations). - /// - /// the sentinel service name - /// - /// http://redis.io/topics/sentinel - Task SentinelFailoverAsync(string serviceName, CommandFlags flags = CommandFlags.None); - - #endregion - } - - - -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ISubscriber.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ISubscriber.cs deleted file mode 100644 index a03f56b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ISubscriber.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Net; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - /// - /// A redis connection used as the subscriber in a pub/sub scenario - /// - public interface ISubscriber : IRedis - { - - /// - /// Inidicate exactly which redis server we are talking to - /// - [IgnoreNamePrefix] - EndPoint IdentifyEndpoint(RedisChannel channel, CommandFlags flags = CommandFlags.None); - - /// - /// Inidicate exactly which redis server we are talking to - /// - [IgnoreNamePrefix] - Task IdentifyEndpointAsync(RedisChannel channel, CommandFlags flags = CommandFlags.None); - - /// - /// Indicates whether the instance can communicate with the server; - /// if a channel is specified, the existing subscription map is queried to - /// resolve the server responsible for that subscription - otherwise the - /// server is chosen aribtraily from the masters. - /// - bool IsConnected(RedisChannel channel = default(RedisChannel)); - - /// - /// Posts a message to the given channel. - /// - /// the number of clients that received the message. - /// http://redis.io/commands/publish - long Publish(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None); - /// - /// Posts a message to the given channel. - /// - /// the number of clients that received the message. - /// http://redis.io/commands/publish - Task PublishAsync(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None); - /// - /// Subscribe to perform some operation when a change to the preferred/active node is broadcast. - /// - /// http://redis.io/commands/subscribe - /// http://redis.io/commands/psubscribe - void Subscribe(RedisChannel channel, Action handler, CommandFlags flags = CommandFlags.None); - - /// - /// Subscribe to perform some operation when a change to the preferred/active node is broadcast. - /// - /// http://redis.io/commands/subscribe - /// http://redis.io/commands/psubscribe - Task SubscribeAsync(RedisChannel channel, Action handler, CommandFlags flags = CommandFlags.None); - - /// - /// Inidicate to which redis server we are actively subscribed for a given channel; returns null if - /// the channel is not actively subscribed - /// - [IgnoreNamePrefix] - EndPoint SubscribedEndpoint(RedisChannel channel); - - /// - /// Unsubscribe from a specified message channel; note; if no handler is specified, the subscription is cancelled regardless - /// of the subscribers; if a handler is specified, the subscription is only cancelled if this handler is the - /// last handler remaining against the channel - /// - /// http://redis.io/commands/unsubscribe - /// http://redis.io/commands/punsubscribe - void Unsubscribe(RedisChannel channel, Action handler = null, CommandFlags flags = CommandFlags.None); - - /// - /// Unsubscribe all subscriptions on this instance - /// - /// http://redis.io/commands/unsubscribe - /// http://redis.io/commands/punsubscribe - void UnsubscribeAll(CommandFlags flags = CommandFlags.None); - - /// - /// Unsubscribe all subscriptions on this instance - /// - /// http://redis.io/commands/unsubscribe - /// http://redis.io/commands/punsubscribe - Task UnsubscribeAllAsync(CommandFlags flags = CommandFlags.None); - - /// - /// Unsubscribe from a specified message channel; note; if no handler is specified, the subscription is cancelled regardless - /// of the subscribers; if a handler is specified, the subscription is only cancelled if this handler is the - /// last handler remaining against the channel - /// - /// http://redis.io/commands/unsubscribe - /// http://redis.io/commands/punsubscribe - Task UnsubscribeAsync(RedisChannel channel, Action handler = null, CommandFlags flags = CommandFlags.None); - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ITransaction.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ITransaction.cs deleted file mode 100644 index cf46345..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ITransaction.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - /// - /// Represents a group of operations that will be sent to the server as a single unit, - /// and processed on the server as a single unit. Transactions can also include constraints - /// (implemented via WATCH), but note that constraint checking involves will (very briefly) - /// block the connection, since the transaction cannot be correctly committed (EXEC), - /// aborted (DISCARD) or not applied in the first place (UNWATCH) until the responses from - /// the constraint checks have arrived. - /// - /// http://redis.io/topics/transactions - /// Note that on a cluster, it may be required that all keys involved in the transaction - /// (including constraints) are in the same hash-slot - public interface ITransaction : IBatch - { - /// - /// Adds a precondition for this transaction - /// - ConditionResult AddCondition(Condition condition); - - /// - /// Execute the batch operation, sending all queued commands to the server. - /// - bool Execute(CommandFlags flags = CommandFlags.None); - - /// - /// Execute the batch operation, sending all queued commands to the server. - /// - Task ExecuteAsync(CommandFlags flags = CommandFlags.None); - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/InternalErrorEventArgs.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/InternalErrorEventArgs.cs deleted file mode 100644 index 633fd1e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/InternalErrorEventArgs.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Net; -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Describes internal errors (mainly intended for debugging) - /// - public class InternalErrorEventArgs : EventArgs, ICompletable - { - private readonly EventHandler handler; - private readonly object sender; - internal InternalErrorEventArgs(EventHandler handler, object sender, EndPoint endpoint, ConnectionType connectionType, Exception exception, string origin) - { - this.handler = handler; - this.sender = sender; - EndPoint = endpoint; - ConnectionType = connectionType; - Exception = exception; - Origin = origin; - } - /// - /// Gets the connection-type of the failing connection - /// - public ConnectionType ConnectionType { get; } - - /// - /// Gets the failing server-endpoint (this can be null) - /// - public EndPoint EndPoint { get; } - - /// - /// Gets the exception if available (this can be null) - /// - public Exception Exception { get; } - - /// - /// The underlying origin of the error - /// - public string Origin { get; } - - void ICompletable.AppendStormLog(StringBuilder sb) - { - sb.Append("event, internal-error: ").Append(Origin); - if (EndPoint != null) sb.Append(", ").Append(Format.ToString(EndPoint)); - } - - bool ICompletable.TryComplete(bool isAsync) - { - return ConnectionMultiplexer.TryCompleteHandler(handler, sender, this, isAsync); - } - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/BatchWrapper.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/BatchWrapper.cs deleted file mode 100644 index b551f18..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/BatchWrapper.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace StackExchange.Redis.KeyspaceIsolation -{ - internal sealed class BatchWrapper : WrapperBase, IBatch - { - public BatchWrapper(IBatch inner, byte[] prefix) : base(inner, prefix) - { - } - - public void Execute() - { - Inner.Execute(); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/DatabaseExtension.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/DatabaseExtension.cs deleted file mode 100644 index 9bcfb9d..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/DatabaseExtension.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; - -namespace StackExchange.Redis.KeyspaceIsolation -{ - /// - /// Provides the extension method to . - /// - public static class DatabaseExtensions - { - /// - /// Creates a new instance that provides an isolated key space - /// of the specified underyling database instance. - /// - /// - /// The underlying database instance that the returned instance shall use. - /// - /// - /// The prefix that defines a key space isolation for the returned database instance. - /// - /// - /// A new instance that invokes the specified underlying - /// but prepends the specified - /// to all key paramters and thus forms a logical key space isolation. - /// - /// - /// - /// The following methods are not supported in a key space isolated database and - /// will throw an when invoked: - /// - /// - /// - /// - /// - /// - /// Please notice that keys passed to a script are prefixed (as normal) but care must - /// be taken when a script returns the name of a key as that will (currently) not be - /// "unprefixed". - /// - /// - public static IDatabase WithKeyPrefix(this IDatabase database, RedisKey keyPrefix) - { - if (database == null) - { - throw new ArgumentNullException(nameof(database)); - } - - if (keyPrefix.IsNull) - { - throw new ArgumentNullException(nameof(keyPrefix)); - } - - if (keyPrefix.IsEmpty) - { - return database; // fine - you can keep using the original, then - } - - if(database is DatabaseWrapper) - { - // combine the key in advance to minimize indirection - var wrapper = (DatabaseWrapper)database; - keyPrefix = wrapper.ToInner(keyPrefix); - database = wrapper.Inner; - } - - return new DatabaseWrapper(database, keyPrefix.AsPrefix()); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/DatabaseWrapper.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/DatabaseWrapper.cs deleted file mode 100644 index 114f96c..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/DatabaseWrapper.cs +++ /dev/null @@ -1,731 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; - -namespace StackExchange.Redis.KeyspaceIsolation -{ - internal sealed class DatabaseWrapper : WrapperBase, IDatabase - { - public DatabaseWrapper(IDatabase inner, byte[] prefix) : base(inner, prefix) - { - } - - public IBatch CreateBatch(object asyncState = null) - { - return new BatchWrapper(Inner.CreateBatch(asyncState), Prefix); - } - - public ITransaction CreateTransaction(object asyncState = null) - { - return new TransactionWrapper(Inner.CreateTransaction(asyncState), Prefix); - } - - public int Database => Inner.Database; - - public RedisValue DebugObject(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.DebugObject(ToInner(key), flags); - } - - public bool GeoAdd(RedisKey key, double longitude, double latitude, RedisValue member, CommandFlags flags = CommandFlags.None) - { - return Inner.GeoAdd(ToInner(key), longitude, latitude, member, flags); - } - - public long GeoAdd(RedisKey key, GeoEntry[] geoEntries, CommandFlags flags = CommandFlags.None) - { - return Inner.GeoAdd(ToInner(key), geoEntries, flags); - } - public bool GeoAdd(RedisKey key, GeoEntry geoEntry, CommandFlags flags = CommandFlags.None) - { - return Inner.GeoAdd(ToInner(key), geoEntry, flags); - } - - public bool GeoRemove(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - return Inner.GeoRemove(ToInner(key), member, flags); - } - - public double? GeoDistance(RedisKey key, RedisValue value0, RedisValue value1, GeoUnit unit = GeoUnit.Meters,CommandFlags flags = CommandFlags.None) - { - return Inner.GeoDistance(ToInner(key), value0, value1, unit, flags); - } - - public string[] GeoHash(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) - { - return Inner.GeoHash(ToInner(key), members, flags); - } - - public string GeoHash(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - return Inner.GeoHash(ToInner(key), member, flags); - } - - public GeoPosition?[] GeoPosition(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) - { - return Inner.GeoPosition(ToInner(key), members, flags); - } - - public GeoPosition? GeoPosition(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - return Inner.GeoPosition(ToInner(key), member, flags); - } - - public GeoRadiusResult[] GeoRadius(RedisKey key, RedisValue member, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null,GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None) - { - return Inner.GeoRadius(ToInner(key), member, radius, unit, count, order, options, flags); - } - public GeoRadiusResult[] GeoRadius(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None) - { - return Inner.GeoRadius(ToInner(key), longitude, latitude, radius, unit, count, order, options, flags); - } - - public double HashDecrement(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None) - { - return Inner.HashDecrement(ToInner(key), hashField, value, flags); - } - - public long HashDecrement(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None) - { - return Inner.HashDecrement(ToInner(key), hashField, value, flags); - } - - public long HashDelete(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None) - { - return Inner.HashDelete(ToInner(key), hashFields, flags); - } - - public bool HashDelete(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) - { - return Inner.HashDelete(ToInner(key), hashField, flags); - } - - public bool HashExists(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) - { - return Inner.HashExists(ToInner(key), hashField, flags); - } - - public HashEntry[] HashGetAll(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.HashGetAll(ToInner(key), flags); - } - - public RedisValue[] HashGet(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None) - { - return Inner.HashGet(ToInner(key), hashFields, flags); - } - - public RedisValue HashGet(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) - { - return Inner.HashGet(ToInner(key), hashField, flags); - } - - public double HashIncrement(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None) - { - return Inner.HashIncrement(ToInner(key), hashField, value, flags); - } - - public long HashIncrement(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None) - { - return Inner.HashIncrement(ToInner(key), hashField, value, flags); - } - - public RedisValue[] HashKeys(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.HashKeys(ToInner(key), flags); - } - - public long HashLength(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.HashLength(ToInner(key), flags); - } - - public bool HashSet(RedisKey key, RedisValue hashField, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.HashSet(ToInner(key), hashField, value, when, flags); - } - - public void HashSet(RedisKey key, HashEntry[] hashFields, CommandFlags flags = CommandFlags.None) - { - Inner.HashSet(ToInner(key), hashFields, flags); - } - - public RedisValue[] HashValues(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.HashValues(ToInner(key), flags); - } - - public bool HyperLogLogAdd(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - return Inner.HyperLogLogAdd(ToInner(key), values, flags); - } - - public bool HyperLogLogAdd(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.HyperLogLogAdd(ToInner(key), value, flags); - } - - public long HyperLogLogLength(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.HyperLogLogLength(ToInner(key), flags); - } - - public long HyperLogLogLength(RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - return Inner.HyperLogLogLength(ToInner(keys), flags); - } - - public void HyperLogLogMerge(RedisKey destination, RedisKey[] sourceKeys, CommandFlags flags = CommandFlags.None) - { - Inner.HyperLogLogMerge(ToInner(destination), ToInner(sourceKeys), flags); - } - - public void HyperLogLogMerge(RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - Inner.HyperLogLogMerge(ToInner(destination), ToInner(first), ToInner(second), flags); - } - - public EndPoint IdentifyEndpoint(RedisKey key = default(RedisKey), CommandFlags flags = CommandFlags.None) - { - return Inner.IdentifyEndpoint(ToInner(key), flags); - } - - public long KeyDelete(RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyDelete(ToInner(keys), flags); - } - - public bool KeyDelete(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyDelete(ToInner(key), flags); - } - - public byte[] KeyDump(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyDump(ToInner(key), flags); - } - - public bool KeyExists(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyExists(ToInner(key), flags); - } - - public bool KeyExpire(RedisKey key, DateTime? expiry, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyExpire(ToInner(key), expiry, flags); - } - - public bool KeyExpire(RedisKey key, TimeSpan? expiry, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyExpire(ToInner(key), expiry, flags); - } - - public void KeyMigrate(RedisKey key, EndPoint toServer, int toDatabase = 0, int timeoutMilliseconds = 0, MigrateOptions migrateOptions = MigrateOptions.None, CommandFlags flags = CommandFlags.None) - { - Inner.KeyMigrate(ToInner(key), toServer, toDatabase, timeoutMilliseconds, migrateOptions, flags); - } - - public bool KeyMove(RedisKey key, int database, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyMove(ToInner(key), database, flags); - } - - public bool KeyPersist(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyPersist(ToInner(key), flags); - } - - public RedisKey KeyRandom(CommandFlags flags = CommandFlags.None) - { - throw new NotSupportedException("RANDOMKEY is not supported when a key-prefix is specified"); - } - - public bool KeyRename(RedisKey key, RedisKey newKey, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyRename(ToInner(key), ToInner(newKey), when, flags); - } - - public void KeyRestore(RedisKey key, byte[] value, TimeSpan? expiry = null, CommandFlags flags = CommandFlags.None) - { - Inner.KeyRestore(ToInner(key), value, expiry, flags); - } - - public TimeSpan? KeyTimeToLive(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyTimeToLive(ToInner(key), flags); - } - - public RedisType KeyType(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyType(ToInner(key), flags); - } - - public RedisValue ListGetByIndex(RedisKey key, long index, CommandFlags flags = CommandFlags.None) - { - return Inner.ListGetByIndex(ToInner(key), index, flags); - } - - public long ListInsertAfter(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.ListInsertAfter(ToInner(key), pivot, value, flags); - } - - public long ListInsertBefore(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.ListInsertBefore(ToInner(key), pivot, value, flags); - } - - public RedisValue ListLeftPop(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.ListLeftPop(ToInner(key), flags); - } - - public long ListLeftPush(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - return Inner.ListLeftPush(ToInner(key), values, flags); - } - - public long ListLeftPush(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.ListLeftPush(ToInner(key), value, when, flags); - } - - public long ListLength(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.ListLength(ToInner(key), flags); - } - - public RedisValue[] ListRange(RedisKey key, long start = 0, long stop = -1, CommandFlags flags = CommandFlags.None) - { - return Inner.ListRange(ToInner(key), start, stop, flags); - } - - public long ListRemove(RedisKey key, RedisValue value, long count = 0, CommandFlags flags = CommandFlags.None) - { - return Inner.ListRemove(ToInner(key), value, count, flags); - } - - public RedisValue ListRightPop(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.ListRightPop(ToInner(key), flags); - } - - public RedisValue ListRightPopLeftPush(RedisKey source, RedisKey destination, CommandFlags flags = CommandFlags.None) - { - return Inner.ListRightPopLeftPush(ToInner(source), ToInner(destination), flags); - } - - public long ListRightPush(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - return Inner.ListRightPush(ToInner(key), values, flags); - } - - public long ListRightPush(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.ListRightPush(ToInner(key), value, when, flags); - } - - public void ListSetByIndex(RedisKey key, long index, RedisValue value, CommandFlags flags = CommandFlags.None) - { - Inner.ListSetByIndex(ToInner(key), index, value, flags); - } - - public void ListTrim(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None) - { - Inner.ListTrim(ToInner(key), start, stop, flags); - } - - public bool LockExtend(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None) - { - return Inner.LockExtend(ToInner(key), value, expiry, flags); - } - - public RedisValue LockQuery(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.LockQuery(ToInner(key), flags); - } - - public bool LockRelease(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.LockRelease(ToInner(key), value, flags); - } - - public bool LockTake(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None) - { - return Inner.LockTake(ToInner(key), value, expiry, flags); - } - - public long Publish(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None) - { - return Inner.Publish(ToInner(channel), message, flags); - } - - public RedisResult Execute(string command, params object[] args) - => Inner.Execute(command, ToInner(args), CommandFlags.None); - - public RedisResult Execute(string command, ICollection args, CommandFlags flags = CommandFlags.None) - => Inner.Execute(command, ToInner(args), flags); - - public RedisResult ScriptEvaluate(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None) - { - // TODO: The return value could contain prefixed keys. It might make sense to 'unprefix' those? - return Inner.ScriptEvaluate(hash, ToInner(keys), values, flags); - } - - public RedisResult ScriptEvaluate(string script, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None) - { - // TODO: The return value could contain prefixed keys. It might make sense to 'unprefix' those? - return Inner.ScriptEvaluate(script, ToInner(keys), values, flags); - } - - public RedisResult ScriptEvaluate(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None) - { - // TODO: The return value could contain prefixed keys. It might make sense to 'unprefix' those? - return script.Evaluate(Inner, parameters, Prefix, flags); - } - - public RedisResult ScriptEvaluate(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None) - { - // TODO: The return value could contain prefixed keys. It might make sense to 'unprefix' those? - return script.Evaluate(Inner, parameters, Prefix, flags); - } - - public long SetAdd(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - return Inner.SetAdd(ToInner(key), values, flags); - } - - public bool SetAdd(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.SetAdd(ToInner(key), value, flags); - } - - public long SetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - return Inner.SetCombineAndStore(operation, ToInner(destination), ToInner(keys), flags); - } - - public long SetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - return Inner.SetCombineAndStore(operation, ToInner(destination), ToInner(first), ToInner(second), flags); - } - - public RedisValue[] SetCombine(SetOperation operation, RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - return Inner.SetCombine(operation, ToInner(keys), flags); - } - - public RedisValue[] SetCombine(SetOperation operation, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - return Inner.SetCombine(operation, ToInner(first), ToInner(second), flags); - } - - public bool SetContains(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.SetContains(ToInner(key), value, flags); - } - - public long SetLength(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.SetLength(ToInner(key), flags); - } - - public RedisValue[] SetMembers(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.SetMembers(ToInner(key), flags); - } - - public bool SetMove(RedisKey source, RedisKey destination, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.SetMove(ToInner(source), ToInner(destination), value, flags); - } - - public RedisValue SetPop(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.SetPop(ToInner(key), flags); - } - - public RedisValue SetRandomMember(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.SetRandomMember(ToInner(key), flags); - } - - public RedisValue[] SetRandomMembers(RedisKey key, long count, CommandFlags flags = CommandFlags.None) - { - return Inner.SetRandomMembers(ToInner(key), count, flags); - } - - public long SetRemove(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - return Inner.SetRemove(ToInner(key), values, flags); - } - - public bool SetRemove(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.SetRemove(ToInner(key), value, flags); - } - - public long SortAndStore(RedisKey destination, RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None) - { - return Inner.SortAndStore(ToInner(destination), ToInner(key), skip, take, order, sortType, SortByToInner(by), SortGetToInner(get), flags); - } - - public RedisValue[] Sort(RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None) - { - return Inner.Sort(ToInner(key), skip, take, order, sortType, SortByToInner(by), SortGetToInner(get), flags); - } - public long SortedSetAdd(RedisKey key, SortedSetEntry[] values, CommandFlags flags) - { - return Inner.SortedSetAdd(ToInner(key), values, flags); - } - public long SortedSetAdd(RedisKey key, SortedSetEntry[] values, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetAdd(ToInner(key), values, when, flags); - } - - public bool SortedSetAdd(RedisKey key, RedisValue member, double score, CommandFlags flags) - { - return Inner.SortedSetAdd(ToInner(key), member, score, flags); - } - public bool SortedSetAdd(RedisKey key, RedisValue member, double score, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetAdd(ToInner(key), member, score, when, flags); - } - - public long SortedSetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey[] keys, double[] weights = null, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetCombineAndStore(operation, ToInner(destination), ToInner(keys), weights, aggregate, flags); - } - - public long SortedSetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetCombineAndStore(operation, ToInner(destination), ToInner(first), ToInner(second), aggregate, flags); - } - - public double SortedSetDecrement(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetDecrement(ToInner(key), member, value, flags); - } - - public double SortedSetIncrement(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetIncrement(ToInner(key), member, value, flags); - } - - public long SortedSetLength(RedisKey key, double min = -1.0 / 0.0, double max = 1.0 / 0.0, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetLength(ToInner(key), min, max, exclude, flags); - } - - public long SortedSetLengthByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetLengthByValue(ToInner(key), min, max, exclude, flags); - } - - public RedisValue[] SortedSetRangeByRank(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRangeByRank(ToInner(key), start, stop, order, flags); - } - - public SortedSetEntry[] SortedSetRangeByRankWithScores(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRangeByRankWithScores(ToInner(key), start, stop, order, flags); - } - - public RedisValue[] SortedSetRangeByScore(RedisKey key, double start = -1.0 / 0.0, double stop = 1.0 / 0.0, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRangeByScore(ToInner(key), start, stop, exclude, order, skip, take, flags); - } - - public SortedSetEntry[] SortedSetRangeByScoreWithScores(RedisKey key, double start = -1.0 / 0.0, double stop = 1.0 / 0.0, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRangeByScoreWithScores(ToInner(key), start, stop, exclude, order, skip, take, flags); - } - - public RedisValue[] SortedSetRangeByValue(RedisKey key, RedisValue min = default(RedisValue), RedisValue max = default(RedisValue), Exclude exclude = Exclude.None, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRangeByValue(ToInner(key), min, max, exclude, skip, take, flags); - } - - public long? SortedSetRank(RedisKey key, RedisValue member, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRank(ToInner(key), member, order, flags); - } - - public long SortedSetRemove(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRemove(ToInner(key), members, flags); - } - - public bool SortedSetRemove(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRemove(ToInner(key), member, flags); - } - - public long SortedSetRemoveRangeByRank(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRemoveRangeByRank(ToInner(key), start, stop, flags); - } - - public long SortedSetRemoveRangeByScore(RedisKey key, double start, double stop, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRemoveRangeByScore(ToInner(key), start, stop, exclude, flags); - } - - public long SortedSetRemoveRangeByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRemoveRangeByValue(ToInner(key), min, max, exclude, flags); - } - - public double? SortedSetScore(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetScore(ToInner(key), member, flags); - } - - public long StringAppend(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.StringAppend(ToInner(key), value, flags); - } - - public long StringBitCount(RedisKey key, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None) - { - return Inner.StringBitCount(ToInner(key), start, end, flags); - } - - public long StringBitOperation(Bitwise operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - return Inner.StringBitOperation(operation, ToInner(destination), ToInner(keys), flags); - } - - public long StringBitOperation(Bitwise operation, RedisKey destination, RedisKey first, RedisKey second = default(RedisKey), CommandFlags flags = CommandFlags.None) - { - return Inner.StringBitOperation(operation, ToInner(destination), ToInner(first), ToInnerOrDefault(second), flags); - } - - public long StringBitPosition(RedisKey key, bool bit, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None) - { - return Inner.StringBitPosition(ToInner(key), bit, start, end, flags); - } - - public double StringDecrement(RedisKey key, double value, CommandFlags flags = CommandFlags.None) - { - return Inner.StringDecrement(ToInner(key), value, flags); - } - - public long StringDecrement(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None) - { - return Inner.StringDecrement(ToInner(key), value, flags); - } - - public RedisValue[] StringGet(RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - return Inner.StringGet(ToInner(keys), flags); - } - - public RedisValue StringGet(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.StringGet(ToInner(key), flags); - } - - public bool StringGetBit(RedisKey key, long offset, CommandFlags flags = CommandFlags.None) - { - return Inner.StringGetBit(ToInner(key), offset, flags); - } - - public RedisValue StringGetRange(RedisKey key, long start, long end, CommandFlags flags = CommandFlags.None) - { - return Inner.StringGetRange(ToInner(key), start, end, flags); - } - - public RedisValue StringGetSet(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.StringGetSet(ToInner(key), value, flags); - } - - public RedisValueWithExpiry StringGetWithExpiry(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.StringGetWithExpiry(ToInner(key), flags); - } - - public double StringIncrement(RedisKey key, double value, CommandFlags flags = CommandFlags.None) - { - return Inner.StringIncrement(ToInner(key), value, flags); - } - - public long StringIncrement(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None) - { - return Inner.StringIncrement(ToInner(key), value, flags); - } - - public long StringLength(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.StringLength(ToInner(key), flags); - } - - public bool StringSet(KeyValuePair[] values, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.StringSet(ToInner(values), when, flags); - } - - public bool StringSet(RedisKey key, RedisValue value, TimeSpan? expiry = null, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.StringSet(ToInner(key), value, expiry, when, flags); - } - - public bool StringSetBit(RedisKey key, long offset, bool bit, CommandFlags flags = CommandFlags.None) - { - return Inner.StringSetBit(ToInner(key), offset, bit, flags); - } - - public RedisValue StringSetRange(RedisKey key, long offset, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.StringSetRange(ToInner(key), offset, value, flags); - } - - public TimeSpan Ping(CommandFlags flags = CommandFlags.None) - { - return Inner.Ping(flags); - } - - - IEnumerable IDatabase.HashScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags) - { - return HashScan(key, pattern, pageSize, RedisBase.CursorUtils.Origin, 0, flags); - } - public IEnumerable HashScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisBase.CursorUtils.DefaultPageSize, long cursor = RedisBase.CursorUtils.Origin, int pageOffset = 0, CommandFlags flags = CommandFlags.None) - { - return Inner.HashScan(ToInner(key), pattern, pageSize, cursor, pageOffset, flags); - } - - IEnumerable IDatabase.SetScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags) - { - return SetScan(key, pattern, pageSize, RedisBase.CursorUtils.Origin, 0, flags); - } - public IEnumerable SetScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisBase.CursorUtils.DefaultPageSize, long cursor = RedisBase.CursorUtils.Origin, int pageOffset = 0, CommandFlags flags = CommandFlags.None) - { - return Inner.SetScan(ToInner(key), pattern, pageSize, cursor, pageOffset, flags); - } - - IEnumerable IDatabase.SortedSetScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags) - { - return SortedSetScan(key, pattern, pageSize, RedisBase.CursorUtils.Origin, 0, flags); - } - public IEnumerable SortedSetScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisBase.CursorUtils.DefaultPageSize, long cursor = RedisBase.CursorUtils.Origin, int pageOffset = 0, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetScan(ToInner(key), pattern, pageSize, cursor, pageOffset, flags); - } - - -#if DEBUG - public string ClientGetName(CommandFlags flags = CommandFlags.None) - { - return Inner.ClientGetName(flags); - } - - public void Quit(CommandFlags flags = CommandFlags.None) - { - Inner.Quit(flags); - } -#endif - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/TransactionWrapper.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/TransactionWrapper.cs deleted file mode 100644 index 2e941fd..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/TransactionWrapper.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Threading.Tasks; - -namespace StackExchange.Redis.KeyspaceIsolation -{ - internal sealed class TransactionWrapper : WrapperBase, ITransaction - { - public TransactionWrapper(ITransaction inner, byte[] prefix) : base(inner, prefix) - { - } - - public ConditionResult AddCondition(Condition condition) - { - return Inner.AddCondition(condition?.MapKeys(GetMapFunction())); - } - - public bool Execute(CommandFlags flags = CommandFlags.None) - { - return Inner.Execute(flags); - } - - public Task ExecuteAsync(CommandFlags flags = CommandFlags.None) - { - return Inner.ExecuteAsync(flags); - } - - public void Execute() - { - Inner.Execute(); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/WrapperBase.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/WrapperBase.cs deleted file mode 100644 index 6a70f67..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/KeyspaceIsolation/WrapperBase.cs +++ /dev/null @@ -1,845 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -namespace StackExchange.Redis.KeyspaceIsolation -{ - internal class WrapperBase : IDatabaseAsync where TInner : IDatabaseAsync - { - internal WrapperBase(TInner inner, byte[] keyPrefix) - { - Inner = inner; - Prefix = keyPrefix; - } - - public ConnectionMultiplexer Multiplexer => Inner.Multiplexer; - - internal TInner Inner { get; } - - internal byte[] Prefix { get; } - - public Task DebugObjectAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.DebugObjectAsync(ToInner(key), flags); - } - - public Task GeoAddAsync(RedisKey key, double longitude, double latitude, RedisValue member, CommandFlags flags = CommandFlags.None) - => Inner.GeoAddAsync(ToInner(key), longitude, latitude, member, flags); - - public Task GeoAddAsync(RedisKey key, StackExchange.Redis.GeoEntry value, CommandFlags flags = CommandFlags.None) - => Inner.GeoAddAsync(ToInner(key), value, flags); - - public Task GeoAddAsync(RedisKey key, StackExchange.Redis.GeoEntry[] values, CommandFlags flags = CommandFlags.None) - => Inner.GeoAddAsync(ToInner(key), values, flags); - - public Task GeoRemoveAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - => Inner.GeoRemoveAsync(ToInner(key), member, flags); - - public Task GeoDistanceAsync(RedisKey key, RedisValue member1, RedisValue member2, GeoUnit unit = GeoUnit.Meters, CommandFlags flags = CommandFlags.None) - => Inner.GeoDistanceAsync(ToInner(key), member1, member2, unit, flags); - - public Task GeoHashAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) - => Inner.GeoHashAsync(ToInner(key), members, flags); - - public Task GeoHashAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - => Inner.GeoHashAsync(ToInner(key), member, flags); - - - public Task GeoPositionAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) - => Inner.GeoPositionAsync(ToInner(key), members, flags); - - public Task GeoPositionAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - => Inner.GeoPositionAsync(ToInner(key), member, flags); - - public Task GeoRadiusAsync(RedisKey key, RedisValue member, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None) - => Inner.GeoRadiusAsync(ToInner(key), member, radius, unit, count, order, options, flags); - - public Task GeoRadiusAsync(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None) - => Inner.GeoRadiusAsync(ToInner(key), longitude, latitude, radius, unit, count, order, options, flags); - - - public Task HashDecrementAsync(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None) - { - return Inner.HashDecrementAsync(ToInner(key), hashField, value, flags); - } - - public Task HashDecrementAsync(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None) - { - return Inner.HashDecrementAsync(ToInner(key), hashField, value, flags); - } - - public Task HashDeleteAsync(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None) - { - return Inner.HashDeleteAsync(ToInner(key), hashFields, flags); - } - - public Task HashDeleteAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) - { - return Inner.HashDeleteAsync(ToInner(key), hashField, flags); - } - - public Task HashExistsAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) - { - return Inner.HashExistsAsync(ToInner(key), hashField, flags); - } - - public Task HashGetAllAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.HashGetAllAsync(ToInner(key), flags); - } - - public Task HashGetAsync(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None) - { - return Inner.HashGetAsync(ToInner(key), hashFields, flags); - } - - public Task HashGetAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) - { - return Inner.HashGetAsync(ToInner(key), hashField, flags); - } - - public Task HashIncrementAsync(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None) - { - return Inner.HashIncrementAsync(ToInner(key), hashField, value, flags); - } - - public Task HashIncrementAsync(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None) - { - return Inner.HashIncrementAsync(ToInner(key), hashField, value, flags); - } - - public Task HashKeysAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.HashKeysAsync(ToInner(key), flags); - } - - public Task HashLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.HashLengthAsync(ToInner(key), flags); - } - - public Task HashSetAsync(RedisKey key, RedisValue hashField, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.HashSetAsync(ToInner(key), hashField, value, when, flags); - } - - public Task HashSetAsync(RedisKey key, HashEntry[] hashFields, CommandFlags flags = CommandFlags.None) - { - return Inner.HashSetAsync(ToInner(key), hashFields, flags); - } - - public Task HashValuesAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.HashValuesAsync(ToInner(key), flags); - } - - public Task HyperLogLogAddAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - return Inner.HyperLogLogAddAsync(ToInner(key), values, flags); - } - - public Task HyperLogLogAddAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.HyperLogLogAddAsync(ToInner(key), value, flags); - } - - public Task HyperLogLogLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.HyperLogLogLengthAsync(ToInner(key), flags); - } - - public Task HyperLogLogLengthAsync(RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - return Inner.HyperLogLogLengthAsync(ToInner(keys), flags); - } - - public Task HyperLogLogMergeAsync(RedisKey destination, RedisKey[] sourceKeys, CommandFlags flags = CommandFlags.None) - { - return Inner.HyperLogLogMergeAsync(ToInner(destination), ToInner(sourceKeys), flags); - } - - public Task HyperLogLogMergeAsync(RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - return Inner.HyperLogLogMergeAsync(ToInner(destination), ToInner(first), ToInner(second), flags); - } - - public Task IdentifyEndpointAsync(RedisKey key = default(RedisKey), CommandFlags flags = CommandFlags.None) - { - return Inner.IdentifyEndpointAsync(ToInner(key), flags); - } - - public bool IsConnected(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.IsConnected(ToInner(key), flags); - } - - public Task KeyDeleteAsync(RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyDeleteAsync(ToInner(keys), flags); - } - - public Task KeyDeleteAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyDeleteAsync(ToInner(key), flags); - } - - public Task KeyDumpAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyDumpAsync(ToInner(key), flags); - } - - public Task KeyExistsAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyExistsAsync(ToInner(key), flags); - } - - public Task KeyExpireAsync(RedisKey key, DateTime? expiry, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyExpireAsync(ToInner(key), expiry, flags); - } - - public Task KeyExpireAsync(RedisKey key, TimeSpan? expiry, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyExpireAsync(ToInner(key), expiry, flags); - } - - public Task KeyMigrateAsync(RedisKey key, EndPoint toServer, int toDatabase = 0, int timeoutMilliseconds = 0, MigrateOptions migrateOptions = MigrateOptions.None, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyMigrateAsync(ToInner(key), toServer, toDatabase, timeoutMilliseconds, migrateOptions, flags); - } - - public Task KeyMoveAsync(RedisKey key, int database, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyMoveAsync(ToInner(key), database, flags); - } - - public Task KeyPersistAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyPersistAsync(ToInner(key), flags); - } - - public Task KeyRandomAsync(CommandFlags flags = CommandFlags.None) - { - throw new NotSupportedException("RANDOMKEY is not supported when a key-prefix is specified"); - } - - public Task KeyRenameAsync(RedisKey key, RedisKey newKey, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyRenameAsync(ToInner(key), ToInner(newKey), when, flags); - } - - public Task KeyRestoreAsync(RedisKey key, byte[] value, TimeSpan? expiry = null, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyRestoreAsync(ToInner(key), value, expiry, flags); - } - - public Task KeyTimeToLiveAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyTimeToLiveAsync(ToInner(key), flags); - } - - public Task KeyTypeAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.KeyTypeAsync(ToInner(key), flags); - } - - public Task ListGetByIndexAsync(RedisKey key, long index, CommandFlags flags = CommandFlags.None) - { - return Inner.ListGetByIndexAsync(ToInner(key), index, flags); - } - - public Task ListInsertAfterAsync(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.ListInsertAfterAsync(ToInner(key), pivot, value, flags); - } - - public Task ListInsertBeforeAsync(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.ListInsertBeforeAsync(ToInner(key), pivot, value, flags); - } - - public Task ListLeftPopAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.ListLeftPopAsync(ToInner(key), flags); - } - - public Task ListLeftPushAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - return Inner.ListLeftPushAsync(ToInner(key), values, flags); - } - - public Task ListLeftPushAsync(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.ListLeftPushAsync(ToInner(key), value, when, flags); - } - - public Task ListLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.ListLengthAsync(ToInner(key), flags); - } - - public Task ListRangeAsync(RedisKey key, long start = 0, long stop = -1, CommandFlags flags = CommandFlags.None) - { - return Inner.ListRangeAsync(ToInner(key), start, stop, flags); - } - - public Task ListRemoveAsync(RedisKey key, RedisValue value, long count = 0, CommandFlags flags = CommandFlags.None) - { - return Inner.ListRemoveAsync(ToInner(key), value, count, flags); - } - - public Task ListRightPopAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.ListRightPopAsync(ToInner(key), flags); - } - - public Task ListRightPopLeftPushAsync(RedisKey source, RedisKey destination, CommandFlags flags = CommandFlags.None) - { - return Inner.ListRightPopLeftPushAsync(ToInner(source), ToInner(destination), flags); - } - - public Task ListRightPushAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - return Inner.ListRightPushAsync(ToInner(key), values, flags); - } - - public Task ListRightPushAsync(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.ListRightPushAsync(ToInner(key), value, when, flags); - } - - public Task ListSetByIndexAsync(RedisKey key, long index, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.ListSetByIndexAsync(ToInner(key), index, value, flags); - } - - public Task ListTrimAsync(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None) - { - return Inner.ListTrimAsync(ToInner(key), start, stop, flags); - } - - public Task LockExtendAsync(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None) - { - return Inner.LockExtendAsync(ToInner(key), value, expiry, flags); - } - - public Task LockQueryAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.LockQueryAsync(ToInner(key), flags); - } - - public Task LockReleaseAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.LockReleaseAsync(ToInner(key), value, flags); - } - - public Task LockTakeAsync(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None) - { - return Inner.LockTakeAsync(ToInner(key), value, expiry, flags); - } - - public Task PublishAsync(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None) - { - return Inner.PublishAsync(ToInner(channel), message, flags); - } - public Task ExecuteAsync(string command, params object[] args) - => Inner.ExecuteAsync(command, ToInner(args), CommandFlags.None); - public Task ExecuteAsync(string command, ICollection args, CommandFlags flags = CommandFlags.None) - => Inner.ExecuteAsync(command, ToInner(args), flags); - - public Task ScriptEvaluateAsync(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None) - { - // TODO: The return value could contain prefixed keys. It might make sense to 'unprefix' those? - return Inner.ScriptEvaluateAsync(hash, ToInner(keys), values, flags); - } - - public Task ScriptEvaluateAsync(string script, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None) - { - // TODO: The return value could contain prefixed keys. It might make sense to 'unprefix' those? - return Inner.ScriptEvaluateAsync(script, ToInner(keys), values, flags); - } - - public Task ScriptEvaluateAsync(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None) - { - return Inner.ScriptEvaluateAsync(script, parameters, flags); - } - - public Task ScriptEvaluateAsync(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None) - { - return Inner.ScriptEvaluateAsync(script, parameters, flags); - } - - public Task SetAddAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - return Inner.SetAddAsync(ToInner(key), values, flags); - } - - public Task SetAddAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.SetAddAsync(ToInner(key), value, flags); - } - - public Task SetCombineAndStoreAsync(SetOperation operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - return Inner.SetCombineAndStoreAsync(operation, ToInner(destination), ToInner(keys), flags); - } - - public Task SetCombineAndStoreAsync(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - return Inner.SetCombineAndStoreAsync(operation, ToInner(destination), ToInner(first), ToInner(second), flags); - } - - public Task SetCombineAsync(SetOperation operation, RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - return Inner.SetCombineAsync(operation, ToInner(keys), flags); - } - - public Task SetCombineAsync(SetOperation operation, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - return Inner.SetCombineAsync(operation, ToInner(first), ToInner(second), flags); - } - - public Task SetContainsAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.SetContainsAsync(ToInner(key), value, flags); - } - - public Task SetLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.SetLengthAsync(ToInner(key), flags); - } - - public Task SetMembersAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.SetMembersAsync(ToInner(key), flags); - } - - public Task SetMoveAsync(RedisKey source, RedisKey destination, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.SetMoveAsync(ToInner(source), ToInner(destination), value, flags); - } - - public Task SetPopAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.SetPopAsync(ToInner(key), flags); - } - - public Task SetRandomMemberAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.SetRandomMemberAsync(ToInner(key), flags); - } - - public Task SetRandomMembersAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None) - { - return Inner.SetRandomMembersAsync(ToInner(key), count, flags); - } - - public Task SetRemoveAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - return Inner.SetRemoveAsync(ToInner(key), values, flags); - } - - public Task SetRemoveAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.SetRemoveAsync(ToInner(key), value, flags); - } - - public Task SortAndStoreAsync(RedisKey destination, RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None) - { - return Inner.SortAndStoreAsync(ToInner(destination), ToInner(key), skip, take, order, sortType, SortByToInner(by), SortGetToInner(get), flags); - } - - public Task SortAsync(RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None) - { - return Inner.SortAsync(ToInner(key), skip, take, order, sortType, SortByToInner(by), SortGetToInner(get), flags); - } - - public Task SortedSetAddAsync(RedisKey key, SortedSetEntry[] values, CommandFlags flags) - { - return Inner.SortedSetAddAsync(ToInner(key), values, flags); - } - public Task SortedSetAddAsync(RedisKey key, SortedSetEntry[] values, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetAddAsync(ToInner(key), values, when, flags); - } - - public Task SortedSetAddAsync(RedisKey key, RedisValue member, double score, CommandFlags flags) - { - return Inner.SortedSetAddAsync(ToInner(key), member, score, flags); - } - public Task SortedSetAddAsync(RedisKey key, RedisValue member, double score, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetAddAsync(ToInner(key), member, score, when, flags); - } - - public Task SortedSetCombineAndStoreAsync(SetOperation operation, RedisKey destination, RedisKey[] keys, double[] weights = null, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetCombineAndStoreAsync(operation, ToInner(destination), ToInner(keys), weights, aggregate, flags); - } - - public Task SortedSetCombineAndStoreAsync(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetCombineAndStoreAsync(operation, ToInner(destination), ToInner(first), ToInner(second), aggregate, flags); - } - - public Task SortedSetDecrementAsync(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetDecrementAsync(ToInner(key), member, value, flags); - } - - public Task SortedSetIncrementAsync(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetIncrementAsync(ToInner(key), member, value, flags); - } - - public Task SortedSetLengthAsync(RedisKey key, double min = -1.0 / 0.0, double max = 1.0 / 0.0, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetLengthAsync(ToInner(key), min, max, exclude, flags); - } - - public Task SortedSetLengthByValueAsync(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetLengthByValueAsync(ToInner(key), min, max, exclude, flags); - } - - public Task SortedSetRangeByRankAsync(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRangeByRankAsync(ToInner(key), start, stop, order, flags); - } - - public Task SortedSetRangeByRankWithScoresAsync(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRangeByRankWithScoresAsync(ToInner(key), start, stop, order, flags); - } - - public Task SortedSetRangeByScoreAsync(RedisKey key, double start = -1.0 / 0.0, double stop = 1.0 / 0.0, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRangeByScoreAsync(ToInner(key), start, stop, exclude, order, skip, take, flags); - } - - public Task SortedSetRangeByScoreWithScoresAsync(RedisKey key, double start = -1.0 / 0.0, double stop = 1.0 / 0.0, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRangeByScoreWithScoresAsync(ToInner(key), start, stop, exclude, order, skip, take, flags); - } - - public Task SortedSetRangeByValueAsync(RedisKey key, RedisValue min = default(RedisValue), RedisValue max = default(RedisValue), Exclude exclude = Exclude.None, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRangeByValueAsync(ToInner(key), min, max, exclude, skip, take, flags); - } - - public Task SortedSetRankAsync(RedisKey key, RedisValue member, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRankAsync(ToInner(key), member, order, flags); - } - - public Task SortedSetRemoveAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRemoveAsync(ToInner(key), members, flags); - } - - public Task SortedSetRemoveAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRemoveAsync(ToInner(key), member, flags); - } - - public Task SortedSetRemoveRangeByRankAsync(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRemoveRangeByRankAsync(ToInner(key), start, stop, flags); - } - - public Task SortedSetRemoveRangeByScoreAsync(RedisKey key, double start, double stop, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRemoveRangeByScoreAsync(ToInner(key), start, stop, exclude, flags); - } - - public Task SortedSetRemoveRangeByValueAsync(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetRemoveRangeByValueAsync(ToInner(key), min, max, exclude, flags); - } - - public Task SortedSetScoreAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - return Inner.SortedSetScoreAsync(ToInner(key), member, flags); - } - - public Task StringAppendAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.StringAppendAsync(ToInner(key), value, flags); - } - - public Task StringBitCountAsync(RedisKey key, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None) - { - return Inner.StringBitCountAsync(ToInner(key), start, end, flags); - } - - public Task StringBitOperationAsync(Bitwise operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - return Inner.StringBitOperationAsync(operation, ToInner(destination), ToInner(keys), flags); - } - - public Task StringBitOperationAsync(Bitwise operation, RedisKey destination, RedisKey first, RedisKey second = default(RedisKey), CommandFlags flags = CommandFlags.None) - { - return Inner.StringBitOperationAsync(operation, ToInner(destination), ToInner(first), ToInnerOrDefault(second), flags); - } - - public Task StringBitPositionAsync(RedisKey key, bool bit, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None) - { - return Inner.StringBitPositionAsync(ToInner(key), bit, start, end, flags); - } - - public Task StringDecrementAsync(RedisKey key, double value, CommandFlags flags = CommandFlags.None) - { - return Inner.StringDecrementAsync(ToInner(key), value, flags); - } - - public Task StringDecrementAsync(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None) - { - return Inner.StringDecrementAsync(ToInner(key), value, flags); - } - - public Task StringGetAsync(RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - return Inner.StringGetAsync(ToInner(keys), flags); - } - - public Task StringGetAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.StringGetAsync(ToInner(key), flags); - } - - public Task StringGetBitAsync(RedisKey key, long offset, CommandFlags flags = CommandFlags.None) - { - return Inner.StringGetBitAsync(ToInner(key), offset, flags); - } - - public Task StringGetRangeAsync(RedisKey key, long start, long end, CommandFlags flags = CommandFlags.None) - { - return Inner.StringGetRangeAsync(ToInner(key), start, end, flags); - } - - public Task StringGetSetAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.StringGetSetAsync(ToInner(key), value, flags); - } - - public Task StringGetWithExpiryAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.StringGetWithExpiryAsync(ToInner(key), flags); - } - - public Task StringIncrementAsync(RedisKey key, double value, CommandFlags flags = CommandFlags.None) - { - return Inner.StringIncrementAsync(ToInner(key), value, flags); - } - - public Task StringIncrementAsync(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None) - { - return Inner.StringIncrementAsync(ToInner(key), value, flags); - } - - public Task StringLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return Inner.StringLengthAsync(ToInner(key), flags); - } - - public Task StringSetAsync(KeyValuePair[] values, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.StringSetAsync(ToInner(values), when, flags); - } - - public Task StringSetAsync(RedisKey key, RedisValue value, TimeSpan? expiry = null, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - return Inner.StringSetAsync(ToInner(key), value, expiry, when, flags); - } - - public Task StringSetBitAsync(RedisKey key, long offset, bool bit, CommandFlags flags = CommandFlags.None) - { - return Inner.StringSetBitAsync(ToInner(key), offset, bit, flags); - } - - public Task StringSetRangeAsync(RedisKey key, long offset, RedisValue value, CommandFlags flags = CommandFlags.None) - { - return Inner.StringSetRangeAsync(ToInner(key), offset, value, flags); - } - - public Task PingAsync(CommandFlags flags = CommandFlags.None) - { - return Inner.PingAsync(flags); - } - - public bool TryWait(Task task) - { - return Inner.TryWait(task); - } - - public TResult Wait(Task task) - { - return Inner.Wait(task); - } - - public void Wait(Task task) - { - Inner.Wait(task); - } - - public void WaitAll(params Task[] tasks) - { - Inner.WaitAll(tasks); - } - -#if DEBUG - public Task ClientGetNameAsync(CommandFlags flags = CommandFlags.None) - { - return Inner.ClientGetNameAsync(flags); - } -#endif - - protected internal RedisKey ToInner(RedisKey outer) - { - return RedisKey.WithPrefix(Prefix, outer); - } - - protected RedisKey ToInnerOrDefault(RedisKey outer) - { - if (outer == default(RedisKey)) - { - return outer; - } - else - { - return ToInner(outer); - } - } - protected ICollection ToInner(ICollection args) - { - if (args != null && args.Any(x => x is RedisKey || x is RedisChannel)) - { - var withPrefix = new object[args.Count]; - int i = 0; - foreach(var oldArg in args) - { - object newArg; - if (oldArg is RedisKey) - { - newArg = ToInner((RedisKey)oldArg); - } - else if (oldArg is RedisChannel) - { - newArg = ToInner((RedisChannel)oldArg); - } - else - { - newArg = oldArg; - } - withPrefix[i++] = newArg; - } - args = withPrefix; - } - return args; - } - protected RedisKey[] ToInner(RedisKey[] outer) - { - if (outer == null || outer.Length == 0) - { - return outer; - } - else - { - RedisKey[] inner = new RedisKey[outer.Length]; - - for (int i = 0; i < outer.Length; ++i) - { - inner[i] = ToInner(outer[i]); - } - - return inner; - } - } - - protected KeyValuePair ToInner(KeyValuePair outer) - { - return new KeyValuePair(ToInner(outer.Key), outer.Value); - } - - protected KeyValuePair[] ToInner(KeyValuePair[] outer) - { - if (outer == null || outer.Length == 0) - { - return outer; - } - else - { - KeyValuePair[] inner = new KeyValuePair[outer.Length]; - - for (int i = 0; i < outer.Length; ++i) - { - inner[i] = ToInner(outer[i]); - } - - return inner; - } - } - - protected RedisValue ToInner(RedisValue outer) - { - return RedisKey.ConcatenateBytes(Prefix, null, (byte[])outer); - } - - protected RedisValue SortByToInner(RedisValue outer) - { - if (outer == "nosort") - { - return outer; - } - else - { - return ToInner(outer); - } - } - - protected RedisValue SortGetToInner(RedisValue outer) - { - if (outer == "#") - { - return outer; - } - else - { - return ToInner(outer); - } - } - - protected RedisValue[] SortGetToInner(RedisValue[] outer) - { - if (outer == null || outer.Length == 0) - { - return outer; - } - else - { - RedisValue[] inner = new RedisValue[outer.Length]; - - for (int i = 0; i < outer.Length; ++i) - { - inner[i] = SortGetToInner(outer[i]); - } - - return inner; - } - } - - protected RedisChannel ToInner(RedisChannel outer) - { - return RedisKey.ConcatenateBytes(Prefix, null, (byte[])outer); - } - - private Func mapFunction; - protected Func GetMapFunction() - { - // create as a delegate when first required, then re-use - return mapFunction ?? (mapFunction = new Func(ToInner)); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/LinearRetry.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/LinearRetry.cs deleted file mode 100644 index 80b9b24..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/LinearRetry.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - /// - /// Represents a retry policy that performs retries at a fixed interval. The retries are performed upto a maximum allowed time. - /// - public class LinearRetry : IReconnectRetryPolicy - { - private int maxRetryElapsedTimeAllowedMilliseconds; - - /// - /// Initializes a new instance using the specified maximum retry elapsed time allowed. - /// - /// maximum elapsed time in milliseconds to be allowed for it to perform retries - public LinearRetry(int maxRetryElapsedTimeAllowedMilliseconds) - { - this.maxRetryElapsedTimeAllowedMilliseconds = maxRetryElapsedTimeAllowedMilliseconds; - } - - /// - /// This method is called by the ConnectionMultiplexer to determine if a reconnect operation can be retried now. - /// - /// The number of times reconnect retries have already been made by the ConnectionMultiplexer while it was in the connecting state - /// Total elapsed time in milliseconds since the last reconnect retry was made - public bool ShouldRetry(long currentRetryCount, int timeElapsedMillisecondsSinceLastRetry) - { - return timeElapsedMillisecondsSinceLastRetry >= maxRetryElapsedTimeAllowedMilliseconds; - } - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/LoggingTextStream.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/LoggingTextStream.cs deleted file mode 100644 index 732a006..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/LoggingTextStream.cs +++ /dev/null @@ -1,141 +0,0 @@ -namespace StackExchange.Redis -{ -#if LOGOUTPUT - sealed class LoggingTextStream : Stream - { - [Conditional("VERBOSE")] - void Trace(string value, [CallerMemberName] string caller = null) - { - Debug.WriteLine(value, this.category + ":" + caller); - } - [Conditional("VERBOSE")] - void Trace(char value, [CallerMemberName] string caller = null) - { - Debug.WriteLine(value, this.category + ":" + caller); - } - - private readonly Stream stream, echo; - private readonly string category; - public LoggingTextStream(Stream stream, string category, Stream echo) - { - if (stream == null) throw new ArgumentNullException("stream"); - if (string.IsNullOrWhiteSpace(category)) category = GetType().Name; - this.stream = stream; - this.category = category; - this.echo = echo; - } - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - asyncBuffer = buffer; - asyncOffset = offset; - asyncCount = count; - return stream.BeginRead(buffer, offset, count, callback, state); - } - private volatile byte[] asyncBuffer; - private volatile int asyncOffset, asyncCount; - public override int EndRead(IAsyncResult asyncResult) - { - int bytes = stream.EndRead(asyncResult); - if (bytes <= 0) - { - Trace(""); - } - else - { - Trace(Encoding.UTF8.GetString(asyncBuffer, asyncOffset, asyncCount)); - } - return bytes; - } - public override bool CanRead { get { return stream.CanRead; } } - public override bool CanSeek { get { return stream.CanSeek; } } - public override bool CanWrite { get { return stream.CanWrite; } } - public override bool CanTimeout { get { return stream.CanTimeout; } } - public override long Length { get { return stream.Length; } } - public override long Position - { - get { return stream.Position; } - set { stream.Position = value; } - } - public override int ReadTimeout - { - get { return stream.ReadTimeout; } - set { stream.ReadTimeout = value; } - } - public override int WriteTimeout - { - get { return stream.WriteTimeout; } - set { stream.WriteTimeout = value; } - } - protected override void Dispose(bool disposing) - { - if (disposing) - { - stream.Dispose(); - if (echo != null) echo.Flush(); - } - base.Dispose(disposing); - } - public override void Close() - { - Trace("Close"); - stream.Close(); - if (echo != null) echo.Close(); - base.Close(); - } - public override void Flush() - { - Trace("Flush"); - stream.Flush(); - if (echo != null) echo.Flush(); - } - public override long Seek(long offset, SeekOrigin origin) - { - return stream.Seek(offset, origin); - } - public override void SetLength(long value) - { - stream.SetLength(value); - } - public override void WriteByte(byte value) - { - Trace((char)value); - stream.WriteByte(value); - if (echo != null) echo.WriteByte(value); - } - public override int ReadByte() - { - int value = stream.ReadByte(); - if(value < 0) - { - Trace(""); - } else - { - Trace((char)value); - } - return value; - } - public override int Read(byte[] buffer, int offset, int count) - { - int bytes = stream.Read(buffer, offset, count); - if(bytes <= 0) - { - Trace(""); - } - else - { - Trace(Encoding.UTF8.GetString(buffer, offset, bytes)); - } - return bytes; - } - public override void Write(byte[] buffer, int offset, int count) - { - if (count != 0) - { - Trace(Encoding.UTF8.GetString(buffer, offset, count)); - } - stream.Write(buffer, offset, count); - if (echo != null) echo.Write(buffer, offset, count); - } - } -#endif -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/LuaScript.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/LuaScript.cs deleted file mode 100644 index 6034eb5..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/LuaScript.cs +++ /dev/null @@ -1,284 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Concurrent; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - /// - /// Represents a Lua script that can be executed on Redis. - /// - /// Unlike normal Redis Lua scripts, LuaScript can have named parameters (prefixed by a @). - /// Public fields and properties of the passed in object are treated as parameters. - /// - /// Parameters of type RedisKey are sent to Redis as KEY (http://redis.io/commands/eval) in addition to arguments, - /// so as to play nicely with Redis Cluster. - /// - /// All members of this class are thread safe. - /// - public sealed class LuaScript - { - // Since the mapping of "script text" -> LuaScript doesn't depend on any particular details of - // the redis connection itself, this cache is global. - static readonly ConcurrentDictionary Cache = new ConcurrentDictionary(); - - /// - /// The original Lua script that was used to create this. - /// - public string OriginalScript { get; private set; } - - /// - /// The Lua script that will actually be sent to Redis for execution. - /// - /// All @-prefixed parameter names have been replaced at this point. - /// - public string ExecutableScript { get; private set; } - - // Arguments are in the order they have to passed to the script in - internal string[] Arguments { get; private set; } - - bool HasArguments => Arguments != null && Arguments.Length > 0; - - Hashtable ParameterMappers; - - internal LuaScript(string originalScript, string executableScript, string[] arguments) - { - OriginalScript = originalScript; - ExecutableScript = executableScript; - Arguments = arguments; - - if (HasArguments) - { - ParameterMappers = new Hashtable(); - } - } - - /// - /// Finalizer, used to prompt cleanups of the script cache when - /// a LuaScript reference goes out of scope. - /// - ~LuaScript() - { - try - { - WeakReference ignored; - Cache.TryRemove(OriginalScript, out ignored); - } - catch { } - } - - /// - /// Invalidates the internal cache of LuaScript objects. - /// Existing LuaScripts will continue to work, but future calls to LuaScript.Prepare - /// return a new LuaScript instance. - /// - public static void PurgeCache() - { - Cache.Clear(); - } - - /// - /// Returns the number of cached LuaScripts. - /// - public static int GetCachedScriptCount() - { - return Cache.Count; - } - - /// - /// Prepares a Lua script with named parameters to be run against any Redis instance. - /// - public static LuaScript Prepare(string script) - { - LuaScript ret; - - WeakReference weakRef; - if (!Cache.TryGetValue(script, out weakRef) || (ret = (LuaScript)weakRef.Target) == null) - { - ret = ScriptParameterMapper.PrepareScript(script); - Cache[script] = new WeakReference(ret); - } - - return ret; - } - - internal void ExtractParameters(object ps, RedisKey? keyPrefix, out RedisKey[] keys, out RedisValue[] args) - { - if (HasArguments) - { - if (ps == null) throw new ArgumentNullException(nameof(ps), "Script requires parameters"); - - var psType = ps.GetType(); - var mapper = (Func)ParameterMappers[psType]; - if (ps != null && mapper == null) - { - lock (ParameterMappers) - { - mapper = (Func)ParameterMappers[psType]; - if (mapper == null) - { - string missingMember; - string badMemberType; - if (!ScriptParameterMapper.IsValidParameterHash(psType, this, out missingMember, out badMemberType)) - { - if (missingMember != null) - { - throw new ArgumentException("ps", "Expected [" + missingMember + "] to be a field or gettable property on [" + psType.FullName + "]"); - } - - throw new ArgumentException("ps", "Expected [" + badMemberType + "] on [" + psType.FullName + "] to be convertable to a RedisValue"); - } - - ParameterMappers[psType] = mapper = ScriptParameterMapper.GetParameterExtractor(psType, this); - } - } - } - - var mapped = mapper(ps, keyPrefix); - keys = mapped.Keys; - args = mapped.Arguments; - } - else - { - keys = null; - args = null; - } - } - - /// - /// Evaluates this LuaScript against the given database, extracting parameters from the passed in object if any. - /// - public RedisResult Evaluate(IDatabase db, object ps = null, RedisKey? withKeyPrefix = null, CommandFlags flags = CommandFlags.None) - { - RedisKey[] keys; - RedisValue[] args; - ExtractParameters(ps, withKeyPrefix, out keys, out args); - - return db.ScriptEvaluate(ExecutableScript, keys, args, flags); - } - - /// - /// Evaluates this LuaScript against the given database, extracting parameters from the passed in object if any. - /// - public Task EvaluateAsync(IDatabaseAsync db, object ps = null, RedisKey? withKeyPrefix = null, CommandFlags flags = CommandFlags.None) - { - RedisKey[] keys; - RedisValue[] args; - ExtractParameters(ps, withKeyPrefix, out keys, out args); - - return db.ScriptEvaluateAsync(ExecutableScript, keys, args, flags); - } - - /// - /// Loads this LuaScript into the given IServer so it can be run with it's SHA1 hash, instead of - /// passing the full script on each Evaluate or EvaluateAsync call. - /// - /// Note: the FireAndForget command flag cannot be set - /// - public LoadedLuaScript Load(IServer server, CommandFlags flags = CommandFlags.None) - { - if (flags.HasFlag(CommandFlags.FireAndForget)) - { - throw new ArgumentOutOfRangeException(nameof(flags), "Loading a script cannot be FireAndForget"); - } - - var hash = server.ScriptLoad(ExecutableScript, flags); - - return new LoadedLuaScript(this, hash); - } - - /// - /// Loads this LuaScript into the given IServer so it can be run with it's SHA1 hash, instead of - /// passing the full script on each Evaluate or EvaluateAsync call. - /// - /// Note: the FireAndForget command flag cannot be set - /// - public async Task LoadAsync(IServer server, CommandFlags flags = CommandFlags.None) - { - if (flags.HasFlag(CommandFlags.FireAndForget)) - { - throw new ArgumentOutOfRangeException(nameof(flags), "Loading a script cannot be FireAndForget"); - } - - var hash = await server.ScriptLoadAsync(ExecutableScript, flags).ForAwait(); - - return new LoadedLuaScript(this, hash); - } - } - - /// - /// Represents a Lua script that can be executed on Redis. - /// - /// Unlike LuaScript, LoadedLuaScript sends the hash of it's ExecutableScript to Redis rather than pass - /// the whole script on each call. This requires that the script be loaded into Redis before it is used. - /// - /// To create a LoadedLuaScript first create a LuaScript via LuaScript.Prepare(string), then - /// call Load(IServer, CommandFlags) on the returned LuaScript. - /// - /// Unlike normal Redis Lua scripts, LoadedLuaScript can have named parameters (prefixed by a @). - /// Public fields and properties of the passed in object are treated as parameters. - /// - /// Parameters of type RedisKey are sent to Redis as KEY (http://redis.io/commands/eval) in addition to arguments, - /// so as to play nicely with Redis Cluster. - /// - /// All members of this class are thread safe. - /// - public sealed class LoadedLuaScript - { - /// - /// The original script that was used to create this LoadedLuaScript. - /// - public string OriginalScript => Original.OriginalScript; - - /// - /// The script that will actually be sent to Redis for execution. - /// - public string ExecutableScript => Original.ExecutableScript; - - /// - /// The SHA1 hash of ExecutableScript. - /// - /// This is sent to Redis instead of ExecutableScript during Evaluate and EvaluateAsync calls. - /// - public byte[] Hash { get; private set; } - - // internal for testing purposes only - internal LuaScript Original; - - internal LoadedLuaScript(LuaScript original, byte[] hash) - { - Original = original; - Hash = hash; - } - - /// - /// Evaluates this LoadedLuaScript against the given database, extracting parameters for the passed in object if any. - /// - /// This method sends the SHA1 hash of the ExecutableScript instead of the script itself. If the script has not - /// been loaded into the passed Redis instance it will fail. - /// - public RedisResult Evaluate(IDatabase db, object ps = null, RedisKey? withKeyPrefix = null, CommandFlags flags = CommandFlags.None) - { - RedisKey[] keys; - RedisValue[] args; - Original.ExtractParameters(ps, withKeyPrefix, out keys, out args); - - return db.ScriptEvaluate(Hash, keys, args, flags); - } - - /// - /// Evaluates this LoadedLuaScript against the given database, extracting parameters for the passed in object if any. - /// - /// This method sends the SHA1 hash of the ExecutableScript instead of the script itself. If the script has not - /// been loaded into the passed Redis instance it will fail. - /// - public Task EvaluateAsync(IDatabaseAsync db, object ps = null, RedisKey? withKeyPrefix = null, CommandFlags flags = CommandFlags.None) - { - RedisKey[] keys; - RedisValue[] args; - Original.ExtractParameters(ps, withKeyPrefix, out keys, out args); - - return db.ScriptEvaluateAsync(Hash, keys, args, flags); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Message.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Message.cs deleted file mode 100644 index 6d75a80..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Message.cs +++ /dev/null @@ -1,1299 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -#if FEATURE_SERIALIZATION -using System.Runtime.Serialization; -#endif -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - /// - /// Indicates that a command was illegal and was not sent to the server - /// -#if FEATURE_SERIALIZATION - [Serializable] -#endif - public sealed class RedisCommandException : Exception - { -#if FEATURE_SERIALIZATION - private RedisCommandException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { } -#endif - internal RedisCommandException(string message) : base(message) { } - internal RedisCommandException(string message, Exception innerException) : base(message, innerException) { } - } - - -/// -/// Indicates the time allotted for a command or operation has expired. -/// -#if FEATURE_SERIALIZATION - [Serializable] -#endif - public sealed class RedisTimeoutException : TimeoutException - { -#if FEATURE_SERIALIZATION - private RedisTimeoutException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) - { - Commandstatus = (CommandStatus) info.GetValue("commandStatus", typeof(CommandStatus)); - } - /// - /// Serialization implementation; not intended for general usage - /// - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - info.AddValue("commandStatus", Commandstatus); - } -#endif - internal RedisTimeoutException(string message, CommandStatus commandStatus) : base(message) - { - Commandstatus = commandStatus; - } - - /// - /// status of the command while communicating with Redis - /// - public CommandStatus Commandstatus { get; } - } - - - - /// - /// Indicates a connection fault when communicating with redis - /// -#if FEATURE_SERIALIZATION - [Serializable] -#endif - public sealed class RedisConnectionException : RedisException - { -#if FEATURE_SERIALIZATION - private RedisConnectionException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) - { - FailureType = (ConnectionFailureType)info.GetInt32("failureType"); - CommandStatus = (CommandStatus)info.GetValue("commandStatus", typeof(CommandStatus)); - } - /// - /// Serialization implementation; not intended for general usage - /// - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - info.AddValue("failureType", (int)FailureType); - info.AddValue("commandStatus", CommandStatus); - } -#endif - - internal RedisConnectionException(ConnectionFailureType failureType, string message) : this(failureType, message, null, CommandStatus.Unknown) - { - } - - internal RedisConnectionException(ConnectionFailureType failureType, string message, Exception innerException) : this(failureType, message, innerException, CommandStatus.Unknown) - { - } - - internal RedisConnectionException(ConnectionFailureType failureType, string message, Exception innerException, CommandStatus commandStatus) : base(message, innerException) - { - FailureType = failureType; - CommandStatus = commandStatus; - } - - /// - /// The type of connection failure - /// - public ConnectionFailureType FailureType { get; } - - /// - /// status of the command while communicating with Redis - /// - public CommandStatus CommandStatus { get; } - } - - /// - /// Indicates an issue communicating with redis - /// -#if FEATURE_SERIALIZATION - [Serializable] -#endif - public class RedisException : Exception - { - /// - /// Deserialization constructor; not intended for general usage - /// -#if FEATURE_SERIALIZATION - protected RedisException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { } -#endif - - internal RedisException(string message) : base(message) { } - internal RedisException(string message, Exception innerException) : base(message, innerException) { } - } - /// - /// Indicates an exception raised by a redis server - /// -#if FEATURE_SERIALIZATION - [Serializable] -#endif - public sealed class RedisServerException : RedisException - { -#if FEATURE_SERIALIZATION - private RedisServerException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { } -#endif - - internal RedisServerException(string message) : base(message) { } - } - - sealed class LoggingMessage : Message - { - public readonly TextWriter log; - private readonly Message tail; - - public static Message Create(TextWriter log, Message tail) - { - return log == null ? tail : new LoggingMessage(log, tail); - } - private LoggingMessage(TextWriter log, Message tail) : base(tail.Db, tail.Flags, tail.Command) - { - this.log = log; - this.tail = tail; - FlagsRaw = tail.FlagsRaw; - } - public override string CommandAndKey => tail.CommandAndKey; - - public override void AppendStormLog(StringBuilder sb) - { - tail.AppendStormLog(sb); - } - public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - return tail.GetHashSlot(serverSelectionStrategy); - } - internal override void WriteImpl(PhysicalConnection physical) - { - try - { - physical.Multiplexer.LogLocked(log, "Writing to {0}: {1}", physical.Bridge, tail.CommandAndKey); - } - catch { } - tail.WriteImpl(physical); - } - - public TextWriter Log => log; - } - - abstract class Message : ICompletable - { - - public static readonly Message[] EmptyArray = new Message[0]; - public readonly int Db; - - internal const CommandFlags InternalCallFlag = (CommandFlags)128; - protected RedisCommand command; - - private const CommandFlags AskingFlag = (CommandFlags)32, - ScriptUnavailableFlag = (CommandFlags)256; - - const CommandFlags MaskMasterServerPreference = CommandFlags.DemandMaster | CommandFlags.DemandSlave | CommandFlags.PreferMaster | CommandFlags.PreferSlave; - - private const CommandFlags UserSelectableFlags - = CommandFlags.None | CommandFlags.DemandMaster | CommandFlags.DemandSlave - | CommandFlags.PreferMaster | CommandFlags.PreferSlave - | CommandFlags.HighPriority | CommandFlags.FireAndForget | CommandFlags.NoRedirect | CommandFlags.NoScriptCache; - - private CommandFlags flags; - internal CommandFlags FlagsRaw { get { return flags; } set { flags = value; } } - private ResultBox resultBox; - - private ResultProcessor resultProcessor; - - // All for profiling purposes - private ProfileStorage performance; - internal DateTime createdDateTime; - internal long createdTimestamp; - - protected Message(int db, CommandFlags flags, RedisCommand command) - { - bool dbNeeded = RequiresDatabase(command); - if (db < 0) - { - if (dbNeeded) - { - throw ExceptionFactory.DatabaseRequired(false, command); - } - } - else - { - if (!dbNeeded) - { - throw ExceptionFactory.DatabaseNotRequired(false, command); - } - } - - bool masterOnly = IsMasterOnly(command); - Db = db; - this.command = command; - this.flags = flags & UserSelectableFlags; - if (masterOnly) SetMasterOnly(); - - createdDateTime = DateTime.UtcNow; - createdTimestamp = System.Diagnostics.Stopwatch.GetTimestamp(); - Status = CommandStatus.WaitingToBeSent; - } - - internal void SetMasterOnly() - { - switch (GetMasterSlaveFlags(flags)) - { - case CommandFlags.DemandSlave: - throw ExceptionFactory.MasterOnly(false, command, null, null); - case CommandFlags.DemandMaster: - // already fine as-is - break; - case CommandFlags.PreferMaster: - case CommandFlags.PreferSlave: - default: // we will run this on the master, then - flags = SetMasterSlaveFlags(flags, CommandFlags.DemandMaster); - break; - } - } - - internal void SetProfileStorage(ProfileStorage storage) - { - performance = storage; - performance.SetMessage(this); - } - - internal void PrepareToResend(ServerEndPoint resendTo, bool isMoved) - { - if (performance == null) return; - - var oldPerformance = performance; - - oldPerformance.SetCompleted(); - performance = null; - - createdDateTime = DateTime.UtcNow; - createdTimestamp = System.Diagnostics.Stopwatch.GetTimestamp(); - performance = ProfileStorage.NewAttachedToSameContext(oldPerformance, resendTo, isMoved); - performance.SetMessage(this); - Status = CommandStatus.WaitingToBeSent; - } - - internal CommandStatus Status { get; private set; } - - public RedisCommand Command => command; - - public virtual string CommandAndKey => Command.ToString(); - - public CommandFlags Flags => flags; - - /// - /// Things with the potential to cause harm, or to reveal configuration information - /// - public bool IsAdmin - { - get - { - switch (Command) - { - case RedisCommand.BGREWRITEAOF: - case RedisCommand.BGSAVE: - case RedisCommand.CLIENT: - case RedisCommand.CLUSTER: - case RedisCommand.CONFIG: - case RedisCommand.DEBUG: - case RedisCommand.FLUSHALL: - case RedisCommand.FLUSHDB: - case RedisCommand.INFO: - case RedisCommand.KEYS: - case RedisCommand.MONITOR: - case RedisCommand.SAVE: - case RedisCommand.SHUTDOWN: - case RedisCommand.SLAVEOF: - case RedisCommand.SLOWLOG: - case RedisCommand.SYNC: - return true; - default: - return false; - } - } - } - - public bool IsAsking => (flags & AskingFlag) != 0; - - internal bool IsScriptUnavailable => (flags & ScriptUnavailableFlag) != 0; - - internal void SetScriptUnavailable() - { - flags |= ScriptUnavailableFlag; - } - - public bool IsFireAndForget => (flags & CommandFlags.FireAndForget) != 0; - - public bool IsHighPriority => (flags & CommandFlags.HighPriority) != 0; - - public bool IsInternalCall => (flags & InternalCallFlag) != 0; - - public ResultBox ResultBox => resultBox; - - public static Message Create(int db, CommandFlags flags, RedisCommand command) - { - if (command == RedisCommand.SELECT) - return new SelectMessage(db, flags); - return new CommandMessage(db, flags, command); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key) - { - return new CommandKeyMessage(db, flags, command, key); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key0, RedisKey key1) - { - return new CommandKeyKeyMessage(db, flags, command, key0, key1); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key0, RedisKey key1, RedisValue value) - { - return new CommandKeyKeyValueMessage(db, flags, command, key0, key1, value); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key0, RedisKey key1, RedisKey key2) - { - return new CommandKeyKeyKeyMessage(db, flags, command, key0, key1, key2); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisValue value) - { - return new CommandValueMessage(db, flags, command, value); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value) - { - return new CommandKeyValueMessage(db, flags, command, key, value); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisChannel channel) - { - return new CommandChannelMessage(db, flags, command, channel); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisChannel channel, RedisValue value) - { - return new CommandChannelValueMessage(db, flags, command, channel, value); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisValue value, RedisChannel channel) - { - return new CommandValueChannelMessage(db, flags, command, value, channel); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value0, RedisValue value1) - { - return new CommandKeyValueValueMessage(db, flags, command, key, value0, value1); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value0, RedisValue value1, RedisValue value2) - { - return new CommandKeyValueValueValueMessage(db, flags, command, key, value0, value1, value2); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key, GeoEntry[] values) - { - if (values == null) throw new ArgumentNullException(nameof(values)); - if (values.Length == 0) - { - throw new ArgumentOutOfRangeException(nameof(values)); - } - if (values.Length == 1) - { - var value = values[0]; - return Message.Create(db, flags, command, key, value.Longitude, value.Latitude, value.Member); - } - var arr = new RedisValue[3 * values.Length]; - int index = 0; - foreach (var value in values) - { - arr[index++] = value.Longitude; - arr[index++] = value.Latitude; - arr[index++] = value.Member; - } - return new CommandKeyValuesMessage(db, flags, command, key, arr); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value0, RedisValue value1, RedisValue value2, RedisValue value3) - { - return new CommandKeyValueValueValueValueMessage(db, flags, command, key, value0, value1, value2, value3); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisValue value0, RedisValue value1) - { - return new CommandValueValueMessage(db, flags, command, value0, value1); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisValue value, RedisKey key) - { - return new CommandValueKeyMessage(db, flags, command, value, key); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisValue value0, RedisValue value1, RedisValue value2) - { - return new CommandValueValueValueMessage(db, flags, command, value0, value1, value2); - } - - public static Message Create(int db, CommandFlags flags, RedisCommand command, RedisValue value0, RedisValue value1, RedisValue value2, RedisValue value3, RedisValue value4) - { - return new CommandValueValueValueValueValueMessage(db, flags, command, value0, value1, value2, value3, value4); - } - - public static Message CreateInSlot(int db, int slot, CommandFlags flags, RedisCommand command, RedisValue[] values) - { - return new CommandSlotValuesMessage(db, slot, flags, command, values); - } - - public static bool IsMasterOnly(RedisCommand command) - { - switch (command) - { - case RedisCommand.APPEND: - case RedisCommand.BITOP: - case RedisCommand.BLPOP: - case RedisCommand.BRPOP: - case RedisCommand.BRPOPLPUSH: - case RedisCommand.DECR: - case RedisCommand.DECRBY: - case RedisCommand.DEL: - case RedisCommand.EXPIRE: - case RedisCommand.EXPIREAT: - case RedisCommand.FLUSHALL: - case RedisCommand.FLUSHDB: - case RedisCommand.GETSET: - case RedisCommand.HDEL: - case RedisCommand.HINCRBY: - case RedisCommand.HINCRBYFLOAT: - case RedisCommand.HMSET: - case RedisCommand.HSET: - case RedisCommand.HSETNX: - case RedisCommand.INCR: - case RedisCommand.INCRBY: - case RedisCommand.INCRBYFLOAT: - case RedisCommand.LINSERT: - case RedisCommand.LPOP: - case RedisCommand.LPUSH: - case RedisCommand.LPUSHX: - case RedisCommand.LREM: - case RedisCommand.LSET: - case RedisCommand.LTRIM: - case RedisCommand.MIGRATE: - case RedisCommand.MOVE: - case RedisCommand.MSET: - case RedisCommand.MSETNX: - case RedisCommand.PERSIST: - case RedisCommand.PEXPIRE: - case RedisCommand.PEXPIREAT: - case RedisCommand.PFADD: - case RedisCommand.PFMERGE: - case RedisCommand.PSETEX: - case RedisCommand.RENAME: - case RedisCommand.RENAMENX: - case RedisCommand.RESTORE: - case RedisCommand.RPOP: - case RedisCommand.RPOPLPUSH: - case RedisCommand.RPUSH: - case RedisCommand.RPUSHX: - case RedisCommand.SADD: - case RedisCommand.SDIFFSTORE: - case RedisCommand.SET: - case RedisCommand.SETBIT: - case RedisCommand.SETEX: - case RedisCommand.SETNX: - case RedisCommand.SETRANGE: - case RedisCommand.SINTERSTORE: - case RedisCommand.SMOVE: - case RedisCommand.SPOP: - case RedisCommand.SREM: - case RedisCommand.SUNIONSTORE: - case RedisCommand.ZADD: - case RedisCommand.ZINTERSTORE: - case RedisCommand.ZINCRBY: - case RedisCommand.ZREM: - case RedisCommand.ZREMRANGEBYLEX: - case RedisCommand.ZREMRANGEBYRANK: - case RedisCommand.ZREMRANGEBYSCORE: - case RedisCommand.ZUNIONSTORE: - return true; - default: - return false; - } - } - - public virtual void AppendStormLog(StringBuilder sb) - { - if (Db >= 0) sb.Append(Db).Append(':'); - sb.Append(CommandAndKey); - } - public virtual int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) { return ServerSelectionStrategy.NoSlot; } - public bool IsMasterOnly() - { - // note that the constructor runs the switch statement above, so - // this will alread be true for master-only commands, even if the - // user specified PreferMaster etc - return GetMasterSlaveFlags(flags) == CommandFlags.DemandMaster; - } - - /// - /// This does a few important things: - /// 1: it suppresses error events for commands that the user isn't interested in - /// (i.e. "why does my standalone server keep saying ERR unknown command 'cluster' ?") - /// 2: it allows the initial PING and GET (during connect) to get queued rather - /// than be rejected as no-server-available (note that this doesn't apply to - /// handshake messages, as they bypass the queue completely) - /// 3: it disables non-pref logging, as it is usually server-targeted - /// - public void SetInternalCall() - { - flags |= InternalCallFlag; - } - - public override string ToString() - { - return $"[{Db}]:{CommandAndKey} ({resultProcessor?.GetType().Name ?? "(n/a)"})"; - } - - public void SetResponseReceived() - { - performance?.SetResponseReceived(); - } - - public bool TryComplete(bool isAsync) - { - //Ensure we can never call TryComplete on the same resultBox from two threads by grabbing it now - var currBox = Interlocked.Exchange(ref resultBox, null); - if (currBox != null) - { - var ret = currBox.TryComplete(isAsync); - - //in async mode TryComplete will have unwrapped and recycled resultBox - if (!(ret && isAsync)) - { - //put result box back if it was not already recycled - Interlocked.Exchange(ref resultBox, currBox); - } - - performance?.SetCompleted(); - return ret; - } - else - { - ConnectionMultiplexer.TraceWithoutContext("No result-box to complete for " + Command, "Message"); - performance?.SetCompleted(); - return true; - } - } - - internal static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisKey[] keys) - { - switch (keys.Length) - { - case 0: return new CommandKeyMessage(db, flags, command, key); - case 1: return new CommandKeyKeyMessage(db, flags, command, key, keys[0]); - case 2: return new CommandKeyKeyKeyMessage(db, flags, command, key, keys[0], keys[1]); - default: return new CommandKeyKeysMessage(db, flags, command, key, keys); - } - } - - internal static Message Create(int db, CommandFlags flags, RedisCommand command, IList keys) - { - switch (keys.Count) - { - case 0: return new CommandMessage(db, flags, command); - case 1: return new CommandKeyMessage(db, flags, command, keys[0]); - case 2: return new CommandKeyKeyMessage(db, flags, command, keys[0], keys[1]); - case 3: return new CommandKeyKeyKeyMessage(db, flags, command, keys[0], keys[1], keys[2]); - default: return new CommandKeysMessage(db, flags, command, (keys as RedisKey[]) ?? keys.ToArray()); - } - } - - internal static Message Create(int db, CommandFlags flags, RedisCommand command, IList values) - { - switch (values.Count) - { - case 0: return new CommandMessage(db, flags, command); - case 1: return new CommandValueMessage(db, flags, command, values[0]); - case 2: return new CommandValueValueMessage(db, flags, command, values[0], values[1]); - case 3: return new CommandValueValueValueMessage(db, flags, command, values[0], values[1], values[2]); - // no 4; not worth adding - case 5: return new CommandValueValueValueValueValueMessage(db, flags, command, values[0], values[1], values[2], values[3], values[4]); - default: return new CommandValuesMessage(db, flags, command, (values as RedisValue[]) ?? values.ToArray()); - } - } - - internal static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue[] values) - { - if (values == null) throw new ArgumentNullException(nameof(values)); - switch (values.Length) - { - case 0: return new CommandKeyMessage(db, flags, command, key); - case 1: return new CommandKeyValueMessage(db, flags, command, key, values[0]); - case 2: return new CommandKeyValueValueMessage(db, flags, command, key, values[0], values[1]); - case 3: return new CommandKeyValueValueValueMessage(db, flags, command, key, values[0], values[1], values[2]); - case 4: return new CommandKeyValueValueValueValueMessage(db, flags, command, key, values[0], values[1], values[2], values[3]); - default: return new CommandKeyValuesMessage(db, flags, command, key, values); - } - } - - internal static Message Create(int db, CommandFlags flags, RedisCommand command, RedisKey key0, RedisValue[] values, RedisKey key1) - { - if (values == null) throw new ArgumentNullException(nameof(values)); - return new CommandKeyValuesKeyMessage(db, flags, command, key0, values, key1); - } - - internal static CommandFlags GetMasterSlaveFlags(CommandFlags flags) - { - // for the purposes of the switch, we only care about two bits - return flags & MaskMasterServerPreference; - } - internal static bool RequiresDatabase(RedisCommand command) - { - switch (command) - { - case RedisCommand.ASKING: - case RedisCommand.AUTH: - case RedisCommand.BGREWRITEAOF: - case RedisCommand.BGSAVE: - case RedisCommand.CLIENT: - case RedisCommand.CLUSTER: - case RedisCommand.CONFIG: - case RedisCommand.DISCARD: - case RedisCommand.ECHO: - case RedisCommand.FLUSHALL: - case RedisCommand.INFO: - case RedisCommand.LASTSAVE: - case RedisCommand.MONITOR: - case RedisCommand.MULTI: - case RedisCommand.PING: - case RedisCommand.PUBLISH: - case RedisCommand.PUBSUB: - case RedisCommand.PUNSUBSCRIBE: - case RedisCommand.PSUBSCRIBE: - case RedisCommand.QUIT: - case RedisCommand.READONLY: - case RedisCommand.READWRITE: - case RedisCommand.SAVE: - case RedisCommand.SCRIPT: - case RedisCommand.SHUTDOWN: - case RedisCommand.SLAVEOF: - case RedisCommand.SLOWLOG: - case RedisCommand.SUBSCRIBE: - case RedisCommand.SYNC: - case RedisCommand.TIME: - case RedisCommand.UNSUBSCRIBE: - case RedisCommand.SENTINEL: - return false; - default: - return true; - } - } - - internal static CommandFlags SetMasterSlaveFlags(CommandFlags everything, CommandFlags masterSlave) - { - // take away the two flags we don't want, and add back the ones we care about - return (everything & ~(CommandFlags.DemandMaster | CommandFlags.DemandSlave | CommandFlags.PreferMaster | CommandFlags.PreferSlave)) - | masterSlave; - } - - internal void Cancel() - { - resultProcessor?.SetException(this, new TaskCanceledException()); - } - - // true if ready to be completed (i.e. false if re-issued to another server) - internal bool ComputeResult(PhysicalConnection connection, RawResult result) - { - return resultProcessor == null || resultProcessor.SetResult(connection, this, result); - } - - internal void Fail(ConnectionFailureType failure, Exception innerException) - { - PhysicalConnection.IdentifyFailureType(innerException, ref failure); - resultProcessor?.ConnectionFail(this, failure, innerException); - } - - internal void SetEnqueued() - { - performance?.SetEnqueued(); - } - - internal void SetRequestSent() - { - Status = CommandStatus.Sent; - performance?.SetRequestSent(); - } - - internal void SetAsking(bool value) - { - if (value) flags |= AskingFlag; // the bits giveth - else flags &= ~AskingFlag; // and the bits taketh away - } - - internal void SetNoRedirect() - { - flags |= CommandFlags.NoRedirect; - } - - internal void SetPreferMaster() - { - flags = (flags & ~MaskMasterServerPreference) | CommandFlags.PreferMaster; - } - - internal void SetPreferSlave() - { - flags = (flags & ~MaskMasterServerPreference) | CommandFlags.PreferSlave; - } - internal void SetSource(ResultProcessor resultProcessor, ResultBox resultBox) - { // note order here reversed to prevent overload resolution errors - this.resultBox = resultBox; - this.resultProcessor = resultProcessor; - } - - internal void SetSource(ResultBox resultBox, ResultProcessor resultProcessor) - { - this.resultBox = resultBox; - this.resultProcessor = resultProcessor; - } - - internal abstract void WriteImpl(PhysicalConnection physical); - - internal void WriteTo(PhysicalConnection physical) - { - try - { - WriteImpl(physical); - } - catch (RedisCommandException) - { // these have specific meaning; don't wrap - throw; - } - catch (Exception ex) - { - physical?.OnInternalError(ex); - Fail(ConnectionFailureType.InternalFailure, ex); - } - } - internal abstract class CommandChannelBase : Message - { - protected readonly RedisChannel Channel; - - public CommandChannelBase(int db, CommandFlags flags, RedisCommand command, RedisChannel channel) : base(db, flags, command) - { - channel.AssertNotNull(); - Channel = channel; - } - - public override string CommandAndKey => Command + " " + Channel; - } - - internal abstract class CommandKeyBase : Message - { - protected readonly RedisKey Key; - - public CommandKeyBase(int db, CommandFlags flags, RedisCommand command, RedisKey key) : base(db, flags, command) - { - key.AssertNotNull(); - Key = key; - } - - public override string CommandAndKey => Command + " " + (string)Key; - - public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - return serverSelectionStrategy.HashSlot(Key); - } - } - sealed class CommandChannelMessage : CommandChannelBase - { - public CommandChannelMessage(int db, CommandFlags flags, RedisCommand command, RedisChannel channel) : base(db, flags, command, channel) - { } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 1); - physical.Write(Channel); - } - } - - sealed class CommandChannelValueMessage : CommandChannelBase - { - private readonly RedisValue value; - public CommandChannelValueMessage(int db, CommandFlags flags, RedisCommand command, RedisChannel channel, RedisValue value) : base(db, flags, command, channel) - { - value.AssertNotNull(); - this.value = value; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 2); - physical.Write(Channel); - physical.Write(value); - } - } - - sealed class CommandKeyKeyKeyMessage : CommandKeyBase - { - private readonly RedisKey key1, key2; - public CommandKeyKeyKeyMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key0, RedisKey key1, RedisKey key2) : base(db, flags, command, key0) - { - key1.AssertNotNull(); - key2.AssertNotNull(); - this.key1 = key1; - this.key2 = key2; - } - public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - var slot = serverSelectionStrategy.HashSlot(Key); - slot = serverSelectionStrategy.CombineSlot(slot, key1); - slot = serverSelectionStrategy.CombineSlot(slot, key2); - return slot; - } - - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 3); - physical.Write(Key); - physical.Write(key1); - physical.Write(key2); - } - } - - class CommandKeyKeyMessage : CommandKeyBase - { - protected readonly RedisKey key1; - public CommandKeyKeyMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key0, RedisKey key1) : base(db, flags, command, key0) - { - key1.AssertNotNull(); - this.key1 = key1; - } - public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - var slot = serverSelectionStrategy.HashSlot(Key); - slot = serverSelectionStrategy.CombineSlot(slot, key1); - return slot; - } - - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 2); - physical.Write(Key); - physical.Write(key1); - } - } - sealed class CommandKeyKeysMessage : CommandKeyBase - { - private readonly RedisKey[] keys; - public CommandKeyKeysMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisKey[] keys) : base(db, flags, command, key) - { - for (int i = 0; i < keys.Length; i++) - { - keys[i].AssertNotNull(); - } - this.keys = keys; - } - public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - var slot = serverSelectionStrategy.HashSlot(Key); - for (int i = 0; i < keys.Length; i++) - { - slot = serverSelectionStrategy.CombineSlot(slot, keys[i]); - } - return slot; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(command, keys.Length + 1); - physical.Write(Key); - for (int i = 0; i < keys.Length; i++) - { - physical.Write(keys[i]); - } - } - } - - sealed class CommandKeyKeyValueMessage : CommandKeyKeyMessage - { - private readonly RedisValue value; - public CommandKeyKeyValueMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key0, RedisKey key1, RedisValue value) : base(db, flags, command, key0, key1) - { - value.AssertNotNull(); - this.value = value; - } - - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 3); - physical.Write(Key); - physical.Write(key1); - physical.Write(value); - } - } - sealed class CommandKeyMessage : CommandKeyBase - { - public CommandKeyMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key) : base(db, flags, command, key) - { } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 1); - physical.Write(Key); - } - } - sealed class CommandValuesMessage : Message - { - private readonly RedisValue[] values; - public CommandValuesMessage(int db, CommandFlags flags, RedisCommand command, RedisValue[] values) : base(db, flags, command) - { - for (int i = 0; i < values.Length; i++) - { - values[i].AssertNotNull(); - } - this.values = values; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(command, values.Length); - for (int i = 0; i < values.Length; i++) - { - physical.Write(values[i]); - } - } - } - sealed class CommandKeysMessage : Message - { - private readonly RedisKey[] keys; - public CommandKeysMessage(int db, CommandFlags flags, RedisCommand command, RedisKey[] keys) : base(db, flags, command) - { - for (int i = 0; i < keys.Length; i++) - { - keys[i].AssertNotNull(); - } - this.keys = keys; - } - - public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - int slot = ServerSelectionStrategy.NoSlot; - for (int i = 0; i < keys.Length; i++) - { - slot = serverSelectionStrategy.CombineSlot(slot, keys[i]); - } - return slot; - } - - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(command, keys.Length); - for (int i = 0; i < keys.Length; i++) - { - physical.Write(keys[i]); - } - } - } - - sealed class CommandKeyValueMessage : CommandKeyBase - { - private readonly RedisValue value; - public CommandKeyValueMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value) : base(db, flags, command, key) - { - value.AssertNotNull(); - this.value = value; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 2); - physical.Write(Key); - physical.Write(value); - } - } - sealed class CommandKeyValuesKeyMessage : CommandKeyBase - { - private readonly RedisKey key1; - private readonly RedisValue[] values; - public CommandKeyValuesKeyMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key0, RedisValue[] values, RedisKey key1) : base(db, flags, command, key0) - { - for (int i = 0; i < values.Length; i++) - { - values[i].AssertNotNull(); - } - this.values = values; - key1.AssertNotNull(); - this.key1 = key1; - } - public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - var slot = base.GetHashSlot(serverSelectionStrategy); - return serverSelectionStrategy.CombineSlot(slot, key1); - } - - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, values.Length + 2); - physical.Write(Key); - for (int i = 0; i < values.Length; i++) physical.Write(values[i]); - physical.Write(key1); - } - } - - sealed class CommandKeyValuesMessage : CommandKeyBase - { - private readonly RedisValue[] values; - public CommandKeyValuesMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue[] values) : base(db, flags, command, key) - { - for (int i = 0; i < values.Length; i++) - { - values[i].AssertNotNull(); - } - this.values = values; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, values.Length + 1); - physical.Write(Key); - for (int i = 0; i < values.Length; i++) physical.Write(values[i]); - } - } - - sealed class CommandKeyValueValueMessage : CommandKeyBase - { - private readonly RedisValue value0, value1; - public CommandKeyValueValueMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value0, RedisValue value1) : base(db, flags, command, key) - { - value0.AssertNotNull(); - value1.AssertNotNull(); - this.value0 = value0; - this.value1 = value1; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 3); - physical.Write(Key); - physical.Write(value0); - physical.Write(value1); - } - } - - sealed class CommandKeyValueValueValueMessage : CommandKeyBase - { - private readonly RedisValue value0, value1, value2; - public CommandKeyValueValueValueMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value0, RedisValue value1, RedisValue value2) : base(db, flags, command, key) - { - value0.AssertNotNull(); - value1.AssertNotNull(); - value2.AssertNotNull(); - this.value0 = value0; - this.value1 = value1; - this.value2 = value2; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 4); - physical.Write(Key); - physical.Write(value0); - physical.Write(value1); - physical.Write(value2); - } - } - - sealed class CommandKeyValueValueValueValueMessage : CommandKeyBase - { - private readonly RedisValue value0, value1, value2, value3; - public CommandKeyValueValueValueValueMessage(int db, CommandFlags flags, RedisCommand command, RedisKey key, RedisValue value0, RedisValue value1, RedisValue value2, RedisValue value3) : base(db, flags, command, key) - { - value0.AssertNotNull(); - value1.AssertNotNull(); - value2.AssertNotNull(); - value3.AssertNotNull(); - this.value0 = value0; - this.value1 = value1; - this.value2 = value2; - this.value3 = value3; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 5); - physical.Write(Key); - physical.Write(value0); - physical.Write(value1); - physical.Write(value2); - physical.Write(value3); - } - } - - sealed class CommandMessage : Message - { - public CommandMessage(int db, CommandFlags flags, RedisCommand command) : base(db, flags, command) { } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 0); - } - } - - private class CommandSlotValuesMessage : Message - { - private readonly int slot; - private readonly RedisValue[] values; - - public CommandSlotValuesMessage(int db, int slot, CommandFlags flags, RedisCommand command, RedisValue[] values) - : base(db, flags, command) - { - this.slot = slot; - for (int i = 0; i < values.Length; i++) - { - values[i].AssertNotNull(); - } - this.values = values; - } - public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - return slot; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(command, values.Length); - for (int i = 0; i < values.Length; i++) - { - physical.Write(values[i]); - } - } - } - - sealed class CommandValueChannelMessage : CommandChannelBase - { - private readonly RedisValue value; - public CommandValueChannelMessage(int db, CommandFlags flags, RedisCommand command, RedisValue value, RedisChannel channel) : base(db, flags, command, channel) - { - value.AssertNotNull(); - this.value = value; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 2); - physical.Write(value); - physical.Write(Channel); - } - } - sealed class CommandValueKeyMessage : CommandKeyBase - { - private readonly RedisValue value; - - public CommandValueKeyMessage(int db, CommandFlags flags, RedisCommand command, RedisValue value, RedisKey key) : base(db, flags, command, key) - { - value.AssertNotNull(); - this.value = value; - } - - public override void AppendStormLog(StringBuilder sb) - { - base.AppendStormLog(sb); - sb.Append(" (").Append((string)value).Append(')'); - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 2); - physical.Write(value); - physical.Write(Key); - } - } - - sealed class CommandValueMessage : Message - { - private readonly RedisValue value; - public CommandValueMessage(int db, CommandFlags flags, RedisCommand command, RedisValue value) : base(db, flags, command) - { - value.AssertNotNull(); - this.value = value; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 1); - physical.Write(value); - } - } - - sealed class CommandValueValueMessage : Message - { - private readonly RedisValue value0, value1; - public CommandValueValueMessage(int db, CommandFlags flags, RedisCommand command, RedisValue value0, RedisValue value1) : base(db, flags, command) - { - value0.AssertNotNull(); - value1.AssertNotNull(); - this.value0 = value0; - this.value1 = value1; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 2); - physical.Write(value0); - physical.Write(value1); - } - } - - sealed class CommandValueValueValueMessage : Message - { - private readonly RedisValue value0, value1, value2; - public CommandValueValueValueMessage(int db, CommandFlags flags, RedisCommand command, RedisValue value0, RedisValue value1, RedisValue value2) : base(db, flags, command) - { - value0.AssertNotNull(); - value1.AssertNotNull(); - value2.AssertNotNull(); - this.value0 = value0; - this.value1 = value1; - this.value2 = value2; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 3); - physical.Write(value0); - physical.Write(value1); - physical.Write(value2); - } - } - - sealed class CommandValueValueValueValueValueMessage : Message - { - private readonly RedisValue value0, value1, value2, value3, value4; - public CommandValueValueValueValueValueMessage(int db, CommandFlags flags, RedisCommand command, RedisValue value0, RedisValue value1, RedisValue value2, RedisValue value3, RedisValue value4) : base(db, flags, command) - { - value0.AssertNotNull(); - value1.AssertNotNull(); - value2.AssertNotNull(); - value3.AssertNotNull(); - value4.AssertNotNull(); - this.value0 = value0; - this.value1 = value1; - this.value2 = value2; - this.value3 = value3; - this.value4 = value4; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 5); - physical.Write(value0); - physical.Write(value1); - physical.Write(value2); - physical.Write(value3); - physical.Write(value4); - } - } - - sealed class SelectMessage : Message - { - public SelectMessage(int db, CommandFlags flags) : base(db, flags, RedisCommand.SELECT) - { - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 1); - physical.Write(Db); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/MessageCompletable.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/MessageCompletable.cs deleted file mode 100644 index 5c0fc51..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/MessageCompletable.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Text; - -namespace StackExchange.Redis -{ - sealed class MessageCompletable : ICompletable - { - private readonly RedisChannel channel; - - private readonly Action handler; - - private readonly RedisValue message; - - public MessageCompletable(RedisChannel channel, RedisValue message, Action handler) - { - this.channel = channel; - this.message = message; - this.handler = handler; - } - - public override string ToString() - { - return (string)channel; - } - public bool TryComplete(bool isAsync) - { - if (handler == null) return true; - if (isAsync) - { - ConnectionMultiplexer.TraceWithoutContext("Invoking...: " + (string)channel, "Subscription"); - foreach(Action sub in handler.GetInvocationList()) - { - try { sub.Invoke(channel, message); } - catch { } - } - ConnectionMultiplexer.TraceWithoutContext("Invoke complete", "Subscription"); - return true; - } - // needs to be called async (unless there is nothing to do!) - return false; - } - - void ICompletable.AppendStormLog(StringBuilder sb) - { - sb.Append("event, pub/sub: ").Append((string)channel); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/MessageQueue.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/MessageQueue.cs deleted file mode 100644 index 9774e22..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/MessageQueue.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System.Collections.Generic; -using System.Text; - -namespace StackExchange.Redis -{ - sealed partial class MessageQueue - { - private readonly Queue - regular = new Queue(), - high = new Queue(); - - public object SyncLock => regular; - - public Message Dequeue() - { - lock (regular) - { - if (high.Count != 0) - { - return high.Dequeue(); - } - if (regular.Count != 0) - { - return regular.Dequeue(); - } - } - return null; - } - - /// - /// Checks both high-pri and regular queues to see if the next item is a PING, and if so: dequeues it and returns it - /// - public Message DequeueUnsentPing(out int queueLength) - { - lock (regular) - { - Message peeked; - queueLength = high.Count + regular.Count; - //In a disconnect scenario, we don't want to complete the Ping message twice, - //dequeue it now so it wont get dequeued in AbortUnsent (if we're going down that code path) - if (high.Count != 0 && (peeked = high.Peek()).Command == RedisCommand.PING) - { - queueLength--; - return high.Dequeue(); - } - if (regular.Count != 0 && (peeked = regular.Peek()).Command == RedisCommand.PING) - { - queueLength--; - return regular.Dequeue(); - } - } - return null; - } - - public bool Push(Message message) - { - lock (regular) - { - (message.IsHighPriority ? high : regular).Enqueue(message); - return high.Count + regular.Count == 1; - } - } - - internal bool Any() - { - lock (regular) - { - return high.Count != 0 || regular.Count != 0; - } - } - - internal int Count() - { - lock (regular) - { - return high.Count + regular.Count; - } - } - - internal Message[] DequeueAll() - { - lock (regular) - { - int count = high.Count + regular.Count; - if (count == 0) return Message.EmptyArray; - - var arr = new Message[count]; - high.CopyTo(arr, 0); - regular.CopyTo(arr, high.Count); - high.Clear(); - regular.Clear(); - return arr; - } - } - internal void GetStormLog(StringBuilder sb) - { - lock(regular) - { - int total = 0; - if (high.Count == 0 && regular.Count == 0) return; - sb.Append("Unsent: ").Append(high.Count + regular.Count).AppendLine(); - foreach (var item in high) - { - if (++total >= 500) break; - item.AppendStormLog(sb); - sb.AppendLine(); - } - foreach (var item in regular) - { - if (++total >= 500) break; - - item.AppendStormLog(sb); - sb.AppendLine(); - } - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/MigrateOptions.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/MigrateOptions.cs deleted file mode 100644 index 68095bd..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/MigrateOptions.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - /// - /// Additional options for the MIGRATE command - /// - [Flags] - public enum MigrateOptions - { - /// - /// No options specified - /// - None = 0, - /// - /// Do not remove the key from the local instance. - /// - Copy = 1, - /// - /// Replace existing key on the remote instance. - /// - Replace = 2 - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Order.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Order.cs deleted file mode 100644 index 34f4cb3..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/Order.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// The direction in which to sequence elements - /// - public enum Order - { - /// - /// Ordered from low values to high values - /// - Ascending, - /// - /// Ordered from high values to low values - /// - Descending - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/PhysicalBridge.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/PhysicalBridge.cs deleted file mode 100644 index ea08399..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/PhysicalBridge.cs +++ /dev/null @@ -1,850 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading; - -namespace StackExchange.Redis -{ - enum WriteResult - { - QueueEmptyAfterWrite, - NothingToDo, - MoreWork, - CompetingWriter, - NoConnection, - } - - sealed partial class PhysicalBridge : IDisposable - { - internal readonly string Name; - - internal int inWriteQueue = 0; - - const int ProfileLogSamples = 10; - - const double ProfileLogSeconds = (ConnectionMultiplexer.MillisecondsPerHeartbeat * ProfileLogSamples) / 1000.0; - - private static readonly Message ReusableAskingCommand = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.ASKING); - - private readonly CompletionManager completionManager; - readonly long[] profileLog = new long[ProfileLogSamples]; - private readonly MessageQueue queue = new MessageQueue(); - int activeWriters = 0; - private int beating; - int failConnectCount = 0; - volatile bool isDisposed; - long nonPreferredEndpointCount; - - //private volatile int missedHeartbeats; - private long operationCount, socketCount; - private volatile PhysicalConnection physical; - - - long profileLastLog; - int profileLogIndex; - volatile bool reportNextFailure = true, reconfigureNextFailure = false; - private volatile int state = (int)State.Disconnected; - - public PhysicalBridge(ServerEndPoint serverEndPoint, ConnectionType type) - { - ServerEndPoint = serverEndPoint; - ConnectionType = type; - Multiplexer = serverEndPoint.Multiplexer; - Name = Format.ToString(serverEndPoint.EndPoint) + "/" + ConnectionType.ToString(); - completionManager = new CompletionManager(Multiplexer, Name); - } - - public enum State : byte - { - Connecting, - ConnectedEstablishing, - ConnectedEstablished, - Disconnected - } - - public Exception LastException { get; private set; } - - public ConnectionType ConnectionType { get; } - - public bool IsConnected => state == (int)State.ConnectedEstablished; - - public ConnectionMultiplexer Multiplexer { get; } - - public ServerEndPoint ServerEndPoint { get; } - - public long SubscriptionCount - { - get - { - var tmp = physical; - return tmp == null ? 0 : physical.SubscriptionCount; - } - } - - internal State ConnectionState => (State)state; - internal bool IsBeating => Interlocked.CompareExchange(ref beating, 0, 0) == 1; - - internal long OperationCount => Interlocked.Read(ref operationCount); - - public void CompleteSyncOrAsync(ICompletable operation) - { - completionManager.CompleteSyncOrAsync(operation); - } - - public void Dispose() - { - isDisposed = true; - using (var tmp = physical) - { - physical = null; - } - } - - public void ReportNextFailure() - { - reportNextFailure = true; - } - - public override string ToString() - { - return ConnectionType + "/" + Format.ToString(ServerEndPoint.EndPoint); - } - - public void TryConnect(TextWriter log) - { - GetConnection(log); - } - - public bool TryEnqueue(Message message, bool isSlave) - { - if (isDisposed) throw new ObjectDisposedException(Name); - if (!IsConnected) - { - if (message.IsInternalCall) - { - // you can go in the queue, but we won't be starting - // a worker, because the handshake has not completed - queue.Push(message); - message.SetEnqueued(); - return true; - } - else - { - // sorry, we're just not ready for you yet; - return false; - } - } - - bool reqWrite = queue.Push(message); - message.SetEnqueued(); - LogNonPreferred(message.Flags, isSlave); - Trace("Now pending: " + GetPendingCount()); - - if (reqWrite) - { - Multiplexer.RequestWrite(this, false); - } - return true; - } - internal void AppendProfile(StringBuilder sb) - { - long[] clone = new long[ProfileLogSamples + 1]; - for (int i = 0; i < ProfileLogSamples; i++) - { - clone[i] = Interlocked.Read(ref profileLog[i]); - } - clone[ProfileLogSamples] = Interlocked.Read(ref operationCount); - Array.Sort(clone); - sb.Append(" ").Append(clone[0]); - for (int i = 1; i < clone.Length; i++) - { - if (clone[i] != clone[i - 1]) - { - sb.Append("+").Append(clone[i] - clone[i - 1]); - } - } - if (clone[0] != clone[ProfileLogSamples]) - { - sb.Append("=").Append(clone[ProfileLogSamples]); - } - double rate = (clone[ProfileLogSamples] - clone[0]) / ProfileLogSeconds; - sb.Append(" (").Append(rate.ToString("N2")).Append(" ops/s; spans ").Append(ProfileLogSeconds).Append("s)"); - } - - internal bool ConfirmRemoveFromWriteQueue() - { - lock (queue.SyncLock) - { - if (queue.Count() == 0) - { - Interlocked.Exchange(ref inWriteQueue, 0); - return true; - } - } - return false; - } - - internal void GetCounters(ConnectionCounters counters) - { - counters.PendingUnsentItems = queue.Count(); - counters.OperationCount = OperationCount; - counters.SocketCount = Interlocked.Read(ref socketCount); - counters.WriterCount = Interlocked.CompareExchange(ref activeWriters, 0, 0); - counters.NonPreferredEndpointCount = Interlocked.Read(ref nonPreferredEndpointCount); - completionManager.GetCounters(counters); - physical?.GetCounters(counters); - } - - internal int GetOutstandingCount(out int inst, out int qu, out int qs, out int qc, out int wr, out int wq, out int @in, out int ar) - {// defined as: PendingUnsentItems + SentItemsAwaitingResponse + ResponsesAwaitingAsyncCompletion - inst = (int)(Interlocked.Read(ref operationCount) - Interlocked.Read(ref profileLastLog)); - qu = queue.Count(); - var tmp = physical; - if(tmp == null) - { - qs = @in = ar = 0; - } else - { - qs = tmp.GetSentAwaitingResponseCount(); - @in = tmp.GetAvailableInboundBytes(out ar); - } - qc = completionManager.GetOutstandingCount(); - wr = Interlocked.CompareExchange(ref activeWriters, 0, 0); - wq = Interlocked.CompareExchange(ref inWriteQueue, 0, 0); - return qu + qs + qc; - } - - internal int GetPendingCount() - { - return queue.Count(); - } - - internal string GetStormLog() - { - var sb = new StringBuilder("Storm log for ").Append(Format.ToString(ServerEndPoint.EndPoint)).Append(" / ").Append(ConnectionType) - .Append(" at ").Append(DateTime.UtcNow) - .AppendLine().AppendLine(); - queue.GetStormLog(sb); - physical?.GetStormLog(sb); - completionManager.GetStormLog(sb); - sb.Append("Circular op-count snapshot:"); - AppendProfile(sb); - sb.AppendLine(); - return sb.ToString(); - } - - internal void IncrementOpCount() - { - Interlocked.Increment(ref operationCount); - } - - internal void KeepAlive() - { - var commandMap = Multiplexer.CommandMap; - Message msg = null; - switch (ConnectionType) - { - case ConnectionType.Interactive: - msg = ServerEndPoint.GetTracerMessage(false); - msg.SetSource(ResultProcessor.Tracer, null); - break; - case ConnectionType.Subscription: - if (commandMap.IsAvailable(RedisCommand.UNSUBSCRIBE)) - { - msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.UNSUBSCRIBE, - (RedisChannel)Guid.NewGuid().ToByteArray()); - msg.SetSource(ResultProcessor.TrackSubscriptions, null); - } - break; - } - if (msg != null) - { - msg.SetInternalCall(); - Multiplexer.Trace("Enqueue: " + msg); - if (!TryEnqueue(msg, ServerEndPoint.IsSlave)) - { - OnInternalError(ExceptionFactory.NoConnectionAvailable(Multiplexer.IncludeDetailInExceptions, Multiplexer.IncludePerformanceCountersInExceptions, msg.Command, msg, ServerEndPoint, Multiplexer.GetServerSnapshot())); - } - } - } - - internal void OnConnected(PhysicalConnection connection, TextWriter log) - { - Trace("OnConnected"); - if (physical == connection && !isDisposed && ChangeState(State.Connecting, State.ConnectedEstablishing)) - { - ServerEndPoint.OnEstablishing(connection, log); - } - else - { - try - { - connection.Dispose(); - } - catch - { } - } - } - - - internal void ResetNonConnected() - { - var tmp = physical; - if (tmp != null && state != (int)State.ConnectedEstablished) - { - tmp.RecordConnectionFailed(ConnectionFailureType.UnableToConnect); - } - GetConnection(null); - } - - internal void OnConnectionFailed(PhysicalConnection connection, ConnectionFailureType failureType, Exception innerException) - { - if (reportNextFailure) - { - LastException = innerException; - reportNextFailure = false; // until it is restored - var endpoint = ServerEndPoint.EndPoint; - Multiplexer.OnConnectionFailed(endpoint, ConnectionType, failureType, innerException, reconfigureNextFailure); - } - } - - internal void OnDisconnected(ConnectionFailureType failureType, PhysicalConnection connection, out bool isCurrent, out State oldState) - { - Trace("OnDisconnected"); - - // if the next thing in the pipe is a PING, we can tell it that we failed (this really helps spot doomed connects) - int count; - var ping = queue.DequeueUnsentPing(out count); - if (ping != null) - { - Trace("Marking PING as failed (queue length: " + count + ")"); - ping.Fail(failureType, null); - CompleteSyncOrAsync(ping); - } - oldState = default(State); // only defined when isCurrent = true - if (isCurrent = (physical == connection)) - { - Trace("Bridge noting disconnect from active connection" + (isDisposed ? " (disposed)" : "")); - oldState = ChangeState(State.Disconnected); - physical = null; - - if (!isDisposed && Interlocked.Increment(ref failConnectCount) == 1) - { - GetConnection(null); // try to connect immediately - } - } - else if (physical == null) - { - Trace("Bridge noting disconnect (already terminated)"); - } - else - { - Trace("Bridge noting disconnect, but from different connection"); - } - } - - internal void OnFullyEstablished(PhysicalConnection connection) - { - Trace("OnFullyEstablished"); - if (physical == connection && !isDisposed && ChangeState(State.ConnectedEstablishing, State.ConnectedEstablished)) - { - reportNextFailure = reconfigureNextFailure = true; - LastException = null; - Interlocked.Exchange(ref failConnectCount, 0); - ServerEndPoint.OnFullyEstablished(connection); - Multiplexer.RequestWrite(this, true); - if(ConnectionType == ConnectionType.Interactive) ServerEndPoint.CheckInfoReplication(); - } - else - { - try { connection.Dispose(); } catch { } - } - } - - private int connectStartTicks; - private long connectTimeoutRetryCount = 0; - - internal void OnHeartbeat(bool ifConnectedOnly) - { - bool runThisTime = false; - try - { - runThisTime = !isDisposed && Interlocked.CompareExchange(ref beating, 1, 0) == 0; - if (!runThisTime) return; - - uint index = (uint)Interlocked.Increment(ref profileLogIndex); - long newSampleCount = Interlocked.Read(ref operationCount); - Interlocked.Exchange(ref profileLog[index % ProfileLogSamples], newSampleCount); - Interlocked.Exchange(ref profileLastLog, newSampleCount); - Trace("OnHeartbeat: " + (State)state); - switch (state) - { - case (int)State.Connecting: - int connectTimeMilliseconds = unchecked(Environment.TickCount - VolatileWrapper.Read(ref connectStartTicks)); - bool shouldRetry = Multiplexer.RawConfig.ReconnectRetryPolicy.ShouldRetry(Interlocked.Read(ref connectTimeoutRetryCount), connectTimeMilliseconds); - if (shouldRetry) - { - Interlocked.Increment(ref connectTimeoutRetryCount); - LastException = ExceptionFactory.UnableToConnect(Multiplexer.RawConfig.AbortOnConnectFail, "ConnectTimeout"); - Trace("Aborting connect"); - // abort and reconnect - var snapshot = physical; - bool isCurrent; - State oldState; - OnDisconnected(ConnectionFailureType.UnableToConnect, snapshot, out isCurrent, out oldState); - using (snapshot) { } // dispose etc - TryConnect(null); - } - if (!ifConnectedOnly) - { - AbortUnsent(); - } - break; - case (int)State.ConnectedEstablishing: - case (int)State.ConnectedEstablished: - var tmp = physical; - if (tmp != null) - { - if(state == (int)State.ConnectedEstablished) - { - Interlocked.Exchange(ref connectTimeoutRetryCount, 0); - tmp.Bridge.ServerEndPoint.ClearUnselectable(UnselectableFlags.DidNotRespond); - } - tmp.OnHeartbeat(); - int writeEverySeconds = ServerEndPoint.WriteEverySeconds, - checkConfigSeconds = Multiplexer.RawConfig.ConfigCheckSeconds; - - if(state == (int)State.ConnectedEstablished && ConnectionType == ConnectionType.Interactive - && checkConfigSeconds > 0 && ServerEndPoint.LastInfoReplicationCheckSecondsAgo >= checkConfigSeconds - && ServerEndPoint.CheckInfoReplication()) - { - // that serves as a keep-alive, if it is accepted - } - else if (writeEverySeconds > 0 && tmp.LastWriteSecondsAgo >= writeEverySeconds) - { - Trace("OnHeartbeat - overdue"); - if (state == (int)State.ConnectedEstablished) - { - KeepAlive(); - } - else - { - bool ignore; - State oldState; - OnDisconnected(ConnectionFailureType.SocketFailure, tmp, out ignore, out oldState); - } - } - else if (!queue.Any() && tmp.GetSentAwaitingResponseCount() != 0) - { - // there's a chance this is a dead socket; sending data will shake that - // up a bit, so if we have an empty unsent queue and a non-empty sent - // queue, test the socket - KeepAlive(); - } - } - break; - case (int)State.Disconnected: - Interlocked.Exchange(ref connectTimeoutRetryCount, 0); - if (!ifConnectedOnly) - { - AbortUnsent(); - Multiplexer.Trace("Resurrecting " + this.ToString()); - GetConnection(null); - } - break; - default: - Interlocked.Exchange(ref connectTimeoutRetryCount, 0); - if (!ifConnectedOnly) - { - AbortUnsent(); - } - break; - } - } - catch (Exception ex) - { - OnInternalError(ex); - Trace("OnHeartbeat error: " + ex.Message); - } - finally - { - if (runThisTime) Interlocked.Exchange(ref beating, 0); - } - } - - internal void RemovePhysical(PhysicalConnection connection) - { -#pragma warning disable 0420 - Interlocked.CompareExchange(ref physical, null, connection); -#pragma warning restore 0420 - } - - [Conditional("VERBOSE")] - internal void Trace(string message) - { - Multiplexer.Trace(message, ToString()); - } - - [Conditional("VERBOSE")] - internal void Trace(bool condition, string message) - { - if (condition) Multiplexer.Trace(message, ToString()); - } - - internal bool TryEnqueue(List messages, bool isSlave) - { - if (messages == null || messages.Count == 0) return true; - - if (isDisposed) throw new ObjectDisposedException(Name); - - if (!IsConnected) - { - return false; - } - bool reqWrite = false; - foreach (var message in messages) - { // deliberately not taking a single lock here; we don't care if - // other threads manage to interleave - in fact, it would be desirable - // (to avoid a batch monopolising the connection) - if (queue.Push(message)) reqWrite = true; - LogNonPreferred(message.Flags, isSlave); - } - Trace("Now pending: " + GetPendingCount()); - if (reqWrite) // was empty before - { - Multiplexer.RequestWrite(this, false); - } - return true; - } - - /// - /// This writes a message **directly** to the output stream; note - /// that this ignores the queue, so should only be used *either* - /// from the regular dequeue loop, *or* from the "I've just - /// connected" handshake (when there is no dequeue loop) - otherwise, - /// you can pretty much assume you're going to destroy the stream - /// - internal bool WriteMessageDirect(PhysicalConnection tmp, Message next) - { - Trace("Writing: " + next); - if (next is IMultiMessage) - { - SelectDatabase(tmp, next); // need to switch database *before* the transaction - foreach (var subCommand in ((IMultiMessage)next).GetMessages(tmp)) - { - if (!WriteMessageToServer(tmp, subCommand)) - { - // we screwed up; abort; note that WriteMessageToServer already - // killed the underlying connection - Trace("Unable to write to server"); - next.Fail(ConnectionFailureType.ProtocolFailure, null); - CompleteSyncOrAsync(next); - return false; - } - } - - next.SetRequestSent(); - - return true; - } - else - { - return WriteMessageToServer(tmp, next); - } - } - - internal WriteResult WriteQueue(int maxWork) - { - bool weAreWriter = false; - PhysicalConnection conn = null; - try - { - Trace("Writing queue from bridge"); - - weAreWriter = Interlocked.CompareExchange(ref activeWriters, 1, 0) == 0; - if (!weAreWriter) - { - Trace("(aborting: existing writer)"); - return WriteResult.CompetingWriter; - } - - conn = GetConnection(null); - if (conn == null) - { - AbortUnsent(); - Trace("Connection not available; exiting"); - return WriteResult.NoConnection; - } - - Message last; - int count = 0; - while (true) - { - var next = queue.Dequeue(); - if (next == null) - { - Trace("Nothing to write; exiting"); - if(count == 0) - { - conn.Flush(); // only flush on an empty run - return WriteResult.NothingToDo; - } - return WriteResult.QueueEmptyAfterWrite; - } - last = next; - - Trace("Now pending: " + GetPendingCount()); - if (!WriteMessageDirect(conn, next)) - { - AbortUnsent(); - Trace("write failed; connection is toast; exiting"); - return WriteResult.NoConnection; - } - count++; - if (maxWork > 0 && count >= maxWork) - { - Trace("Work limit; exiting"); - Trace(last != null, "Flushed up to: " + last); - conn.Flush(); - break; - } - } - } - catch (IOException ex) - { - if (conn != null) - { - conn.RecordConnectionFailed(ConnectionFailureType.SocketFailure, ex); - conn = null; - } - AbortUnsent(); - } - catch (Exception ex) - { - AbortUnsent(); - OnInternalError(ex); - } - finally - { - if (weAreWriter) - { - Interlocked.Exchange(ref activeWriters, 0); - Trace("Exiting writer"); - } - } - return queue.Any() ? WriteResult.MoreWork : WriteResult.QueueEmptyAfterWrite; - } - - private void AbortUnsent() - { - var dead = queue.DequeueAll(); - Trace(dead.Length != 0, "Aborting " + dead.Length + " messages"); - for (int i = 0; i < dead.Length; i++) - { - var msg = dead[i]; - msg.Fail(ConnectionFailureType.UnableToResolvePhysicalConnection, null); - CompleteSyncOrAsync(msg); - } - } - - private State ChangeState(State newState) - { -#pragma warning disable 0420 - var oldState = (State)Interlocked.Exchange(ref state, (int)newState); -#pragma warning restore 0420 - if (oldState != newState) - { - Multiplexer.Trace(ConnectionType + " state changed from " + oldState + " to " + newState); - - if (newState == State.Disconnected) - { - AbortUnsent(); - } - } - return oldState; - } - - private bool ChangeState(State oldState, State newState) - { -#pragma warning disable 0420 - bool result = Interlocked.CompareExchange(ref state, (int)newState, (int)oldState) == (int)oldState; -#pragma warning restore 0420 - if (result) - { - Multiplexer.Trace(ConnectionType + " state changed from " + oldState + " to " + newState); - } - return result; - } - - private PhysicalConnection GetConnection(TextWriter log) - { - if (state == (int)State.Disconnected) - { - try - { - if (!Multiplexer.IsDisposed) - { - Multiplexer.LogLocked(log, "Connecting {0}...", Name); - Multiplexer.Trace("Connecting...", Name); - if (ChangeState(State.Disconnected, State.Connecting)) - { - Interlocked.Increment(ref socketCount); - Interlocked.Exchange(ref connectStartTicks, Environment.TickCount); - // separate creation and connection for case when connection completes synchronously - // in that case PhysicalConnection will call back to PhysicalBridge, and most of PhysicalBridge methods assumes that physical is not null; - physical = new PhysicalConnection(this); - physical.BeginConnect(log); - } - } - return null; - } - catch (Exception ex) - { - Multiplexer.LogLocked(log, "Connect {0} failed: {1}", Name, ex.Message); - Multiplexer.Trace("Connect failed: " + ex.Message, Name); - ChangeState(State.Disconnected); - OnInternalError(ex); - throw; - } - } - return physical; - } - - private void LogNonPreferred(CommandFlags flags, bool isSlave) - { - if ((flags & Message.InternalCallFlag) == 0) // don't log internal-call - { - if (isSlave) - { - if (Message.GetMasterSlaveFlags(flags) == CommandFlags.PreferMaster) - Interlocked.Increment(ref nonPreferredEndpointCount); - } - else - { - if (Message.GetMasterSlaveFlags(flags) == CommandFlags.PreferSlave) - Interlocked.Increment(ref nonPreferredEndpointCount); - } - } - } - private void OnInternalError(Exception exception, [CallerMemberName] string origin = null) - { - Multiplexer.OnInternalError(exception, ServerEndPoint.EndPoint, ConnectionType, origin); - } - private void SelectDatabase(PhysicalConnection connection, Message message) - { - int db = message.Db; - if (db >= 0) - { - var sel = connection.GetSelectDatabaseCommand(db, message); - if (sel != null) - { - connection.Enqueue(sel); - sel.WriteImpl(connection); - sel.SetRequestSent(); - IncrementOpCount(); - } - } - } - private bool WriteMessageToServer(PhysicalConnection connection, Message message) - { - if (message == null) return true; - - try - { - var cmd = message.Command; - bool isMasterOnly = message.IsMasterOnly(); - if (isMasterOnly && ServerEndPoint.IsSlave && (ServerEndPoint.SlaveReadOnly || !ServerEndPoint.AllowSlaveWrites)) - { - throw ExceptionFactory.MasterOnly(Multiplexer.IncludeDetailInExceptions, message.Command, message, ServerEndPoint); - } - - SelectDatabase(connection, message); - - if (!connection.TransactionActive) - { - var readmode = connection.GetReadModeCommand(isMasterOnly); - if (readmode != null) - { - connection.Enqueue(readmode); - readmode.WriteTo(connection); - readmode.SetRequestSent(); - IncrementOpCount(); - } - - if (message.IsAsking) - { - var asking = ReusableAskingCommand; - connection.Enqueue(asking); - asking.WriteImpl(connection); - asking.SetRequestSent(); - IncrementOpCount(); - } - } - switch (cmd) - { - case RedisCommand.WATCH: - case RedisCommand.MULTI: - connection.TransactionActive = true; - break; - case RedisCommand.UNWATCH: - case RedisCommand.EXEC: - case RedisCommand.DISCARD: - connection.TransactionActive = false; - break; - } - - connection.Enqueue(message); - message.WriteImpl(connection); - message.SetRequestSent(); - IncrementOpCount(); - - // some commands smash our ability to trust the database; some commands - // demand an immediate flush - switch (cmd) - { - case RedisCommand.EVAL: - case RedisCommand.EVALSHA: - if(!ServerEndPoint.GetFeatures().ScriptingDatabaseSafe) - { - connection.SetUnknownDatabase(); - } - break; - case RedisCommand.UNKNOWN: - case RedisCommand.DISCARD: - case RedisCommand.EXEC: - connection.SetUnknownDatabase(); - break; - } - return true; - } - catch (RedisCommandException ex) - { - Trace("Write failed: " + ex.Message); - message.Fail(ConnectionFailureType.ProtocolFailure, ex); - CompleteSyncOrAsync(message); - // this failed without actually writing; we're OK with that... unless there's a transaction - - if (connection != null && connection.TransactionActive) - { - // we left it in a broken state; need to kill the connection - connection.RecordConnectionFailed(ConnectionFailureType.ProtocolFailure, ex); - return false; - } - return true; - } - catch (Exception ex) - { - Trace("Write failed: " + ex.Message); - message.Fail(ConnectionFailureType.InternalFailure, ex); - CompleteSyncOrAsync(message); - - // we're not sure *what* happened here; probably an IOException; kill the connection - connection?.RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); - return false; - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/PhysicalConnection.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/PhysicalConnection.cs deleted file mode 100644 index 647505a..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/PhysicalConnection.cs +++ /dev/null @@ -1,1170 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Security; -using System.Net.Sockets; -using System.Runtime.CompilerServices; -using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Threading; -#if CORE_CLR -using System.Threading.Tasks; -#endif - -namespace StackExchange.Redis -{ - - internal sealed partial class PhysicalConnection : IDisposable, ISocketCallback - { - - internal readonly byte[] ChannelPrefix; - - private const int DefaultRedisDatabaseCount = 16; - - private static readonly byte[] Crlf = Encoding.ASCII.GetBytes("\r\n"); - -#if CORE_CLR - readonly Action> endRead; - private static Action> EndReadFactory(PhysicalConnection physical) - { - return result => - { // can't capture AsyncState on SocketRead, so we'll do it once per physical instead - if (result.IsFaulted) - { - GC.KeepAlive(result.Exception); - } - try - { - physical.Multiplexer.Trace("Completed asynchronously: processing in callback", physical.physicalName); - if (physical.EndReading(result)) physical.BeginReading(); - } - catch (Exception ex) - { - physical.RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); - } - }; - } -#else - static readonly AsyncCallback endRead = result => - { - PhysicalConnection physical; - if (result.CompletedSynchronously || (physical = result.AsyncState as PhysicalConnection) == null) return; - try - { - physical.Multiplexer.Trace("Completed asynchronously: processing in callback", physical.physicalName); - if (physical.EndReading(result)) physical.BeginReading(); - } - catch (Exception ex) - { - physical.RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); - } - }; -#endif - - private static readonly byte[] message = Encoding.UTF8.GetBytes("message"), pmessage = Encoding.UTF8.GetBytes("pmessage"); - - static readonly Message[] ReusableChangeDatabaseCommands = Enumerable.Range(0, DefaultRedisDatabaseCount).Select( - i => Message.Create(i, CommandFlags.FireAndForget, RedisCommand.SELECT)).ToArray(); - - private static readonly Message - ReusableReadOnlyCommand = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.READONLY), - ReusableReadWriteCommand = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.READWRITE); - - private static int totalCount; - - private readonly ConnectionType connectionType; - - // things sent to this physical, but not yet received - private readonly Queue outstanding = new Queue(); - - readonly string physicalName; - - volatile int currentDatabase = 0; - - ReadMode currentReadMode = ReadMode.NotSpecified; - - int failureReported; - - byte[] ioBuffer = new byte[512]; - - int ioBufferBytes = 0; - - int lastWriteTickCount, lastReadTickCount, lastBeatTickCount; - int firstUnansweredWriteTickCount; - - private Stream netStream, outStream; - - private SocketToken socketToken; - - public PhysicalConnection(PhysicalBridge bridge) - { - lastWriteTickCount = lastReadTickCount = Environment.TickCount; - lastBeatTickCount = 0; - this.connectionType = bridge.ConnectionType; - this.Multiplexer = bridge.Multiplexer; - this.ChannelPrefix = Multiplexer.RawConfig.ChannelPrefix; - if (this.ChannelPrefix != null && this.ChannelPrefix.Length == 0) this.ChannelPrefix = null; // null tests are easier than null+empty - var endpoint = bridge.ServerEndPoint.EndPoint; - physicalName = connectionType + "#" + Interlocked.Increment(ref totalCount) + "@" + Format.ToString(endpoint); - this.Bridge = bridge; -#if CORE_CLR - endRead = EndReadFactory(this); -#endif - OnCreateEcho(); - } - - public void BeginConnect(TextWriter log) - { - VolatileWrapper.Write(ref firstUnansweredWriteTickCount, 0); - var endpoint = this.Bridge.ServerEndPoint.EndPoint; - - Multiplexer.Trace("Connecting...", physicalName); - this.socketToken = Multiplexer.SocketManager.BeginConnect(endpoint, this, Multiplexer, log); - } - - private enum ReadMode : byte - { - NotSpecified, - ReadOnly, - ReadWrite - } - - public PhysicalBridge Bridge { get; } - - public long LastWriteSecondsAgo => unchecked(Environment.TickCount - VolatileWrapper.Read(ref lastWriteTickCount)) / 1000; - - public ConnectionMultiplexer Multiplexer { get; } - - public long SubscriptionCount { get; set; } - - public bool TransactionActive { get; internal set; } - - public void Dispose() - { - if (outStream != null) - { - Multiplexer.Trace("Disconnecting...", physicalName); -#if !CORE_CLR - try { outStream.Close(); } catch { } -#endif - try { outStream.Dispose(); } catch { } - outStream = null; - } - if (netStream != null) - { -#if !CORE_CLR - try { netStream.Close(); } catch { } -#endif - try { netStream.Dispose(); } catch { } - netStream = null; - } - if (socketToken.HasValue) - { - Multiplexer.SocketManager?.Shutdown(socketToken); - socketToken = default(SocketToken); - Multiplexer.Trace("Disconnected", physicalName); - RecordConnectionFailed(ConnectionFailureType.ConnectionDisposed); - } - OnCloseEcho(); - } - - public void Flush() - { - var tmp = outStream; - if (tmp != null) - { - tmp.Flush(); - Interlocked.Exchange(ref lastWriteTickCount, Environment.TickCount); - } - } - public void RecordConnectionFailed(ConnectionFailureType failureType, Exception innerException = null, [CallerMemberName] string origin = null) - { - SocketManager.ManagerState mgrState = SocketManager.ManagerState.CheckForStaleConnections; - RecordConnectionFailed(failureType, ref mgrState, innerException, origin); - } - public void RecordConnectionFailed(ConnectionFailureType failureType, ref SocketManager.ManagerState managerState, Exception innerException = null, [CallerMemberName] string origin = null) - { - IdentifyFailureType(innerException, ref failureType); - - managerState = SocketManager.ManagerState.RecordConnectionFailed_OnInternalError; - if (failureType == ConnectionFailureType.InternalFailure) OnInternalError(innerException, origin); - - // stop anything new coming in... - Bridge.Trace("Failed: " + failureType); - bool isCurrent; - PhysicalBridge.State oldState; - int @in = -1, ar = -1; - managerState = SocketManager.ManagerState.RecordConnectionFailed_OnDisconnected; - Bridge.OnDisconnected(failureType, this, out isCurrent, out oldState); - if(oldState == PhysicalBridge.State.ConnectedEstablished) - { - try - { - @in = GetAvailableInboundBytes(out ar); - } - catch { /* best effort only */ } - } - - if (isCurrent && Interlocked.CompareExchange(ref failureReported, 1, 0) == 0) - { - managerState = SocketManager.ManagerState.RecordConnectionFailed_ReportFailure; - int now = Environment.TickCount, lastRead = VolatileWrapper.Read(ref lastReadTickCount), lastWrite = VolatileWrapper.Read(ref lastWriteTickCount), - lastBeat = VolatileWrapper.Read(ref lastBeatTickCount); - int unansweredRead = VolatileWrapper.Read(ref firstUnansweredWriteTickCount); - - var exMessage = new StringBuilder(failureType + " on " + Format.ToString(Bridge.ServerEndPoint.EndPoint) + "/" + connectionType); - var data = new List> - { - Tuple.Create("FailureType", failureType.ToString()), - Tuple.Create("EndPoint", Format.ToString(Bridge.ServerEndPoint.EndPoint)) - }; - Action add = (lk, sk, v) => - { - data.Add(Tuple.Create(lk, v)); - exMessage.Append(", " + sk + ": " + v); - }; - - add("Origin", "origin", origin); - add("Input-Buffer", "input-buffer", ioBufferBytes.ToString()); - add("Outstanding-Responses", "outstanding", GetSentAwaitingResponseCount().ToString()); - add("Last-Read", "last-read", unchecked(now - lastRead) / 1000 + "s ago"); - add("Last-Write", "last-write", unchecked(now - lastWrite) / 1000 + "s ago"); - add("Unanswered-Write", "unanswered-write", unchecked(now - unansweredRead) / 1000 + "s ago"); - add("Keep-Alive", "keep-alive", Bridge.ServerEndPoint.WriteEverySeconds + "s"); - add("Pending", "pending", Bridge.GetPendingCount().ToString()); - add("Previous-Physical-State", "state", oldState.ToString()); - - if(@in >= 0) - { - add("Inbound-Bytes", "in", @in.ToString()); - add("Active-Readers", "ar", ar.ToString()); - } - - add("Last-Heartbeat", "last-heartbeat", (lastBeat == 0 ? "never" : (unchecked(now - lastBeat)/1000 + "s ago"))+ (Bridge.IsBeating ? " (mid-beat)" : "") ); - add("Last-Multiplexer-Heartbeat", "last-mbeat", Multiplexer.LastHeartbeatSecondsAgo + "s ago"); - add("Last-Global-Heartbeat", "global", ConnectionMultiplexer.LastGlobalHeartbeatSecondsAgo + "s ago"); -#if FEATURE_SOCKET_MODE_POLL - var mgr = Bridge.Multiplexer.SocketManager; - add("SocketManager-State", "mgr", mgr.State.ToString()); - add("Last-Error", "err", mgr.LastErrorTimeRelative()); -#endif - - var ex = innerException == null - ? new RedisConnectionException(failureType, exMessage.ToString()) - : new RedisConnectionException(failureType, exMessage.ToString(), innerException); - - foreach (var kv in data) - { - ex.Data["Redis-" + kv.Item1] = kv.Item2; - } - - managerState = SocketManager.ManagerState.RecordConnectionFailed_OnConnectionFailed; - Bridge.OnConnectionFailed(this, failureType, ex); - } - - // cleanup - managerState = SocketManager.ManagerState.RecordConnectionFailed_FailOutstanding; - lock (outstanding) - { - Bridge.Trace(outstanding.Count != 0, "Failing outstanding messages: " + outstanding.Count); - while (outstanding.Count != 0) - { - var next = outstanding.Dequeue(); - Bridge.Trace("Failing: " + next); - next.Fail(failureType, innerException); - Bridge.CompleteSyncOrAsync(next); - } - } - - // burn the socket - managerState = SocketManager.ManagerState.RecordConnectionFailed_ShutdownSocket; - Multiplexer.SocketManager?.Shutdown(socketToken); - } - - public override string ToString() - { - return physicalName; - } - - internal static void IdentifyFailureType(Exception exception, ref ConnectionFailureType failureType) - { - if (exception != null && failureType == ConnectionFailureType.InternalFailure) - { - if (exception is AggregateException) exception = exception.InnerException ?? exception; - if (exception is AuthenticationException) failureType = ConnectionFailureType.AuthenticationFailure; - else if (exception is SocketException || exception is IOException) failureType = ConnectionFailureType.SocketFailure; - else if (exception is EndOfStreamException) failureType = ConnectionFailureType.SocketClosed; - else if (exception is ObjectDisposedException) failureType = ConnectionFailureType.SocketClosed; - } - } - - internal void Enqueue(Message next) - { - lock (outstanding) - { - outstanding.Enqueue(next); - } - } - - internal void GetCounters(ConnectionCounters counters) - { - lock (outstanding) - { - counters.SentItemsAwaitingResponse = outstanding.Count; - } - counters.Subscriptions = SubscriptionCount; - } - - internal Message GetReadModeCommand(bool isMasterOnly) - { - var serverEndpoint = Bridge.ServerEndPoint; - if (serverEndpoint.RequiresReadMode) - { - ReadMode requiredReadMode = isMasterOnly ? ReadMode.ReadWrite : ReadMode.ReadOnly; - if (requiredReadMode != currentReadMode) - { - currentReadMode = requiredReadMode; - switch (requiredReadMode) - { - case ReadMode.ReadOnly: return ReusableReadOnlyCommand; - case ReadMode.ReadWrite: return ReusableReadWriteCommand; - } - } - } - else if (currentReadMode == ReadMode.ReadOnly) - { // we don't need it (because we're not a cluster, or not a slave), - // but we are in read-only mode; switch to read-write - currentReadMode = ReadMode.ReadWrite; - return ReusableReadWriteCommand; - } - return null; - } - - internal Message GetSelectDatabaseCommand(int targetDatabase, Message message) - { - if (targetDatabase < 0) return null; - if (targetDatabase != currentDatabase) - { - var serverEndpoint = Bridge.ServerEndPoint; - int available = serverEndpoint.Databases; - - if (!serverEndpoint.HasDatabases) // only db0 is available on cluster/twemproxy - { - if (targetDatabase != 0) - { // should never see this, since the API doesn't allow it; thus not too worried about ExceptionFactory - throw new RedisCommandException("Multiple databases are not supported on this server; cannot switch to database: " + targetDatabase); - } - return null; - } - - if(message.Command == RedisCommand.SELECT) - { - // this could come from an EVAL/EVALSHA inside a transaction, for example; we'll accept it - Bridge.Trace("Switching database: " + targetDatabase); - currentDatabase = targetDatabase; - return null; - } - - if (TransactionActive) - {// should never see this, since the API doesn't allow it; thus not too worried about ExceptionFactory - throw new RedisCommandException("Multiple databases inside a transaction are not currently supported: " + targetDatabase); - } - - if (available != 0 && targetDatabase >= available) // we positively know it is out of range - { - throw ExceptionFactory.DatabaseOutfRange(Multiplexer.IncludeDetailInExceptions, targetDatabase, message, serverEndpoint); - } - Bridge.Trace("Switching database: " + targetDatabase); - currentDatabase = targetDatabase; - return GetSelectDatabaseCommand(targetDatabase); - } - return null; - } - internal static Message GetSelectDatabaseCommand(int targetDatabase) - { - return targetDatabase < DefaultRedisDatabaseCount - ? ReusableChangeDatabaseCommands[targetDatabase] // 0-15 by default - : Message.Create(targetDatabase, CommandFlags.FireAndForget, RedisCommand.SELECT); - } - - internal int GetSentAwaitingResponseCount() - { - lock (outstanding) - { - return outstanding.Count; - } - } - - internal void GetStormLog(StringBuilder sb) - { - lock (outstanding) - { - if (outstanding.Count == 0) return; - sb.Append("Sent, awaiting response from server: ").Append(outstanding.Count).AppendLine(); - int total = 0; - foreach (var item in outstanding) - { - if (++total >= 500) break; - item.AppendStormLog(sb); - sb.AppendLine(); - } - } - } - - internal void OnHeartbeat() - { - Interlocked.Exchange(ref lastBeatTickCount, Environment.TickCount); - } - - internal void OnInternalError(Exception exception, [CallerMemberName] string origin = null) - { - Multiplexer.OnInternalError(exception, Bridge.ServerEndPoint.EndPoint, connectionType, origin); - } - - internal void SetUnknownDatabase() - { // forces next db-specific command to issue a select - currentDatabase = -1; - } - - internal void Write(RedisKey key) - { - var val = key.KeyValue; - if (val is string) - { - WriteUnified(outStream, key.KeyPrefix, (string)val); - } - else - { - WriteUnified(outStream, key.KeyPrefix, (byte[])val); - } - } - - internal void Write(RedisChannel channel) - { - WriteUnified(outStream, ChannelPrefix, channel.Value); - } - - internal void Write(RedisValue value) - { - if (value.IsInteger) - { - WriteUnified(outStream, (long)value); - } - else - { - WriteUnified(outStream, (byte[])value); - } - } - - internal void WriteHeader(RedisCommand command, int arguments) - { - var commandBytes = Multiplexer.CommandMap.GetBytes(command); - if (commandBytes == null) - { - throw ExceptionFactory.CommandDisabled(Multiplexer.IncludeDetailInExceptions, command, null, Bridge.ServerEndPoint); - } - outStream.WriteByte((byte)'*'); - - // remember the time of the first write that still not followed by read - Interlocked.CompareExchange(ref firstUnansweredWriteTickCount, Environment.TickCount, 0); - - WriteRaw(outStream, arguments + 1); - WriteUnified(outStream, commandBytes); - } - internal const int REDIS_MAX_ARGS = 1024 * 1024; // there is a <= 1024*1024 max constraint inside redis itself: https://github.com/antirez/redis/blob/6c60526db91e23fb2d666fc52facc9a11780a2a3/src/networking.c#L1024 - - internal void WriteHeader(string command, int arguments) - { - if(arguments >= REDIS_MAX_ARGS) // using >= here because we will be adding 1 for the command itself (which is an arg for the purposes of the multi-bulk protocol) - { - throw ExceptionFactory.TooManyArgs(Multiplexer.IncludeDetailInExceptions, command, null, Bridge.ServerEndPoint, arguments + 1); - } - var commandBytes = Multiplexer.CommandMap.GetBytes(command); - if (commandBytes == null) - { - throw ExceptionFactory.CommandDisabled(Multiplexer.IncludeDetailInExceptions, command, null, Bridge.ServerEndPoint); - } - outStream.WriteByte((byte)'*'); - - // remember the time of the first write that still not followed by read - Interlocked.CompareExchange(ref firstUnansweredWriteTickCount, Environment.TickCount, 0); - - WriteRaw(outStream, arguments + 1); - WriteUnified(outStream, commandBytes); - } - - static void WriteRaw(Stream stream, long value, bool withLengthPrefix = false) - { - if (value >= 0 && value <= 9) - { - if (withLengthPrefix) - { - stream.WriteByte((byte)'1'); - stream.Write(Crlf, 0, 2); - } - stream.WriteByte((byte)((int)'0' + (int)value)); - } - else if (value >= 10 && value < 100) - { - if (withLengthPrefix) - { - stream.WriteByte((byte)'2'); - stream.Write(Crlf, 0, 2); - } - stream.WriteByte((byte)((int)'0' + (int)value / 10)); - stream.WriteByte((byte)((int)'0' + (int)value % 10)); - } - else if (value >= 100 && value < 1000) - { - int v = (int)value; - int units = v % 10; - v /= 10; - int tens = v % 10, hundreds = v / 10; - if (withLengthPrefix) - { - stream.WriteByte((byte)'3'); - stream.Write(Crlf, 0, 2); - } - stream.WriteByte((byte)((int)'0' + hundreds)); - stream.WriteByte((byte)((int)'0' + tens)); - stream.WriteByte((byte)((int)'0' + units)); - } - else if (value < 0 && value >= -9) - { - if (withLengthPrefix) - { - stream.WriteByte((byte)'2'); - stream.Write(Crlf, 0, 2); - } - stream.WriteByte((byte)'-'); - stream.WriteByte((byte)((int)'0' - (int)value)); - } - else if (value <= -10 && value > -100) - { - if (withLengthPrefix) - { - stream.WriteByte((byte)'3'); - stream.Write(Crlf, 0, 2); - } - value = -value; - stream.WriteByte((byte)'-'); - stream.WriteByte((byte)((int)'0' + (int)value / 10)); - stream.WriteByte((byte)((int)'0' + (int)value % 10)); - } - else - { - var bytes = Encoding.ASCII.GetBytes(Format.ToString(value)); - if (withLengthPrefix) - { - WriteRaw(stream, bytes.Length, false); - } - stream.Write(bytes, 0, bytes.Length); - } - stream.Write(Crlf, 0, 2); - } - - static void WriteUnified(Stream stream, byte[] value) - { - stream.WriteByte((byte)'$'); - if (value == null) - { - WriteRaw(stream, -1); // note that not many things like this... - } - else - { - WriteRaw(stream, value.Length); - stream.Write(value, 0, value.Length); - stream.Write(Crlf, 0, 2); - } - } - - internal void WriteAsHex(byte[] value) - { - var stream = outStream; - stream.WriteByte((byte)'$'); - if (value == null) - { - WriteRaw(stream, -1); - } else - { - WriteRaw(stream, value.Length * 2); - for(int i = 0; i < value.Length; i++) - { - stream.WriteByte(ToHexNibble(value[i] >> 4)); - stream.WriteByte(ToHexNibble(value[i] & 15)); - } - stream.Write(Crlf, 0, 2); - } - } - internal static byte ToHexNibble(int value) - { - return value < 10 ? (byte)('0' + value) : (byte)('a' - 10 + value); - } - - void WriteUnified(Stream stream, byte[] prefix, string value) - { - stream.WriteByte((byte)'$'); - if (value == null) - { - WriteRaw(stream, -1); // note that not many things like this... - } - else - { - int encodedLength = Encoding.UTF8.GetByteCount(value); - if (prefix == null) - { - WriteRaw(stream, encodedLength); - WriteRaw(stream, value, encodedLength); - stream.Write(Crlf, 0, 2); - } - else - { - WriteRaw(stream, prefix.Length + encodedLength); - stream.Write(prefix, 0, prefix.Length); - WriteRaw(stream, value, encodedLength); - stream.Write(Crlf, 0, 2); - } - } - - } - unsafe void WriteRaw(Stream stream, string value, int encodedLength) - { - if (encodedLength <= ScratchSize) - { - int bytes = Encoding.UTF8.GetBytes(value, 0, value.Length, outScratch, 0); - stream.Write(outScratch, 0, bytes); - } - else - { -#if !CORE_CLR - fixed (char* c = value) - fixed (byte* b = outScratch) - { - int charsRemaining = value.Length, charOffset = 0, bytesWritten; - while (charsRemaining > Scratch_CharsPerBlock) - { - bytesWritten = outEncoder.GetBytes(c + charOffset, Scratch_CharsPerBlock, b, ScratchSize, false); - stream.Write(outScratch, 0, bytesWritten); - charOffset += Scratch_CharsPerBlock; - charsRemaining -= Scratch_CharsPerBlock; - } - bytesWritten = outEncoder.GetBytes(c + charOffset, charsRemaining, b, ScratchSize, true); - if (bytesWritten != 0) stream.Write(outScratch, 0, bytesWritten); - } -#else - int charsRemaining = value.Length, charOffset = 0, bytesWritten; - var valueCharArray = value.ToCharArray(); - while (charsRemaining > Scratch_CharsPerBlock) - { - bytesWritten = outEncoder.GetBytes(valueCharArray, charOffset, Scratch_CharsPerBlock, outScratch, 0, false); - stream.Write(outScratch, 0, bytesWritten); - charOffset += Scratch_CharsPerBlock; - charsRemaining -= Scratch_CharsPerBlock; - } - bytesWritten = outEncoder.GetBytes(valueCharArray, charOffset, charsRemaining, outScratch, 0, true); - if (bytesWritten != 0) stream.Write(outScratch, 0, bytesWritten); -#endif - } - } - const int ScratchSize = 512; - static readonly int Scratch_CharsPerBlock = ScratchSize / Encoding.UTF8.GetMaxByteCount(1); - private readonly byte[] outScratch = new byte[ScratchSize]; - private readonly Encoder outEncoder = Encoding.UTF8.GetEncoder(); - static void WriteUnified(Stream stream, byte[] prefix, byte[] value) - { - stream.WriteByte((byte)'$'); - if (value == null) - { - WriteRaw(stream, -1); // note that not many things like this... - } - else if (prefix == null) - { - WriteRaw(stream, value.Length); - stream.Write(value, 0, value.Length); - stream.Write(Crlf, 0, 2); - } - else - { - WriteRaw(stream, prefix.Length + value.Length); - stream.Write(prefix, 0, prefix.Length); - stream.Write(value, 0, value.Length); - stream.Write(Crlf, 0, 2); - } - } - - static void WriteUnified(Stream stream, long value) - { - // note from specification: A client sends to the Redis server a RESP Array consisting of just Bulk Strings. - // (i.e. we can't just send ":123\r\n", we need to send "$3\r\n123\r\n" - stream.WriteByte((byte)'$'); - WriteRaw(stream, value, withLengthPrefix: true); - } - - void BeginReading() - { - bool keepReading; - try - { - do - { - keepReading = false; - int space = EnsureSpaceAndComputeBytesToRead(); - Multiplexer.Trace("Beginning async read...", physicalName); -#if CORE_CLR - var result = netStream.ReadAsync(ioBuffer, ioBufferBytes, space); - switch (result.Status) - { - case TaskStatus.RanToCompletion: - case TaskStatus.Faulted: - Multiplexer.Trace("Completed synchronously: processing immediately", physicalName); - keepReading = EndReading(result); - break; - default: - result.ContinueWith(endRead); - break; - } -#else - var result = netStream.BeginRead(ioBuffer, ioBufferBytes, space, endRead, this); - if (result.CompletedSynchronously) - { - Multiplexer.Trace("Completed synchronously: processing immediately", physicalName); - keepReading = EndReading(result); - } -#endif - } while (keepReading); - } -#if CORE_CLR - catch (AggregateException ex) - { - throw ex.InnerException; - } -#endif - catch (System.IO.IOException ex) - { - Multiplexer.Trace("Could not connect: " + ex.Message, physicalName); - } - } - int haveReader; - - internal int GetAvailableInboundBytes(out int activeReaders) - { - activeReaders = Interlocked.CompareExchange(ref haveReader, 0, 0); - return this.socketToken.Available; - } - - static LocalCertificateSelectionCallback GetAmbientCertificateCallback() - { - try - { - var pfxPath = Environment.GetEnvironmentVariable("SERedis_ClientCertPfxPath"); - var pfxPassword = Environment.GetEnvironmentVariable("SERedis_ClientCertPassword"); - var pfxStorageFlags = Environment.GetEnvironmentVariable("SERedis_ClientCertStorageFlags"); - - X509KeyStorageFlags? flags = null; - if (!string.IsNullOrEmpty(pfxStorageFlags)) - { - flags = Enum.Parse(typeof(X509KeyStorageFlags), pfxStorageFlags) as X509KeyStorageFlags?; - } - - if (!string.IsNullOrEmpty(pfxPath) && File.Exists(pfxPath)) - { - return delegate { return new X509Certificate2(pfxPath, pfxPassword ?? "", flags ?? X509KeyStorageFlags.DefaultKeySet); }; - } - } catch - { } - return null; - } - SocketMode ISocketCallback.Connected(Stream stream, TextWriter log) - { - try - { - var socketMode = SocketManager.DefaultSocketMode; - - // disallow connection in some cases - OnDebugAbort(); - - // the order is important here: - // [network]<==[ssl]<==[logging]<==[buffered] - var config = Multiplexer.RawConfig; - - if(config.Ssl) - { - Multiplexer.LogLocked(log, "Configuring SSL"); - var host = config.SslHost; - if (string.IsNullOrWhiteSpace(host)) host = Format.ToStringHostOnly(Bridge.ServerEndPoint.EndPoint); - - var ssl = new SslStream(stream, false, config.CertificateValidationCallback, - config.CertificateSelectionCallback ?? GetAmbientCertificateCallback() -#if !__MonoCS__ - , EncryptionPolicy.RequireEncryption -#endif - ); - try - { - ssl.AuthenticateAsClient(host, config.SslProtocols); - - Multiplexer.LogLocked(log, $"SSL connection established successfully using protocol: {ssl.SslProtocol}"); - } - catch (AuthenticationException authexception) - { - RecordConnectionFailed(ConnectionFailureType.AuthenticationFailure, authexception); - Multiplexer.Trace("Encryption failure"); - return SocketMode.Abort; - } - stream = ssl; - socketMode = SocketMode.Async; - } - OnWrapForLogging(ref stream, physicalName); - - int bufferSize = config.WriteBuffer; - this.netStream = stream; - this.outStream = bufferSize <= 0 ? stream : new BufferedStream(stream, bufferSize); - Multiplexer.LogLocked(log, "Connected {0}", Bridge); - - Bridge.OnConnected(this, log); - return socketMode; - } - catch (Exception ex) - { - RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); // includes a bridge.OnDisconnected - Multiplexer.Trace("Could not connect: " + ex.Message, physicalName); - return SocketMode.Abort; - } - } - -#if CORE_CLR - private bool EndReading(Task result) - { - try - { - var tmp = netStream; - int bytesRead = tmp == null ? 0 : result.Result; // note we expect this to be completed - return ProcessReadBytes(bytesRead); - } - catch (Exception ex) - { - RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); - return false; - } - } -#else - private bool EndReading(IAsyncResult result) - { - try - { - int bytesRead = netStream?.EndRead(result) ?? 0; - return ProcessReadBytes(bytesRead); - } - catch (Exception ex) - { - RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); - return false; - } - } -#endif - int EnsureSpaceAndComputeBytesToRead() - { - int space = ioBuffer.Length - ioBufferBytes; - if (space == 0) - { - Array.Resize(ref ioBuffer, ioBuffer.Length * 2); - space = ioBuffer.Length - ioBufferBytes; - } - return space; - } - - void ISocketCallback.Error() - { - RecordConnectionFailed(ConnectionFailureType.SocketFailure); - } - void MatchResult(RawResult result) - { - // check to see if it could be an out-of-band pubsub message - if (connectionType == ConnectionType.Subscription && result.Type == ResultType.MultiBulk) - { // out of band message does not match to a queued message - var items = result.GetItems(); - if (items.Length >= 3 && items[0].IsEqual(message)) - { - // special-case the configuration change broadcasts (we don't keep that in the usual pub/sub registry) - var configChanged = Multiplexer.ConfigurationChangedChannel; - if (configChanged != null && items[1].IsEqual(configChanged)) - { - EndPoint blame = null; - try - { - if (!items[2].IsEqual(RedisLiterals.ByteWildcard)) - { - blame = Format.TryParseEndPoint(items[2].GetString()); - } - } - catch { /* no biggie */ } - Multiplexer.Trace("Configuration changed: " + Format.ToString(blame), physicalName); - Multiplexer.ReconfigureIfNeeded(blame, true, "broadcast"); - } - - // invoke the handlers - var channel = items[1].AsRedisChannel(ChannelPrefix, RedisChannel.PatternMode.Literal); - Multiplexer.Trace("MESSAGE: " + channel, physicalName); - if (!channel.IsNull) - { - Multiplexer.OnMessage(channel, channel, items[2].AsRedisValue()); - } - return; // AND STOP PROCESSING! - } - else if (items.Length >= 4 && items[0].IsEqual(pmessage)) - { - var channel = items[2].AsRedisChannel(ChannelPrefix, RedisChannel.PatternMode.Literal); - Multiplexer.Trace("PMESSAGE: " + channel, physicalName); - if (!channel.IsNull) - { - var sub = items[1].AsRedisChannel(ChannelPrefix, RedisChannel.PatternMode.Pattern); - Multiplexer.OnMessage(sub, channel, items[3].AsRedisValue()); - } - return; // AND STOP PROCESSING! - } - - // if it didn't look like "[p]message", then we still need to process the pending queue - } - Multiplexer.Trace("Matching result...", physicalName); - Message msg; - lock (outstanding) - { - Multiplexer.Trace(outstanding.Count == 0, "Nothing to respond to!", physicalName); - msg = outstanding.Dequeue(); - } - - Multiplexer.Trace("Response to: " + msg.ToString(), physicalName); - if (msg.ComputeResult(this, result)) - { - Bridge.CompleteSyncOrAsync(msg); - } - } - partial void OnCloseEcho(); - - partial void OnCreateEcho(); - partial void OnDebugAbort(); - void ISocketCallback.OnHeartbeat() - { - try - { - Bridge.OnHeartbeat(true); // all the fun code is here - } - catch (Exception ex) - { - OnInternalError(ex); - } - } - - partial void OnWrapForLogging(ref Stream stream, string name); - private int ProcessBuffer(byte[] underlying, ref int offset, ref int count) - { - int messageCount = 0; - RawResult result; - do - { - int tmpOffset = offset, tmpCount = count; - // we want TryParseResult to be able to mess with these without consequence - result = TryParseResult(underlying, ref tmpOffset, ref tmpCount); - if (result.HasValue) - { - messageCount++; - // entire message: update the external counters - offset = tmpOffset; - count = tmpCount; - - Multiplexer.Trace(result.ToString(), physicalName); - MatchResult(result); - } - } while (result.HasValue); - return messageCount; - } - private bool ProcessReadBytes(int bytesRead) - { - if (bytesRead <= 0) - { - Multiplexer.Trace("EOF", physicalName); - RecordConnectionFailed(ConnectionFailureType.SocketClosed); - return false; - } - - Interlocked.Exchange(ref lastReadTickCount, Environment.TickCount); - - // reset unanswered write timestamp - VolatileWrapper.Write(ref firstUnansweredWriteTickCount, 0); - - ioBufferBytes += bytesRead; - Multiplexer.Trace("More bytes available: " + bytesRead + " (" + ioBufferBytes + ")", physicalName); - int offset = 0, count = ioBufferBytes; - int handled = ProcessBuffer(ioBuffer, ref offset, ref count); - Multiplexer.Trace("Processed: " + handled, physicalName); - if (handled != 0) - { - // read stuff - if (count != 0) - { - Multiplexer.Trace("Copying remaining bytes: " + count, physicalName); - // if anything was left over, we need to copy it to - // the start of the buffer so it can be used next time - Buffer.BlockCopy(ioBuffer, offset, ioBuffer, 0, count); - } - ioBufferBytes = count; - } - return true; - } - - void ISocketCallback.Read() - { - Interlocked.Increment(ref haveReader); - try - { - do - { - int space = EnsureSpaceAndComputeBytesToRead(); - int bytesRead = netStream?.Read(ioBuffer, ioBufferBytes, space) ?? 0; - - if (!ProcessReadBytes(bytesRead)) return; // EOF - } while (socketToken.Available != 0); - Multiplexer.Trace("Buffer exhausted", physicalName); - // ^^^ note that the socket manager will call us again when there is something to do - } - catch (Exception ex) - { - RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); - }finally - { - Interlocked.Decrement(ref haveReader); - } - } - - bool ISocketCallback.IsDataAvailable - { - get - { - try { return socketToken.Available > 0; } - catch { return false; } - } - } - private RawResult ReadArray(byte[] buffer, ref int offset, ref int count) - { - var itemCount = ReadLineTerminatedString(ResultType.Integer, buffer, ref offset, ref count); - if (itemCount.HasValue) - { - long i64; - if (!itemCount.TryGetInt64(out i64)) throw ExceptionFactory.ConnectionFailure(Multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid array length", Bridge.ServerEndPoint); - int itemCountActual = checked((int)i64); - - if (itemCountActual < 0) - { - //for null response by command like EXEC, RESP array: *-1\r\n - return new RawResult(ResultType.SimpleString, null, 0, 0); - } - else if (itemCountActual == 0) - { - //for zero array response by command like SCAN, Resp array: *0\r\n - return RawResult.EmptyArray; - } - - var arr = new RawResult[itemCountActual]; - for (int i = 0; i < itemCountActual; i++) - { - if (!(arr[i] = TryParseResult(buffer, ref offset, ref count)).HasValue) - return RawResult.Nil; - } - return new RawResult(arr); - } - return RawResult.Nil; - } - - private RawResult ReadBulkString(byte[] buffer, ref int offset, ref int count) - { - var prefix = ReadLineTerminatedString(ResultType.Integer, buffer, ref offset, ref count); - if (prefix.HasValue) - { - long i64; - if (!prefix.TryGetInt64(out i64)) throw ExceptionFactory.ConnectionFailure(Multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid bulk string length", Bridge.ServerEndPoint); - int bodySize = checked((int)i64); - if (bodySize < 0) - { - return new RawResult(ResultType.BulkString, null, 0, 0); - } - else if (count >= bodySize + 2) - { - if (buffer[offset + bodySize] != '\r' || buffer[offset + bodySize + 1] != '\n') - { - throw ExceptionFactory.ConnectionFailure(Multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid bulk string terminator", Bridge.ServerEndPoint); - } - var result = new RawResult(ResultType.BulkString, buffer, offset, bodySize); - offset += bodySize + 2; - count -= bodySize + 2; - return result; - } - } - return RawResult.Nil; - } - - private RawResult ReadLineTerminatedString(ResultType type, byte[] buffer, ref int offset, ref int count) - { - int max = offset + count - 2; - for (int i = offset; i < max; i++) - { - if (buffer[i + 1] == '\r' && buffer[i + 2] == '\n') - { - int len = i - offset + 1; - var result = new RawResult(type, buffer, offset, len); - count -= (len + 2); - offset += (len + 2); - return result; - } - } - return RawResult.Nil; - } - - void ISocketCallback.StartReading() - { - BeginReading(); - } - RawResult TryParseResult(byte[] buffer, ref int offset, ref int count) - { - if(count == 0) return RawResult.Nil; - - char resultType = (char)buffer[offset++]; - count--; - switch(resultType) - { - case '+': // simple string - return ReadLineTerminatedString(ResultType.SimpleString, buffer, ref offset, ref count); - case '-': // error - return ReadLineTerminatedString(ResultType.Error, buffer, ref offset, ref count); - case ':': // integer - return ReadLineTerminatedString(ResultType.Integer, buffer, ref offset, ref count); - case '$': // bulk string - return ReadBulkString(buffer, ref offset, ref count); - case '*': // array - return ReadArray(buffer, ref offset, ref count); - default: - throw new InvalidOperationException("Unexpected response prefix: " + (char)resultType); - } - } - - partial void DebugEmulateStaleConnection(ref int firstUnansweredWrite); - - public void CheckForStaleConnection(ref SocketManager.ManagerState managerState) - { - int firstUnansweredWrite = VolatileWrapper.Read(ref firstUnansweredWriteTickCount); - - DebugEmulateStaleConnection(ref firstUnansweredWrite); - - int now = Environment.TickCount; - - if (firstUnansweredWrite != 0 && (now - firstUnansweredWrite) > this.Multiplexer.RawConfig.ResponseTimeout) - { - this.RecordConnectionFailed(ConnectionFailureType.SocketFailure, ref managerState, origin: "CheckForStaleConnection"); - } - } - } - - -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ProfileContextTracker.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ProfileContextTracker.cs deleted file mode 100644 index 40f8112..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ProfileContextTracker.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading; - -namespace StackExchange.Redis -{ - /// - /// Big ol' wrapper around most of the profiling storage logic, 'cause it got too big to just live in ConnectionMultiplexer. - /// - sealed class ProfileContextTracker - { - /// - /// Necessary, because WeakReference can't be readily comparable (since the reference is... weak). - /// - /// This lets us detect leaks* with some reasonable confidence, and cleanup periodically. - /// - /// Some calisthenics are done to avoid allocating WeakReferences for no reason, as often - /// we're just looking up ProfileStorage. - /// - /// * Somebody starts profiling, but for whatever reason never *stops* with a context object - /// - struct ProfileContextCell : IEquatable - { - // This is a union of (object|WeakReference); if it's a WeakReference - // then we're actually interested in it's Target, otherwise - // we're concerned about the actual value of Reference - object Reference; - - // It is absolutely crucial that this value **never change** once instantiated - readonly int HashCode; - - public bool IsContextLeaked - { - get - { - object ignored; - return !TryGetTarget(out ignored); - } - } - - private ProfileContextCell(object forObj, bool isEphemeral) - { - HashCode = forObj.GetHashCode(); - - if (isEphemeral) - { - Reference = forObj; - } - else - { - Reference = new WeakReference(forObj, trackResurrection: true); // ughhh, have to handle finalizers - } - } - - /// - /// Suitable for use as a key into something. - /// - /// This instance **WILL NOT** keep forObj alive, so it can - /// be copied out of the calling method's scope. - /// - public static ProfileContextCell ToStoreUnder(object forObj) - { - return new ProfileContextCell(forObj, isEphemeral: false); - } - - /// - /// Only suitable for looking up. - /// - /// This instance **ABSOLUTELY WILL** keep forObj alive, so this - /// had better not be copied into anything outside the scope of the - /// calling method. - /// - public static ProfileContextCell ToLookupBy(object forObj) - { - return new ProfileContextCell(forObj, isEphemeral: true); - } - - bool TryGetTarget(out object target) - { - var asWeakRef = Reference as WeakReference; - - if (asWeakRef == null) - { - target = Reference; - return true; - } - - // Do not use IsAlive here, it's race city - target = asWeakRef.Target; - return target != null; - } - - public override bool Equals(object obj) - { - if (!(obj is ProfileContextCell)) return false; - - return Equals((ProfileContextCell)obj); - } - - public override int GetHashCode() - { - return HashCode; - } - - public bool Equals(ProfileContextCell other) - { - object thisObj, otherObj; - - if (other.TryGetTarget(out otherObj) != TryGetTarget(out thisObj)) return false; - - // dead references are equal - if (thisObj == null) return true; - - return thisObj.Equals(otherObj); - } - } - - // provided so default behavior doesn't do any boxing, for sure - sealed class ProfileContextCellComparer : IEqualityComparer - { - public static readonly ProfileContextCellComparer Singleton = new ProfileContextCellComparer(); - - private ProfileContextCellComparer() { } - - public bool Equals(ProfileContextCell x, ProfileContextCell y) - { - return x.Equals(y); - } - - public int GetHashCode(ProfileContextCell obj) - { - return obj.GetHashCode(); - } - } - - private long lastCleanupSweep; - private ConcurrentDictionary profiledCommands; - - public int ContextCount => profiledCommands.Count; - - public ProfileContextTracker() - { - profiledCommands = new ConcurrentDictionary(ProfileContextCellComparer.Singleton); - lastCleanupSweep = DateTime.UtcNow.Ticks; - } - - /// - /// Registers the passed context with a collection that can be retried with subsequent calls to TryGetValue. - /// - /// Returns false if the passed context object is already registered. - /// - public bool TryCreate(object ctx) - { - var cell = ProfileContextCell.ToStoreUnder(ctx); - - // we can't pass this as a delegate, because TryAdd may invoke the factory multiple times, - // which would lead to over allocation. - var storage = ConcurrentProfileStorageCollection.GetOrCreate(); - return profiledCommands.TryAdd(cell, storage); - } - - /// - /// Returns true and sets val to the tracking collection associated with the given context if the context - /// was registered with TryCreate. - /// - /// Otherwise returns false and sets val to null. - /// - public bool TryGetValue(object ctx, out ConcurrentProfileStorageCollection val) - { - var cell = ProfileContextCell.ToLookupBy(ctx); - return profiledCommands.TryGetValue(cell, out val); - } - - /// - /// Removes a context, setting all commands to a (non-thread safe) enumerable of - /// all the commands attached to that context. - /// - /// If the context was never registered, will return false and set commands to null. - /// - /// Subsequent calls to TryRemove with the same context will return false unless it is - /// re-registered with TryCreate. - /// - public bool TryRemove(object ctx, out ProfiledCommandEnumerable commands) - { - var cell = ProfileContextCell.ToLookupBy(ctx); - ConcurrentProfileStorageCollection storage; - if (!profiledCommands.TryRemove(cell, out storage)) - { - commands = default(ProfiledCommandEnumerable); - return false; - } - - commands = storage.EnumerateAndReturnForReuse(); - return true; - } - - /// - /// If enough time has passed (1 minute) since the last call, this does walk of all contexts - /// and removes those that the GC has collected. - /// - public bool TryCleanup() - { - const long SweepEveryTicks = 600000000; // once a minute, tops - - var now = DateTime.UtcNow.Ticks; // resolution on this isn't great, but it's good enough - var last = lastCleanupSweep; - var since = now - last; - if (since < SweepEveryTicks) return false; - - // this is just to keep other threads from wasting time, in theory - // it'd be perfectly safe for this to run concurrently - var saw = Interlocked.CompareExchange(ref lastCleanupSweep, now, last); - if (saw != last) return false; - - if (profiledCommands.Count == 0) return false; - - using(var e = profiledCommands.GetEnumerator()) - { - while(e.MoveNext()) - { - var pair = e.Current; - if(pair.Key.IsContextLeaked) - { - ConcurrentProfileStorageCollection abandoned; - if(profiledCommands.TryRemove(pair.Key, out abandoned)) - { - // shove it back in the pool, but don't bother enumerating - abandoned.ReturnForReuse(); - } - } - } - } - - return true; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ProfileStorage.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ProfileStorage.cs deleted file mode 100644 index ca9b13b..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ProfileStorage.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System; -using System.Diagnostics; -using System.Net; -using System.Threading; - -namespace StackExchange.Redis -{ - class ProfileStorage : IProfiledCommand - { - #region IProfiledCommand Impl - public EndPoint EndPoint => Server.EndPoint; - - public int Db => Message.Db; - - public string Command => Message.Command.ToString(); - - public CommandFlags Flags => Message.Flags; - - public DateTime CommandCreated => MessageCreatedDateTime; - - public TimeSpan CreationToEnqueued => TimeSpan.FromTicks(EnqueuedTimeStamp - MessageCreatedTimeStamp); - - public TimeSpan EnqueuedToSending => TimeSpan.FromTicks(RequestSentTimeStamp - EnqueuedTimeStamp); - - public TimeSpan SentToResponse => TimeSpan.FromTicks(ResponseReceivedTimeStamp - RequestSentTimeStamp); - - public TimeSpan ResponseToCompletion => TimeSpan.FromTicks(CompletedTimeStamp - ResponseReceivedTimeStamp); - - public TimeSpan ElapsedTime => TimeSpan.FromTicks(CompletedTimeStamp - MessageCreatedTimeStamp); - - public IProfiledCommand RetransmissionOf => OriginalProfiling; - - public RetransmissionReasonType? RetransmissionReason { get; } - - #endregion - - public ProfileStorage NextElement { get; set; } - - private Message Message; - private ServerEndPoint Server; - private ProfileStorage OriginalProfiling; - - private DateTime MessageCreatedDateTime; - private long MessageCreatedTimeStamp; - private long EnqueuedTimeStamp; - private long RequestSentTimeStamp; - private long ResponseReceivedTimeStamp; - private long CompletedTimeStamp; - - private ConcurrentProfileStorageCollection PushToWhenFinished; - - private ProfileStorage(ConcurrentProfileStorageCollection pushTo, ServerEndPoint server, ProfileStorage resentFor, RetransmissionReasonType? reason) - { - PushToWhenFinished = pushTo; - OriginalProfiling = resentFor; - Server = server; - RetransmissionReason = reason; - } - - public static ProfileStorage NewWithContext(ConcurrentProfileStorageCollection pushTo, ServerEndPoint server) - { - return new ProfileStorage(pushTo, server, null, null); - } - - public static ProfileStorage NewAttachedToSameContext(ProfileStorage resentFor, ServerEndPoint server, bool isMoved) - { - return new ProfileStorage(resentFor.PushToWhenFinished, server, resentFor, isMoved ? RetransmissionReasonType.Moved : RetransmissionReasonType.Ask); - } - - public void SetMessage(Message msg) - { - // This method should never be called twice - if (Message != null) throw new InvalidOperationException(); - - Message = msg; - MessageCreatedDateTime = msg.createdDateTime; - MessageCreatedTimeStamp = msg.createdTimestamp; - } - - public void SetEnqueued() - { - // This method should never be called twice - if (EnqueuedTimeStamp > 0) throw new InvalidOperationException(); - - EnqueuedTimeStamp = Stopwatch.GetTimestamp(); - } - - public void SetRequestSent() - { - // This method should never be called twice - if (RequestSentTimeStamp > 0) throw new InvalidOperationException(); - - RequestSentTimeStamp = Stopwatch.GetTimestamp(); - } - - public void SetResponseReceived() - { - if (ResponseReceivedTimeStamp > 0) throw new InvalidOperationException(); - - ResponseReceivedTimeStamp = Stopwatch.GetTimestamp(); - } - - public void SetCompleted() - { - // this method can be called multiple times, depending on how the task completed (async vs not) - // so we actually have to guard against it. - - var now = Stopwatch.GetTimestamp(); - var oldVal = Interlocked.CompareExchange(ref CompletedTimeStamp, now, 0); - - // second call - if (oldVal != 0) return; - - // only push on the first call, no dupes! - PushToWhenFinished.Add(this); - } - - public override string ToString() - { - return - $@"EndPoint = {EndPoint} -Db = {Db} -Command = {Command} -CommandCreated = {CommandCreated:u} -CreationToEnqueued = {CreationToEnqueued} -EnqueuedToSending = {EnqueuedToSending} -SentToResponse = {SentToResponse} -ResponseToCompletion = {ResponseToCompletion} -ElapsedTime = {ElapsedTime} -Flags = {Flags} -RetransmissionOf = ({RetransmissionOf})"; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RawResult.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RawResult.cs deleted file mode 100644 index 4996982..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RawResult.cs +++ /dev/null @@ -1,364 +0,0 @@ -using System; -using System.Text; - -namespace StackExchange.Redis -{ - - - internal struct RawResult - { - public static readonly RawResult EmptyArray = new RawResult(new RawResult[0]); - public static readonly RawResult Nil = new RawResult(); - private static readonly byte[] emptyBlob = new byte[0]; - private readonly int offset, count; - private Array arr; - public RawResult(ResultType resultType, byte[] buffer, int offset, int count) - { - switch (resultType) - { - case ResultType.SimpleString: - case ResultType.Error: - case ResultType.Integer: - case ResultType.BulkString: - break; - default: - throw new ArgumentOutOfRangeException(nameof(resultType)); - } - Type = resultType; - arr = buffer; - this.offset = offset; - this.count = count; - } - - public RawResult(RawResult[] arr) - { - if (arr == null) throw new ArgumentNullException(nameof(arr)); - Type = ResultType.MultiBulk; - offset = 0; - count = arr.Length; - this.arr = arr; - } - - public bool HasValue => Type != ResultType.None; - - public bool IsError => Type == ResultType.Error; - - public ResultType Type { get; } - - internal bool IsNull => arr == null; - - public override string ToString() - { - if (arr == null) - { - return "(null)"; - } - switch (Type) - { - case ResultType.SimpleString: - case ResultType.Integer: - case ResultType.Error: - return $"{Type}: {GetString()}"; - case ResultType.BulkString: - return $"{Type}: {count} bytes"; - case ResultType.MultiBulk: - return $"{Type}: {count} items"; - default: - return "(unknown)"; - } - } - internal RedisChannel AsRedisChannel(byte[] channelPrefix, RedisChannel.PatternMode mode) - { - switch (Type) - { - case ResultType.SimpleString: - case ResultType.BulkString: - if (channelPrefix == null) - { - return new RedisChannel(GetBlob(), mode); - } - if (AssertStarts(channelPrefix)) - { - var src = (byte[])arr; - - byte[] copy = new byte[count - channelPrefix.Length]; - Buffer.BlockCopy(src, offset + channelPrefix.Length, copy, 0, copy.Length); - return new RedisChannel(copy, mode); - } - return default(RedisChannel); - default: - throw new InvalidCastException("Cannot convert to RedisChannel: " + Type); - } - } - - internal RedisKey AsRedisKey() - { - switch (Type) - { - case ResultType.SimpleString: - case ResultType.BulkString: - return (RedisKey)GetBlob(); - default: - throw new InvalidCastException("Cannot convert to RedisKey: " + Type); - } - } - internal RedisValue AsRedisValue() - { - switch (Type) - { - case ResultType.Integer: - long i64; - if (TryGetInt64(out i64)) return (RedisValue)i64; - break; - case ResultType.SimpleString: - case ResultType.BulkString: - return (RedisValue)GetBlob(); - } - throw new InvalidCastException("Cannot convert to RedisValue: " + Type); - } - - internal unsafe bool IsEqual(byte[] expected) - { - if (expected == null) throw new ArgumentNullException(nameof(expected)); - if (expected.Length != count) return false; - var actual = arr as byte[]; - if (actual == null) return false; - - int octets = count / 8, spare = count % 8; - fixed (byte* actual8 = &actual[offset]) - fixed (byte* expected8 = expected) - { - long* actual64 = (long*)actual8; - long* expected64 = (long*)expected8; - - for (int i = 0; i < octets; i++) - { - if (actual64[i] != expected64[i]) return false; - } - int index = count - spare; - while (spare-- != 0) - { - if (actual8[index] != expected8[index]) return false; - } - } - return true; - } - - internal bool AssertStarts(byte[] expected) - { - if (expected == null) throw new ArgumentNullException(nameof(expected)); - if (expected.Length > count) return false; - var actual = arr as byte[]; - if (actual == null) return false; - - for (int i = 0; i < expected.Length; i++) - { - if (expected[i] != actual[offset + i]) return false; - } - return true; - } - internal byte[] GetBlob() - { - var src = (byte[])arr; - if (src == null) return null; - - if (count == 0) return emptyBlob; - - byte[] copy = new byte[count]; - Buffer.BlockCopy(src, offset, copy, 0, count); - return copy; - } - - internal bool GetBoolean() - { - if (count != 1) throw new InvalidCastException(); - byte[] actual = arr as byte[]; - if (actual == null) throw new InvalidCastException(); - switch (actual[offset]) - { - case (byte)'1': return true; - case (byte)'0': return false; - default: throw new InvalidCastException(); - } - } - - internal RawResult[] GetItems() - { - return (RawResult[])arr; - } - - internal RedisKey[] GetItemsAsKeys() - { - RawResult[] items = GetItems(); - if (items == null) - { - return null; - } - else if (items.Length == 0) - { - return RedisKey.EmptyArray; - } - else - { - var arr = new RedisKey[items.Length]; - for (int i = 0; i < arr.Length; i++) - { - arr[i] = items[i].AsRedisKey(); - } - return arr; - } - } - - internal RedisValue[] GetItemsAsValues() - { - RawResult[] items = GetItems(); - if (items == null) - { - return null; - } - else if (items.Length == 0) - { - return RedisValue.EmptyArray; - } - else - { - var arr = new RedisValue[items.Length]; - for (int i = 0; i < arr.Length; i++) - { - arr[i] = items[i].AsRedisValue(); - } - return arr; - } - } - static readonly string[] NilStrings = new string[0]; - internal string[] GetItemsAsStrings() - { - RawResult[] items = GetItems(); - if (items == null) - { - return null; - } - else if (items.Length == 0) - { - return NilStrings; - } - else - { - var arr = new string[items.Length]; - for (int i = 0; i < arr.Length; i++) - { - arr[i] = (string)(items[i].AsRedisValue()); - } - return arr; - } - } - internal GeoPosition? GetItemsAsGeoPosition() - { - RawResult[] items = GetItems(); - if (items == null || items.Length == 0) - { - return null; - } - - var coords = items[0].GetArrayOfRawResults(); - if (coords == null) - { - return null; - } - return new GeoPosition((double)coords[0].AsRedisValue(), (double)coords[1].AsRedisValue()); - } - internal GeoPosition?[] GetItemsAsGeoPositionArray() - { - RawResult[] items = GetItems(); - if (items == null) - { - return null; - } - else if (items.Length == 0) - { - return new GeoPosition?[0]; - } - else - { - var arr = new GeoPosition?[items.Length]; - for (int i = 0; i < arr.Length; i++) - { - RawResult[] item = items[i].GetArrayOfRawResults(); - if (item == null) - { - arr[i] = null; - } - else - { - arr[i] = new GeoPosition((double)item[0].AsRedisValue(), (double)item[1].AsRedisValue()); - } - } - return arr; - } - } - - internal RawResult[] GetItemsAsRawResults() - { - return GetItems(); - } - - - // returns an array of RawResults - internal RawResult[] GetArrayOfRawResults() - { - if (arr == null) - { - return null; - } - else if (arr.Length == 0) - { - return new RawResult[0]; - } - else - { - var rawResultArray = new RawResult[arr.Length]; - for (int i = 0; i < arr.Length; i++) - { - var rawResult = (RawResult)arr.GetValue(i); - rawResultArray.SetValue(rawResult, i); - } - return rawResultArray; - } - } - - internal string GetString() - { - if (arr == null) return null; - var blob = (byte[])arr; - if (blob.Length == 0) return ""; - return Encoding.UTF8.GetString(blob, offset, count); - } - - internal bool TryGetDouble(out double val) - { - if (arr == null) - { - val = 0; - return false; - } - long i64; - if (TryGetInt64(out i64)) - { - val = i64; - return true; - } - return Format.TryParseDouble(GetString(), out val); - } - - internal bool TryGetInt64(out long value) - { - if (arr == null) - { - value = 0; - return false; - } - return RedisValue.TryParseInt64(arr as byte[], offset, count, out value); - } - } -} - diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisBase.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisBase.cs deleted file mode 100644 index 97568ad..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisBase.cs +++ /dev/null @@ -1,340 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - internal abstract partial class RedisBase : IRedis - { - internal static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - internal readonly ConnectionMultiplexer multiplexer; - protected readonly object asyncState; - - internal RedisBase(ConnectionMultiplexer multiplexer, object asyncState) - { - this.multiplexer = multiplexer; - this.asyncState = asyncState; - } - - ConnectionMultiplexer IRedisAsync.Multiplexer => multiplexer; - - public virtual TimeSpan Ping(CommandFlags flags = CommandFlags.None) - { - var msg = GetTimerMessage(flags); - return ExecuteSync(msg, ResultProcessor.ResponseTimer); - } - - public virtual Task PingAsync(CommandFlags flags = CommandFlags.None) - { - var msg = GetTimerMessage(flags); - return ExecuteAsync(msg, ResultProcessor.ResponseTimer); - } - - public void Quit(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.QUIT); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - - public Task QuitAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.QUIT); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public override string ToString() - { - return multiplexer.ToString(); - } - - public bool TryWait(Task task) - { - return task.Wait(multiplexer.TimeoutMilliseconds); - } - - public void Wait(Task task) - { - multiplexer.Wait(task); - } - - public T Wait(Task task) - { - return multiplexer.Wait(task); - } - - public void WaitAll(params Task[] tasks) - { - multiplexer.WaitAll(tasks); - } - - internal virtual Task ExecuteAsync(Message message, ResultProcessor processor, ServerEndPoint server = null) - { - if (message == null) return CompletedTask.Default(asyncState); - multiplexer.CheckMessage(message); - return multiplexer.ExecuteAsyncImpl(message, processor, asyncState, server); - } - - internal virtual T ExecuteSync(Message message, ResultProcessor processor, ServerEndPoint server = null) - { - if (message == null) return default(T); // no-op - multiplexer.CheckMessage(message); - return multiplexer.ExecuteSyncImpl(message, processor, server); - } - - internal virtual RedisFeatures GetFeatures(int db, RedisKey key, CommandFlags flags, out ServerEndPoint server) - { - server = multiplexer.SelectServer(db, RedisCommand.PING, flags, key); - var version = server == null ? multiplexer.RawConfig.DefaultVersion : server.Version; - return new RedisFeatures(version); - } - - protected void WhenAlwaysOrExists(When when) - { - switch (when) - { - case When.Always: - case When.Exists: - break; - default: - throw new ArgumentException(when + " is not valid in this context; the permitted values are: Always, Exists"); - } - } - - protected void WhenAlwaysOrExistsOrNotExists(When when) - { - switch (when) - { - case When.Always: - case When.Exists: - case When.NotExists: - break; - default: - throw new ArgumentException(when + " is not valid in this context; the permitted values are: Always, Exists, NotExists"); - } - } - - protected void WhenAlwaysOrNotExists(When when) - { - switch (when) - { - case When.Always: - case When.NotExists: - break; - default: - throw new ArgumentException(when + " is not valid in this context; the permitted values are: Always, NotExists"); - } - } - - private ResultProcessor.TimingProcessor.TimerMessage GetTimerMessage(CommandFlags flags) - { - // do the best we can with available commands - var map = multiplexer.CommandMap; - if(map.IsAvailable(RedisCommand.PING)) - return ResultProcessor.TimingProcessor.CreateMessage(-1, flags, RedisCommand.PING); - if(map.IsAvailable(RedisCommand.TIME)) - return ResultProcessor.TimingProcessor.CreateMessage(-1, flags, RedisCommand.TIME); - if (map.IsAvailable(RedisCommand.ECHO)) - return ResultProcessor.TimingProcessor.CreateMessage(-1, flags, RedisCommand.ECHO, RedisLiterals.PING); - // as our fallback, we'll do something odd... we'll treat a key like a value, out of sheer desperation - // note: this usually means: twemproxy - in which case we're fine anyway, since the proxy does the routing - return ResultProcessor.TimingProcessor.CreateMessage(0, flags, RedisCommand.EXISTS, (RedisValue)multiplexer.UniqueId); - } - - - internal static class CursorUtils - { - internal const int Origin = 0, DefaultPageSize = 10; - internal static bool IsNil(RedisValue pattern) - { - if (pattern.IsNullOrEmpty) return true; - if (pattern.IsInteger) return false; - byte[] rawValue = pattern; - return rawValue.Length == 1 && rawValue[0] == '*'; - } - } - internal abstract class CursorEnumerable : IEnumerable, IScanningCursor - { - private readonly RedisBase redis; - private readonly ServerEndPoint server; - protected readonly int db; - protected readonly CommandFlags flags; - protected readonly int pageSize, initialOffset; - protected readonly long initialCursor; - private volatile IScanningCursor activeCursor; - - protected CursorEnumerable(RedisBase redis, ServerEndPoint server, int db, int pageSize, long cursor, int pageOffset, CommandFlags flags) - { - if (pageOffset < 0) throw new ArgumentOutOfRangeException(nameof(pageOffset)); - this.redis = redis; - this.server = server; - this.db = db; - this.pageSize = pageSize; - this.flags = flags; - initialCursor = cursor; - initialOffset = pageOffset; - } - - public IEnumerator GetEnumerator() - { - return new CursorEnumerator(this); - } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - internal struct ScanResult - { - public readonly long Cursor; - public readonly T[] Values; - public ScanResult(long cursor, T[] values) - { - Cursor = cursor; - Values = values; - } - } - - protected abstract Message CreateMessage(long cursor); - - - protected abstract ResultProcessor Processor { get; } - - protected ScanResult GetNextPageSync(IScanningCursor obj, long cursor) - { - activeCursor = obj; - return redis.ExecuteSync(CreateMessage(cursor), Processor, server); - } - protected Task GetNextPageAsync(IScanningCursor obj, long cursor) - { - activeCursor = obj; - return redis.ExecuteAsync(CreateMessage(cursor), Processor, server); - } - protected ScanResult Wait(Task pending) - { - return redis.Wait(pending); - } - - class CursorEnumerator : IEnumerator, IScanningCursor - { - private CursorEnumerable parent; - public CursorEnumerator(CursorEnumerable parent) - { - if (parent == null) throw new ArgumentNullException(nameof(parent)); - this.parent = parent; - Reset(); - } - public T Current => page[pageIndex]; - - void IDisposable.Dispose() { parent = null; state = State.Disposed; } - - object System.Collections.IEnumerator.Current => page[pageIndex]; - - private void LoadNextPageAsync() - { - if(pending == null && nextCursor != 0) - pending = parent.GetNextPageAsync(this, nextCursor); - } - - private bool SimpleNext() - { - if (page != null && ++pageIndex < page.Length) - { - // first of a new page? cool; start a new background op, because we're about to exit the iterator - if (pageIndex == 0) LoadNextPageAsync(); - return true; - } - return false; - } - - T[] page; - Task pending; - int pageIndex; - private long currentCursor, nextCursor; - - private State state; - private enum State : byte - { - Initial, - Running, - Complete, - Disposed, - } - - void ProcessReply(ScanResult result) - { - currentCursor = nextCursor; - nextCursor = result.Cursor; - pageIndex = -1; - page = result.Values; - pending = null; - } - - public bool MoveNext() - { - switch(state) - { - case State.Complete: - return false; - case State.Initial: - ProcessReply(parent.GetNextPageSync(this, nextCursor)); - pageIndex = parent.initialOffset - 1; // will be incremented in a moment - state = State.Running; - LoadNextPageAsync(); - goto case State.Running; - case State.Running: - // are we working through the current buffer? - if (SimpleNext()) return true; - - // do we have an outstanding operation? wait for the background task to finish - while (pending != null) - { - ProcessReply(parent.Wait(pending)); - if (SimpleNext()) return true; - } - - // nothing outstanding? wait synchronously - while(nextCursor != 0) - { - ProcessReply(parent.GetNextPageSync(this, nextCursor)); - if (SimpleNext()) return true; - } - - // we're exhausted - state = State.Complete; - return false; - case State.Disposed: - default: - throw new ObjectDisposedException(GetType().Name); - } - } - - public void Reset() - { - if(state == State.Disposed) throw new ObjectDisposedException(GetType().Name); - nextCursor = currentCursor = parent.initialCursor; - pageIndex = parent.initialOffset; // don't -1 here; this makes it look "right" before incremented - state = State.Initial; - page = null; - pending = null; - } - - long IScanningCursor.Cursor => currentCursor; - - int IScanningCursor.PageSize => parent.pageSize; - - int IScanningCursor.PageOffset => pageIndex; - } - - long IScanningCursor.Cursor - { - get { var tmp = activeCursor; return tmp?.Cursor ?? initialCursor; } - } - - int IScanningCursor.PageSize => pageSize; - - int IScanningCursor.PageOffset - { - get { var tmp = activeCursor; return tmp?.PageOffset ?? initialOffset; } - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisBatch.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisBatch.cs deleted file mode 100644 index b018974..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisBatch.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - class RedisBatch : RedisDatabase, IBatch - { - List pending; - - public RedisBatch(RedisDatabase wrapped, object asyncState) : base(wrapped.multiplexer, wrapped.Database, asyncState ?? wrapped.AsyncState) - { - } - - public void Execute() - { - var snapshot = pending; - pending = null; - if (snapshot == null || snapshot.Count == 0) return; - - // group into per-bridge chunks - var byBridge = new Dictionary>(); - - // optimisation: assume most things are in a single bridge - PhysicalBridge lastBridge = null; - List lastList = null; - foreach (var message in snapshot) - { - var server = multiplexer.SelectServer(message); - if (server == null) - { - FailNoServer(snapshot); - throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, multiplexer.IncludePerformanceCountersInExceptions, message.Command, message, server,multiplexer.GetServerSnapshot()); - } - var bridge = server.GetBridge(message.Command); - if (bridge == null) - { - FailNoServer(snapshot); - throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, multiplexer.IncludePerformanceCountersInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot()); - } - - // identity a list - List list; - if (bridge == lastBridge) - { - list = lastList; - } - else if (!byBridge.TryGetValue(bridge, out list)) - { - list = new List(); - byBridge.Add(bridge, list); - } - lastBridge = bridge; - lastList = list; - - list.Add(message); - } - - foreach (var pair in byBridge) - { - if (!pair.Key.TryEnqueue(pair.Value, pair.Key.ServerEndPoint.IsSlave)) - { - FailNoServer(pair.Value); - } - } - } - - internal override Task ExecuteAsync(Message message, ResultProcessor processor, ServerEndPoint server = null) - { - if (message == null) return CompletedTask.Default(asyncState); - multiplexer.CheckMessage(message); - - // prepare the inner command as a task - Task task; - if (message.IsFireAndForget) - { - task = CompletedTask.Default(null); // F+F explicitly does not get async-state - } - else - { - var tcs = TaskSource.CreateDenyExecSync(asyncState); - var source = ResultBox.Get(tcs); - message.SetSource(source, processor); - task = tcs.Task; - } - - // store it - (pending ?? (pending = new List())).Add(message); - return task; - } - - internal override T ExecuteSync(Message message, ResultProcessor processor, ServerEndPoint server = null) - { - throw new NotSupportedException("ExecuteSync cannot be used inside a transaction"); - } - private void FailNoServer(List messages) - { - if (messages == null) return; - var completion = multiplexer.UnprocessableCompletionManager; - foreach(var msg in messages) - { - msg.Fail(ConnectionFailureType.UnableToResolvePhysicalConnection, null); - completion.CompleteSyncOrAsync(msg); - - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisChannel.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisChannel.cs deleted file mode 100644 index 47caf79..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisChannel.cs +++ /dev/null @@ -1,261 +0,0 @@ -using System; -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Represents a pub/sub channel name - /// - public struct RedisChannel : IEquatable - { - internal static readonly RedisChannel[] EmptyArray = new RedisChannel[0]; - - private readonly byte[] value; - - /// - /// Create a new redis channel from a buffer, explicitly controlling the pattern mode - /// - public RedisChannel(byte[] value, PatternMode mode) : this(value, DeterminePatternBased(value, mode)) - { - } - - /// - /// Create a new redis channel from a string, explicitly controlling the pattern mode - /// - public RedisChannel(string value, PatternMode mode) : this(value == null ? null : Encoding.UTF8.GetBytes(value), mode) - { - } - - private RedisChannel(byte[] value, bool isPatternBased) - { - this.value = value; - IsPatternBased = isPatternBased; - } - private static bool DeterminePatternBased(byte[] value, PatternMode mode) - { - switch (mode) - { - case PatternMode.Auto: - return value != null && Array.IndexOf(value, (byte)'*') >= 0; - case PatternMode.Literal: return false; - case PatternMode.Pattern: return true; - default: - throw new ArgumentOutOfRangeException(nameof(mode)); - } - } - - /// - /// Indicates whether the channel-name is either null or a zero-length value - /// - public bool IsNullOrEmpty => value == null || value.Length == 0; - - internal bool IsNull => value == null; - - internal byte[] Value => value; - - /// - /// Indicate whether two channel names are not equal - /// - public static bool operator !=(RedisChannel x, RedisChannel y) - { - return !(x == y); - } - - /// - /// Indicate whether two channel names are not equal - /// - public static bool operator !=(string x, RedisChannel y) - { - return !(x == y); - } - - /// - /// Indicate whether two channel names are not equal - /// - public static bool operator !=(byte[] x, RedisChannel y) - { - return !(x == y); - } - - /// - /// Indicate whether two channel names are not equal - /// - public static bool operator !=(RedisChannel x, string y) - { - return !(x == y); - } - - /// - /// Indicate whether two channel names are not equal - /// - public static bool operator !=(RedisChannel x, byte[] y) - { - return !(x == y); - } - - /// - /// Indicate whether two channel names are equal - /// - public static bool operator ==(RedisChannel x, RedisChannel y) - { - return x.IsPatternBased == y.IsPatternBased && RedisValue.Equals(x.value, y.value); - } - - /// - /// Indicate whether two channel names are equal - /// - public static bool operator ==(string x, RedisChannel y) - { - return RedisValue.Equals(x == null ? null : Encoding.UTF8.GetBytes(x), y.value); - } - - /// - /// Indicate whether two channel names are equal - /// - public static bool operator ==(byte[] x, RedisChannel y) - { - return RedisValue.Equals(x, y.value); - } - - /// - /// Indicate whether two channel names are equal - /// - public static bool operator ==(RedisChannel x, string y) - { - return RedisValue.Equals(x.value, y == null ? null : Encoding.UTF8.GetBytes(y)); - } - - /// - /// Indicate whether two channel names are equal - /// - public static bool operator ==(RedisChannel x, byte[] y) - { - return RedisValue.Equals(x.value, y); - } - - /// - /// See Object.Equals - /// - public override bool Equals(object obj) - { - if (obj is RedisChannel) - { - return RedisValue.Equals(value, ((RedisChannel)obj).value); - } - if (obj is string) - { - return RedisValue.Equals(value, Encoding.UTF8.GetBytes((string)obj)); - } - if (obj is byte[]) - { - return RedisValue.Equals(value, (byte[])obj); - } - return false; - } - - /// - /// Indicate whether two channel names are equal - /// - public bool Equals(RedisChannel other) - { - return IsPatternBased == other.IsPatternBased && - RedisValue.Equals(value, other.value); - } - - /// - /// See Object.GetHashCode - /// - public override int GetHashCode() - { - return RedisValue.GetHashCode(value) + (IsPatternBased ? 1 : 0); - } - - /// - /// Obtains a string representation of the channel name - /// - public override string ToString() - { - return ((string)this) ?? "(null)"; - } - - internal static bool AssertStarts(byte[] value, byte[] expected) - { - for (int i = 0; i < expected.Length; i++) - { - if (expected[i] != value[i]) return false; - } - return true; - } - - internal void AssertNotNull() - { - if (IsNull) throw new ArgumentException("A null key is not valid in this context"); - } - - internal RedisChannel Clone() - { - byte[] clone = (byte[]) value?.Clone(); - return clone; - } - - internal readonly bool IsPatternBased; - - /// - /// The matching pattern for this channel - /// - public enum PatternMode - { - /// - /// Will be treated as a pattern if it includes * - /// - Auto = 0, - /// - /// Never a pattern - /// - Literal = 1, - /// - /// Always a pattern - /// - Pattern = 2 - } - /// - /// Create a channel name from a String - /// - public static implicit operator RedisChannel(string key) - { - if (key == null) return default(RedisChannel); - return new RedisChannel(Encoding.UTF8.GetBytes(key), PatternMode.Auto); - } - /// - /// Create a channel name from a Byte[] - /// - public static implicit operator RedisChannel(byte[] key) - { - if (key == null) return default(RedisChannel); - return new RedisChannel(key, PatternMode.Auto); - } - /// - /// Obtain the channel name as a Byte[] - /// - public static implicit operator byte[] (RedisChannel key) - { - return key.value; - } - /// - /// Obtain the channel name as a String - /// - public static implicit operator string (RedisChannel key) - { - var arr = key.value; - if (arr == null) return null; - try - { - return Encoding.UTF8.GetString(arr); - } - catch - { - return BitConverter.ToString(arr); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisCommand.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisCommand.cs deleted file mode 100644 index 2fbc975..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisCommand.cs +++ /dev/null @@ -1,189 +0,0 @@ -namespace StackExchange.Redis -{ - enum RedisCommand - { - APPEND, - ASKING, - AUTH, - - BGREWRITEAOF, - BGSAVE, - BITCOUNT, - BITOP, - BITPOS, - BLPOP, - BRPOP, - BRPOPLPUSH, - - CLIENT, - CLUSTER, - CONFIG, - - DBSIZE, - DEBUG, - DECR, - DECRBY, - DEL, - DISCARD, - DUMP, - - ECHO, - EVAL, - EVALSHA, - EXEC, - EXISTS, - EXPIRE, - EXPIREAT, - - FLUSHALL, - FLUSHDB, - - GEOADD, - GEODIST, - GEOHASH, - GEOPOS, - GEORADIUS, - GEORADIUSBYMEMBER, - - GET, - GETBIT, - GETRANGE, - GETSET, - - HDEL, - HEXISTS, - HGET, - HGETALL, - HINCRBY, - HINCRBYFLOAT, - HKEYS, - HLEN, - HMGET, - HMSET, - HSCAN, - HSET, - HSETNX, - HVALS, - - INCR, - INCRBY, - INCRBYFLOAT, - INFO, - - KEYS, - - LASTSAVE, - LINDEX, - LINSERT, - LLEN, - LPOP, - LPUSH, - LPUSHX, - LRANGE, - LREM, - LSET, - LTRIM, - - MGET, - MIGRATE, - MONITOR, - MOVE, - MSET, - MSETNX, - MULTI, - - OBJECT, - - PERSIST, - PEXPIRE, - PEXPIREAT, - PFADD, - PFCOUNT, - PFMERGE, - PING, - PSETEX, - PSUBSCRIBE, - PTTL, - PUBLISH, - PUBSUB, - PUNSUBSCRIBE, - - QUIT, - - RANDOMKEY, - READONLY, - READWRITE, - RENAME, - RENAMENX, - RESTORE, - RPOP, - RPOPLPUSH, - RPUSH, - RPUSHX, - - SADD, - SAVE, - SCAN, - SCARD, - SCRIPT, - SDIFF, - SDIFFSTORE, - SELECT, - SENTINEL, - SET, - SETBIT, - SETEX, - SETNX, - SETRANGE, - SHUTDOWN, - SINTER, - SINTERSTORE, - SISMEMBER, - SLAVEOF, - SLOWLOG, - SMEMBERS, - SMOVE, - SORT, - SPOP, - SRANDMEMBER, - SREM, - STRLEN, - SUBSCRIBE, - SUNION, - SUNIONSTORE, - SSCAN, - SYNC, - - TIME, - TTL, - TYPE, - - UNSUBSCRIBE, - UNWATCH, - - WATCH, - - ZADD, - ZCARD, - ZCOUNT, - ZINCRBY, - ZINTERSTORE, - ZLEXCOUNT, - ZRANGE, - ZRANGEBYLEX, - ZRANGEBYSCORE, - ZRANK, - ZREM, - ZREMRANGEBYLEX, - ZREMRANGEBYRANK, - ZREMRANGEBYSCORE, - ZREVRANGE, - ZREVRANGEBYSCORE, - ZREVRANK, - ZSCAN, - ZSCORE, - ZUNIONSTORE, - - UNKNOWN, - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisDatabase.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisDatabase.cs deleted file mode 100644 index e9be1a6..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisDatabase.cs +++ /dev/null @@ -1,2702 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - internal class RedisDatabase : RedisBase, IDatabase - { - internal RedisDatabase(ConnectionMultiplexer multiplexer, int db, object asyncState) - : base(multiplexer, asyncState) - { - Database = db; - } - - public object AsyncState => asyncState; - - public int Database { get; } - - public IBatch CreateBatch(object asyncState) - { - if (this is IBatch) throw new NotSupportedException("Nested batches are not supported"); - return new RedisBatch(this, asyncState); - } - - public ITransaction CreateTransaction(object asyncState) - { - if (this is IBatch) throw new NotSupportedException("Nested transactions are not supported"); - return new RedisTransaction(this, asyncState); - } - - private ITransaction CreateTransactionIfAvailable(object asyncState) - { - var map = multiplexer.CommandMap; - if (!map.IsAvailable(RedisCommand.MULTI) || !map.IsAvailable(RedisCommand.EXEC)) - { - return null; - } - return CreateTransaction(asyncState); - } - - public RedisValue DebugObject(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.DEBUG, RedisLiterals.OBJECT, key); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - public Task DebugObjectAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.DEBUG, RedisLiterals.OBJECT, key); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public bool GeoAdd(RedisKey key, double longitude, double latitude, RedisValue member, CommandFlags flags = CommandFlags.None) - { - return GeoAdd(key, new GeoEntry(longitude, latitude, member), flags); - } - - public Task GeoAddAsync(RedisKey key, double longitude, double latitude, RedisValue member, CommandFlags flags = CommandFlags.None) - { - return GeoAddAsync(key, new GeoEntry(longitude, latitude, member), flags); - } - - public bool GeoAdd(RedisKey key, GeoEntry value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, value.Longitude, value.Latitude, value.Member); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - public Task GeoAddAsync(RedisKey key, GeoEntry value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, value.Longitude, value.Latitude, value.Member); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public long GeoAdd(RedisKey key, GeoEntry[] values, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, values); - return ExecuteSync(msg, ResultProcessor.Int64); - } - public Task GeoAddAsync(RedisKey key, GeoEntry[] values, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, values); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public bool GeoRemove(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - return SortedSetRemove(key, member, flags); - } - public Task GeoRemoveAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - return SortedSetRemoveAsync(key, member, flags); - } - - public double? GeoDistance(RedisKey key, RedisValue value0, RedisValue value1, GeoUnit unit = GeoUnit.Meters, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GEODIST, key, value0, value1, StackExchange.Redis.GeoPosition.GetRedisUnit(unit)); - return ExecuteSync(msg, ResultProcessor.NullableDouble); - } - public Task GeoDistanceAsync(RedisKey key, RedisValue value0, RedisValue value1, GeoUnit unit = GeoUnit.Meters, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GEODIST, key, value0, value1, StackExchange.Redis.GeoPosition.GetRedisUnit(unit)); - return ExecuteAsync(msg, ResultProcessor.NullableDouble); - } - public string[] GeoHash(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) - { - if (members == null) throw new ArgumentNullException(nameof(members)); - var redisValues = new RedisValue[members.Length]; - for (var i = 0; i < members.Length; i++) redisValues[i] = members[i]; - var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, redisValues); - return ExecuteSync(msg, ResultProcessor.StringArray); - } - public Task GeoHashAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) - { - if (members == null) throw new ArgumentNullException(nameof(members)); - var redisValues = new RedisValue[members.Length]; - for (var i = 0; i < members.Length; i++) redisValues[i] = members[i]; - var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, redisValues); - return ExecuteAsync(msg, ResultProcessor.StringArray); - } - - public string GeoHash(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, member); - return ExecuteSync(msg, ResultProcessor.String); - } - public Task GeoHashAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, member); - return ExecuteAsync(msg, ResultProcessor.String); - } - - public GeoPosition?[] GeoPosition(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) - { - if (members == null) throw new ArgumentNullException(nameof(members)); - var redisValues = new RedisValue[members.Length]; - for (var i = 0; i < members.Length; i++) redisValues[i] = members[i]; - var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, redisValues); - return ExecuteSync(msg, ResultProcessor.RedisGeoPositionArray); - } - public Task GeoPositionAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) - { - if (members == null) throw new ArgumentNullException(nameof(members)); - var redisValues = new RedisValue[members.Length]; - for (var i = 0; i < members.Length; i++) redisValues[i] = members[i]; - var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, redisValues); - return ExecuteAsync(msg, ResultProcessor.RedisGeoPositionArray); - } - - public GeoPosition? GeoPosition(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, member); - return ExecuteSync(msg, ResultProcessor.RedisGeoPosition); - } - public Task GeoPositionAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, member); - return ExecuteAsync(msg, ResultProcessor.RedisGeoPosition); - } - static readonly RedisValue - WITHCOORD = Encoding.ASCII.GetBytes("WITHCOORD"), - WITHDIST = Encoding.ASCII.GetBytes("WITHDIST"), - WITHHASH = Encoding.ASCII.GetBytes("WITHHASH"), - COUNT = Encoding.ASCII.GetBytes("COUNT"), - ASC = Encoding.ASCII.GetBytes("ASC"), - DESC = Encoding.ASCII.GetBytes("DESC"); - private Message GetGeoRadiusMessage(RedisKey key, RedisValue? member, double longitude, double latitude, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags) - { - var redisValues = new List(); - RedisCommand command; - if (member == null) - { - redisValues.Add(longitude); - redisValues.Add(latitude); - command = RedisCommand.GEORADIUS; - } - else - { - redisValues.Add(member.Value); - command = RedisCommand.GEORADIUSBYMEMBER; - } - redisValues.Add(radius); - redisValues.Add(StackExchange.Redis.GeoPosition.GetRedisUnit(unit)); - if ((options & GeoRadiusOptions.WithCoordinates) != 0) redisValues.Add(WITHCOORD); - if ((options & GeoRadiusOptions.WithDistance) != 0) redisValues.Add(WITHDIST); - if ((options & GeoRadiusOptions.WithGeoHash) != 0) redisValues.Add(WITHHASH); - if (count > 0) - { - redisValues.Add(COUNT); - redisValues.Add(count); - } - if (order != null) - { - switch (order.Value) - { - case Order.Ascending: redisValues.Add(ASC); break; - case Order.Descending: redisValues.Add(DESC); break; - default: throw new ArgumentOutOfRangeException(nameof(order)); - } - } - - return Message.Create(Database, flags, command, key, redisValues.ToArray()); - } - public GeoRadiusResult[] GeoRadius(RedisKey key, RedisValue member, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags) - { - return ExecuteSync(GetGeoRadiusMessage(key, member, double.NaN, double.NaN, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options)); - } - public Task GeoRadiusAsync(RedisKey key, RedisValue member, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags) - { - return ExecuteAsync(GetGeoRadiusMessage(key, member, double.NaN, double.NaN, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options)); - } - public GeoRadiusResult[] GeoRadius(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags) - { - return ExecuteSync(GetGeoRadiusMessage(key, null, longitude, latitude, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options)); - } - public Task GeoRadiusAsync(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags) - { - return ExecuteAsync(GetGeoRadiusMessage(key, null, longitude, latitude, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options)); - } - - public long HashDecrement(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None) - { - return HashIncrement(key, hashField, -value, flags); - } - - public double HashDecrement(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None) - { - return HashIncrement(key, hashField, -value, flags); - } - - public Task HashDecrementAsync(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None) - { - return HashIncrementAsync(key, hashField, -value, flags); - } - - public Task HashDecrementAsync(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None) - { - return HashIncrementAsync(key, hashField, -value, flags); - } - - public bool HashDelete(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HDEL, key, hashField); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public long HashDelete(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None) - { - if (hashFields == null) throw new ArgumentNullException(nameof(hashFields)); - var msg = hashFields.Length == 0 ? null : Message.Create(Database, flags, RedisCommand.HDEL, key, hashFields); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task HashDeleteAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HDEL, key, hashField); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public Task HashDeleteAsync(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None) - { - if (hashFields == null) throw new ArgumentNullException(nameof(hashFields)); - - var msg = hashFields.Length == 0 ? null : Message.Create(Database, flags, RedisCommand.HDEL, key, hashFields); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public bool HashExists(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HEXISTS, key, hashField); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public Task HashExistsAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HEXISTS, key, hashField); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public RedisValue HashGet(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HGET, key, hashField); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - - public RedisValue[] HashGet(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None) - { - if (hashFields == null) throw new ArgumentNullException(nameof(hashFields)); - if (hashFields.Length == 0) return new RedisValue[0]; - var msg = Message.Create(Database, flags, RedisCommand.HMGET, key, hashFields); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public HashEntry[] HashGetAll(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HGETALL, key); - return ExecuteSync(msg, ResultProcessor.HashEntryArray); - } - - public Task HashGetAllAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HGETALL, key); - return ExecuteAsync(msg, ResultProcessor.HashEntryArray); - } - - public Task HashGetAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HGET, key, hashField); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public Task HashGetAsync(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None) - { - if (hashFields == null) throw new ArgumentNullException(nameof(hashFields)); - if (hashFields.Length == 0) return CompletedTask.FromResult(new RedisValue[0], asyncState); - var msg = Message.Create(Database, flags, RedisCommand.HMGET, key, hashFields); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - - public long HashIncrement(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None) - { - var msg = value == 0 && (flags & CommandFlags.FireAndForget) != 0 - ? null : Message.Create(Database, flags, RedisCommand.HINCRBY, key, hashField, value); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public double HashIncrement(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None) - { - var msg = value == 0 && (flags & CommandFlags.FireAndForget) != 0 - ? null : Message.Create(Database, flags, RedisCommand.HINCRBYFLOAT, key, hashField, value); - return ExecuteSync(msg, ResultProcessor.Double); - } - - public Task HashIncrementAsync(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None) - { - var msg = value == 0 && (flags & CommandFlags.FireAndForget) != 0 - ? null : Message.Create(Database, flags, RedisCommand.HINCRBY, key, hashField, value); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public Task HashIncrementAsync(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None) - { - var msg = value == 0 && (flags & CommandFlags.FireAndForget) != 0 - ? null : Message.Create(Database, flags, RedisCommand.HINCRBYFLOAT, key, hashField, value); - return ExecuteAsync(msg, ResultProcessor.Double); - } - - public RedisValue[] HashKeys(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HKEYS, key); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public Task HashKeysAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HKEYS, key); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - - public long HashLength(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HLEN, key); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task HashLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HLEN, key); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - IEnumerable IDatabase.HashScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags) - { - return HashScan(key, pattern, pageSize, CursorUtils.Origin, 0, flags); - } - - public IEnumerable HashScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = CursorUtils.DefaultPageSize, long cursor = CursorUtils.Origin, int pageOffset = 0, CommandFlags flags = CommandFlags.None) - { - var scan = TryScan(key, pattern, pageSize, cursor, pageOffset, flags, RedisCommand.HSCAN, HashScanResultProcessor.Default); - if (scan != null) return scan; - - if (cursor != 0 || pageOffset != 0) throw ExceptionFactory.NoCursor(RedisCommand.HGETALL); - if (pattern.IsNull) return HashGetAll(key, flags); - throw ExceptionFactory.NotSupported(true, RedisCommand.HSCAN); - } - - public bool HashSet(RedisKey key, RedisValue hashField, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - WhenAlwaysOrNotExists(when); - var msg = value.IsNull - ? Message.Create(Database, flags, RedisCommand.HDEL, key, hashField) - : Message.Create(Database, flags, when == When.Always ? RedisCommand.HSET : RedisCommand.HSETNX, key, hashField, value); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public void HashSet(RedisKey key, HashEntry[] hashFields, CommandFlags flags = CommandFlags.None) - { - var msg = GetHashSetMessage(key, hashFields, flags); - if (msg == null) return; - ExecuteSync(msg, ResultProcessor.DemandOK); - } - - public Task HashSetAsync(RedisKey key, RedisValue hashField, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - WhenAlwaysOrNotExists(when); - var msg = value.IsNull - ? Message.Create(Database, flags, RedisCommand.HDEL, key, hashField) - : Message.Create(Database, flags, when == When.Always ? RedisCommand.HSET : RedisCommand.HSETNX, key, hashField, value); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public Task HashSetAsync(RedisKey key, HashEntry[] hashFields, CommandFlags flags = CommandFlags.None) - { - var msg = GetHashSetMessage(key, hashFields, flags); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public Task HashSetIfNotExistsAsync(RedisKey key, RedisValue hashField, RedisValue value, CommandFlags flags) - { - var msg = Message.Create(Database, flags, RedisCommand.HSETNX, key, hashField, value); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public RedisValue[] HashValues(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HVALS, key); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public Task HashValuesAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.HVALS, key); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - - public bool HyperLogLogAdd(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var cmd = Message.Create(Database, flags, RedisCommand.PFADD, key, value); - return ExecuteSync(cmd, ResultProcessor.Boolean); - } - - public bool HyperLogLogAdd(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - var cmd = Message.Create(Database, flags, RedisCommand.PFADD, key, values); - return ExecuteSync(cmd, ResultProcessor.Boolean); - } - - public Task HyperLogLogAddAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var cmd = Message.Create(Database, flags, RedisCommand.PFADD, key, value); - return ExecuteAsync(cmd, ResultProcessor.Boolean); - } - - public Task HyperLogLogAddAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - var cmd = Message.Create(Database, flags, RedisCommand.PFADD, key, values); - return ExecuteAsync(cmd, ResultProcessor.Boolean); - } - - public long HyperLogLogLength(RedisKey key, CommandFlags flags = CommandFlags.None) - { - ServerEndPoint server; - var features = GetFeatures(Database, key, flags, out server); - var cmd = Message.Create(Database, flags, RedisCommand.PFCOUNT, key); - // technically a write / master-only command until 2.8.18 - if (server != null && !features.HyperLogLogCountSlaveSafe) cmd.SetMasterOnly(); - return ExecuteSync(cmd, ResultProcessor.Int64, server); - } - - public long HyperLogLogLength(RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - if (keys == null) throw new ArgumentNullException(nameof(keys)); - ServerEndPoint server = null; - var cmd = Message.Create(Database, flags, RedisCommand.PFCOUNT, keys); - if (keys.Length != 0) - { - var features = GetFeatures(Database, keys[0], flags, out server); - // technically a write / master-only command until 2.8.18 - if (server != null && !features.HyperLogLogCountSlaveSafe) cmd.SetMasterOnly(); - } - return ExecuteSync(cmd, ResultProcessor.Int64, server); - } - - public Task HyperLogLogLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - ServerEndPoint server; - var features = GetFeatures(Database, key, flags, out server); - var cmd = Message.Create(Database, flags, RedisCommand.PFCOUNT, key); - // technically a write / master-only command until 2.8.18 - if (server != null && !features.HyperLogLogCountSlaveSafe) cmd.SetMasterOnly(); - return ExecuteAsync(cmd, ResultProcessor.Int64, server); - } - - public Task HyperLogLogLengthAsync(RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - if (keys == null) throw new ArgumentNullException(nameof(keys)); - ServerEndPoint server = null; - var cmd = Message.Create(Database, flags, RedisCommand.PFCOUNT, keys); - if (keys.Length != 0) - { - var features = GetFeatures(Database, keys[0], flags, out server); - // technically a write / master-only command until 2.8.18 - if (server != null && !features.HyperLogLogCountSlaveSafe) cmd.SetMasterOnly(); - } - return ExecuteAsync(cmd, ResultProcessor.Int64, server); - } - - public void HyperLogLogMerge(RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - var cmd = Message.Create(Database, flags, RedisCommand.PFMERGE, destination, first, second); - ExecuteSync(cmd, ResultProcessor.DemandOK); - } - - public void HyperLogLogMerge(RedisKey destination, RedisKey[] sourceKeys, CommandFlags flags = CommandFlags.None) - { - var cmd = Message.Create(Database, flags, RedisCommand.PFMERGE, destination, sourceKeys); - ExecuteSync(cmd, ResultProcessor.DemandOK); - } - - public Task HyperLogLogMergeAsync(RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - var cmd = Message.Create(Database, flags, RedisCommand.PFMERGE, destination, first, second); - return ExecuteAsync(cmd, ResultProcessor.DemandOK); - } - - public Task HyperLogLogMergeAsync(RedisKey destination, RedisKey[] sourceKeys, CommandFlags flags = CommandFlags.None) - { - var cmd = Message.Create(Database, flags, RedisCommand.PFMERGE, destination, sourceKeys); - return ExecuteAsync(cmd, ResultProcessor.DemandOK); - } - - public EndPoint IdentifyEndpoint(RedisKey key = default(RedisKey), CommandFlags flags = CommandFlags.None) - { - var msg = key.IsNull ? Message.Create(-1, flags, RedisCommand.PING) : Message.Create(Database, flags, RedisCommand.EXISTS, key); - return ExecuteSync(msg, ResultProcessor.ConnectionIdentity); - } - - public Task IdentifyEndpointAsync(RedisKey key = default(RedisKey), CommandFlags flags = CommandFlags.None) - { - var msg = key.IsNull ? Message.Create(-1, flags, RedisCommand.PING) : Message.Create(Database, flags, RedisCommand.EXISTS, key); - return ExecuteAsync(msg, ResultProcessor.ConnectionIdentity); - } - - public bool IsConnected(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var server = multiplexer.SelectServer(Database, RedisCommand.PING, flags, key); - return server != null && server.IsConnected; - } - - public bool KeyDelete(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.DEL, key); - return ExecuteSync(msg, ResultProcessor.DemandZeroOrOne); - } - - public long KeyDelete(RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - if (keys == null) throw new ArgumentNullException(nameof(keys)); - var msg = keys.Length == 0 ? null : Message.Create(Database, flags, RedisCommand.DEL, keys); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task KeyDeleteAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.DEL, key); - return ExecuteAsync(msg, ResultProcessor.DemandZeroOrOne); - } - - public Task KeyDeleteAsync(RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - if (keys == null) throw new ArgumentNullException(nameof(keys)); - - var msg = keys.Length == 0 ? null : Message.Create(Database, flags, RedisCommand.DEL, keys); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public byte[] KeyDump(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.DUMP, key); - return ExecuteSync(msg, ResultProcessor.ByteArray); - } - - public Task KeyDumpAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.DUMP, key); - return ExecuteAsync(msg, ResultProcessor.ByteArray); - } - - public bool KeyExists(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.EXISTS, key); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public Task KeyExistsAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.EXISTS, key); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public bool KeyExpire(RedisKey key, TimeSpan? expiry, CommandFlags flags = CommandFlags.None) - { - ServerEndPoint server; - var msg = GetExpiryMessage(key, flags, expiry, out server); - return ExecuteSync(msg, ResultProcessor.Boolean, server: server); - } - - public bool KeyExpire(RedisKey key, DateTime? expiry, CommandFlags flags = CommandFlags.None) - { - ServerEndPoint server; - var msg = GetExpiryMessage(key, flags, expiry, out server); - return ExecuteSync(msg, ResultProcessor.Boolean, server: server); - } - - public Task KeyExpireAsync(RedisKey key, TimeSpan? expiry, CommandFlags flags = CommandFlags.None) - { - ServerEndPoint server; - var msg = GetExpiryMessage(key, flags, expiry, out server); - return ExecuteAsync(msg, ResultProcessor.Boolean, server: server); - } - - public Task KeyExpireAsync(RedisKey key, DateTime? expiry, CommandFlags flags = CommandFlags.None) - { - ServerEndPoint server; - var msg = GetExpiryMessage(key, flags, expiry, out server); - return ExecuteAsync(msg, ResultProcessor.Boolean, server: server); - } - - public void KeyMigrate(RedisKey key, EndPoint toServer, int toDatabase = 0, int timeoutMilliseconds = 0, MigrateOptions migrateOptions = MigrateOptions.None, CommandFlags flags = CommandFlags.None) - { - if (timeoutMilliseconds <= 0) timeoutMilliseconds = multiplexer.TimeoutMilliseconds; - var msg = new KeyMigrateCommandMessage(Database, key, toServer, toDatabase, timeoutMilliseconds, migrateOptions, flags); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - public Task KeyMigrateAsync(RedisKey key, EndPoint toServer, int toDatabase = 0, int timeoutMilliseconds = 0, MigrateOptions migrateOptions = MigrateOptions.None, CommandFlags flags = CommandFlags.None) - { - if (timeoutMilliseconds <= 0) timeoutMilliseconds = multiplexer.TimeoutMilliseconds; - var msg = new KeyMigrateCommandMessage(Database, key, toServer, toDatabase, timeoutMilliseconds, migrateOptions, flags); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - sealed class KeyMigrateCommandMessage : Message.CommandKeyBase // MIGRATE is atypical - { - private MigrateOptions migrateOptions; - private int timeoutMilliseconds; - private int toDatabase; - RedisValue toHost, toPort; - - public KeyMigrateCommandMessage(int db, RedisKey key, EndPoint toServer, int toDatabase, int timeoutMilliseconds, MigrateOptions migrateOptions, CommandFlags flags) - : base(db, flags, RedisCommand.MIGRATE, key) - { - if (toServer == null) throw new ArgumentNullException(nameof(toServer)); - string toHost; - int toPort; - if (!Format.TryGetHostPort(toServer, out toHost, out toPort)) throw new ArgumentException("toServer"); - this.toHost = toHost; - this.toPort = toPort; - if (toDatabase < 0) throw new ArgumentOutOfRangeException(nameof(toDatabase)); - this.toDatabase = toDatabase; - this.timeoutMilliseconds = timeoutMilliseconds; - this.migrateOptions = migrateOptions; - } - - internal override void WriteImpl(PhysicalConnection physical) - { - bool isCopy = (migrateOptions & MigrateOptions.Copy) != 0; - bool isReplace = (migrateOptions & MigrateOptions.Replace) != 0; - physical.WriteHeader(Command, 5 + (isCopy ? 1 : 0) + (isReplace ? 1 : 0)); - physical.Write(toHost); - physical.Write(toPort); - physical.Write(Key); - physical.Write(toDatabase); - physical.Write(timeoutMilliseconds); - if (isCopy) physical.Write(RedisLiterals.COPY); - if (isReplace) physical.Write(RedisLiterals.REPLACE); - } - } - - public bool KeyMove(RedisKey key, int database, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.MOVE, key, database); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public Task KeyMoveAsync(RedisKey key, int database, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.MOVE, key, database); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public bool KeyPersist(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.PERSIST, key); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public Task KeyPersistAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.PERSIST, key); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public RedisKey KeyRandom(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.RANDOMKEY); - return ExecuteSync(msg, ResultProcessor.RedisKey); - } - - public Task KeyRandomAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.RANDOMKEY); - return ExecuteAsync(msg, ResultProcessor.RedisKey); - } - - public bool KeyRename(RedisKey key, RedisKey newKey, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - WhenAlwaysOrNotExists(when); - var msg = Message.Create(Database, flags, when == When.Always ? RedisCommand.RENAME : RedisCommand.RENAMENX, key, newKey); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public Task KeyRenameAsync(RedisKey key, RedisKey newKey, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - WhenAlwaysOrNotExists(when); - var msg = Message.Create(Database, flags, when == When.Always ? RedisCommand.RENAME : RedisCommand.RENAMENX, key, newKey); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public void KeyRestore(RedisKey key, byte[] value, TimeSpan? expiry = null, CommandFlags flags = CommandFlags.None) - { - var msg = GetRestoreMessage(key, value, expiry, flags); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - - public Task KeyRestoreAsync(RedisKey key, byte[] value, TimeSpan? expiry = null, CommandFlags flags = CommandFlags.None) - { - var msg = GetRestoreMessage(key, value, expiry, flags); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public TimeSpan? KeyTimeToLive(RedisKey key, CommandFlags flags = CommandFlags.None) - { - ServerEndPoint server; - var features = GetFeatures(Database, key, flags, out server); - Message msg; - if (server != null && features.MillisecondExpiry && multiplexer.CommandMap.IsAvailable(RedisCommand.PTTL)) - { - msg = Message.Create(Database, flags, RedisCommand.PTTL, key); - return ExecuteSync(msg, ResultProcessor.TimeSpanFromMilliseconds, server); - } - msg = Message.Create(Database, flags, RedisCommand.TTL, key); - return ExecuteSync(msg, ResultProcessor.TimeSpanFromSeconds); - } - - public Task KeyTimeToLiveAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - ServerEndPoint server; - var features = GetFeatures(Database, key, flags, out server); - Message msg; - if (server != null && features.MillisecondExpiry && multiplexer.CommandMap.IsAvailable(RedisCommand.PTTL)) - { - msg = Message.Create(Database, flags, RedisCommand.PTTL, key); - return ExecuteAsync(msg, ResultProcessor.TimeSpanFromMilliseconds, server); - } - msg = Message.Create(Database, flags, RedisCommand.TTL, key); - return ExecuteAsync(msg, ResultProcessor.TimeSpanFromSeconds); - - } - - public RedisType KeyType(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.TYPE, key); - return ExecuteSync(msg, ResultProcessor.RedisType); - } - - public Task KeyTypeAsync(RedisKey key, CommandFlags flags) - { - var msg = Message.Create(Database, flags, RedisCommand.TYPE, key); - return ExecuteAsync(msg, ResultProcessor.RedisType); - } - - public RedisValue ListGetByIndex(RedisKey key, long index, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LINDEX, key, index); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - - public Task ListGetByIndexAsync(RedisKey key, long index, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LINDEX, key, index); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public long ListInsertAfter(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LINSERT, key, RedisLiterals.AFTER, pivot, value); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task ListInsertAfterAsync(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LINSERT, key, RedisLiterals.AFTER, pivot, value); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public long ListInsertBefore(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LINSERT, key, RedisLiterals.BEFORE, pivot, value); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task ListInsertBeforeAsync(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LINSERT, key, RedisLiterals.BEFORE, pivot, value); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public RedisValue ListLeftPop(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LPOP, key); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - - public Task ListLeftPopAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LPOP, key); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public long ListLeftPush(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - WhenAlwaysOrExists(when); - var msg = Message.Create(Database, flags, when == When.Always ? RedisCommand.LPUSH : RedisCommand.LPUSHX, key, value); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public long ListLeftPush(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - if (values == null) throw new ArgumentNullException(nameof(values)); - var msg = values.Length == 0 ? Message.Create(Database, flags, RedisCommand.LLEN, key) : Message.Create(Database, flags, RedisCommand.LPUSH, key, values); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task ListLeftPushAsync(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - WhenAlwaysOrExists(when); - var msg = Message.Create(Database, flags, when == When.Always ? RedisCommand.LPUSH : RedisCommand.LPUSHX, key, value); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public Task ListLeftPushAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - if (values == null) throw new ArgumentNullException(nameof(values)); - var msg = values.Length == 0 ? Message.Create(Database, flags, RedisCommand.LLEN, key) : Message.Create(Database, flags, RedisCommand.LPUSH, key, values); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public long ListLength(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LLEN, key); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task ListLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LLEN, key); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public RedisValue[] ListRange(RedisKey key, long start = 0, long stop = -1, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LRANGE, key, start, stop); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public Task ListRangeAsync(RedisKey key, long start = 0, long stop = -1, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LRANGE, key, start, stop); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - - public long ListRemove(RedisKey key, RedisValue value, long count = 0, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LREM, key, count, value); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task ListRemoveAsync(RedisKey key, RedisValue value, long count = 0, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LREM, key, count, value); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public RedisValue ListRightPop(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.RPOP, key); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - - public Task ListRightPopAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.RPOP, key); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public RedisValue ListRightPopLeftPush(RedisKey source, RedisKey destination, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.RPOPLPUSH, source, destination); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - - public Task ListRightPopLeftPushAsync(RedisKey source, RedisKey destination, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.RPOPLPUSH, source, destination); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public long ListRightPush(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - WhenAlwaysOrExists(when); - var msg = Message.Create(Database, flags, when == When.Always ? RedisCommand.RPUSH : RedisCommand.RPUSHX, key, value); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public long ListRightPush(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - if (values == null) throw new ArgumentNullException(nameof(values)); - var msg = values.Length == 0 ? Message.Create(Database, flags, RedisCommand.LLEN, key) : Message.Create(Database, flags, RedisCommand.RPUSH, key, values); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task ListRightPushAsync(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - WhenAlwaysOrExists(when); - var msg = Message.Create(Database, flags, when == When.Always ? RedisCommand.RPUSH : RedisCommand.RPUSHX, key, value); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public Task ListRightPushAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - if (values == null) throw new ArgumentNullException(nameof(values)); - var msg = values.Length == 0 ? Message.Create(Database, flags, RedisCommand.LLEN, key) : Message.Create(Database, flags, RedisCommand.RPUSH, key, values); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public void ListSetByIndex(RedisKey key, long index, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LSET, key, index, value); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - - public Task ListSetByIndexAsync(RedisKey key, long index, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LSET, key, index, value); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public void ListTrim(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LTRIM, key, start, stop); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - - public Task ListTrimAsync(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.LTRIM, key, start, stop); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public bool LockExtend(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None) - { - if (value.IsNull) throw new ArgumentNullException(nameof(value)); - var tran = GetLockExtendTransaction(key, value, expiry); - - if (tran != null) return tran.Execute(flags); - - // without transactions (twemproxy etc), we can't enforce the "value" part - return KeyExpire(key, expiry, flags); - } - - public Task LockExtendAsync(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None) - { - if (value.IsNull) throw new ArgumentNullException(nameof(value)); - var tran = GetLockExtendTransaction(key, value, expiry); - if (tran != null) return tran.ExecuteAsync(flags); - - // without transactions (twemproxy etc), we can't enforce the "value" part - return KeyExpireAsync(key, expiry, flags); - } - - public RedisValue LockQuery(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return StringGet(key, flags); - } - - public Task LockQueryAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - return StringGetAsync(key, flags); - } - - public bool LockRelease(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - if (value.IsNull) throw new ArgumentNullException(nameof(value)); - var tran = GetLockReleaseTransaction(key, value); - if (tran != null) return tran.Execute(flags); - - // without transactions (twemproxy etc), we can't enforce the "value" part - return KeyDelete(key, flags); - } - - public Task LockReleaseAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - if (value.IsNull) throw new ArgumentNullException(nameof(value)); - var tran = GetLockReleaseTransaction(key, value); - if (tran != null) return tran.ExecuteAsync(flags); - - // without transactions (twemproxy etc), we can't enforce the "value" part - return KeyDeleteAsync(key, flags); - } - - public bool LockTake(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None) - { - if (value.IsNull) throw new ArgumentNullException(nameof(value)); - return StringSet(key, value, expiry, When.NotExists, flags); - } - - public Task LockTakeAsync(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None) - { - if (value.IsNull) throw new ArgumentNullException(nameof(value)); - return StringSetAsync(key, value, expiry, When.NotExists, flags); - } - - public long Publish(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None) - { - if (channel.IsNullOrEmpty) throw new ArgumentNullException(nameof(channel)); - var msg = Message.Create(-1, flags, RedisCommand.PUBLISH, channel, message); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task PublishAsync(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None) - { - if (channel.IsNullOrEmpty) throw new ArgumentNullException(nameof(channel)); - var msg = Message.Create(-1, flags, RedisCommand.PUBLISH, channel, message); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - public RedisResult ScriptEvaluate(string script, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None) - { - var msg = new ScriptEvalMessage(Database, flags, script, keys, values); - try - { - return ExecuteSync(msg, ResultProcessor.ScriptResult); - - } - catch (RedisServerException) - { - // could be a NOSCRIPT; for a sync call, we can re-issue that without problem - if (msg.IsScriptUnavailable) return ExecuteSync(msg, ResultProcessor.ScriptResult); - throw; - } - } - public RedisResult Execute(string command, params object[] args) - => Execute(command, args, CommandFlags.None); - public RedisResult Execute(string command, ICollection args, CommandFlags flags = CommandFlags.None) - { - var msg = new ExecuteMessage(Database, flags, command, args); - return ExecuteSync(msg, ResultProcessor.ScriptResult); - } - public Task ExecuteAsync(string command, params object[] args) - => ExecuteAsync(command, args, CommandFlags.None); - public Task ExecuteAsync(string command, ICollection args, CommandFlags flags = CommandFlags.None) - { - var msg = new ExecuteMessage(Database, flags, command, args); - return ExecuteAsync(msg, ResultProcessor.ScriptResult); - } - public RedisResult ScriptEvaluate(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None) - { - var msg = new ScriptEvalMessage(Database, flags, hash, keys, values); - return ExecuteSync(msg, ResultProcessor.ScriptResult); - } - - public RedisResult ScriptEvaluate(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None) - { - return script.Evaluate(this, parameters, null, flags); - } - public RedisResult ScriptEvaluate(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None) - { - return script.Evaluate(this, parameters, null, flags); - } - - - public Task ScriptEvaluateAsync(string script, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None) - { - var msg = new ScriptEvalMessage(Database, flags, script, keys, values); - return ExecuteAsync(msg, ResultProcessor.ScriptResult); - } - public Task ScriptEvaluateAsync(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None) - { - var msg = new ScriptEvalMessage(Database, flags, hash, keys, values); - return ExecuteAsync(msg, ResultProcessor.ScriptResult); - } - - public Task ScriptEvaluateAsync(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None) - { - return script.EvaluateAsync(this, parameters, null, flags); - } - public Task ScriptEvaluateAsync(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None) - { - return script.EvaluateAsync(this, parameters, null, flags); - } - public bool SetAdd(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SADD, key, value); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public long SetAdd(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SADD, key, values); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SetAddAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SADD, key, value); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public Task SetAddAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SADD, key, values); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public RedisValue[] SetCombine(SetOperation operation, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, SetOperationCommand(operation, false), first, second); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public RedisValue[] SetCombine(SetOperation operation, RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, SetOperationCommand(operation, false), keys); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public long SetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, SetOperationCommand(operation, true), destination, first, second); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public long SetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, SetOperationCommand(operation, true), destination, keys); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SetCombineAndStoreAsync(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, SetOperationCommand(operation, true), destination, first, second); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public Task SetCombineAndStoreAsync(SetOperation operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, SetOperationCommand(operation, true), destination, keys); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public Task SetCombineAsync(SetOperation operation, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, SetOperationCommand(operation, false), first, second); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - - public Task SetCombineAsync(SetOperation operation, RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, SetOperationCommand(operation, false), keys); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - - public bool SetContains(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SISMEMBER, key, value); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public Task SetContainsAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SISMEMBER, key, value); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - - public long SetLength(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SCARD, key); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SetLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SCARD, key); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public RedisValue[] SetMembers(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SMEMBERS, key); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public Task SetMembersAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SMEMBERS, key); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - - public bool SetMove(RedisKey source, RedisKey destination, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SMOVE, source, destination, value); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public Task SetMoveAsync(RedisKey source, RedisKey destination, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SMOVE, source, destination, value); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public RedisValue SetPop(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SPOP, key); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - - public Task SetPopAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SPOP, key); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public RedisValue SetRandomMember(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SRANDMEMBER, key); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - - public Task SetRandomMemberAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SRANDMEMBER, key); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public RedisValue[] SetRandomMembers(RedisKey key, long count, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SRANDMEMBER, key, count); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public Task SetRandomMembersAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SRANDMEMBER, key, count); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - - public bool SetRemove(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SREM, key, value); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public long SetRemove(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SREM, key, values); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SetRemoveAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SREM, key, value); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public Task SetRemoveAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SREM, key, values); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - IEnumerable IDatabase.SetScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags) - { - return SetScan(key, pattern, pageSize, CursorUtils.Origin, 0, flags); - } - - public IEnumerable SetScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = CursorUtils.DefaultPageSize, long cursor = CursorUtils.Origin, int pageOffset = 0, CommandFlags flags = CommandFlags.None) - { - var scan = TryScan(key, pattern, pageSize, cursor, pageOffset, flags, RedisCommand.SSCAN, SetScanResultProcessor.Default); - if (scan != null) return scan; - - if (cursor != 0 || pageOffset != 0) throw ExceptionFactory.NoCursor(RedisCommand.SMEMBERS); - if (pattern.IsNull) return SetMembers(key, flags); - throw ExceptionFactory.NotSupported(true, RedisCommand.SSCAN); - } - public RedisValue[] Sort(RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetAddMessage(default(RedisKey), key, skip, take, order, sortType, by, get, flags); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public long SortAndStore(RedisKey destination, RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetAddMessage(destination, key, skip, take, order, sortType, by, get, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SortAndStoreAsync(RedisKey destination, RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetAddMessage(destination, key, skip, take, order, sortType, by, get, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public Task SortAsync(RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetAddMessage(default(RedisKey), key, skip, take, order, sortType, by, get, flags); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - public bool SortedSetAdd(RedisKey key, RedisValue member, double score, CommandFlags flags) - { - var msg = GetSortedSetAddMessage(key, member, score, When.Always, flags); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - public bool SortedSetAdd(RedisKey key, RedisValue member, double score, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetAddMessage(key, member, score, when, flags); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - public long SortedSetAdd(RedisKey key, SortedSetEntry[] values, CommandFlags flags) - { - var msg = GetSortedSetAddMessage(key, values, When.Always, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - public long SortedSetAdd(RedisKey key, SortedSetEntry[] values, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetAddMessage(key, values, when, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SortedSetAddAsync(RedisKey key, RedisValue member, double score, CommandFlags flags) - { - var msg = GetSortedSetAddMessage(key, member, score, When.Always, flags); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - public Task SortedSetAddAsync(RedisKey key, RedisValue member, double score, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetAddMessage(key, member, score, when, flags); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - public Task SortedSetAddAsync(RedisKey key, SortedSetEntry[] values, CommandFlags flags) - { - var msg = GetSortedSetAddMessage(key, values, When.Always, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - public Task SortedSetAddAsync(RedisKey key, SortedSetEntry[] values, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetAddMessage(key, values, when, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public long SortedSetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetCombineAndStoreCommandMessage(operation, destination, new[] { first, second }, null, aggregate, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public long SortedSetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey[] keys, double[] weights = null, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetCombineAndStoreCommandMessage(operation, destination, keys, weights, aggregate, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SortedSetCombineAndStoreAsync(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetCombineAndStoreCommandMessage(operation, destination, new[] { first, second }, null, aggregate, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public Task SortedSetCombineAndStoreAsync(SetOperation operation, RedisKey destination, RedisKey[] keys, double[] weights = null, Aggregate aggregate = Aggregate.Sum, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetCombineAndStoreCommandMessage(operation, destination, keys, weights, aggregate, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public double SortedSetDecrement(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None) - { - return SortedSetIncrement(key, member, -value, flags); - } - - public Task SortedSetDecrementAsync(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None) - { - return SortedSetIncrementAsync(key, member, -value, flags); - } - - public double SortedSetIncrement(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.ZINCRBY, key, value, member); - return ExecuteSync(msg, ResultProcessor.Double); - } - - public Task SortedSetIncrementAsync(RedisKey key, RedisValue member, double value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.ZINCRBY, key, value, member); - return ExecuteAsync(msg, ResultProcessor.Double); - } - - public long SortedSetLength(RedisKey key, double min = double.NegativeInfinity, double max = double.PositiveInfinity, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetLengthMessage(key, min, max, exclude, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SortedSetLengthAsync(RedisKey key, double min = double.NegativeInfinity, double max = double.PositiveInfinity, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetLengthMessage(key, min, max, exclude, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public RedisValue[] SortedSetRangeByRank(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, order == Order.Descending ? RedisCommand.ZREVRANGE : RedisCommand.ZRANGE, key, start, stop); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public Task SortedSetRangeByRankAsync(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, order == Order.Descending ? RedisCommand.ZREVRANGE : RedisCommand.ZRANGE, key, start, stop); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - - public SortedSetEntry[] SortedSetRangeByRankWithScores(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, order == Order.Descending ? RedisCommand.ZREVRANGE : RedisCommand.ZRANGE, key, start, stop, RedisLiterals.WITHSCORES); - return ExecuteSync(msg, ResultProcessor.SortedSetWithScores); - } - - public Task SortedSetRangeByRankWithScoresAsync(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, order == Order.Descending ? RedisCommand.ZREVRANGE : RedisCommand.ZRANGE, key, start, stop, RedisLiterals.WITHSCORES); - return ExecuteAsync(msg, ResultProcessor.SortedSetWithScores); - } - - public RedisValue[] SortedSetRangeByScore(RedisKey key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetRangeByScoreMessage(key, start, stop, exclude, order, skip, take, flags, false); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public Task SortedSetRangeByScoreAsync(RedisKey key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetRangeByScoreMessage(key, start, stop, exclude, order, skip, take, flags, false); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - - public SortedSetEntry[] SortedSetRangeByScoreWithScores(RedisKey key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetRangeByScoreMessage(key, start, stop, exclude, order, skip, take, flags, true); - return ExecuteSync(msg, ResultProcessor.SortedSetWithScores); - } - - public Task SortedSetRangeByScoreWithScoresAsync(RedisKey key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetRangeByScoreMessage(key, start, stop, exclude, order, skip, take, flags, true); - return ExecuteAsync(msg, ResultProcessor.SortedSetWithScores); - } - - public long? SortedSetRank(RedisKey key, RedisValue member, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, order == Order.Descending ? RedisCommand.ZREVRANK : RedisCommand.ZRANK, key, member); - return ExecuteSync(msg, ResultProcessor.NullableInt64); - } - - public Task SortedSetRankAsync(RedisKey key, RedisValue member, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, order == Order.Descending ? RedisCommand.ZREVRANK : RedisCommand.ZRANK, key, member); - return ExecuteAsync(msg, ResultProcessor.NullableInt64); - } - - public bool SortedSetRemove(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.ZREM, key, member); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public long SortedSetRemove(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.ZREM, key, members); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SortedSetRemoveAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.ZREM, key, member); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public Task SortedSetRemoveAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.ZREM, key, members); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public long SortedSetRemoveRangeByRank(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.ZREMRANGEBYRANK, key, start, stop); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SortedSetRemoveRangeByRankAsync(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.ZREMRANGEBYRANK, key, start, stop); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public long SortedSetRemoveRangeByScore(RedisKey key, double start, double stop, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetRemoveRangeByScoreMessage(key, start, stop, exclude, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SortedSetRemoveRangeByScoreAsync(RedisKey key, double start, double stop, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - var msg = GetSortedSetRemoveRangeByScoreMessage(key, start, stop, exclude, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - IEnumerable IDatabase.SortedSetScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags) - { - return SortedSetScan(key, pattern, pageSize, CursorUtils.Origin, 0, flags); - } - - public IEnumerable SortedSetScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = CursorUtils.DefaultPageSize, long cursor = CursorUtils.Origin, int pageOffset = 0, CommandFlags flags = CommandFlags.None) - { - var scan = TryScan(key, pattern, pageSize, cursor, pageOffset, flags, RedisCommand.ZSCAN, SortedSetScanResultProcessor.Default); - if (scan != null) return scan; - - if (cursor != 0 || pageOffset != 0) throw ExceptionFactory.NoCursor(RedisCommand.ZRANGE); - if (pattern.IsNull) return SortedSetRangeByRankWithScores(key, flags: flags); - throw ExceptionFactory.NotSupported(true, RedisCommand.ZSCAN); - } - - public double? SortedSetScore(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.ZSCORE, key, member); - return ExecuteSync(msg, ResultProcessor.NullableDouble); - } - - public Task SortedSetScoreAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.ZSCORE, key, member); - return ExecuteAsync(msg, ResultProcessor.NullableDouble); - } - - public long StringAppend(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.APPEND, key, value); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task StringAppendAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.APPEND, key, value); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public long StringBitCount(RedisKey key, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.BITCOUNT, key, start, end); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task StringBitCountAsync(RedisKey key, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.BITCOUNT, key, start, end); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public long StringBitOperation(Bitwise operation, RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - var msg = GetStringBitOperationMessage(operation, destination, first, second, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public long StringBitOperation(Bitwise operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - var msg = GetStringBitOperationMessage(operation, destination, keys, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task StringBitOperationAsync(Bitwise operation, RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) - { - var msg = GetStringBitOperationMessage(operation, destination, first, second, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public Task StringBitOperationAsync(Bitwise operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - var msg = GetStringBitOperationMessage(operation, destination, keys, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public long StringBitPosition(RedisKey key, bool value, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.BITPOS, key, value, start, end); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task StringBitPositionAsync(RedisKey key, bool value, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.BITPOS, key, value, start, end); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public long StringDecrement(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None) - { - return StringIncrement(key, -value, flags); - } - - public double StringDecrement(RedisKey key, double value, CommandFlags flags = CommandFlags.None) - { - return StringIncrement(key, -value, flags); - } - - public Task StringDecrementAsync(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None) - { - return StringIncrementAsync(key, -value, flags); - } - - public Task StringDecrementAsync(RedisKey key, double value, CommandFlags flags = CommandFlags.None) - { - return StringIncrementAsync(key, -value, flags); - } - - public RedisValue StringGet(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GET, key); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - - public RedisValue[] StringGet(RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - if (keys == null) throw new ArgumentNullException(nameof(keys)); - if (keys.Length == 0) return new RedisValue[0]; - var msg = Message.Create(Database, flags, RedisCommand.MGET, keys); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public Task StringGetAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GET, key); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public Task StringGetAsync(RedisKey[] keys, CommandFlags flags = CommandFlags.None) - { - if (keys == null) throw new ArgumentNullException(nameof(keys)); - if (keys.Length == 0) return CompletedTask.FromResult(new RedisValue[0], asyncState); - var msg = Message.Create(Database, flags, RedisCommand.MGET, keys); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - - public bool StringGetBit(RedisKey key, long offset, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GETBIT, key, offset); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public Task StringGetBitAsync(RedisKey key, long offset, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GETBIT, key, offset); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public RedisValue StringGetRange(RedisKey key, long start, long end, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GETRANGE, key, start, end); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - - public Task StringGetRangeAsync(RedisKey key, long start, long end, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GETRANGE, key, start, end); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public RedisValue StringGetSet(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GETSET, key, value); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - - public Task StringGetSetAsync(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.GETSET, key, value); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public RedisValueWithExpiry StringGetWithExpiry(RedisKey key, CommandFlags flags = CommandFlags.None) - { - ServerEndPoint server; - ResultProcessor processor; - var msg = GetStringGetWithExpiryMessage(key, flags, out processor, out server); - return ExecuteSync(msg, processor, server); - } - - public Task StringGetWithExpiryAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - ServerEndPoint server; - ResultProcessor processor; - var msg = GetStringGetWithExpiryMessage(key, flags, out processor, out server); - return ExecuteAsync(msg, processor, server); - } - - public long StringIncrement(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None) - { - var msg = IncrMessage(key, value, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public double StringIncrement(RedisKey key, double value, CommandFlags flags = CommandFlags.None) - { - var msg = value == 0 && (flags & CommandFlags.FireAndForget) != 0 - ? null : Message.Create(Database, flags, RedisCommand.INCRBYFLOAT, key, value); - return ExecuteSync(msg, ResultProcessor.Double); - } - - public Task StringIncrementAsync(RedisKey key, long value = 1, CommandFlags flags = CommandFlags.None) - { - var msg = IncrMessage(key, value, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public Task StringIncrementAsync(RedisKey key, double value, CommandFlags flags = CommandFlags.None) - { - var msg = value == 0 && (flags & CommandFlags.FireAndForget) != 0 - ? null : Message.Create(Database, flags, RedisCommand.INCRBYFLOAT, key, value); - return ExecuteAsync(msg, ResultProcessor.Double); - } - - public long StringLength(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.STRLEN, key); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task StringLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.STRLEN, key); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public bool StringSet(RedisKey key, RedisValue value, TimeSpan? expiry = null, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - var msg = GetStringSetMessage(key, value, expiry, when, flags); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public bool StringSet(KeyValuePair[] values, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - var msg = GetStringSetMessage(values, when, flags); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public Task StringSetAsync(RedisKey key, RedisValue value, TimeSpan? expiry = null, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - var msg = GetStringSetMessage(key, value, expiry, when, flags); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public Task StringSetAsync(KeyValuePair[] values, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - var msg = GetStringSetMessage(values, when, flags); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public bool StringSetBit(RedisKey key, long offset, bool value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SETBIT, key, offset, value); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public Task StringSetBitAsync(RedisKey key, long offset, bool value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SETBIT, key, offset, value); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public RedisValue StringSetRange(RedisKey key, long offset, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SETRANGE, key, offset, value); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - - public Task StringSetRangeAsync(RedisKey key, long offset, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(Database, flags, RedisCommand.SETRANGE, key, offset, value); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - Message GetExpiryMessage(RedisKey key, CommandFlags flags, TimeSpan? expiry, out ServerEndPoint server) - { - TimeSpan duration; - if (expiry == null || (duration = expiry.Value) == TimeSpan.MaxValue) - { - server = null; - return Message.Create(Database, flags, RedisCommand.PERSIST, key); - } - long milliseconds = duration.Ticks / TimeSpan.TicksPerMillisecond; - if ((milliseconds % 1000) != 0) - { - var features = GetFeatures(Database, key, flags, out server); - if (server != null && features.MillisecondExpiry && multiplexer.CommandMap.IsAvailable(RedisCommand.PEXPIRE)) - { - return Message.Create(Database, flags, RedisCommand.PEXPIRE, key, milliseconds); - } - } - server = null; - long seconds = milliseconds / 1000; - return Message.Create(Database, flags, RedisCommand.EXPIRE, key, seconds); - } - - Message GetExpiryMessage(RedisKey key, CommandFlags flags, DateTime? expiry, out ServerEndPoint server) - { - DateTime when; - if (expiry == null || (when = expiry.Value) == DateTime.MaxValue) - { - server = null; - return Message.Create(Database, flags, RedisCommand.PERSIST, key); - } - switch (when.Kind) - { - case DateTimeKind.Local: - case DateTimeKind.Utc: - break; // fine, we can work with that - default: - throw new ArgumentException("Expiry time must be either Utc or Local", nameof(expiry)); - } - long milliseconds = (when.ToUniversalTime() - RedisBase.UnixEpoch).Ticks / TimeSpan.TicksPerMillisecond; - - if ((milliseconds % 1000) != 0) - { - var features = GetFeatures(Database, key, flags, out server); - if (server != null && features.MillisecondExpiry && multiplexer.CommandMap.IsAvailable(RedisCommand.PEXPIREAT)) - { - return Message.Create(Database, flags, RedisCommand.PEXPIREAT, key, milliseconds); - } - } - server = null; - long seconds = milliseconds / 1000; - return Message.Create(Database, flags, RedisCommand.EXPIREAT, key, seconds); - } - - private Message GetHashSetMessage(RedisKey key, HashEntry[] hashFields, CommandFlags flags) - { - if (hashFields == null) throw new ArgumentNullException(nameof(hashFields)); - switch (hashFields.Length) - { - case 0: return null; - case 1: - return Message.Create(Database, flags, RedisCommand.HMSET, key, - hashFields[0].name, hashFields[0].value); - case 2: - return Message.Create(Database, flags, RedisCommand.HMSET, key, - hashFields[0].name, hashFields[0].value, - hashFields[1].name, hashFields[1].value); - default: - var arr = new RedisValue[hashFields.Length * 2]; - int offset = 0; - for (int i = 0; i < hashFields.Length; i++) - { - arr[offset++] = hashFields[i].name; - arr[offset++] = hashFields[i].value; - } - return Message.Create(Database, flags, RedisCommand.HMSET, key, arr); - } - } - - ITransaction GetLockExtendTransaction(RedisKey key, RedisValue value, TimeSpan expiry) - { - var tran = CreateTransactionIfAvailable(asyncState); - if (tran != null) - { - tran.AddCondition(Condition.StringEqual(key, value)); - tran.KeyExpireAsync(key, expiry, CommandFlags.FireAndForget); - } - return tran; - } - - ITransaction GetLockReleaseTransaction(RedisKey key, RedisValue value) - { - var tran = CreateTransactionIfAvailable(asyncState); - if (tran != null) - { - tran.AddCondition(Condition.StringEqual(key, value)); - tran.KeyDeleteAsync(key, CommandFlags.FireAndForget); - } - return tran; - } - - private RedisValue GetLexRange(RedisValue value, Exclude exclude, bool isStart) - { - if (value.IsNull) - { - return isStart ? RedisLiterals.MinusSymbol : RedisLiterals.PlusSumbol; - } - byte[] orig = value; - - byte[] result = new byte[orig.Length + 1]; - // no defaults here; must always explicitly specify [ / ( - result[0] = (exclude & (isStart ? Exclude.Start : Exclude.Stop)) == 0 ? (byte)'[' : (byte)'('; - Buffer.BlockCopy(orig, 0, result, 1, orig.Length); - return result; - } - private RedisValue GetRange(double value, Exclude exclude, bool isStart) - { - if (isStart) - { - if ((exclude & Exclude.Start) == 0) return value; // inclusive is default - } - else - { - if ((exclude & Exclude.Stop) == 0) return value; // inclusive is default - } - return "(" + Format.ToString(value); // '(' prefix means exclusive - } - - Message GetRestoreMessage(RedisKey key, byte[] value, TimeSpan? expiry, CommandFlags flags) - { - long pttl = (expiry == null || expiry.Value == TimeSpan.MaxValue) ? 0 : (expiry.Value.Ticks / TimeSpan.TicksPerMillisecond); - return Message.Create(Database, flags, RedisCommand.RESTORE, key, pttl, value); - } - - private Message GetSortedSetAddMessage(RedisKey key, RedisValue member, double score, When when, CommandFlags flags) - { - WhenAlwaysOrExistsOrNotExists(when); - switch (when) - { - case When.Always: return Message.Create(Database, flags, RedisCommand.ZADD, key, score, member); - case When.NotExists: return Message.Create(Database, flags, RedisCommand.ZADD, key, RedisLiterals.NX, score, member); - case When.Exists: return Message.Create(Database, flags, RedisCommand.ZADD, key, RedisLiterals.XX, score, member); - default: throw new ArgumentOutOfRangeException(nameof(when)); - } - } - - private Message GetSortedSetAddMessage(RedisKey key, SortedSetEntry[] values, When when, CommandFlags flags) - { - WhenAlwaysOrExistsOrNotExists(when); - if (values == null) throw new ArgumentNullException(nameof(values)); - switch (values.Length) - { - case 0: return null; - case 1: - return GetSortedSetAddMessage(key, values[0].element, values[0].score, when, flags); - default: - RedisValue[] arr; - int index = 0; - switch (when) - { - case When.Always: - arr = new RedisValue[values.Length * 2]; - break; - case When.NotExists: - arr = new RedisValue[values.Length * 2 + 1]; - arr[index++] = RedisLiterals.NX; - break; - case When.Exists: - arr = new RedisValue[values.Length * 2 + 1]; - arr[index++] = RedisLiterals.XX; - break; - default: throw new ArgumentOutOfRangeException(nameof(when)); - } - for (int i = 0; i < values.Length; i++) - { - arr[index++] = values[i].score; - arr[index++] = values[i].element; - } - return Message.Create(Database, flags, RedisCommand.ZADD, key, arr); - } - } - - private Message GetSortedSetAddMessage(RedisKey destination, RedisKey key, long skip, long take, Order order, SortType sortType, RedisValue by, RedisValue[] get, CommandFlags flags) - { - // most common cases; no "get", no "by", no "destination", no "skip", no "take" - if (destination.IsNull && skip == 0 && take == -1 && by.IsNull && (get == null || get.Length == 0)) - { - switch (order) - { - case Order.Ascending: - switch (sortType) - { - case SortType.Numeric: return Message.Create(Database, flags, RedisCommand.SORT, key); - case SortType.Alphabetic: return Message.Create(Database, flags, RedisCommand.SORT, key, RedisLiterals.ALPHA); - } - break; - case Order.Descending: - switch (sortType) - { - case SortType.Numeric: return Message.Create(Database, flags, RedisCommand.SORT, key, RedisLiterals.DESC); - case SortType.Alphabetic: return Message.Create(Database, flags, RedisCommand.SORT, key, RedisLiterals.DESC, RedisLiterals.ALPHA); - } - break; - } - } - - // and now: more complicated scenarios... - List values = new List(); - if (!by.IsNull) - { - values.Add(RedisLiterals.BY); - values.Add(by); - } - if (skip != 0 || take != -1)// these are our defaults that mean "everything"; anything else needs to be sent explicitly - { - values.Add(RedisLiterals.LIMIT); - values.Add(skip); - values.Add(take); - } - switch (order) - { - case Order.Ascending: - break; // default - case Order.Descending: - values.Add(RedisLiterals.DESC); - break; - default: - throw new ArgumentOutOfRangeException(nameof(order)); - } - switch (sortType) - { - case SortType.Numeric: - break; // default - case SortType.Alphabetic: - values.Add(RedisLiterals.ALPHA); - break; - default: - throw new ArgumentOutOfRangeException(nameof(sortType)); - } - if (get != null && get.Length != 0) - { - foreach (var item in get) - { - values.Add(RedisLiterals.GET); - values.Add(item); - } - } - if (destination.IsNull) return Message.Create(Database, flags, RedisCommand.SORT, key, values.ToArray()); - - // because we are using STORE, we need to push this to a master - if (Message.GetMasterSlaveFlags(flags) == CommandFlags.DemandSlave) - { - throw ExceptionFactory.MasterOnly(multiplexer.IncludeDetailInExceptions, RedisCommand.SORT, null, null); - } - flags = Message.SetMasterSlaveFlags(flags, CommandFlags.DemandMaster); - values.Add(RedisLiterals.STORE); - return Message.Create(Database, flags, RedisCommand.SORT, key, values.ToArray(), destination); - } - - private Message GetSortedSetCombineAndStoreCommandMessage(SetOperation operation, RedisKey destination, RedisKey[] keys, double[] weights, Aggregate aggregate, CommandFlags flags) - { - RedisCommand command; - switch (operation) - { - case SetOperation.Intersect: command = RedisCommand.ZINTERSTORE; break; - case SetOperation.Union: command = RedisCommand.ZUNIONSTORE; break; - default: throw new ArgumentOutOfRangeException(nameof(operation)); - } - if (keys == null) throw new ArgumentNullException(nameof(keys)); - - List values = null; - if (weights != null && weights.Length != 0) - { - (values ?? (values = new List())).Add(RedisLiterals.WEIGHTS); - foreach (var weight in weights) - values.Add(weight); - } - switch (aggregate) - { - case Aggregate.Sum: break; // default - case Aggregate.Min: - (values ?? (values = new List())).Add(RedisLiterals.AGGREGATE); - values.Add(RedisLiterals.MIN); - break; - case Aggregate.Max: - (values ?? (values = new List())).Add(RedisLiterals.AGGREGATE); - values.Add(RedisLiterals.MAX); - break; - default: - throw new ArgumentOutOfRangeException(nameof(aggregate)); - } - return new SortedSetCombineAndStoreCommandMessage(Database, flags, command, destination, keys, values?.ToArray() ?? RedisValue.EmptyArray); - - } - - private Message GetSortedSetLengthMessage(RedisKey key, double min, double max, Exclude exclude, CommandFlags flags) - { - if (double.IsNegativeInfinity(min) && double.IsPositiveInfinity(max)) - return Message.Create(Database, flags, RedisCommand.ZCARD, key); - - var from = GetRange(min, exclude, true); - var to = GetRange(max, exclude, false); - return Message.Create(Database, flags, RedisCommand.ZCOUNT, key, from, to); - } - - private Message GetSortedSetRangeByScoreMessage(RedisKey key, double start, double stop, Exclude exclude, Order order, long skip, long take, CommandFlags flags, bool withScores) - { - // usage: {ZRANGEBYSCORE|ZREVRANGEBYSCORE} key from to [WITHSCORES] [LIMIT offset count] - // there's basically only 4 layouts; with/without each of scores/limit - var command = order == Order.Descending ? RedisCommand.ZREVRANGEBYSCORE : RedisCommand.ZRANGEBYSCORE; - bool unlimited = skip == 0 && take == -1; // these are our defaults that mean "everything"; anything else needs to be sent explicitly - - bool reverseLimits = (order == Order.Ascending) == (start > stop); - if (reverseLimits) - { - var tmp = start; - start = stop; - stop = tmp; - switch (exclude) - { - case Exclude.Start: exclude = Exclude.Stop; break; - case Exclude.Stop: exclude = Exclude.Start; break; - } - } - - RedisValue from = GetRange(start, exclude, true), to = GetRange(stop, exclude, false); - if (withScores) - { - return unlimited ? Message.Create(Database, flags, command, key, from, to, RedisLiterals.WITHSCORES) - : Message.Create(Database, flags, command, key, new[] { from, to, RedisLiterals.WITHSCORES, RedisLiterals.LIMIT, skip, take }); - } - else - { - return unlimited ? Message.Create(Database, flags, command, key, from, to) - : Message.Create(Database, flags, command, key, new[] { from, to, RedisLiterals.LIMIT, skip, take }); - } - } - - private Message GetSortedSetRemoveRangeByScoreMessage(RedisKey key, double start, double stop, Exclude exclude, CommandFlags flags) - { - return Message.Create(Database, flags, RedisCommand.ZREMRANGEBYSCORE, key, - GetRange(start, exclude, true), GetRange(stop, exclude, false)); - } - - private Message GetStringBitOperationMessage(Bitwise operation, RedisKey destination, RedisKey[] keys, CommandFlags flags) - { - if (keys == null) throw new ArgumentNullException(nameof(keys)); - if (keys.Length == 0) return null; - - // these ones are too bespoke to warrant custom Message implementations - var serverSelectionStrategy = multiplexer.ServerSelectionStrategy; - int slot = serverSelectionStrategy.HashSlot(destination); - var values = new RedisValue[keys.Length + 2]; - values[0] = RedisLiterals.Get(operation); - values[1] = destination.AsRedisValue(); - for (int i = 0; i < keys.Length; i++) - { - values[i + 2] = keys[i].AsRedisValue(); - slot = serverSelectionStrategy.CombineSlot(slot, keys[i]); - } - return Message.CreateInSlot(Database, slot, flags, RedisCommand.BITOP, values); - } - - private Message GetStringBitOperationMessage(Bitwise operation, RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags) - { - // these ones are too bespoke to warrant custom Message implementations - var op = RedisLiterals.Get(operation); - var serverSelectionStrategy = multiplexer.ServerSelectionStrategy; - int slot = serverSelectionStrategy.HashSlot(destination); - slot = serverSelectionStrategy.CombineSlot(slot, first); - if (second.IsNull || operation == Bitwise.Not) - { // unary - return Message.CreateInSlot(Database, slot, flags, RedisCommand.BITOP, new[] { op, destination.AsRedisValue(), first.AsRedisValue() }); - } - // binary - slot = serverSelectionStrategy.CombineSlot(slot, second); - return Message.CreateInSlot(Database, slot, flags, RedisCommand.BITOP, new[] { op, destination.AsRedisValue(), first.AsRedisValue(), second.AsRedisValue() }); - } - - Message GetStringGetWithExpiryMessage(RedisKey key, CommandFlags flags, out ResultProcessor processor, out ServerEndPoint server) - { - if (this is IBatch) - { - throw new NotSupportedException("This operation is not possible inside a transaction or batch; please issue separate GetString and KeyTimeToLive requests"); - } - var features = GetFeatures(Database, key, flags, out server); - processor = StringGetWithExpiryProcessor.Default; - if (server != null && features.MillisecondExpiry && multiplexer.CommandMap.IsAvailable(RedisCommand.PTTL)) - { - return new StringGetWithExpiryMessage(Database, flags, RedisCommand.PTTL, key); - } - // if we use TTL, it doesn't matter which server - server = null; - return new StringGetWithExpiryMessage(Database, flags, RedisCommand.TTL, key); - } - - private Message GetStringSetMessage(KeyValuePair[] values, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - if (values == null) throw new ArgumentNullException(nameof(values)); - switch (values.Length) - { - case 0: return null; - case 1: return GetStringSetMessage(values[0].Key, values[0].Value, null, when, flags); - default: - WhenAlwaysOrNotExists(when); - int slot = ServerSelectionStrategy.NoSlot, offset = 0; - var args = new RedisValue[values.Length * 2]; - var serverSelectionStrategy = multiplexer.ServerSelectionStrategy; - for (int i = 0; i < values.Length; i++) - { - args[offset++] = values[i].Key.AsRedisValue(); - args[offset++] = values[i].Value; - slot = serverSelectionStrategy.CombineSlot(slot, values[i].Key); - } - return Message.CreateInSlot(Database, slot, flags, when == When.NotExists ? RedisCommand.MSETNX : RedisCommand.MSET, args); - } - } - - Message GetStringSetMessage(RedisKey key, RedisValue value, TimeSpan? expiry = null, When when = When.Always, CommandFlags flags = CommandFlags.None) - { - WhenAlwaysOrExistsOrNotExists(when); - if (value.IsNull) return Message.Create(Database, flags, RedisCommand.DEL, key); - - if (expiry == null || expiry.Value == TimeSpan.MaxValue) - { // no expiry - switch (when) - { - case When.Always: return Message.Create(Database, flags, RedisCommand.SET, key, value); - case When.NotExists: return Message.Create(Database, flags, RedisCommand.SETNX, key, value); - case When.Exists: return Message.Create(Database, flags, RedisCommand.SET, key, value, RedisLiterals.XX); - } - } - long milliseconds = expiry.Value.Ticks / TimeSpan.TicksPerMillisecond; - - if ((milliseconds % 1000) == 0) - { - // a nice round number of seconds - long seconds = milliseconds / 1000; - switch (when) - { - case When.Always: return Message.Create(Database, flags, RedisCommand.SETEX, key, seconds, value); - case When.Exists: return Message.Create(Database, flags, RedisCommand.SET, key, value, RedisLiterals.EX, seconds, RedisLiterals.XX); - case When.NotExists: return Message.Create(Database, flags, RedisCommand.SET, key, value, RedisLiterals.EX, seconds, RedisLiterals.NX); - } - } - - switch (when) - { - case When.Always: return Message.Create(Database, flags, RedisCommand.PSETEX, key, milliseconds, value); - case When.Exists: return Message.Create(Database, flags, RedisCommand.SET, key, value, RedisLiterals.PX, milliseconds, RedisLiterals.XX); - case When.NotExists: return Message.Create(Database, flags, RedisCommand.SET, key, value, RedisLiterals.PX, milliseconds, RedisLiterals.NX); - } - throw new NotSupportedException(); - } - - Message IncrMessage(RedisKey key, long value, CommandFlags flags) - { - switch (value) - { - case 0: - if ((flags & CommandFlags.FireAndForget) != 0) return null; - return Message.Create(Database, flags, RedisCommand.INCRBY, key, value); - case 1: - return Message.Create(Database, flags, RedisCommand.INCR, key); - case -1: - return Message.Create(Database, flags, RedisCommand.DECR, key); - default: - return value > 0 - ? Message.Create(Database, flags, RedisCommand.INCRBY, key, value) - : Message.Create(Database, flags, RedisCommand.DECRBY, key, -value); - } - } - - private RedisCommand SetOperationCommand(SetOperation operation, bool store) - { - switch (operation) - { - case SetOperation.Difference: return store ? RedisCommand.SDIFFSTORE : RedisCommand.SDIFF; - case SetOperation.Intersect: return store ? RedisCommand.SINTERSTORE : RedisCommand.SINTER; - case SetOperation.Union: return store ? RedisCommand.SUNIONSTORE : RedisCommand.SUNION; - default: throw new ArgumentOutOfRangeException(nameof(operation)); - } - } - - private IEnumerable TryScan(RedisKey key, RedisValue pattern, int pageSize, long cursor, int pageOffset, CommandFlags flags, RedisCommand command, ResultProcessor.ScanResult> processor) - { - if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize)); - if (!multiplexer.CommandMap.IsAvailable(command)) return null; - - ServerEndPoint server; - var features = GetFeatures(Database, key, flags, out server); - if (!features.Scan) return null; - - if (CursorUtils.IsNil(pattern)) pattern = (byte[])null; - return new ScanIterator(this, server, key, pattern, pageSize, cursor, pageOffset, flags, command, processor); - } - - private Message GetLexMessage(RedisCommand command, RedisKey key, RedisValue min, RedisValue max, Exclude exclude, long skip, long take, CommandFlags flags) - { - RedisValue start = GetLexRange(min, exclude, true), stop = GetLexRange(max, exclude, false); - - if (skip == 0 && take == -1) - return Message.Create(Database, flags, command, key, start, stop); - - return Message.Create(Database, flags, command, key, new[] { start, stop, RedisLiterals.LIMIT, skip, take }); - } - public long SortedSetLengthByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - var msg = GetLexMessage(RedisCommand.ZLEXCOUNT, key, min, max, exclude, 0, -1, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public RedisValue[] SortedSetRangeByValue(RedisKey key, RedisValue min = default(RedisValue), RedisValue max = default(RedisValue), Exclude exclude = Exclude.None, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) - { - var msg = GetLexMessage(RedisCommand.ZRANGEBYLEX, key, min, max, exclude, skip, take, flags); - return ExecuteSync(msg, ResultProcessor.RedisValueArray); - } - - public long SortedSetRemoveRangeByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - var msg = GetLexMessage(RedisCommand.ZREMRANGEBYLEX, key, min, max, exclude, 0, -1, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SortedSetLengthByValueAsync(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - var msg = GetLexMessage(RedisCommand.ZLEXCOUNT, key, min, max, exclude, 0, -1, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public Task SortedSetRangeByValueAsync(RedisKey key, RedisValue min = default(RedisValue), RedisValue max = default(RedisValue), Exclude exclude = Exclude.None, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) - { - var msg = GetLexMessage(RedisCommand.ZRANGEBYLEX, key, min, max, exclude, skip, take, flags); - return ExecuteAsync(msg, ResultProcessor.RedisValueArray); - } - - public Task SortedSetRemoveRangeByValueAsync(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) - { - var msg = GetLexMessage(RedisCommand.ZREMRANGEBYLEX, key, min, max, exclude, 0, -1, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - - internal class ScanIterator : CursorEnumerable - { - private readonly RedisKey key; - private readonly RedisValue pattern; - private readonly RedisCommand command; - - public ScanIterator(RedisDatabase database, ServerEndPoint server, RedisKey key, RedisValue pattern, int pageSize, long cursor, int pageOffset, CommandFlags flags, - RedisCommand command, ResultProcessor processor) - : base(database, server, database.Database, pageSize, cursor, pageOffset, flags) - { - this.key = key; - this.pattern = pattern; - this.command = command; - this.Processor = processor; - } - protected override ResultProcessor.ScanResult> Processor { get; } - - protected override Message CreateMessage(long cursor) - { - if (CursorUtils.IsNil(pattern)) - { - if (pageSize == CursorUtils.DefaultPageSize) - { - return Message.Create(db, flags, command, key, cursor); - } - else - { - return Message.Create(db, flags, command, key, cursor, RedisLiterals.COUNT, pageSize); - } - } - else - { - if (pageSize == CursorUtils.DefaultPageSize) - { - return Message.Create(db, flags, command, key, cursor, RedisLiterals.MATCH, pattern); - } - else - { - return Message.Create(db, flags, command, key, new RedisValue[] { cursor, RedisLiterals.MATCH, pattern, RedisLiterals.COUNT, pageSize }); - } - } - } - } - - internal sealed class ScriptLoadMessage : Message - { - internal readonly string Script; - public ScriptLoadMessage(CommandFlags flags, string script) - : base(-1, flags, RedisCommand.SCRIPT) - { - if (script == null) throw new ArgumentNullException(nameof(script)); - this.Script = script; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 2); - physical.Write(RedisLiterals.LOAD); - physical.Write((RedisValue)Script); - } - } - sealed class HashScanResultProcessor : ScanResultProcessor - { - public static readonly ResultProcessor.ScanResult> Default = new HashScanResultProcessor(); - private HashScanResultProcessor() { } - protected override HashEntry[] Parse(RawResult result) - { - HashEntry[] pairs; - if (!HashEntryArray.TryParse(result, out pairs)) pairs = null; - return pairs; - } - } - - private abstract class ScanResultProcessor : ResultProcessor.ScanResult> - { - protected abstract T[] Parse(RawResult result); - - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.MultiBulk: - var arr = result.GetItems(); - long i64; - if (arr.Length == 2 && arr[1].Type == ResultType.MultiBulk && arr[0].TryGetInt64(out i64)) - { - var sscanResult = new ScanIterator.ScanResult(i64, Parse(arr[1])); - SetResult(message, sscanResult); - return true; - } - break; - } - return false; - } - } - private sealed class ExecuteMessage : Message - { - private readonly string _command; - private static readonly object[] NoArgs = new object[0]; - private readonly ICollection args; - public ExecuteMessage(int db, CommandFlags flags, string command, ICollection args) : base(db, flags, RedisCommand.UNKNOWN) - { - _command = command; - this.args = args ?? NoArgs; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(_command, args.Count); - foreach(object arg in args) - { - if (arg is RedisKey) - { - physical.Write((RedisKey)arg); - } - else if (arg is RedisChannel) - { - physical.Write((RedisChannel)arg); - } - else - { // recognises well-known types - physical.Write(RedisValue.Parse(arg)); - } - } - } - public override string CommandAndKey => _command; - - public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - int slot = ServerSelectionStrategy.NoSlot; - foreach(object arg in args) - { - if(arg is RedisKey) - { - slot = serverSelectionStrategy.CombineSlot(slot, (RedisKey)arg); - } - } - return slot; - } - } - private sealed class ScriptEvalMessage : Message, IMultiMessage - { - private readonly RedisKey[] keys; - private readonly string script; - private readonly RedisValue[] values; - private byte[] asciiHash, hexHash; - public ScriptEvalMessage(int db, CommandFlags flags, string script, RedisKey[] keys, RedisValue[] values) - : this(db, flags, ResultProcessor.ScriptLoadProcessor.IsSHA1(script) ? RedisCommand.EVALSHA : RedisCommand.EVAL, script, null, keys, values) - { - if (script == null) throw new ArgumentNullException(nameof(script)); - } - public ScriptEvalMessage(int db, CommandFlags flags, byte[] hash, RedisKey[] keys, RedisValue[] values) - : this(db, flags, RedisCommand.EVAL, null, hash, keys, values) - { - if (hash == null) throw new ArgumentNullException(nameof(hash)); - } - - private ScriptEvalMessage(int db, CommandFlags flags, RedisCommand command, string script, byte[] hexHash, RedisKey[] keys, RedisValue[] values) - : base(db, flags, command) - { - this.script = script; - this.hexHash = hexHash; - - if (keys == null) keys = RedisKey.EmptyArray; - if (values == null) values = RedisValue.EmptyArray; - for (int i = 0; i < keys.Length; i++) - keys[i].AssertNotNull(); - this.keys = keys; - for (int i = 0; i < values.Length; i++) - values[i].AssertNotNull(); - this.values = values; - } - - public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - int slot = ServerSelectionStrategy.NoSlot; - for (int i = 0; i < keys.Length; i++) - slot = serverSelectionStrategy.CombineSlot(slot, keys[i]); - return slot; - } - - public IEnumerable GetMessages(PhysicalConnection connection) - { - if (script != null && connection.Multiplexer.CommandMap.IsAvailable(RedisCommand.SCRIPT) - && (Flags & CommandFlags.NoScriptCache) == 0) - { - // a script was provided (rather than a hash); check it is known and supported - asciiHash = connection.Bridge.ServerEndPoint.GetScriptHash(script, command); - - if (asciiHash == null) - { - var msg = new ScriptLoadMessage(Flags, script); - msg.SetInternalCall(); - msg.SetSource(ResultProcessor.ScriptLoad, null); - yield return msg; - } - } - yield return this; - } - - internal override void WriteImpl(PhysicalConnection physical) - { - if (hexHash != null) - { - physical.WriteHeader(RedisCommand.EVALSHA, 2 + keys.Length + values.Length); - physical.WriteAsHex(hexHash); - } - else if (asciiHash != null) - { - physical.WriteHeader(RedisCommand.EVALSHA, 2 + keys.Length + values.Length); - physical.Write((RedisValue)asciiHash); - } - else - { - physical.WriteHeader(RedisCommand.EVAL, 2 + keys.Length + values.Length); - physical.Write((RedisValue)script); - } - physical.Write(keys.Length); - for (int i = 0; i < keys.Length; i++) - physical.Write(keys[i]); - for (int i = 0; i < values.Length; i++) - physical.Write(values[i]); - } - } - - sealed class SetScanResultProcessor : ScanResultProcessor - { - public static readonly ResultProcessor.ScanResult> Default = new SetScanResultProcessor(); - private SetScanResultProcessor() { } - protected override RedisValue[] Parse(RawResult result) - { - return result.GetItemsAsValues(); - } - } - sealed class SortedSetCombineAndStoreCommandMessage : Message.CommandKeyBase // ZINTERSTORE and ZUNIONSTORE have a very unusual signature - { - private readonly RedisKey[] keys; - private readonly RedisValue[] values; - public SortedSetCombineAndStoreCommandMessage(int db, CommandFlags flags, RedisCommand command, RedisKey destination, RedisKey[] keys, RedisValue[] values) - : base(db, flags, command, destination) - { - for (int i = 0; i < keys.Length; i++) - keys[i].AssertNotNull(); - this.keys = keys; - for (int i = 0; i < values.Length; i++) - values[i].AssertNotNull(); - this.values = values; - } - public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - int slot = base.GetHashSlot(serverSelectionStrategy); - for (int i = 0; i < keys.Length; i++) - slot = serverSelectionStrategy.CombineSlot(slot, keys[i]); - return slot; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 2 + keys.Length + values.Length); - physical.Write(Key); - physical.Write(keys.Length); - for (int i = 0; i < keys.Length; i++) - physical.Write(keys[i]); - for (int i = 0; i < values.Length; i++) - physical.Write(values[i]); - } - } - - sealed class SortedSetScanResultProcessor : ScanResultProcessor - { - public static readonly ResultProcessor.ScanResult> Default = new SortedSetScanResultProcessor(); - private SortedSetScanResultProcessor() { } - protected override SortedSetEntry[] Parse(RawResult result) - { - SortedSetEntry[] pairs; - if (!SortedSetWithScores.TryParse(result, out pairs)) pairs = null; - return pairs; - } - } - private class StringGetWithExpiryMessage : Message.CommandKeyBase, IMultiMessage - { - private readonly RedisCommand ttlCommand; - private ResultBox box; - - public StringGetWithExpiryMessage(int db, CommandFlags flags, RedisCommand ttlCommand, RedisKey key) - : base(db, flags | CommandFlags.NoRedirect /* <== not implemented/tested */, RedisCommand.GET, key) - { - this.ttlCommand = ttlCommand; - } - public override string CommandAndKey => ttlCommand + "+" + RedisCommand.GET + " " + (string)Key; - - public IEnumerable GetMessages(PhysicalConnection connection) - { - box = ResultBox.Get(null); - var ttl = Message.Create(Db, Flags, ttlCommand, Key); - var proc = ttlCommand == RedisCommand.PTTL ? ResultProcessor.TimeSpanFromMilliseconds : ResultProcessor.TimeSpanFromSeconds; - ttl.SetSource(proc, box); - yield return ttl; - yield return this; - } - - public bool UnwrapValue(out TimeSpan? value, out Exception ex) - { - if (box != null) - { - ResultBox.UnwrapAndRecycle(box, false, out value, out ex); - box = null; - return ex == null; - } - value = null; - ex = null; - return false; - } - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(command, 1); - physical.Write(Key); - } - } - - private class StringGetWithExpiryProcessor : ResultProcessor - { - public static readonly ResultProcessor Default = new StringGetWithExpiryProcessor(); - private StringGetWithExpiryProcessor() { } - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.Integer: - case ResultType.SimpleString: - case ResultType.BulkString: - RedisValue value = result.AsRedisValue(); - var sgwem = message as StringGetWithExpiryMessage; - TimeSpan? expiry; - Exception ex; - if (sgwem != null && sgwem.UnwrapValue(out expiry, out ex)) - { - if (ex == null) - { - SetResult(message, new RedisValueWithExpiry(value, expiry)); - } - else - { - SetException(message, ex); - } - return true; - } - break; - } - return false; - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisErrorEventArgs.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisErrorEventArgs.cs deleted file mode 100644 index a5fee38..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisErrorEventArgs.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Net; -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Notification of errors from the redis server - /// - public sealed class RedisErrorEventArgs : EventArgs, ICompletable - { - private readonly EventHandler handler; - private readonly object sender; - internal RedisErrorEventArgs( - EventHandler handler, object sender, - EndPoint endpoint, string message) - { - this.handler = handler; - this.sender = sender; - Message = message; - EndPoint = endpoint; - } - - /// - /// The origin of the message - /// - public EndPoint EndPoint { get; } - - /// - /// The message from the server - /// - public string Message { get; } - - void ICompletable.AppendStormLog(StringBuilder sb) - { - sb.Append("event, error: ").Append(Message); - } - - bool ICompletable.TryComplete(bool isAsync) - { - return ConnectionMultiplexer.TryCompleteHandler(handler, sender, this, isAsync); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisFeatures.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisFeatures.cs deleted file mode 100644 index 8d7f2f9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisFeatures.cs +++ /dev/null @@ -1,172 +0,0 @@ -using System; -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Provides basic information about the features available on a particular version of Redis - /// - public struct RedisFeatures - { - internal static readonly Version v2_0_0 = new Version(2, 0, 0), - v2_1_0 = new Version(2, 1, 0), - v2_1_1 = new Version(2, 1, 1), - v2_1_2 = new Version(2, 1, 2), - v2_1_3 = new Version(2, 1, 3), - v2_1_8 = new Version(2, 1, 8), - v2_2_0 = new Version(2, 2, 0), - v2_4_0 = new Version(2, 4, 0), - v2_5_7 = new Version(2, 5, 7), - v2_5_10 = new Version(2, 5, 10), - v2_5_14 = new Version(2, 5, 14), - v2_6_0 = new Version(2, 6, 0), - v2_6_5 = new Version(2, 6, 5), - v2_6_9 = new Version(2, 6, 9), - v2_6_12 = new Version(2, 6, 12), - v2_8_0 = new Version(2, 8, 0), - v2_8_12 = new Version(2, 8, 12), - v2_8_18 = new Version(2, 8, 18), - v2_9_5 = new Version(2, 9, 5), - v3_0_0 = new Version(3, 0, 0), - v3_2_0 = new Version(3, 2, 0); - - private readonly Version version; - /// - /// Create a new RedisFeatures instance for the given version - /// - public RedisFeatures(Version version) - { - if (version == null) throw new ArgumentNullException(nameof(version)); - this.version = version; - } - - /// - /// Does BITOP / BITCOUNT exist? - /// - public bool BitwiseOperations => Version >= v2_5_10; - - /// - /// Is CLIENT SETNAME available? - /// - public bool ClientName => Version >= v2_6_9; - - /// - /// Does EXEC support EXECABORT if there are errors? - /// - public bool ExecAbort => Version >= v2_6_5 && Version != v2_9_5; - - /// - /// Can EXPIRE be used to set expiration on a key that is already volatile (i.e. has an expiration)? - /// - public bool ExpireOverwrite => Version >= v2_1_3; - - /// - /// Does HDEL support varadic usage? - /// - public bool HashVaradicDelete => Version >= v2_4_0; - - /// - /// Does INCRBYFLOAT / HINCRBYFLOAT exist? - /// - public bool IncrementFloat => Version >= v2_5_7; - - /// - /// Does INFO support sections? - /// - public bool InfoSections => Version >= v2_8_0; - - /// - /// Is LINSERT available? - /// - public bool ListInsert => Version >= v2_1_1; - - /// - /// Indicates whether PEXPIRE and PTTL are supported - /// - public bool MillisecondExpiry => Version >= v2_6_0; - - /// - /// Does SRANDMEMBER support "count"? - /// - public bool MultipleRandom => Version >= v2_5_14; - - /// - /// Is the PERSIST operation supported? - /// - public bool Persist => Version >= v2_1_2; - - /// - /// Is RPUSHX and LPUSHX available? - /// - public bool PushIfNotExists => Version >= v2_1_1; - - /// - /// Are cursor-based scans available? - /// - public bool Scan => Version >= v2_8_0; - - /// - /// Does EVAL / EVALSHA / etc exist? - /// - public bool Scripting => Version >= v2_5_7; - - /// - /// Does SET have the EX|PX|NX|XX extensions? - /// - public bool SetConditional => Version >= v2_6_12; - - /// - /// Does SADD support varadic usage? - /// - public bool SetVaradicAddRemove => Version >= v2_4_0; - - /// - /// Is STRLEN available? - /// - public bool StringLength => Version >= v2_1_2; - - /// - /// Is SETRANGE available? - /// - public bool StringSetRange => Version >= v2_1_8; - - /// - /// Does TIME exist? - /// - public bool Time => Version >= v2_6_0; - - /// - /// Are Lua changes to the calling database transparent to the calling client? - /// - public bool ScriptingDatabaseSafe => Version >= v2_8_12; - - /// - /// Is PFCOUNT supported on slaves? - /// - public bool HyperLogLogCountSlaveSafe => Version >= v2_8_18; - - /// - /// Are the GEO commands available? - /// - public bool Geo => Version >= v3_2_0; - - /// - /// The Redis version of the server - /// - public Version Version => version ?? v2_0_0; - - /// - /// Create a string representation of the available features - /// - public override string ToString() - { - var sb = new StringBuilder().Append("Features in ").Append(Version).AppendLine() - .Append("ExpireOverwrite: ").Append(ExpireOverwrite).AppendLine() - .Append("Persist: ").Append(Persist).AppendLine(); - - return sb.ToString(); - } - // 2.9.5 (cluster beta 1) has a bug in EXECABORT re MOVED and ASK; it only affects cluster, but - // frankly if you aren't playing with cluster, why are you using 2.9.5 in the first place? - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisKey.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisKey.cs deleted file mode 100644 index 06b6655..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisKey.cs +++ /dev/null @@ -1,318 +0,0 @@ -using System; -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Represents a key that can be stored in redis - /// - public struct RedisKey : IEquatable - { - internal static readonly RedisKey[] EmptyArray = new RedisKey[0]; - private readonly byte[] keyPrefix; - private readonly object keyValue; // always either a string or a byte[] - internal RedisKey(byte[] keyPrefix, object keyValue) - { - this.keyPrefix = (keyPrefix != null && keyPrefix.Length == 0) ? null : keyPrefix; - this.keyValue = keyValue; - } - - internal RedisKey AsPrefix() - { - return new RedisKey((byte[])this, null); - } - internal bool IsNull => keyPrefix == null && keyValue == null; - - internal bool IsEmpty - { - get - { - if (keyPrefix != null) return false; - if (keyValue == null) return true; - if (keyValue is string) return ((string)keyValue).Length == 0; - return ((byte[])keyValue).Length == 0; - } - } - - internal byte[] KeyPrefix => keyPrefix; - internal object KeyValue => keyValue; - - /// - /// Indicate whether two keys are not equal - /// - public static bool operator !=(RedisKey x, RedisKey y) - { - return !(x == y); - } - - /// - /// Indicate whether two keys are not equal - /// - public static bool operator !=(string x, RedisKey y) - { - return !(x == y); - } - - /// - /// Indicate whether two keys are not equal - /// - public static bool operator !=(byte[] x, RedisKey y) - { - return !(x == y); - } - - /// - /// Indicate whether two keys are not equal - /// - public static bool operator !=(RedisKey x, string y) - { - return !(x == y); - } - - /// - /// Indicate whether two keys are not equal - /// - public static bool operator !=(RedisKey x, byte[] y) - { - return !(x == y); - } - - /// - /// Indicate whether two keys are equal - /// - public static bool operator ==(RedisKey x, RedisKey y) - { - return CompositeEquals(x.keyPrefix, x.keyValue, y.keyPrefix, y.keyValue); - } - - /// - /// Indicate whether two keys are equal - /// - public static bool operator ==(string x, RedisKey y) - { - return CompositeEquals(null, x, y.keyPrefix, y.keyValue); - } - - /// - /// Indicate whether two keys are equal - /// - public static bool operator ==(byte[] x, RedisKey y) - { - return CompositeEquals(null, x, y.keyPrefix, y.keyValue); - } - - /// - /// Indicate whether two keys are equal - /// - public static bool operator ==(RedisKey x, string y) - { - return CompositeEquals(x.keyPrefix, x.keyValue, null, y); - } - - /// - /// Indicate whether two keys are equal - /// - public static bool operator ==(RedisKey x, byte[] y) - { - return CompositeEquals(x.keyPrefix, x.keyValue, null, y); - } - - /// - /// See Object.Equals - /// - public override bool Equals(object obj) - { - if (obj is RedisKey) - { - var other = (RedisKey)obj; - return CompositeEquals(this.keyPrefix, this.keyValue, other.keyPrefix, other.keyValue); - } - if (obj is string || obj is byte[]) - { - return CompositeEquals(this.keyPrefix, this.keyValue, null, obj); - } - return false; - } - - /// - /// Indicate whether two keys are equal - /// - public bool Equals(RedisKey other) - { - return CompositeEquals(this.keyPrefix, this.keyValue, other.keyPrefix, other.keyValue); - } - - private static bool CompositeEquals(byte[] keyPrefix0, object keyValue0, byte[] keyPrefix1, object keyValue1) - { - if(RedisValue.Equals(keyPrefix0, keyPrefix1)) - { - if (keyValue0 == keyValue1) return true; // ref equal - if (keyValue0 == null || keyValue1 == null) return false; // null vs non-null - - if (keyValue0 is string && keyValue1 is string) return ((string)keyValue0) == ((string)keyValue1); - if (keyValue0 is byte[] && keyValue1 is byte[]) return RedisValue.Equals((byte[])keyValue0, (byte[])keyValue1); - } - - return RedisValue.Equals(ConcatenateBytes(keyPrefix0, keyValue0, null), ConcatenateBytes(keyPrefix1, keyValue1, null)); - } - - /// - /// See Object.GetHashCode - /// - public override int GetHashCode() - { - int chk0 = keyPrefix == null ? 0 : RedisValue.GetHashCode(this.keyPrefix), - chk1 = keyValue is string ? keyValue.GetHashCode() : RedisValue.GetHashCode((byte[])keyValue); - - return unchecked((17 * chk0) + chk1); - } - - /// - /// Obtains a string representation of the key - /// - public override string ToString() - { - return ((string)this) ?? "(null)"; - } - - internal RedisValue AsRedisValue() - { - return (byte[])this; - } - - internal void AssertNotNull() - { - if (IsNull) throw new ArgumentException("A null key is not valid in this context"); - } - - /// - /// Create a key from a String - /// - public static implicit operator RedisKey(string key) - { - if (key == null) return default(RedisKey); - return new RedisKey(null, key); - } - /// - /// Create a key from a Byte[] - /// - public static implicit operator RedisKey(byte[] key) - { - if (key == null) return default(RedisKey); - return new RedisKey(null, key); - } - /// - /// Obtain the key as a Byte[] - /// - public static implicit operator byte[](RedisKey key) - { - return ConcatenateBytes(key.keyPrefix, key.keyValue, null); - } - /// - /// Obtain the key as a String - /// - public static implicit operator string(RedisKey key) - { - byte[] arr; - if(key.keyPrefix == null) - { - if (key.keyValue == null) return null; - - if (key.keyValue is string) return (string)key.keyValue; - - arr = (byte[])key.keyValue; - } - else - { - arr = (byte[])key; - } - if (arr == null) return null; - try - { - return Encoding.UTF8.GetString(arr); - } - catch - { - return BitConverter.ToString(arr); - } - - } - - /// - /// Concatenate two keys - /// - [Obsolete] - public static RedisKey operator +(RedisKey x, RedisKey y) - { - return new RedisKey(ConcatenateBytes(x.keyPrefix, x.keyValue, y.keyPrefix), y.keyValue); - } - - internal static RedisKey WithPrefix(byte[] prefix, RedisKey value) - { - if(prefix == null || prefix.Length == 0) return value; - if (value.keyPrefix == null) return new RedisKey(prefix, value.keyValue); - if (value.keyValue == null) return new RedisKey(prefix, value.keyPrefix); - - // two prefixes; darn - byte[] copy = new byte[prefix.Length + value.keyPrefix.Length]; - Buffer.BlockCopy(prefix, 0, copy, 0, prefix.Length); - Buffer.BlockCopy(value.keyPrefix, 0, copy, prefix.Length, value.keyPrefix.Length); - return new RedisKey(copy, value.keyValue); - } - - internal static byte[] ConcatenateBytes(byte[] a, object b, byte[] c) - { - if ((a == null || a.Length == 0) && (c == null || c.Length == 0)) - { - if (b == null) return null; - if (b is string) return Encoding.UTF8.GetBytes((string)b); - return (byte[])b; - } - - int aLen = a?.Length ?? 0, - bLen = b == null ? 0 : (b is string - ? Encoding.UTF8.GetByteCount((string)b) - : ((byte[])b).Length), - cLen = c?.Length ?? 0; - - byte[] result = new byte[aLen + bLen + cLen]; - if (aLen != 0) Buffer.BlockCopy(a, 0, result, 0, aLen); - if (bLen != 0) - { - if (b is string) - { - string s = (string)b; - Encoding.UTF8.GetBytes(s, 0, s.Length, result, aLen); - } - else - { - Buffer.BlockCopy((byte[])b, 0, result, aLen, bLen); - } - } - if (cLen != 0) Buffer.BlockCopy(c, 0, result, aLen + bLen, cLen); - return result; - } - - /// - /// Prepends p to this RedisKey, returning a new RedisKey. - /// - /// Avoids some allocations if possible, repeated Prepend/Appends make - /// it less possible. - /// - public RedisKey Prepend(RedisKey p) - { - return WithPrefix(p, this); - } - - /// - /// Appends p to this RedisKey, returning a new RedisKey. - /// - /// Avoids some allocations if possible, repeated Prepend/Appends make - /// it less possible. - /// - public RedisKey Append(RedisKey p) - { - return WithPrefix(this, p); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisLiterals.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisLiterals.cs deleted file mode 100644 index 588e39d..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisLiterals.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Text; - -namespace StackExchange.Redis -{ - internal static class RedisLiterals - { - // unlike primary commands, these do not get altered by the command-map; we may as - // well compute the bytes once and share them - public static readonly RedisValue - ADDR = "ADDR", - AFTER = "AFTER", - AGGREGATE = "AGGREGATE", - ALPHA = "ALPHA", - AND = "AND", - BEFORE = "BEFORE", - BY = "BY", - CHANNELS = "CHANNELS", - COPY = "COPY", - COUNT = "COUNT", - DESC = "DESC", - EX = "EX", - EXISTS = "EXISTS", - FLUSH = "FLUSH", - GET = "GET", - GETNAME = "GETNAME", - ID = "ID", - KILL = "KILL", - LIMIT = "LIMIT", - LIST = "LIST", - LOAD = "LOAD", - MATCH = "MATCH", - MAX = "MAX", - MIN = "MIN", - NODES = "NODES", - NOSAVE = "NOSAVE", - NOT = "NOT", - NUMPAT = "NUMPAT", - NUMSUB = "NUMSUB", - NX = "NX", - OBJECT = "OBJECT", - OR = "OR", - PAUSE = "PAUSE", - PING = "PING", - PX = "PX", - REPLACE = "REPLACE", - RESET = "RESET", - RESETSTAT = "RESETSTAT", - REWRITE = "REWRITE", - SAVE = "SAVE", - SEGFAULT = "SEGFAULT", - SET = "SET", - SETNAME = "SETNAME", - SKIPME = "SKIPME", - STORE = "STORE", - TYPE = "TYPE", - WEIGHTS = "WEIGHTS", - WITHSCORES = "WITHSCORES", - XOR = "XOR", - XX = "XX", - - - - // Sentinel Literals - MASTERS = "MASTERS", - MASTER = "MASTER", - SLAVES = "SLAVES", - GETMASTERADDRBYNAME = "GET-MASTER-ADDR-BY-NAME", -// RESET = "RESET", - FAILOVER = "FAILOVER", - - // Sentinel Literals as of 2.8.4 - MONITOR = "MONITOR", - REMOVE = "REMOVE", -// SET = "SET", - - // DO NOT CHANGE CASE: these are configuration settings and MUST be as-is - databases = "databases", - no = "no", - normal = "normal", - pubsub = "pubsub", - replication = "replication", - server = "server", - slave = "slave", - slave_read_only = "slave-read-only", - timeout = "timeout", - yes = "yes", - - MinusSymbol = "-", - PlusSumbol = "+", - Wildcard = "*"; - - public static readonly byte[] BytesOK = Encoding.UTF8.GetBytes("OK"); - public static readonly byte[] BytesPONG = Encoding.UTF8.GetBytes("PONG"); - public static readonly byte[] BytesBackgroundSavingStarted = Encoding.UTF8.GetBytes("Background saving started"); - public static readonly byte[] ByteWildcard = { (byte)'*' }; - internal static RedisValue Get(Bitwise operation) - { - switch(operation) - { - case Bitwise.And: return AND; - case Bitwise.Or: return OR; - case Bitwise.Xor: return XOR; - case Bitwise.Not: return NOT; - default: throw new ArgumentOutOfRangeException(nameof(operation)); - } - } - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisResult.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisResult.cs deleted file mode 100644 index fc5c871..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisResult.cs +++ /dev/null @@ -1,389 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - /// - /// Represents a general-purpose result from redis, that may be cast into various anticipated types - /// - public abstract class RedisResult - { - /// - /// Create a new RedisResult. - /// - /// - public static RedisResult Create(RedisValue value) - { - return new SingleRedisResult(value); - } - - // internally, this is very similar to RawResult, except it is designed to be usable - // outside of the IO-processing pipeline: the buffers are standalone, etc - - internal static RedisResult TryCreate(PhysicalConnection connection, RawResult result) - { - try - { - switch (result.Type) - { - case ResultType.Integer: - case ResultType.SimpleString: - case ResultType.BulkString: - return new SingleRedisResult(result.AsRedisValue()); - case ResultType.MultiBulk: - var items = result.GetItems(); - var arr = new RedisResult[items.Length]; - for (int i = 0; i < arr.Length; i++) - { - var next = TryCreate(connection, items[i]); - if (next == null) return null; // means we didn't understand - arr[i] = next; - } - return new ArrayRedisResult(arr); - case ResultType.Error: - return new ErrorRedisResult(result.GetString()); - default: - return null; - } - } catch(Exception ex) - { - connection?.OnInternalError(ex); - return null; // will be logged as a protocol fail by the processor - } - } - - /// - /// Indicates whether this result was a null result - /// - public abstract bool IsNull { get; } - - /// - /// Interprets the result as a String - /// - public static explicit operator string (RedisResult result) { return result.AsString(); } - /// - /// Interprets the result as a Byte[] - /// - public static explicit operator byte[] (RedisResult result) { return result.AsByteArray(); } - /// - /// Interprets the result as a Double - /// - public static explicit operator double (RedisResult result) { return result.AsDouble(); } - /// - /// Interprets the result as an Int64 - /// - public static explicit operator long (RedisResult result) { return result.AsInt64(); } - /// - /// Interprets the result as an Int32 - /// - public static explicit operator int (RedisResult result) { return result.AsInt32(); } - /// - /// Interprets the result as a Boolean - /// - public static explicit operator bool (RedisResult result) { return result.AsBoolean(); } - /// - /// Interprets the result as a RedisValue - /// - public static explicit operator RedisValue (RedisResult result) { return result.AsRedisValue(); } - /// - /// Interprets the result as a RedisKey - /// - public static explicit operator RedisKey (RedisResult result) { return result.AsRedisKey(); } - /// - /// Interprets the result as a Nullable Double - /// - public static explicit operator double? (RedisResult result) { return result.AsNullableDouble(); } - /// - /// Interprets the result as a Nullable Int64 - /// - public static explicit operator long? (RedisResult result) { return result.AsNullableInt64(); } - /// - /// Interprets the result as a Nullable Int32 - /// - public static explicit operator int? (RedisResult result) { return result.AsNullableInt32(); } - /// - /// Interprets the result as a Nullable Boolean - /// - public static explicit operator bool? (RedisResult result) { return result.AsNullableBoolean(); } - /// - /// Interprets the result as an array of String - /// - public static explicit operator string[] (RedisResult result) { return result.AsStringArray(); } - /// - /// Interprets the result as an array of Byte[] - /// - public static explicit operator byte[][] (RedisResult result) { return result.AsByteArrayArray(); } - /// - /// Interprets the result as an array of Double - /// - public static explicit operator double[] (RedisResult result) { return result.AsDoubleArray(); } - /// - /// Interprets the result as an array of Int64 - /// - public static explicit operator long[] (RedisResult result) { return result.AsInt64Array(); } - /// - /// Interprets the result as an array of Int32 - /// - public static explicit operator int[] (RedisResult result) { return result.AsInt32Array(); } - /// - /// Interprets the result as an array of Boolean - /// - public static explicit operator bool[] (RedisResult result) { return result.AsBooleanArray(); } - /// - /// Interprets the result as an array of RedisValue - /// - public static explicit operator RedisValue[] (RedisResult result) { return result.AsRedisValueArray(); } - /// - /// Interprets the result as an array of RedisKey - /// - public static explicit operator RedisKey[] (RedisResult result) { return result.AsRedisKeyArray(); } - /// - /// Interprets the result as an array of RedisResult - /// - public static explicit operator RedisResult[] (RedisResult result) { return result.AsRedisResultArray(); } - - internal abstract bool AsBoolean(); - - internal abstract bool[] AsBooleanArray(); - - internal abstract byte[] AsByteArray(); - - internal abstract byte[][] AsByteArrayArray(); - - internal abstract double AsDouble(); - - internal abstract double[] AsDoubleArray(); - - internal abstract int AsInt32(); - - internal abstract int[] AsInt32Array(); - - internal abstract long AsInt64(); - - internal abstract long[] AsInt64Array(); - - internal abstract bool? AsNullableBoolean(); - - internal abstract double? AsNullableDouble(); - - internal abstract int? AsNullableInt32(); - - internal abstract long? AsNullableInt64(); - - internal abstract RedisKey AsRedisKey(); - - internal abstract RedisKey[] AsRedisKeyArray(); - - internal abstract RedisResult[] AsRedisResultArray(); - - internal abstract RedisValue AsRedisValue(); - - internal abstract RedisValue[] AsRedisValueArray(); - internal abstract string AsString(); - internal abstract string[] AsStringArray(); - private sealed class ArrayRedisResult : RedisResult - { - public override bool IsNull => value == null; - private readonly RedisResult[] value; - public ArrayRedisResult(RedisResult[] value) - { - if (value == null) throw new ArgumentNullException(nameof(value)); - this.value = value; - } - public override string ToString() - { - return value.Length + " element(s)"; - } - internal override bool AsBoolean() - { - if (value.Length == 1) return value[0].AsBoolean(); - throw new InvalidCastException(); - } - - internal override bool[] AsBooleanArray() { return ConvertHelper.ConvertAll(value, x => x.AsBoolean()); } - - internal override byte[] AsByteArray() - { - if (value.Length == 1) return value[0].AsByteArray(); - throw new InvalidCastException(); - } - internal override byte[][] AsByteArrayArray() { return ConvertHelper.ConvertAll(value, x => x.AsByteArray()); } - - internal override double AsDouble() - { - if (value.Length == 1) return value[0].AsDouble(); - throw new InvalidCastException(); - } - - internal override double[] AsDoubleArray() { return ConvertHelper.ConvertAll(value, x => x.AsDouble()); } - - internal override int AsInt32() - { - if (value.Length == 1) return value[0].AsInt32(); - throw new InvalidCastException(); - } - - internal override int[] AsInt32Array() { return ConvertHelper.ConvertAll(value, x => x.AsInt32()); } - - internal override long AsInt64() - { - if (value.Length == 1) return value[0].AsInt64(); - throw new InvalidCastException(); - } - - internal override long[] AsInt64Array() { return ConvertHelper.ConvertAll(value, x => x.AsInt64()); } - - internal override bool? AsNullableBoolean() - { - if (value.Length == 1) return value[0].AsNullableBoolean(); - throw new InvalidCastException(); - } - - internal override double? AsNullableDouble() - { - if (value.Length == 1) return value[0].AsNullableDouble(); - throw new InvalidCastException(); - } - - internal override int? AsNullableInt32() - { - if (value.Length == 1) return value[0].AsNullableInt32(); - throw new InvalidCastException(); - } - - internal override long? AsNullableInt64() - { - if (value.Length == 1) return value[0].AsNullableInt64(); - throw new InvalidCastException(); - } - - internal override RedisKey AsRedisKey() - { - if (value.Length == 1) return value[0].AsRedisKey(); - throw new InvalidCastException(); - } - - internal override RedisKey[] AsRedisKeyArray() { return ConvertHelper.ConvertAll(value, x => x.AsRedisKey()); } - - internal override RedisResult[] AsRedisResultArray() { return value; } - - internal override RedisValue AsRedisValue() - { - if (value.Length == 1) return value[0].AsRedisValue(); - throw new InvalidCastException(); - } - - internal override RedisValue[] AsRedisValueArray() { return ConvertHelper.ConvertAll(value, x => x.AsRedisValue()); } - - internal override string AsString() - { - if (value.Length == 1) return value[0].AsString(); - throw new InvalidCastException(); - } - internal override string[] AsStringArray() { return ConvertHelper.ConvertAll(value, x => x.AsString()); } - } - - private sealed class ErrorRedisResult : RedisResult - { - private readonly string value; - public ErrorRedisResult(string value) - { - if (value == null) throw new ArgumentNullException(nameof(value)); - this.value = value; - } - public override bool IsNull => value == null; - public override string ToString() { return value; } - internal override bool AsBoolean() { throw new RedisServerException(value); } - - internal override bool[] AsBooleanArray() { throw new RedisServerException(value); } - - internal override byte[] AsByteArray() { throw new RedisServerException(value); } - - internal override byte[][] AsByteArrayArray() { throw new RedisServerException(value); } - - internal override double AsDouble() { throw new RedisServerException(value); } - - internal override double[] AsDoubleArray() { throw new RedisServerException(value); } - - internal override int AsInt32() { throw new RedisServerException(value); } - - internal override int[] AsInt32Array() { throw new RedisServerException(value); } - - internal override long AsInt64() { throw new RedisServerException(value); } - - internal override long[] AsInt64Array() { throw new RedisServerException(value); } - - internal override bool? AsNullableBoolean() { throw new RedisServerException(value); } - - internal override double? AsNullableDouble() { throw new RedisServerException(value); } - - internal override int? AsNullableInt32() { throw new RedisServerException(value); } - - internal override long? AsNullableInt64() { throw new RedisServerException(value); } - - internal override RedisKey AsRedisKey() { throw new RedisServerException(value); } - - internal override RedisKey[] AsRedisKeyArray() { throw new RedisServerException(value); } - - internal override RedisResult[] AsRedisResultArray() { throw new RedisServerException(value); } - - internal override RedisValue AsRedisValue() { throw new RedisServerException(value); } - - internal override RedisValue[] AsRedisValueArray() { throw new RedisServerException(value); } - - internal override string AsString() { throw new RedisServerException(value); } - internal override string[] AsStringArray() { throw new RedisServerException(value); } - } - - private sealed class SingleRedisResult : RedisResult - { - private readonly RedisValue value; - public SingleRedisResult(RedisValue value) - { - this.value = value; - } - - public override bool IsNull => value.IsNull; - - public override string ToString() { return value.ToString(); } - internal override bool AsBoolean() { return (bool)value; } - - internal override bool[] AsBooleanArray() { return new[] { AsBoolean() }; } - - internal override byte[] AsByteArray() { return (byte[])value; } - internal override byte[][] AsByteArrayArray() { return new[] { AsByteArray() }; } - - internal override double AsDouble() { return (double)value; } - - internal override double[] AsDoubleArray() { return new[] { AsDouble() }; } - - internal override int AsInt32() { return (int)value; } - - internal override int[] AsInt32Array() { return new[] { AsInt32() }; } - - internal override long AsInt64() { return (long)value; } - - internal override long[] AsInt64Array() { return new[] { AsInt64() }; } - - internal override bool? AsNullableBoolean() { return (bool?)value; } - - internal override double? AsNullableDouble() { return (double?)value; } - - internal override int? AsNullableInt32() { return (int?)value; } - - internal override long? AsNullableInt64() { return (long?)value; } - - internal override RedisKey AsRedisKey() { return (byte[])value; } - - internal override RedisKey[] AsRedisKeyArray() { return new[] { AsRedisKey() }; } - - internal override RedisResult[] AsRedisResultArray() { throw new InvalidCastException(); } - - internal override RedisValue AsRedisValue() { return value; } - - internal override RedisValue[] AsRedisValueArray() { return new[] { AsRedisValue() }; } - - internal override string AsString() { return (string)value; } - internal override string[] AsStringArray() { return new[] { AsString() }; } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisServer.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisServer.cs deleted file mode 100644 index 8690963..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisServer.cs +++ /dev/null @@ -1,818 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - - internal sealed partial class RedisServer : RedisBase, IServer - { - private readonly ServerEndPoint server; - - internal RedisServer(ConnectionMultiplexer multiplexer, ServerEndPoint server, object asyncState) : base(multiplexer, asyncState) - { - if (server == null) throw new ArgumentNullException(nameof(server)); - this.server = server; - } - - public ClusterConfiguration ClusterConfiguration => server.ClusterConfiguration; - - public EndPoint EndPoint => server.EndPoint; - - public RedisFeatures Features => server.GetFeatures(); - - public bool IsConnected => server.IsConnected; - - public bool IsSlave => server.IsSlave; - - public bool AllowSlaveWrites - { - get { return server.AllowSlaveWrites; } - set { server.AllowSlaveWrites = value; } - } - - public ServerType ServerType => server.ServerType; - - public Version Version => server.Version; - - public void ClientKill(EndPoint endpoint, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CLIENT, RedisLiterals.KILL, (RedisValue)Format.ToString(endpoint)); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - - public Task ClientKillAsync(EndPoint endpoint, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CLIENT, RedisLiterals.KILL, (RedisValue)Format.ToString(endpoint)); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public long ClientKill(long? id = null, ClientType? clientType = null, EndPoint endpoint = null, bool skipMe = true, CommandFlags flags = CommandFlags.None) - { - var msg = GetClientKillMessage(endpoint, id, clientType, skipMe, flags); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task ClientKillAsync(long? id = null, ClientType? clientType = null, EndPoint endpoint = null, bool skipMe = true, CommandFlags flags = CommandFlags.None) - { - var msg = GetClientKillMessage(endpoint, id, clientType, skipMe, flags); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - Message GetClientKillMessage(EndPoint endpoint, long? id, ClientType? clientType, bool skipMe, CommandFlags flags) - { - List parts = new List(9) - { - RedisLiterals.KILL - }; - if(id != null) - { - parts.Add(RedisLiterals.ID); - parts.Add(id.Value); - } - if (clientType != null) - { - parts.Add(RedisLiterals.TYPE); - switch(clientType.Value) - { - case ClientType.Normal: - parts.Add(RedisLiterals.normal); - break; - case ClientType.Slave: - parts.Add(RedisLiterals.slave); - break; - case ClientType.PubSub: - parts.Add(RedisLiterals.pubsub); - break; - default: - throw new ArgumentOutOfRangeException(nameof(clientType)); - } - parts.Add(id.Value); - } - if (endpoint != null) - { - parts.Add(RedisLiterals.ADDR); - parts.Add((RedisValue)Format.ToString(endpoint)); - } - if(!skipMe) - { - parts.Add(RedisLiterals.SKIPME); - parts.Add(RedisLiterals.no); - } - return Message.Create(-1, flags, RedisCommand.CLIENT, parts); - } - - public ClientInfo[] ClientList(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CLIENT, RedisLiterals.LIST); - return ExecuteSync(msg, ClientInfo.Processor); - } - - public Task ClientListAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CLIENT, RedisLiterals.LIST); - return ExecuteAsync(msg, ClientInfo.Processor); - } - - public ClusterConfiguration ClusterNodes(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CLUSTER, RedisLiterals.NODES); - return ExecuteSync(msg, ResultProcessor.ClusterNodes); - } - - public Task ClusterNodesAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CLUSTER, RedisLiterals.NODES); - return ExecuteAsync(msg, ResultProcessor.ClusterNodes); - } - - public string ClusterNodesRaw(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CLUSTER, RedisLiterals.NODES); - return ExecuteSync(msg, ResultProcessor.ClusterNodesRaw); - } - - public Task ClusterNodesRawAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CLUSTER, RedisLiterals.NODES); - return ExecuteAsync(msg, ResultProcessor.ClusterNodesRaw); - } - - public KeyValuePair[] ConfigGet(RedisValue pattern = default(RedisValue), CommandFlags flags = CommandFlags.None) - { - if (pattern.IsNullOrEmpty) pattern = RedisLiterals.Wildcard; - var msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, pattern); - return ExecuteSync(msg, ResultProcessor.StringPairInterleaved); - } - - public Task[]> ConfigGetAsync(RedisValue pattern = default(RedisValue), CommandFlags flags = CommandFlags.None) - { - if (pattern.IsNullOrEmpty) pattern = RedisLiterals.Wildcard; - var msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, pattern); - return ExecuteAsync(msg, ResultProcessor.StringPairInterleaved); - } - - public void ConfigResetStatistics(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.RESETSTAT); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - - public Task ConfigResetStatisticsAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.RESETSTAT); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public void ConfigRewrite(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.REWRITE); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - - public Task ConfigRewriteAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.REWRITE); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public void ConfigSet(RedisValue setting, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.SET, setting, value); - ExecuteSync(msg, ResultProcessor.DemandOK); - ExecuteSync(Message.Create(-1, flags | CommandFlags.FireAndForget, RedisCommand.CONFIG, RedisLiterals.GET, setting), ResultProcessor.AutoConfigure); - } - - public Task ConfigSetAsync(RedisValue setting, RedisValue value, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.SET, setting, value); - var task = ExecuteAsync(msg, ResultProcessor.DemandOK); - ExecuteSync(Message.Create(-1, flags | CommandFlags.FireAndForget, RedisCommand.CONFIG, RedisLiterals.GET, setting), ResultProcessor.AutoConfigure); - return task; - } - public long DatabaseSize(int database = 0, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(database, flags, RedisCommand.DBSIZE); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task DatabaseSizeAsync(int database = 0, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(database, flags, RedisCommand.DBSIZE); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public RedisValue Echo(RedisValue message, CommandFlags flags) - { - var msg = Message.Create(-1, flags, RedisCommand.ECHO, message); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - public Task EchoAsync(RedisValue message, CommandFlags flags) - { - var msg = Message.Create(-1, flags, RedisCommand.ECHO, message); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public void FlushAllDatabases(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.FLUSHALL); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - public Task FlushAllDatabasesAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.FLUSHALL); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public void FlushDatabase(int database = 0, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(database, flags, RedisCommand.FLUSHDB); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - - public Task FlushDatabaseAsync(int database = 0, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(database, flags, RedisCommand.FLUSHDB); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public ServerCounters GetCounters() - { - return server.GetCounters(); - } - - public IGrouping>[] Info(RedisValue section = default(RedisValue), CommandFlags flags = CommandFlags.None) - { - var msg = section.IsNullOrEmpty - ? Message.Create(-1, flags, RedisCommand.INFO) - : Message.Create(-1, flags, RedisCommand.INFO, section); - - return ExecuteSync(msg, ResultProcessor.Info); - } - - public Task>[]> InfoAsync(RedisValue section = default(RedisValue), CommandFlags flags = CommandFlags.None) - { - var msg = section.IsNullOrEmpty - ? Message.Create(-1, flags, RedisCommand.INFO) - : Message.Create(-1, flags, RedisCommand.INFO, section); - - return ExecuteAsync(msg, ResultProcessor.Info); - } - - public string InfoRaw(RedisValue section = default(RedisValue), CommandFlags flags = CommandFlags.None) - { - var msg = section.IsNullOrEmpty - ? Message.Create(-1, flags, RedisCommand.INFO) - : Message.Create(-1, flags, RedisCommand.INFO, section); - - return ExecuteSync(msg, ResultProcessor.String); - } - - public Task InfoRawAsync(RedisValue section = default(RedisValue), CommandFlags flags = CommandFlags.None) - { - var msg = section.IsNullOrEmpty - ? Message.Create(-1, flags, RedisCommand.INFO) - : Message.Create(-1, flags, RedisCommand.INFO, section); - - return ExecuteAsync(msg, ResultProcessor.String); - } - - IEnumerable IServer.Keys(int database, RedisValue pattern, int pageSize, CommandFlags flags) - { - return Keys(database, pattern, pageSize, CursorUtils.Origin, 0, flags); - } - - public IEnumerable Keys(int database = 0, RedisValue pattern = default(RedisValue), int pageSize = CursorUtils.DefaultPageSize, long cursor = CursorUtils.Origin, int pageOffset = 0, CommandFlags flags = CommandFlags.None) - { - if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize)); - if (CursorUtils.IsNil(pattern)) pattern = RedisLiterals.Wildcard; - - if (multiplexer.CommandMap.IsAvailable(RedisCommand.SCAN)) - { - var features = server.GetFeatures(); - - if (features.Scan) return new KeysScanEnumerable(this, database, pattern, pageSize, cursor, pageOffset, flags); - } - - if (cursor != 0 || pageOffset != 0) throw ExceptionFactory.NoCursor(RedisCommand.KEYS); - Message msg = Message.Create(database, flags, RedisCommand.KEYS, pattern); - return ExecuteSync(msg, ResultProcessor.RedisKeyArray); - } - - public DateTime LastSave(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.LASTSAVE); - return ExecuteSync(msg, ResultProcessor.DateTime); - } - - public Task LastSaveAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.LASTSAVE); - return ExecuteAsync(msg, ResultProcessor.DateTime); - } - - public void MakeMaster(ReplicationChangeOptions options, TextWriter log = null) - { - multiplexer.MakeMaster(server, options, log); - } - public void Save(SaveType type, CommandFlags flags = CommandFlags.None) - { - var msg = GetSaveMessage(type, flags); - ExecuteSync(msg, GetSaveResultProcessor(type)); - } - - public Task SaveAsync(SaveType type, CommandFlags flags = CommandFlags.None) - { - var msg = GetSaveMessage(type, flags); - return ExecuteAsync(msg, GetSaveResultProcessor(type)); - } - - public bool ScriptExists(string script, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SCRIPT, RedisLiterals.EXISTS, ScriptHash.Hash(script)); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public bool ScriptExists(byte[] sha1, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SCRIPT, RedisLiterals.EXISTS, ScriptHash.Encode(sha1)); - return ExecuteSync(msg, ResultProcessor.Boolean); - } - - public Task ScriptExistsAsync(string script, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SCRIPT, RedisLiterals.EXISTS, ScriptHash.Hash(script)); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public Task ScriptExistsAsync(byte[] sha1, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SCRIPT, RedisLiterals.EXISTS, ScriptHash.Encode(sha1)); - return ExecuteAsync(msg, ResultProcessor.Boolean); - } - - public void ScriptFlush(CommandFlags flags = CommandFlags.None) - { - if (!multiplexer.RawConfig.AllowAdmin) throw ExceptionFactory.AdminModeNotEnabled(multiplexer.IncludeDetailInExceptions, RedisCommand.SCRIPT, null, server); - var msg = Message.Create(-1, flags, RedisCommand.SCRIPT, RedisLiterals.FLUSH); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - - public Task ScriptFlushAsync(CommandFlags flags = CommandFlags.None) - { - if (!multiplexer.RawConfig.AllowAdmin) throw ExceptionFactory.AdminModeNotEnabled(multiplexer.IncludeDetailInExceptions, RedisCommand.SCRIPT, null, server); - var msg = Message.Create(-1, flags, RedisCommand.SCRIPT, RedisLiterals.FLUSH); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public byte[] ScriptLoad(string script, CommandFlags flags = CommandFlags.None) - { - var msg = new RedisDatabase.ScriptLoadMessage(flags, script); - return ExecuteSync(msg, ResultProcessor.ScriptLoad); - } - - public Task ScriptLoadAsync(string script, CommandFlags flags = CommandFlags.None) - { - var msg = new RedisDatabase.ScriptLoadMessage(flags, script); - return ExecuteAsync(msg, ResultProcessor.ScriptLoad); - } - - public LoadedLuaScript ScriptLoad(LuaScript script, CommandFlags flags = CommandFlags.None) - { - return script.Load(this, flags); - } - - public Task ScriptLoadAsync(LuaScript script, CommandFlags flags = CommandFlags.None) - { - return script.LoadAsync(this, flags); - } - - public void Shutdown(ShutdownMode shutdownMode = ShutdownMode.Default, CommandFlags flags = CommandFlags.None) - { - Message msg; - switch (shutdownMode) - { - case ShutdownMode.Default: - msg = Message.Create(-1, flags, RedisCommand.SHUTDOWN); - break; - case ShutdownMode.Always: - msg = Message.Create(-1, flags, RedisCommand.SHUTDOWN, RedisLiterals.SAVE); - break; - case ShutdownMode.Never: - msg = Message.Create(-1, flags, RedisCommand.SHUTDOWN, RedisLiterals.NOSAVE); - break; - default: - throw new ArgumentOutOfRangeException(nameof(shutdownMode)); - } - try - { - ExecuteSync(msg, ResultProcessor.DemandOK); - } - catch (RedisConnectionException ex) - { - switch (ex.FailureType) - { - case ConnectionFailureType.SocketClosed: - case ConnectionFailureType.SocketFailure: - // that's fine - return; - } - throw; // otherwise, not something we were expecting - } - } - - public CommandTrace[] SlowlogGet(int count = 0, CommandFlags flags = CommandFlags.None) - { - var msg = count > 0 - ? Message.Create(-1, flags, RedisCommand.SLOWLOG, RedisLiterals.GET, count) - : Message.Create(-1, flags, RedisCommand.SLOWLOG, RedisLiterals.GET); - - return ExecuteSync(msg, CommandTrace.Processor); - } - - public Task SlowlogGetAsync(int count = 0, CommandFlags flags = CommandFlags.None) - { - var msg = count > 0 - ? Message.Create(-1, flags, RedisCommand.SLOWLOG, RedisLiterals.GET, count) - : Message.Create(-1, flags, RedisCommand.SLOWLOG, RedisLiterals.GET); - - return ExecuteAsync(msg, CommandTrace.Processor); - } - - public void SlowlogReset(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SLOWLOG, RedisLiterals.RESET); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - - public Task SlowlogResetAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SLOWLOG, RedisLiterals.RESET); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public RedisValue StringGet(int db, RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(db, flags, RedisCommand.GET, key); - return ExecuteSync(msg, ResultProcessor.RedisValue); - } - - public Task StringGetAsync(int db, RedisKey key, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(db, flags, RedisCommand.GET, key); - return ExecuteAsync(msg, ResultProcessor.RedisValue); - } - - public RedisChannel[] SubscriptionChannels(RedisChannel pattern = default(RedisChannel), CommandFlags flags = CommandFlags.None) - { - var msg = pattern.IsNullOrEmpty ? Message.Create(-1, flags, RedisCommand.PUBSUB, RedisLiterals.CHANNELS) - : Message.Create(-1, flags, RedisCommand.PUBSUB, RedisLiterals.CHANNELS, pattern); - return ExecuteSync(msg, ResultProcessor.RedisChannelArrayLiteral); - } - - public Task SubscriptionChannelsAsync(RedisChannel pattern = default(RedisChannel), CommandFlags flags = CommandFlags.None) - { - var msg = pattern.IsNullOrEmpty ? Message.Create(-1, flags, RedisCommand.PUBSUB, RedisLiterals.CHANNELS) - : Message.Create(-1, flags, RedisCommand.PUBSUB, RedisLiterals.CHANNELS, pattern); - return ExecuteAsync(msg, ResultProcessor.RedisChannelArrayLiteral); - } - - public long SubscriptionPatternCount(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.PUBSUB, RedisLiterals.NUMPAT); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task SubscriptionPatternCountAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.PUBSUB, RedisLiterals.NUMPAT); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public long SubscriptionSubscriberCount(RedisChannel channel, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.PUBSUB, RedisLiterals.NUMSUB, channel); - return ExecuteSync(msg, ResultProcessor.PubSubNumSub); - } - - public Task SubscriptionSubscriberCountAsync(RedisChannel channel, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.PUBSUB, RedisLiterals.NUMSUB, channel); - return ExecuteAsync(msg, ResultProcessor.PubSubNumSub); - } - - public DateTime Time(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.TIME); - return ExecuteSync(msg, ResultProcessor.DateTime); - } - - public Task TimeAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.TIME); - return ExecuteAsync(msg, ResultProcessor.DateTime); - } - - internal static Message CreateSlaveOfMessage(EndPoint endpoint, CommandFlags flags = CommandFlags.None) - { - RedisValue host, port; - if (endpoint == null) - { - host = "NO"; - port = "ONE"; - } - else - { - string hostRaw; - int portRaw; - if (Format.TryGetHostPort(endpoint, out hostRaw, out portRaw)) - { - host = hostRaw; - port = portRaw; - } - else - { - throw new NotSupportedException("Unknown endpoint type: " + endpoint.GetType().Name); - } - } - return Message.Create(-1, flags, RedisCommand.SLAVEOF, host, port); - } - - internal override Task ExecuteAsync(Message message, ResultProcessor processor, ServerEndPoint server = null) - { // inject our expected server automatically - if (server == null) server = this.server; - FixFlags(message, server); - if (!server.IsConnected) - { - if (message == null) return CompletedTask.Default(asyncState); - if (message.IsFireAndForget) return CompletedTask.Default(null); // F+F explicitly does not get async-state - - // no need to deny exec-sync here; will be complete before they see if - var tcs = TaskSource.Create(asyncState); - ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, multiplexer.IncludePerformanceCountersInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot())); - return tcs.Task; - } - return base.ExecuteAsync(message, processor, server); - } - - internal override T ExecuteSync(Message message, ResultProcessor processor, ServerEndPoint server = null) - { // inject our expected server automatically - if (server == null) server = this.server; - FixFlags(message, server); - if (!server.IsConnected) - { - if (message == null || message.IsFireAndForget) return default(T); - throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, multiplexer.IncludePerformanceCountersInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot()); - } - return base.ExecuteSync(message, processor, server); - } - - internal override RedisFeatures GetFeatures(int db, RedisKey key, CommandFlags flags, out ServerEndPoint server) - { - server = this.server; - return new RedisFeatures(server.Version); - } - - public void SlaveOf(EndPoint endpoint, CommandFlags flags = CommandFlags.None) - { - if (endpoint == server.EndPoint) - { - throw new ArgumentException("Cannot slave to self"); - } - // prepare the actual slaveof message (not sent yet) - var slaveofMsg = CreateSlaveOfMessage(endpoint, flags); - - var configuration = this.multiplexer.RawConfig; - - - // attempt to cease having an opinion on the master; will resume that when replication completes - // (note that this may fail; we aren't depending on it) - if (!string.IsNullOrWhiteSpace(configuration.TieBreaker) - && this.multiplexer.CommandMap.IsAvailable(RedisCommand.DEL)) - { - var del = Message.Create(0, CommandFlags.FireAndForget | CommandFlags.NoRedirect, RedisCommand.DEL, (RedisKey)configuration.TieBreaker); - del.SetInternalCall(); - server.QueueDirectFireAndForget(del, ResultProcessor.Boolean); - } - ExecuteSync(slaveofMsg, ResultProcessor.DemandOK); - - // attempt to broadcast a reconfigure message to anybody listening to this server - var channel = this.multiplexer.ConfigurationChangedChannel; - if (channel != null && this.multiplexer.CommandMap.IsAvailable(RedisCommand.PUBLISH)) - { - var pub = Message.Create(-1, CommandFlags.FireAndForget | CommandFlags.NoRedirect, RedisCommand.PUBLISH, (RedisValue)channel, RedisLiterals.Wildcard); - pub.SetInternalCall(); - server.QueueDirectFireAndForget(pub, ResultProcessor.Int64); - } - } - - public Task SlaveOfAsync(EndPoint endpoint, CommandFlags flags = CommandFlags.None) - { - var msg = CreateSlaveOfMessage(endpoint, flags); - if (endpoint == server.EndPoint) - { - throw new ArgumentException("Cannot slave to self"); - } - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - private void FixFlags(Message message, ServerEndPoint server) - { - // since the server is specified explicitly, we don't want defaults - // to make the "non-preferred-endpoint" counters look artificially - // inflated; note we only change *prefer* options - switch (Message.GetMasterSlaveFlags(message.Flags)) - { - case CommandFlags.PreferMaster: - if (server.IsSlave) message.SetPreferSlave(); - break; - case CommandFlags.PreferSlave: - if (!server.IsSlave) message.SetPreferMaster(); - break; - } - } - - Message GetSaveMessage(SaveType type, CommandFlags flags = CommandFlags.None) - { - switch(type) - { - case SaveType.BackgroundRewriteAppendOnlyFile: return Message.Create(-1, flags, RedisCommand.BGREWRITEAOF); - case SaveType.BackgroundSave: return Message.Create(-1, flags, RedisCommand.BGSAVE); -#pragma warning disable 0618 - case SaveType.ForegroundSave: return Message.Create(-1, flags, RedisCommand.SAVE); -#pragma warning restore 0618 - default: throw new ArgumentOutOfRangeException(nameof(type)); - } - } - - ResultProcessor GetSaveResultProcessor(SaveType type) - { - switch (type) - { - case SaveType.BackgroundRewriteAppendOnlyFile: return ResultProcessor.DemandOK; - case SaveType.BackgroundSave: return ResultProcessor.BackgroundSaveStarted; -#pragma warning disable 0618 - case SaveType.ForegroundSave: return ResultProcessor.DemandOK; -#pragma warning restore 0618 - default: throw new ArgumentOutOfRangeException(nameof(type)); - } - } - - static class ScriptHash - { - static readonly byte[] hex = { - (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', - (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f' }; - public static RedisValue Encode(byte[] value) - { - if (value == null) return default(RedisValue); - byte[] result = new byte[value.Length * 2]; - int offset = 0; - for (int i = 0; i < value.Length; i++) - { - int val = value[i]; - result[offset++] = hex[val / 16]; - result[offset++] = hex[val % 16]; - } - return result; - } - public static RedisValue Hash(string value) - { - if (value == null) return default(RedisValue); - using (var sha1 = SHA1.Create()) - { - var bytes = sha1.ComputeHash(Encoding.UTF8.GetBytes(value)); - return Encode(bytes); - } - } - } - - sealed class KeysScanEnumerable : CursorEnumerable - { - private readonly RedisValue pattern; - - public KeysScanEnumerable(RedisServer server, int db, RedisValue pattern, int pageSize, long cursor, int pageOffset, CommandFlags flags) - : base(server, server.server, db, pageSize, cursor, pageOffset, flags) - { - this.pattern = pattern; - } - - protected override Message CreateMessage(long cursor) - { - if (CursorUtils.IsNil(pattern)) - { - if (pageSize == CursorUtils.DefaultPageSize) - { - return Message.Create(db, flags, RedisCommand.SCAN, cursor); - } - else - { - return Message.Create(db, flags, RedisCommand.SCAN, cursor, RedisLiterals.COUNT, pageSize); - } - } - else - { - if (pageSize == CursorUtils.DefaultPageSize) - { - return Message.Create(db, flags, RedisCommand.SCAN, cursor, RedisLiterals.MATCH, pattern); - } - else - { - return Message.Create(db, flags, RedisCommand.SCAN, cursor, RedisLiterals.MATCH, pattern, RedisLiterals.COUNT, pageSize); - } - } - } - protected override ResultProcessor Processor => processor; - - public static readonly ResultProcessor processor = new KeysResultProcessor(); - private class KeysResultProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.MultiBulk: - var arr = result.GetItems(); - long i64; - if (arr.Length == 2 && arr[1].Type == ResultType.MultiBulk && arr[0].TryGetInt64(out i64)) - { - var keysResult = new ScanResult(i64, arr[1].GetItemsAsKeys()); - SetResult(message, keysResult); - return true; - } - break; - } - return false; - } - } - } - - #region Sentinel - - public EndPoint SentinelGetMasterAddressByName(string serviceName, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.GETMASTERADDRBYNAME, (RedisValue)serviceName); - return ExecuteSync(msg, ResultProcessor.SentinelMasterEndpoint); - } - - public Task SentinelGetMasterAddressByNameAsync(string serviceName, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.GETMASTERADDRBYNAME, (RedisValue)serviceName); - return ExecuteAsync(msg, ResultProcessor.SentinelMasterEndpoint); - } - - public KeyValuePair[] SentinelMaster(string serviceName, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.MASTER, (RedisValue)serviceName); - return ExecuteSync(msg, ResultProcessor.StringPairInterleaved); - } - - public Task[]> SentinelMasterAsync(string serviceName, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.MASTER, (RedisValue)serviceName); - return ExecuteAsync(msg, ResultProcessor.StringPairInterleaved); - } - - public void SentinelFailover(string serviceName, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.FAILOVER, (RedisValue)serviceName); - ExecuteSync(msg, ResultProcessor.DemandOK); - } - - public Task SentinelFailoverAsync(string serviceName, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.FAILOVER, (RedisValue)serviceName); - return ExecuteAsync(msg, ResultProcessor.DemandOK); - } - - public KeyValuePair[][] SentinelMasters(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.MASTERS); - return ExecuteSync(msg, ResultProcessor.SentinelArrayOfArrays); - } - - public Task[][]> SentinelMastersAsync(CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.MASTERS); - return ExecuteAsync(msg, ResultProcessor.SentinelArrayOfArrays); - } - - public KeyValuePair[][] SentinelSlaves(string serviceName, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.SLAVES, (RedisValue)serviceName); - return ExecuteSync(msg, ResultProcessor.SentinelArrayOfArrays); - } - - public Task[][]> SentinelSlavesAsync(string serviceName, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.SLAVES, (RedisValue)serviceName); - return ExecuteAsync(msg, ResultProcessor.SentinelArrayOfArrays); - } - - #endregion - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisSubscriber.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisSubscriber.cs deleted file mode 100644 index 25dbed2..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisSubscriber.cs +++ /dev/null @@ -1,347 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - partial class ConnectionMultiplexer - { - private readonly Dictionary subscriptions = new Dictionary(); - - internal static bool TryCompleteHandler(EventHandler handler, object sender, T args, bool isAsync) where T : EventArgs - { - if (handler == null) return true; - if (isAsync) - { - foreach (EventHandler sub in handler.GetInvocationList()) - { - try - { sub.Invoke(sender, args); } - catch - { } - } - return true; - } - return false; - } - - internal Task AddSubscription(RedisChannel channel, Action handler, CommandFlags flags, object asyncState) - { - if (handler != null) - { - lock (subscriptions) - { - Subscription sub; - if (subscriptions.TryGetValue(channel, out sub)) - { - sub.Add(handler); - } - else - { - sub = new Subscription(handler); - subscriptions.Add(channel, sub); - var task = sub.SubscribeToServer(this, channel, flags, asyncState, false); - if (task != null) return task; - } - - } - } - return CompletedTask.Default(asyncState); - } - - internal ServerEndPoint GetSubscribedServer(RedisChannel channel) - { - if (!channel.IsNullOrEmpty) - { - lock (subscriptions) - { - Subscription sub; - if (subscriptions.TryGetValue(channel, out sub)) - { - return sub.GetOwner(); - } - } - } - return null; - } - - internal void OnMessage(RedisChannel subscription, RedisChannel channel, RedisValue payload) - { - ICompletable completable = null; - lock (subscriptions) - { - Subscription sub; - if (subscriptions.TryGetValue(subscription, out sub)) - { - completable = sub.ForInvoke(channel, payload); - } - } - if (completable != null) unprocessableCompletionManager.CompleteSyncOrAsync(completable); - } - - internal Task RemoveAllSubscriptions(CommandFlags flags, object asyncState) - { - Task last = CompletedTask.Default(asyncState); - lock (subscriptions) - { - foreach (var pair in subscriptions) - { - pair.Value.Remove(null); // always wipes - var task = pair.Value.UnsubscribeFromServer(pair.Key, flags, asyncState, false); - if (task != null) last = task; - } - subscriptions.Clear(); - } - return last; - } - - internal Task RemoveSubscription(RedisChannel channel, Action handler, CommandFlags flags, object asyncState) - { - lock (subscriptions) - { - Subscription sub; - if (subscriptions.TryGetValue(channel, out sub)) - { - if (sub.Remove(handler)) - { - subscriptions.Remove(channel); - var task = sub.UnsubscribeFromServer(channel, flags, asyncState, false); - if (task != null) return task; - } - } - } - return CompletedTask.Default(asyncState); - } - - internal void ResendSubscriptions(ServerEndPoint server) - { - if (server == null) return; - lock (subscriptions) - { - foreach (var pair in subscriptions) - { - pair.Value.Resubscribe(pair.Key, server); - } - } - } - - internal bool SubscriberConnected(RedisChannel channel = default(RedisChannel)) - { - var server = GetSubscribedServer(channel); - if (server != null) return server.IsConnected; - - server = SelectServer(-1, RedisCommand.SUBSCRIBE, CommandFlags.DemandMaster, default(RedisKey)); - return server != null && server.IsConnected; - } - - - - internal long ValidateSubscriptions() - { - lock (subscriptions) - { - long count = 0; - foreach (var pair in subscriptions) - { - if (pair.Value.Validate(this, pair.Key)) count++; - } - return count; - } - } - - private sealed class Subscription - { - private Action handler; - private ServerEndPoint owner; - - public Subscription(Action value) - { - handler = value; - } - public void Add(Action value) - { - handler += value; - } - public ICompletable ForInvoke(RedisChannel channel, RedisValue message) - { - var tmp = handler; - return tmp == null ? null : new MessageCompletable(channel, message, tmp); - } - - public bool Remove(Action value) - { - if (value == null) - { // treat as blanket wipe - handler = null; - return true; - } - else - { - return (handler -= value) == null; - } - } - public Task SubscribeToServer(ConnectionMultiplexer multiplexer, RedisChannel channel, CommandFlags flags, object asyncState, bool internalCall) - { - var cmd = channel.IsPatternBased ? RedisCommand.PSUBSCRIBE : RedisCommand.SUBSCRIBE; - var selected = multiplexer.SelectServer(-1, cmd, flags, default(RedisKey)); - - if (selected == null || Interlocked.CompareExchange(ref owner, selected, null) != null) return null; - - var msg = Message.Create(-1, flags, cmd, channel); - - return selected.QueueDirectAsync(msg, ResultProcessor.TrackSubscriptions, asyncState); - } - - public Task UnsubscribeFromServer(RedisChannel channel, CommandFlags flags, object asyncState, bool internalCall) - { - var oldOwner = Interlocked.Exchange(ref owner, null); - if (oldOwner == null) return null; - - var cmd = channel.IsPatternBased ? RedisCommand.PUNSUBSCRIBE : RedisCommand.UNSUBSCRIBE; - var msg = Message.Create(-1, flags, cmd, channel); - if (internalCall) msg.SetInternalCall(); - return oldOwner.QueueDirectAsync(msg, ResultProcessor.TrackSubscriptions, asyncState); - } - - internal ServerEndPoint GetOwner() - { - return Interlocked.CompareExchange(ref owner, null, null); - } - internal void Resubscribe(RedisChannel channel, ServerEndPoint server) - { - if (server != null && Interlocked.CompareExchange(ref owner, server, server) == server) - { - var cmd = channel.IsPatternBased ? RedisCommand.PSUBSCRIBE : RedisCommand.SUBSCRIBE; - var msg = Message.Create(-1, CommandFlags.FireAndForget, cmd, channel); - msg.SetInternalCall(); - server.QueueDirectFireAndForget(msg, ResultProcessor.TrackSubscriptions); - } - } - - internal bool Validate(ConnectionMultiplexer multiplexer, RedisChannel channel) - { - bool changed = false; - var oldOwner = Interlocked.CompareExchange(ref owner, null, null); - if (oldOwner != null && !oldOwner.IsSelectable(RedisCommand.PSUBSCRIBE)) - { - if (UnsubscribeFromServer(channel, CommandFlags.FireAndForget, null, true) != null) - { - changed = true; - } - oldOwner = null; - } - if (oldOwner == null) - { - if (SubscribeToServer(multiplexer, channel, CommandFlags.FireAndForget, null, true) != null) - { - changed = true; - } - } - return changed; - } - - - } - } - - internal sealed class RedisSubscriber : RedisBase, ISubscriber - { - internal RedisSubscriber(ConnectionMultiplexer multiplexer, object asyncState) : base(multiplexer, asyncState) - { - } - - public EndPoint IdentifyEndpoint(RedisChannel channel, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.PUBSUB, RedisLiterals.NUMSUB, channel); - msg.SetInternalCall(); - return ExecuteSync(msg, ResultProcessor.ConnectionIdentity); - } - - public Task IdentifyEndpointAsync(RedisChannel channel, CommandFlags flags = CommandFlags.None) - { - var msg = Message.Create(-1, flags, RedisCommand.PUBSUB, RedisLiterals.NUMSUB, channel); - msg.SetInternalCall(); - return ExecuteAsync(msg, ResultProcessor.ConnectionIdentity); - } - - public bool IsConnected(RedisChannel channel = default(RedisChannel)) - { - return multiplexer.SubscriberConnected(channel); - } - - public override TimeSpan Ping(CommandFlags flags = CommandFlags.None) - { - // can't use regular PING, but we can unsubscribe from something random that we weren't even subscribed to... - RedisValue channel = Guid.NewGuid().ToByteArray(); - var msg = ResultProcessor.TimingProcessor.CreateMessage(-1, flags, RedisCommand.UNSUBSCRIBE, channel); - return ExecuteSync(msg, ResultProcessor.ResponseTimer); - } - - public override Task PingAsync(CommandFlags flags = CommandFlags.None) - { - // can't use regular PING, but we can unsubscribe from something random that we weren't even subscribed to... - RedisValue channel = Guid.NewGuid().ToByteArray(); - var msg = ResultProcessor.TimingProcessor.CreateMessage(-1, flags, RedisCommand.UNSUBSCRIBE, channel); - return ExecuteAsync(msg, ResultProcessor.ResponseTimer); - } - - public long Publish(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None) - { - if (channel.IsNullOrEmpty) throw new ArgumentNullException(nameof(channel)); - var msg = Message.Create(-1, flags, RedisCommand.PUBLISH, channel, message); - return ExecuteSync(msg, ResultProcessor.Int64); - } - - public Task PublishAsync(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None) - { - if (channel.IsNullOrEmpty) throw new ArgumentNullException(nameof(channel)); - var msg = Message.Create(-1, flags, RedisCommand.PUBLISH, channel, message); - return ExecuteAsync(msg, ResultProcessor.Int64); - } - - public void Subscribe(RedisChannel channel, Action handler, CommandFlags flags = CommandFlags.None) - { - var task = SubscribeAsync(channel, handler, flags); - if ((flags & CommandFlags.FireAndForget) == 0) Wait(task); - } - - public Task SubscribeAsync(RedisChannel channel, Action handler, CommandFlags flags = CommandFlags.None) - { - - if (channel.IsNullOrEmpty) throw new ArgumentNullException(nameof(channel)); - return multiplexer.AddSubscription(channel, handler, flags, asyncState); - } - - - public EndPoint SubscribedEndpoint(RedisChannel channel) - { - var server = multiplexer.GetSubscribedServer(channel); - return server?.EndPoint; - } - - public void Unsubscribe(RedisChannel channel, Action handler = null, CommandFlags flags = CommandFlags.None) - { - var task = UnsubscribeAsync(channel, handler, flags); - if ((flags & CommandFlags.FireAndForget) == 0) Wait(task); - } - - public void UnsubscribeAll(CommandFlags flags = CommandFlags.None) - { - var task = UnsubscribeAllAsync(flags); - if ((flags & CommandFlags.FireAndForget) == 0) Wait(task); - } - - public Task UnsubscribeAllAsync(CommandFlags flags = CommandFlags.None) - { - return multiplexer.RemoveAllSubscriptions(flags, asyncState); - } - - public Task UnsubscribeAsync(RedisChannel channel, Action handler = null, CommandFlags flags = CommandFlags.None) - { - if (channel.IsNullOrEmpty) throw new ArgumentNullException(nameof(channel)); - return multiplexer.RemoveSubscription(channel, handler, flags, asyncState); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisTransaction.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisTransaction.cs deleted file mode 100644 index 7e600f3..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisTransaction.cs +++ /dev/null @@ -1,487 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - internal class RedisTransaction : RedisDatabase, ITransaction - { - private List conditions; - - private List pending; - - public RedisTransaction(RedisDatabase wrapped, object asyncState) : base(wrapped.multiplexer, wrapped.Database, asyncState ?? wrapped.AsyncState) - { - // need to check we can reliably do this... - var commandMap = multiplexer.CommandMap; - commandMap.AssertAvailable(RedisCommand.MULTI); - commandMap.AssertAvailable(RedisCommand.EXEC); - commandMap.AssertAvailable(RedisCommand.DISCARD); - } - - public ConditionResult AddCondition(Condition condition) - { - if (condition == null) throw new ArgumentNullException(nameof(condition)); - - var commandMap = multiplexer.CommandMap; - if (conditions == null) - { - // we don't demand these unless the user is requesting conditions, but we need both... - commandMap.AssertAvailable(RedisCommand.WATCH); - commandMap.AssertAvailable(RedisCommand.UNWATCH); - conditions = new List(); - } - condition.CheckCommands(commandMap); - var result = new ConditionResult(condition); - conditions.Add(result); - return result; - } - - public void Execute() - { - Execute(CommandFlags.FireAndForget); - } - - public bool Execute(CommandFlags flags) - { - ResultProcessor proc; - var msg = CreateMessage(flags, out proc); - return base.ExecuteSync(msg, proc); // need base to avoid our local "not supported" override - } - - public Task ExecuteAsync(CommandFlags flags) - { - ResultProcessor proc; - var msg = CreateMessage(flags, out proc); - return base.ExecuteAsync(msg, proc); // need base to avoid our local wrapping override - } - - internal override Task ExecuteAsync(Message message, ResultProcessor processor, ServerEndPoint server = null) - { - if (message == null) return CompletedTask.Default(asyncState); - multiplexer.CheckMessage(message); - - multiplexer.Trace("Wrapping " + message.Command, "Transaction"); - // prepare the inner command as a task - Task task; - if (message.IsFireAndForget) - { - task = CompletedTask.Default(null); // F+F explicitly does not get async-state - } - else - { - var tcs = TaskSource.CreateDenyExecSync(asyncState); - var source = ResultBox.Get(tcs); - message.SetSource(source, processor); - task = tcs.Task; - } - - // prepare an outer-command that decorates that, but expects QUEUED - var queued = new QueuedMessage(message); - var wasQueued = ResultBox.Get(null); - queued.SetSource(wasQueued, QueuedProcessor.Default); - - // store it, and return the task of the *outer* command - // (there is no task for the inner command) - (pending ?? (pending = new List())).Add(queued); - - - switch(message.Command) - { - case RedisCommand.UNKNOWN: - case RedisCommand.EVAL: - case RedisCommand.EVALSHA: - // people can do very naughty things in an EVAL - // including change the DB; change it back to what we - // think it should be! - var sel = PhysicalConnection.GetSelectDatabaseCommand(message.Db); - queued = new QueuedMessage(sel); - wasQueued = ResultBox.Get(null); - queued.SetSource(wasQueued, QueuedProcessor.Default); - pending.Add(queued); - break; - } - return task; - } - - internal override T ExecuteSync(Message message, ResultProcessor processor, ServerEndPoint server = null) - { - throw new NotSupportedException("ExecuteSync cannot be used inside a transaction"); - } - private Message CreateMessage(CommandFlags flags, out ResultProcessor processor) - { - var work = pending; - pending = null; // any new operations go into a different queue - var cond = conditions; - conditions = null; // any new conditions go into a different queue - - if ((work == null || work.Count == 0) && (cond == null || cond.Count == 0)) - { - if ((flags & CommandFlags.FireAndForget) != 0) - { - processor = null; - return null; // they won't notice if we don't do anything... - } - processor = ResultProcessor.DemandPONG; - return Message.Create(-1, flags, RedisCommand.PING); - } - processor = TransactionProcessor.Default; - return new TransactionMessage(Database, flags, cond, work); - } - class QueuedMessage : Message - { - private readonly Message wrapped; - private volatile bool wasQueued; - - public QueuedMessage(Message message) : base(message.Db, message.Flags | CommandFlags.NoRedirect, message.Command) - { - message.SetNoRedirect(); - this.wrapped = message; - } - - public bool WasQueued - { - get { return wasQueued; } - set { wasQueued = value; } - } - - public Message Wrapped => wrapped; - - internal override void WriteImpl(PhysicalConnection physical) - { - wrapped.WriteImpl(physical); - wrapped.SetRequestSent(); - } - } - - class QueuedProcessor : ResultProcessor - { - public static readonly ResultProcessor Default = new QueuedProcessor(); - static readonly byte[] QUEUED = Encoding.UTF8.GetBytes("QUEUED"); - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - if(result.Type == ResultType.SimpleString && result.IsEqual(QUEUED)) - { - var q = message as QueuedMessage; - if (q != null) q.WasQueued = true; - return true; - } - return false; - } - } - class TransactionMessage : Message, IMultiMessage - { - - static readonly ConditionResult[] NixConditions = new ConditionResult[0]; - - static readonly QueuedMessage[] NixMessages = new QueuedMessage[0]; - - private ConditionResult[] conditions; - - private QueuedMessage[] operations; - - public TransactionMessage(int db, CommandFlags flags, List conditions, List operations) - : base(db, flags, RedisCommand.EXEC) - { - this.operations = (operations == null || operations.Count == 0) ? NixMessages : operations.ToArray(); - this.conditions = (conditions == null || conditions.Count == 0) ? NixConditions : conditions.ToArray(); - } - - public QueuedMessage[] InnerOperations => operations; - - public bool IsAborted => command != RedisCommand.EXEC; - - public override void AppendStormLog(StringBuilder sb) - { - base.AppendStormLog(sb); - if (conditions.Length != 0) sb.Append(", ").Append(conditions.Length).Append(" conditions"); - sb.Append(", ").Append(operations.Length).Append(" operations"); - } - public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) - { - int slot = ServerSelectionStrategy.NoSlot; - for(int i = 0; i < conditions.Length;i++) - { - int newSlot = conditions[i].Condition.GetHashSlot(serverSelectionStrategy); - slot = serverSelectionStrategy.CombineSlot(slot, newSlot); - if (slot == ServerSelectionStrategy.MultipleSlots) return slot; - } - for(int i = 0; i < operations.Length;i++) - { - int newSlot = operations[i].Wrapped.GetHashSlot(serverSelectionStrategy); - slot = serverSelectionStrategy.CombineSlot(slot, newSlot); - if (slot == ServerSelectionStrategy.MultipleSlots) return slot; - } - return slot; - } - - public IEnumerable GetMessages(PhysicalConnection connection) - { - ResultBox lastBox = null; - try - { - // Important: if the server supports EXECABORT, then we can check the pre-conditions (pause there), - // which will usually be pretty small and cheap to do - if that passes, we can just isue all the commands - // and rely on EXECABORT to kick us if we are being idiotic inside the MULTI. However, if the server does - // *not* support EXECABORT, then we need to explicitly check for QUEUED anyway; we might as well defer - // checking the preconditions to the same time to avoid having to pause twice. This will mean that on - // up-version servers, pre-condition failures exit with UNWATCH; and on down-version servers pre-condition - // failures exit with DISCARD - but that's ok : both work fine - - bool explicitCheckForQueued = !connection.Bridge.ServerEndPoint.GetFeatures().ExecAbort; - var multiplexer = connection.Multiplexer; - - // PART 1: issue the pre-conditions - if (!IsAborted && conditions.Length != 0) - { - for (int i = 0; i < conditions.Length; i++) - { - // need to have locked them before sending them - // to guarantee that we see the pulse - ResultBox latestBox = conditions[i].GetBox(); - Monitor.Enter(latestBox); - if (lastBox != null) Monitor.Exit(lastBox); - lastBox = latestBox; - foreach (var msg in conditions[i].CreateMessages(Db)) - { - msg.SetNoRedirect(); // need to keep them in the current context only - yield return msg; - } - } - - if (!explicitCheckForQueued && lastBox != null) - { - // need to get those sent ASAP; if they are stuck in the buffers, we die - multiplexer.Trace("Flushing and waiting for precondition responses"); - connection.Flush(); - if (Monitor.Wait(lastBox, multiplexer.TimeoutMilliseconds)) - { - if (!AreAllConditionsSatisfied(multiplexer)) - command = RedisCommand.UNWATCH; // somebody isn't happy - } - else - { // timeout running pre-conditions - multiplexer.Trace("Timeout checking preconditions"); - command = RedisCommand.UNWATCH; - } - Monitor.Exit(lastBox); - lastBox = null; - } - } - - // PART 2: begin the transaction - if (!IsAborted) - { - multiplexer.Trace("Begining transaction"); - yield return Message.Create(-1, CommandFlags.None, RedisCommand.MULTI); - } - - // PART 3: issue the commands - if (!IsAborted && operations.Length != 0) - { - multiplexer.Trace("Issuing transaction operations"); - - foreach (var op in operations) - { - if (explicitCheckForQueued) - { // need to have locked them before sending them - // to guarantee that we see the pulse - ResultBox thisBox = op.ResultBox; - if (thisBox != null) - { - Monitor.Enter(thisBox); - if (lastBox != null) Monitor.Exit(lastBox); - lastBox = thisBox; - } - } - yield return op; - } - - if (explicitCheckForQueued && lastBox != null) - { - multiplexer.Trace("Flushing and waiting for precondition+queued responses"); - connection.Flush(); // make sure they get sent, so we can check for QUEUED (and the pre-conditions if necessary) - if (Monitor.Wait(lastBox, multiplexer.TimeoutMilliseconds)) - { - if (!AreAllConditionsSatisfied(multiplexer)) - { - command = RedisCommand.DISCARD; - } - else - { - foreach (var op in operations) - { - if (!op.WasQueued) - { - multiplexer.Trace("Aborting: operation was not queued: " + op.Command); - command = RedisCommand.DISCARD; - break; - } - } - } - multiplexer.Trace("Confirmed: QUEUED x " + operations.Length); - } - else - { - multiplexer.Trace("Aborting: timeout checking queued messages"); - command = RedisCommand.DISCARD; - } - Monitor.Exit(lastBox); - lastBox = null; - } - } - } - finally - { - if (lastBox != null) Monitor.Exit(lastBox); - } - if (IsAborted) - { - connection.Multiplexer.Trace("Aborting: canceling wrapped messages"); - var bridge = connection.Bridge; - foreach (var op in operations) - { - op.Wrapped.Cancel(); - bridge.CompleteSyncOrAsync(op.Wrapped); - } - } - connection.Multiplexer.Trace("End ot transaction: " + Command); - yield return this; // acts as either an EXEC or an UNWATCH, depending on "aborted" - } - - internal override void WriteImpl(PhysicalConnection physical) - { - physical.WriteHeader(Command, 0); - } - - private bool AreAllConditionsSatisfied(ConnectionMultiplexer multiplexer) - { - bool result = true; - for (int i = 0; i < conditions.Length; i++) - { - var condition = conditions[i]; - if (condition.UnwrapBox()) - { - multiplexer.Trace("Precondition passed: " + condition.Condition); - } - else - { - multiplexer.Trace("Precondition failed: " + condition.Condition); - result = false; - } - } - return result; - } - } - - class TransactionProcessor : ResultProcessor - { - public static readonly TransactionProcessor Default = new TransactionProcessor(); - - public override bool SetResult(PhysicalConnection connection, Message message, RawResult result) - { - if (result.IsError) - { - var tran = message as TransactionMessage; - if (tran != null) - { - string error = result.GetString(); - var bridge = connection.Bridge; - foreach(var op in tran.InnerOperations) - { - ServerFail(op.Wrapped, error); - bridge.CompleteSyncOrAsync(op.Wrapped); - } - } - } - return base.SetResult(connection, message, result); - } - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - var tran = message as TransactionMessage; - if (tran != null) - { - var bridge = connection.Bridge; - var wrapped = tran.InnerOperations; - switch (result.Type) - { - case ResultType.SimpleString: - if (tran.IsAborted && result.IsEqual(RedisLiterals.BytesOK)) - { - connection.Multiplexer.Trace("Acknowledging UNWATCH (aborted electively)"); - SetResult(message, false); - return true; - } - //EXEC returned with a NULL - if (!tran.IsAborted && result.IsNull) - { - connection.Multiplexer.Trace("Server aborted due to failed EXEC"); - //cancel the commands in the transaction and mark them as complete with the completion manager - foreach (var op in wrapped) - { - op.Wrapped.Cancel(); - bridge.CompleteSyncOrAsync(op.Wrapped); - } - SetResult(message, false); - return true; - } - break; - case ResultType.MultiBulk: - if (!tran.IsAborted) - { - var arr = result.GetItems(); - if (arr == null) - { - connection.Multiplexer.Trace("Server aborted due to failed WATCH"); - foreach (var op in wrapped) - { - op.Wrapped.Cancel(); - bridge.CompleteSyncOrAsync(op.Wrapped); - } - SetResult(message, false); - return true; - } - else if (wrapped.Length == arr.Length) - { - connection.Multiplexer.Trace("Server committed; processing nested replies"); - for (int i = 0; i < arr.Length; i++) - { - if (wrapped[i].Wrapped.ComputeResult(connection, arr[i])) - { - bridge.CompleteSyncOrAsync(wrapped[i].Wrapped); - } - } - SetResult(message, true); - return true; - } - } - break; - } - // even if we didn't fully understand the result, we still need to do something with - // the pending tasks - foreach (var op in wrapped) - { - op.Wrapped.Fail(ConnectionFailureType.ProtocolFailure, null); - bridge.CompleteSyncOrAsync(op.Wrapped); - } - } - return false; - } - } - } - //internal class RedisDatabaseTransaction : RedisCoreTransaction, ITransaction - //{ - // public IRedisDatabaseAsync Pending { get { return this; } } - - // bool ITransaction.Execute(CommandFlags flags) - // { - // return ExecuteTransaction(flags); - // } - // Task ITransaction.ExecuteAsync(CommandFlags flags) - // { - // return ExecuteTransactionAsync(flags); - // } - //} -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisType.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisType.cs deleted file mode 100644 index 4a51f93..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisType.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// The intrinsinc data-types supported by redis - /// - /// http://redis.io/topics/data-types - public enum RedisType - { - /// - /// The specified key does not exist - /// - None, - /// - /// Strings are the most basic kind of Redis value. Redis Strings are binary safe, this means that a Redis string can contain any kind of data, for instance a JPEG image or a serialized Ruby object. - /// A String value can be at max 512 Megabytes in length. - /// - /// http://redis.io/commands#string - String, - /// - /// Redis Lists are simply lists of strings, sorted by insertion order. It is possible to add elements to a Redis List pushing new elements on the head (on the left) or on the tail (on the right) of the list. - /// - /// http://redis.io/commands#list - List, - /// - /// Redis Sets are an unordered collection of Strings. It is possible to add, remove, and test for existence of members in O(1) (constant time regardless of the number of elements contained inside the Set). - /// Redis Sets have the desirable property of not allowing repeated members. Adding the same element multiple times will result in a set having a single copy of this element. Practically speaking this means that adding a member does not require a check if exists then add operation. - /// - /// http://redis.io/commands#set - Set, - /// - /// Redis Sorted Sets are, similarly to Redis Sets, non repeating collections of Strings. The difference is that every member of a Sorted Set is associated with score, that is used in order to take the sorted set ordered, from the smallest to the greatest score. While members are unique, scores may be repeated. - /// - /// http://redis.io/commands#sorted_set - SortedSet, - /// - /// Redis Hashes are maps between string fields and string values, so they are the perfect data type to represent objects (eg: A User with a number of fields like name, surname, age, and so forth) - /// - /// http://redis.io/commands#hash - Hash, - /// - /// The data-type was not recognised by the client library - /// - Unknown, - } - -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisValue.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisValue.cs deleted file mode 100644 index 28bcace..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/RedisValue.cs +++ /dev/null @@ -1,726 +0,0 @@ -using System; -#if CORE_CLR -using System.Collections.Generic; -using System.Reflection; -#endif -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Represents values that can be stored in redis - /// - public struct RedisValue : IEquatable, IComparable, IComparable, IConvertible - { - internal static readonly RedisValue[] EmptyArray = new RedisValue[0]; - - static readonly byte[] EmptyByteArr = new byte[0]; - - private static readonly byte[] IntegerSentinel = new byte[0]; - - private readonly byte[] valueBlob; - - private readonly long valueInt64; - - // internal bool IsNullOrDefaultValue { get { return (valueBlob == null && valueInt64 == 0L) || ((object)valueBlob == (object)NullSentinel); } } - private RedisValue(long valueInt64, byte[] valueBlob) - { - this.valueInt64 = valueInt64; - this.valueBlob = valueBlob; - } - - /// - /// Represents the string "" - /// - public static RedisValue EmptyString { get; } = new RedisValue(0, EmptyByteArr); - - /// - /// A null value - /// - public static RedisValue Null { get; } = new RedisValue(0, null); - - /// - /// Indicates whether the value is a primitive integer - /// - public bool IsInteger => valueBlob == IntegerSentinel; - - /// - /// Indicates whether the value should be considered a null value - /// - public bool IsNull => valueBlob == null; - - /// - /// Indicates whether the value is either null or a zero-length value - /// - public bool IsNullOrEmpty => valueBlob == null || (valueBlob.Length == 0 && !(valueBlob == IntegerSentinel)); - - /// - /// Indicates whether the value is greater than zero-length - /// - public bool HasValue => valueBlob != null && valueBlob.Length > 0; - - /// - /// Indicates whether two RedisValue values are equivalent - /// - public static bool operator !=(RedisValue x, RedisValue y) - { - return !(x == y); - } - - /// - /// Indicates whether two RedisValue values are equivalent - /// - public static bool operator ==(RedisValue x, RedisValue y) - { - if (x.valueBlob == null) return y.valueBlob == null; - - if (x.valueBlob == IntegerSentinel) - { - if (y.valueBlob == IntegerSentinel) - { - return x.valueInt64 == y.valueInt64; - } - else - { - return Equals((byte[])x, (byte[])y); - } - } - else if (y.valueBlob == IntegerSentinel) - { - return Equals((byte[])x, (byte[])y); - } - - return Equals(x.valueBlob, y.valueBlob); - } - - /// - /// See Object.Equals() - /// - public override bool Equals(object obj) - { - if (obj == null) return valueBlob == null; - - if (obj is RedisValue) - { - return Equals((RedisValue)obj); - } - if (obj is string) - { - return (string)obj == (string)this; - } - if (obj is byte[]) - { - return Equals((byte[])obj, (byte[])this); - } - if (obj is long) - { - return (long)obj == (long)this; - } - if (obj is int) - { - return (int)obj == (int)this; - } - return false; - } - - /// - /// Indicates whether two RedisValue values are equivalent - /// - public bool Equals(RedisValue other) - { - return this == other; - } - - /// - /// See Object.GetHashCode() - /// - public override int GetHashCode() - { - if (valueBlob == IntegerSentinel) return valueInt64.GetHashCode(); - if (valueBlob == null) return -1; - return GetHashCode(valueBlob); - } - - /// - /// Returns a string representation of the value - /// - public override string ToString() - { - return (string)this; - } - - internal static unsafe bool Equals(byte[] x, byte[] y) - { - if ((object)x == (object)y) return true; // ref equals - if (x == null || y == null) return false; - int len = x.Length; - if (len != y.Length) return false; - - int octets = len / 8, spare = len % 8; - fixed (byte* x8 = x, y8 = y) - { - long* x64 = (long*)x8, y64 = (long*)y8; - for (int i = 0; i < octets; i++) - { - if (x64[i] != y64[i]) return false; - } - int offset = len - spare; - while (spare-- != 0) - { - if (x8[offset] != y8[offset++]) return false; - } - } - return true; - } - - internal static unsafe int GetHashCode(byte[] value) - { - unchecked - { - if (value == null) return -1; - int len = value.Length; - if (len == 0) return 0; - int octets = len / 8, spare = len % 8; - int acc = 728271210; - fixed (byte* ptr8 = value) - { - long* ptr64 = (long*)ptr8; - for (int i = 0; i < octets; i++) - { - long val = ptr64[i]; - int valHash = (((int)val) ^ ((int)(val >> 32))); - acc = (((acc << 5) + acc) ^ valHash); - } - int offset = len - spare; - while (spare-- != 0) - { - acc = (((acc << 5) + acc) ^ ptr8[offset++]); - } - } - return acc; - } - } - - internal static bool TryParseInt64(byte[] value, int offset, int count, out long result) - { - result = 0; - if (value == null || count <= 0) return false; - checked - { - int max = offset + count; - if (value[offset] == '-') - { - for (int i = offset + 1; i < max; i++) - { - var b = value[i]; - if (b < '0' || b > '9') return false; - result = (result * 10) - (b - '0'); - } - return true; - } - else - { - for (int i = offset; i < max; i++) - { - var b = value[i]; - if (b < '0' || b > '9') return false; - result = (result * 10) + (b - '0'); - } - return true; - } - } - } - - internal void AssertNotNull() - { - if (IsNull) throw new ArgumentException("A null value is not valid in this context"); - } - - enum CompareType { - Null, Int64, Double, Raw - } - CompareType ResolveType(out long i64, out double r8) - { - byte[] blob = valueBlob; - if (blob == IntegerSentinel) - { - i64 = valueInt64; - r8 = default(double); - return CompareType.Int64; - } - if(blob == null) - { - i64 = default(long); - r8 = default(double); - return CompareType.Null; - } - if(TryParseInt64(blob, 0, blob.Length, out i64)) - { - r8 = default(double); - return CompareType.Int64; - } - if(TryParseDouble(blob, out r8)) - { - i64 = default(long); - return CompareType.Double; - } - i64 = default(long); - r8 = default(double); - return CompareType.Raw; - } - - /// - /// Compare against a RedisValue for relative order - /// - public int CompareTo(RedisValue other) - { - try - { - long thisInt64, otherInt64; - double thisDouble, otherDouble; - CompareType thisType = this.ResolveType(out thisInt64, out thisDouble), - otherType = other.ResolveType(out otherInt64, out otherDouble); - - if(thisType == CompareType.Null) - { - return otherType == CompareType.Null ? 0 : -1; - } - if(otherType == CompareType.Null) - { - return 1; - } - - if(thisType == CompareType.Int64) - { - if (otherType == CompareType.Int64) return thisInt64.CompareTo(otherInt64); - if (otherType == CompareType.Double) return ((double)thisInt64).CompareTo(otherDouble); - } - else if(thisType == CompareType.Double) - { - if (otherType == CompareType.Int64) return thisDouble.CompareTo((double)otherInt64); - if (otherType == CompareType.Double) return thisDouble.CompareTo(otherDouble); - } - // otherwise, compare as strings -#if !CORE_CLR - return StringComparer.InvariantCulture.Compare((string)this, (string)other); -#else - var compareInfo = System.Globalization.CultureInfo.InvariantCulture.CompareInfo; - return compareInfo.Compare((string)this, (string)other, System.Globalization.CompareOptions.Ordinal); -#endif - } - catch(Exception ex) - { - ConnectionMultiplexer.TraceWithoutContext(ex.Message); - } - // if all else fails, consider equivalent - return 0; - } - - int IComparable.CompareTo(object obj) - { - if (obj is RedisValue) return CompareTo((RedisValue)obj); - if (obj is long) return CompareTo((RedisValue)(long)obj); - if (obj is double) return CompareTo((RedisValue)(double)obj); - if (obj is string) return CompareTo((RedisValue)(string)obj); - if (obj is byte[]) return CompareTo((RedisValue)(byte[])obj); - if (obj is bool) return CompareTo((RedisValue)(bool)obj); - return -1; - } - - - /// - /// Creates a new RedisValue from an Int32 - /// - public static implicit operator RedisValue(int value) - { - return new RedisValue(value, IntegerSentinel); - } - /// - /// Creates a new RedisValue from a nullable Int32 - /// - public static implicit operator RedisValue(int? value) - { - return value == null ? Null : (RedisValue)value.GetValueOrDefault(); - } - /// - /// Creates a new RedisValue from an Int64 - /// - public static implicit operator RedisValue(long value) - { - return new RedisValue(value, IntegerSentinel); - } - /// - /// Creates a new RedisValue from a nullable Int64 - /// - public static implicit operator RedisValue(long? value) - { - return value == null ? Null : (RedisValue)value.GetValueOrDefault(); - } - /// - /// Creates a new RedisValue from a Double - /// - public static implicit operator RedisValue(double value) - { - return Format.ToString(value); - } - - /// - /// Creates a new RedisValue from a nullable Double - /// - public static implicit operator RedisValue(double? value) - { - return value == null ? Null : (RedisValue)value.GetValueOrDefault(); - } - /// - /// Creates a new RedisValue from a String - /// - public static implicit operator RedisValue(string value) - { - byte[] blob; - if (value == null) blob = null; - else if (value.Length == 0) blob = EmptyByteArr; - else blob = Encoding.UTF8.GetBytes(value); - return new RedisValue(0, blob); - } - /// - /// Creates a new RedisValue from a Byte[] - /// - public static implicit operator RedisValue(byte[] value) - { - byte[] blob; - if (value == null) blob = null; - else if (value.Length == 0) blob = EmptyByteArr; - else blob = value; - return new RedisValue(0, blob); - } - - internal static RedisValue Parse(object obj) - { - if (obj == null) return RedisValue.Null; - if (obj is RedisValue) return (RedisValue)obj; - if (obj is string) return (RedisValue)(string)obj; - if (obj is int) return (RedisValue)(int)obj; - if (obj is double) return (RedisValue)(double)obj; - if (obj is byte[]) return (RedisValue)(byte[])obj; - if (obj is bool) return (RedisValue)(bool)obj; - if (obj is long) return (RedisValue)(long)obj; - if (obj is float) return (RedisValue)(float)obj; - - throw new InvalidOperationException("Unable to format type for redis: " + obj.GetType().FullName); - } - /// - /// Creates a new RedisValue from a Boolean - /// - public static implicit operator RedisValue(bool value) - { - return new RedisValue(value ? 1 : 0, IntegerSentinel); - } - /// - /// Creates a new RedisValue from a nullable Boolean - /// - public static implicit operator RedisValue(bool? value) - { - return value == null ? Null : (RedisValue)value.GetValueOrDefault(); - } - /// - /// Converts the value to a Boolean - /// - public static explicit operator bool (RedisValue value) - { - switch((long)value) - { - case 0: return false; - case 1: return true; - default: throw new InvalidCastException(); - } - } - - /// - /// Converts the value to an Int32 - /// - public static explicit operator int(RedisValue value) - { - checked - { - return (int)(long)value; - } - } - /// - /// Converts the value to an Int64 - /// - public static explicit operator long(RedisValue value) - { - var blob = value.valueBlob; - if (blob == IntegerSentinel) return value.valueInt64; - if (blob == null) return 0; // in redis, an arithmetic zero is kinda the same thing as not-exists (think "incr") - long i64; - if (TryParseInt64(blob, 0, blob.Length, out i64)) return i64; - throw new InvalidCastException(); - } - - /// - /// Converts the value to a Double - /// - public static explicit operator double (RedisValue value) - { - var blob = value.valueBlob; - if (blob == IntegerSentinel) return value.valueInt64; - if (blob == null) return 0; // in redis, an arithmetic zero is kinda the same thing as not-exists (think "incr") - - double r8; - if (TryParseDouble(blob, out r8)) return r8; - throw new InvalidCastException(); - } - - static bool TryParseDouble(byte[] blob, out double value) - { - // simple integer? - if (blob.Length == 1 && blob[0] >= '0' && blob[0] <= '9') - { - value = blob[0] - '0'; - return true; - } - - return Format.TryParseDouble(Encoding.UTF8.GetString(blob), out value); - } - - /// - /// Converts the value to a nullable Double - /// - public static explicit operator double? (RedisValue value) - { - if (value.valueBlob == null) return null; - return (double)value; - } - /// - /// Converts the value to a nullable Int64 - /// - public static explicit operator long? (RedisValue value) - { - if (value.valueBlob == null) return null; - return (long)value; - } - /// - /// Converts the value to a nullable Int32 - /// - public static explicit operator int? (RedisValue value) - { - if (value.valueBlob == null) return null; - return (int)value; - } - /// - /// Converts the value to a nullable Boolean - /// - public static explicit operator bool? (RedisValue value) - { - if (value.valueBlob == null) return null; - return (bool)value; - } - - /// - /// Converts the value to a String - /// - public static implicit operator string(RedisValue value) - { - var valueBlob = value.valueBlob; - if (valueBlob == IntegerSentinel) - return Format.ToString(value.valueInt64); - if (valueBlob == null) return null; - - if (valueBlob.Length == 0) return ""; - if (valueBlob.Length == 2 && valueBlob[0] == (byte)'O' && valueBlob[1] == (byte)'K') - { - return "OK"; // special case for +OK status results from modules - } - try - { - return Encoding.UTF8.GetString(valueBlob); - } - catch - { - return BitConverter.ToString(valueBlob); - } - } - /// - /// Converts the value to a byte[] - /// - public static implicit operator byte[](RedisValue value) - { - var valueBlob = value.valueBlob; - if (valueBlob == IntegerSentinel) - { - return Encoding.UTF8.GetBytes(Format.ToString(value.valueInt64)); - } - return valueBlob; - } - - TypeCode IConvertible.GetTypeCode() => TypeCode.Object; - - bool IConvertible.ToBoolean(IFormatProvider provider) => (bool)this; - - byte IConvertible.ToByte(IFormatProvider provider) => (byte)this; - - char IConvertible.ToChar(IFormatProvider provider) => (char)this; - - DateTime IConvertible.ToDateTime(IFormatProvider provider) => DateTime.Parse((string)this, provider); - - decimal IConvertible.ToDecimal(IFormatProvider provider) => (decimal)this; - - double IConvertible.ToDouble(IFormatProvider provider) => (double)this; - - short IConvertible.ToInt16(IFormatProvider provider) => (short)this; - - int IConvertible.ToInt32(IFormatProvider provider) => (int)this; - - long IConvertible.ToInt64(IFormatProvider provider) => (long)this; - - sbyte IConvertible.ToSByte(IFormatProvider provider) => (sbyte)this; - - float IConvertible.ToSingle(IFormatProvider provider) => (float)this; - - string IConvertible.ToString(IFormatProvider provider) => (string)this; - - object IConvertible.ToType(Type conversionType, IFormatProvider provider) - { - if (conversionType== null) throw new ArgumentNullException(nameof(conversionType)); - if (conversionType== typeof(byte[])) return (byte[])this; - if (conversionType == typeof(RedisValue)) return this; - switch(conversionType.GetTypeCode()) - { - case TypeCode.Boolean: return (bool)this; - case TypeCode.Byte: return (byte)this; - case TypeCode.Char: return (char)this; - case TypeCode.DateTime: return DateTime.Parse((string)this, provider); - case TypeCode.Decimal: return (decimal)this; - case TypeCode.Double: return (double)this; - case TypeCode.Int16: return (short)this; - case TypeCode.Int32: return (int)this; - case TypeCode.Int64: return (long)this; - case TypeCode.SByte: return (sbyte)this; - case TypeCode.Single: return (float)this; - case TypeCode.String: return (string)this; - case TypeCode.UInt16: return (ushort)this; - case TypeCode.UInt32: return (uint)this; - case TypeCode.UInt64: return (long)this; - case TypeCode.Object: return this; - default: - throw new NotSupportedException(); - } - } - - ushort IConvertible.ToUInt16(IFormatProvider provider) => (ushort)this; - - uint IConvertible.ToUInt32(IFormatProvider provider) => (uint)this; - - ulong IConvertible.ToUInt64(IFormatProvider provider) => (ulong)this; - - /// - /// Convert to a long if possible, returning true. - /// - /// Returns false otherwise. - /// - public bool TryParse(out long val) - { - var blob = valueBlob; - if (blob == IntegerSentinel) - { - val = valueInt64; - return true; - } - - if (blob == null) - { - // in redis-land 0 approx. equal null; so roll with it - val = 0; - return true; - } - - return TryParseInt64(blob, 0, blob.Length, out val); - } - - /// - /// Convert to a int if possible, returning true. - /// - /// Returns false otherwise. - /// - public bool TryParse(out int val) - { - long l; - if (!TryParse(out l) || l > int.MaxValue || l < int.MinValue) - { - val = 0; - return false; - } - - val = (int)l; - return true; - } - - /// - /// Convert to a double if possible, returning true. - /// - /// Returns false otherwise. - /// - public bool TryParse(out double val) - { - var blob = valueBlob; - if (blob == IntegerSentinel) - { - val = valueInt64; - return true; - } - if (blob == null) - { - // in redis-land 0 approx. equal null; so roll with it - val = 0; - return true; - } - - return TryParseDouble(blob, out val); - } - } - - internal static class ReflectionExtensions - { -#if CORE_CLR - internal static TypeCode GetTypeCode(this Type type) - { - if (type == null) return TypeCode.Empty; - TypeCode result; - if (typeCodeLookup.TryGetValue(type, out result)) return result; - - if (type.GetTypeInfo().IsEnum) - { - type = Enum.GetUnderlyingType(type); - if (typeCodeLookup.TryGetValue(type, out result)) return result; - } - return TypeCode.Object; - } - - static readonly Dictionary typeCodeLookup = new Dictionary - { - {typeof(bool), TypeCode.Boolean }, - {typeof(byte), TypeCode.Byte }, - {typeof(char), TypeCode.Char}, - {typeof(DateTime), TypeCode.DateTime}, - {typeof(decimal), TypeCode.Decimal}, - {typeof(double), TypeCode.Double }, - {typeof(short), TypeCode.Int16 }, - {typeof(int), TypeCode.Int32 }, - {typeof(long), TypeCode.Int64 }, - {typeof(object), TypeCode.Object}, - {typeof(sbyte), TypeCode.SByte }, - {typeof(float), TypeCode.Single }, - {typeof(string), TypeCode.String }, - {typeof(ushort), TypeCode.UInt16 }, - {typeof(uint), TypeCode.UInt32 }, - {typeof(ulong), TypeCode.UInt64 }, - }; -#else - internal static TypeCode GetTypeCode(this Type type) - { - return Type.GetTypeCode(type); - } -#endif - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ReplicationChangeOptions.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ReplicationChangeOptions.cs deleted file mode 100644 index 5ce2f12..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ReplicationChangeOptions.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// Additional operations to perform when making a server a master - /// - public enum ReplicationChangeOptions - { - /// - /// No additional operations - /// - None = 0, - /// - /// Set the tie-breaker key on all available masters, to specify this server - /// - SetTiebreaker = 1, - /// - /// Broadcast to the pub-sub channel to listening clients to reconfigure themselves - /// - Broadcast = 2, - /// - /// Issue a SLAVEOF to all other known nodes, making this this master of all - /// - EnslaveSubordinates = 4, - /// - /// All additional operations - /// - All = SetTiebreaker | Broadcast | EnslaveSubordinates - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ResultBox.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ResultBox.cs deleted file mode 100644 index ef74789..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ResultBox.cs +++ /dev/null @@ -1,148 +0,0 @@ -using System; -using System.Diagnostics; -using System.Threading; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - abstract partial class ResultBox - { - protected Exception exception; - - public void SetException(Exception exception) - { - this.exception = exception; - //try - //{ - // throw exception; - //} - //catch (Exception caught) - //{ // stacktrace etc - // this.exception = caught; - //} - } - - public abstract bool TryComplete(bool isAsync); - - [Conditional("DEBUG")] - protected static void IncrementAllocationCount() - { - OnAllocated(); - } - - static partial void OnAllocated(); - } - sealed class ResultBox : ResultBox - { - private static readonly ResultBox[] store = new ResultBox[64]; - - private object stateOrCompletionSource; - - private T value; - - public ResultBox(object stateOrCompletionSource) - { - this.stateOrCompletionSource = stateOrCompletionSource; - } - - public object AsyncState => - stateOrCompletionSource is TaskCompletionSource - ? ((TaskCompletionSource) stateOrCompletionSource).Task.AsyncState - : stateOrCompletionSource; - - public static ResultBox Get(object stateOrCompletionSource) - { - ResultBox found; - for (int i = 0; i < store.Length; i++) - { - if ((found = Interlocked.Exchange(ref store[i], null)) != null) - { - found.Reset(stateOrCompletionSource); - return found; - } - } - IncrementAllocationCount(); - - return new ResultBox(stateOrCompletionSource); - } - - public static void UnwrapAndRecycle(ResultBox box, bool recycle, out T value, out Exception exception) - { - if (box == null) - { - value = default(T); - exception = null; - } - else - { - value = box.value; - exception = box.exception; - box.value = default(T); - box.exception = null; - if (recycle) - { - for (int i = 0; i < store.Length; i++) - { - if (Interlocked.CompareExchange(ref store[i], box, null) == null) return; - } - } - } - } - - public void SetResult(T value) - { - this.value = value; - } - - public override bool TryComplete(bool isAsync) - { - if (stateOrCompletionSource is TaskCompletionSource) - { - var tcs = (TaskCompletionSource)stateOrCompletionSource; -#if !PLAT_SAFE_CONTINUATIONS // we don't need to check in this scenario - if (isAsync || TaskSource.IsSyncSafe(tcs.Task)) -#endif - { - T val; - Exception ex; - UnwrapAndRecycle(this, true, out val, out ex); - - if (ex == null) tcs.TrySetResult(val); - else - { - if (ex is TaskCanceledException) tcs.TrySetCanceled(); - else tcs.TrySetException(ex); - // mark it as observed - GC.KeepAlive(tcs.Task.Exception); - GC.SuppressFinalize(tcs.Task); - } - return true; - } -#if !PLAT_SAFE_CONTINUATIONS - else - { // looks like continuations; push to async to preserve the reader thread - return false; - } -#endif - } - else - { - lock (this) - { // tell the waiting thread that we're done - Monitor.PulseAll(this); - } - ConnectionMultiplexer.TraceWithoutContext("Pulsed", "Result"); - return true; - } - } - - private void Reset(object stateOrCompletionSource) - { - value = default(T); - exception = null; - - this.stateOrCompletionSource = stateOrCompletionSource; - } - } - -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ResultProcessor.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ResultProcessor.cs deleted file mode 100644 index 7fee00f..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ResultProcessor.cs +++ /dev/null @@ -1,1456 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using System.Text.RegularExpressions; - -namespace StackExchange.Redis -{ - abstract class ResultProcessor - { - public static readonly ResultProcessor - Boolean = new BooleanProcessor(), - DemandOK = new ExpectBasicStringProcessor(RedisLiterals.BytesOK), - DemandPONG = new ExpectBasicStringProcessor(RedisLiterals.BytesPONG), - DemandZeroOrOne = new DemandZeroOrOneProcessor(), - AutoConfigure = new AutoConfigureProcessor(), - TrackSubscriptions = new TrackSubscriptionsProcessor(), - Tracer = new TracerProcessor(false), - EstablishConnection = new TracerProcessor(true), - BackgroundSaveStarted = new ExpectBasicStringProcessor(RedisLiterals.BytesBackgroundSavingStarted); - - public static readonly ResultProcessor - ByteArray = new ByteArrayProcessor(), - ScriptLoad = new ScriptLoadProcessor(); - - public static readonly ResultProcessor - ClusterNodes = new ClusterNodesProcessor(); - - public static readonly ResultProcessor - ConnectionIdentity = new ConnectionIdentityProcessor(); - - public static readonly ResultProcessor - DateTime = new DateTimeProcessor(); - - public static readonly ResultProcessor - Double = new DoubleProcessor(); - public static readonly ResultProcessor>[]> - Info = new InfoProcessor(); - - public static readonly ResultProcessor - Int64 = new Int64Processor(), - PubSubNumSub = new PubSubNumSubProcessor(); - - public static readonly ResultProcessor - NullableDouble = new NullableDoubleProcessor(); - public static readonly ResultProcessor - NullableInt64 = new NullableInt64Processor(); - - public static readonly ResultProcessor - RedisChannelArrayLiteral = new RedisChannelArrayProcessor(RedisChannel.PatternMode.Literal); - - public static readonly ResultProcessor - RedisKey = new RedisKeyProcessor(); - - public static readonly ResultProcessor - RedisKeyArray = new RedisKeyArrayProcessor(); - - public static readonly ResultProcessor - RedisType = new RedisTypeProcessor(); - - public static readonly ResultProcessor - RedisValue = new RedisValueProcessor(); - - public static readonly ResultProcessor - RedisValueArray = new RedisValueArrayProcessor(); - - public static readonly ResultProcessor - StringArray = new StringArrayProcessor(); - - public static readonly ResultProcessor - RedisGeoPositionArray = new RedisValueGeoPositionArrayProcessor(); - public static readonly ResultProcessor - RedisGeoPosition = new RedisValueGeoPositionProcessor(); - - public static readonly ResultProcessor - ResponseTimer = new TimingProcessor(); - - public static readonly ResultProcessor - ScriptResult = new ScriptResultProcessor(); - - public static readonly SortedSetEntryArrayProcessor - SortedSetWithScores = new SortedSetEntryArrayProcessor(); - - public static ResultProcessor GeoRadiusArray(GeoRadiusOptions options) => GeoRadiusResultArrayProcessor.Get(options); - - public static readonly ResultProcessor - String = new StringProcessor(), - ClusterNodesRaw = new ClusterNodesRawProcessor(); - - #region Sentinel - - public static readonly ResultProcessor - SentinelMasterEndpoint = new SentinelGetMasterAddressByNameProcessor(); - - public static readonly ResultProcessor[][]> - SentinelArrayOfArrays = new SentinelArrayOfArraysProcessor(); - - #endregion - - public static readonly ResultProcessor[]> - StringPairInterleaved = new StringPairInterleavedProcessor(); - public static readonly TimeSpanProcessor - TimeSpanFromMilliseconds = new TimeSpanProcessor(true), - TimeSpanFromSeconds = new TimeSpanProcessor(false); - public static readonly HashEntryArrayProcessor - HashEntryArray = new HashEntryArrayProcessor(); - static readonly byte[] MOVED = Encoding.UTF8.GetBytes("MOVED "), ASK = Encoding.UTF8.GetBytes("ASK "); - - public void ConnectionFail(Message message, ConnectionFailureType fail, Exception innerException) - { - PhysicalConnection.IdentifyFailureType(innerException, ref fail); - - string exMessage = fail.ToString() + (message == null ? "" : (" on " + message.Command)); - var ex = innerException == null ? new RedisConnectionException(fail, exMessage) - : new RedisConnectionException(fail, exMessage, innerException); - SetException(message, ex); - } - - public void ConnectionFail(Message message, ConnectionFailureType fail, string errorMessage) - { - SetException(message, new RedisConnectionException(fail, errorMessage)); - } - - public void ServerFail(Message message, string errorMessage) - { - SetException(message, new RedisServerException(errorMessage)); - } - - public void SetException(Message message, Exception ex) - { - var box = message?.ResultBox; - box?.SetException(ex); - } - // true if ready to be completed (i.e. false if re-issued to another server) - public virtual bool SetResult(PhysicalConnection connection, Message message, RawResult result) - { - var logging = message as LoggingMessage; - if (logging != null) - { - try - { - connection.Multiplexer.LogLocked(logging.Log, "Response from {0} / {1}: {2}", connection.Bridge, message.CommandAndKey, result); - } - catch { } - } - if (result.IsError) - { - var bridge = connection.Bridge; - var server = bridge.ServerEndPoint; - bool log = !message.IsInternalCall; - bool isMoved = result.AssertStarts(MOVED); - string err = string.Empty; - if (isMoved || result.AssertStarts(ASK)) - { - message.SetResponseReceived(); - - log = false; - string[] parts = result.GetString().Split(StringSplits.Space, 3); - int hashSlot; - EndPoint endpoint; - if (Format.TryParseInt32(parts[1], out hashSlot) && - (endpoint = Format.TryParseEndPoint(parts[2])) != null) - { - - // no point sending back to same server, and no point sending to a dead server - if (!Equals(server.EndPoint, endpoint)) - { - if (bridge.Multiplexer.TryResend(hashSlot, message, endpoint, isMoved)) - { - connection.Multiplexer.Trace(message.Command + " re-issued to " + endpoint, isMoved ? "MOVED" : "ASK"); - return false; - } - else - { - err = string.Format("Endpoint {0} serving hashslot {1} is not reachable at this point of time. Please check connectTimeout value. If it is low, try increasing it to give the ConnectionMultiplexer a chance to recover from the network disconnect. ", endpoint, hashSlot); -#if !CORE_CLR - err += ConnectionMultiplexer.GetThreadPoolAndCPUSummary(bridge.Multiplexer.IncludePerformanceCountersInExceptions); -#endif - } - } - } - } - - if (string.IsNullOrWhiteSpace(err)) - { - err = result.GetString(); - } - - if (log) - { - bridge.Multiplexer.OnErrorMessage(server.EndPoint, err); - } - connection.Multiplexer.Trace("Completed with error: " + err + " (" + GetType().Name + ")", ToString()); - ServerFail(message, err); - } - else - { - bool coreResult = SetResultCore(connection, message, result); - if (coreResult) - { - connection.Multiplexer.Trace("Completed with success: " + result.ToString() + " (" + GetType().Name + ")", ToString()); - } - else - { - UnexpectedResponse(message, result); - } - } - return true; - } - protected abstract bool SetResultCore(PhysicalConnection connection, Message message, RawResult result); - - private void UnexpectedResponse(Message message, RawResult result) - { - ConnectionMultiplexer.TraceWithoutContext("From " + GetType().Name, "Unexpected Response"); - ConnectionFail(message, ConnectionFailureType.ProtocolFailure, "Unexpected response to " + (message?.Command.ToString() ?? "n/a") + ": " + result.ToString()); - } - - public sealed class TimeSpanProcessor : ResultProcessor - { - private readonly bool isMilliseconds; - public TimeSpanProcessor(bool isMilliseconds) - { - this.isMilliseconds = isMilliseconds; - } - public bool TryParse(RawResult result, out TimeSpan? expiry) - { - switch (result.Type) - { - case ResultType.Integer: - long time; - if (result.TryGetInt64(out time)) - { - if (time < 0) - { - expiry = null; - } - else if (isMilliseconds) - { - expiry = TimeSpan.FromMilliseconds(time); - } - else - { - expiry = TimeSpan.FromSeconds(time); - } - return true; - } - break; - } - expiry = null; - return false; - } - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - TimeSpan? expiry; - if (TryParse(result, out expiry)) - { - SetResult(message, expiry); - return true; - } - return false; - } - } - - public sealed class TimingProcessor : ResultProcessor - { - public static TimerMessage CreateMessage(int db, CommandFlags flags, RedisCommand command, RedisValue value = default(RedisValue)) - { - return new TimerMessage(db, flags, command, value); - } - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - if (result.Type == ResultType.Error) - { - return false; - } - else - { // don't check the actual reply; there are multiple ways of constructing - // a timing message, and we don't actually care about what approach was used - var timingMessage = message as TimerMessage; - TimeSpan duration; - if (timingMessage != null) - { - var watch = timingMessage.Watch; - watch.Stop(); - duration = watch.Elapsed; - } - else - { - duration = TimeSpan.MaxValue; - } - SetResult(message, duration); - return true; - } - } - - internal sealed class TimerMessage : Message - { - public readonly Stopwatch Watch; - private readonly RedisValue value; - public TimerMessage(int db, CommandFlags flags, RedisCommand command, RedisValue value) - : base(db, flags, command) - { - this.Watch = Stopwatch.StartNew(); - this.value = value; - } - internal override void WriteImpl(PhysicalConnection physical) - { - if (value.IsNull) - { - physical.WriteHeader(command, 0); - } - else - { - physical.WriteHeader(command, 1); - physical.Write(value); - } - } - } - } - - public sealed class TrackSubscriptionsProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - if (result.Type == ResultType.MultiBulk) - { - var items = result.GetItems(); - long count; - if (items.Length >= 3 && items[2].TryGetInt64(out count)) - { - connection.SubscriptionCount = count; - return true; - } - } - return false; - } - } - internal sealed class DemandZeroOrOneProcessor : ResultProcessor - { - static readonly byte[] zero = { (byte)'0' }, one = { (byte)'1' }; - - public static bool TryGet(RawResult result, out bool value) - { - switch (result.Type) - { - case ResultType.Integer: - case ResultType.SimpleString: - case ResultType.BulkString: - if (result.IsEqual(one)) { value = true; return true; } - else if (result.IsEqual(zero)) { value = false; return true; } - break; - } - value = false; - return false; - } - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - bool value; - if (TryGet(result, out value)) - { - SetResult(message, value); - return true; - } - return false; - } - } - - internal sealed class ScriptLoadProcessor : ResultProcessor - { - static readonly Regex sha1 = new Regex("^[0-9a-f]{40}$", RegexOptions.Compiled | RegexOptions.IgnoreCase); - - internal static bool IsSHA1(string script) - { - return script != null && sha1.IsMatch(script); - } - internal static byte[] ParseSHA1(byte[] value) - { - if (value != null && value.Length == 40) - { - var tmp = new byte[20]; - int charIndex = 0; - for (int i = 0; i < tmp.Length; i++) - { - int x = FromHex((char)value[charIndex++]), y = FromHex((char)value[charIndex++]); - if (x < 0 || y < 0) return null; - tmp[i] = (byte)((x << 4) | y); - } - return tmp; - } - return null; - } - internal static byte[] ParseSHA1(string value) - { - if (value != null && value.Length == 40 && sha1.IsMatch(value)) - { - var tmp = new byte[20]; - int charIndex = 0; - for (int i = 0; i < tmp.Length; i++) - { - int x = FromHex(value[charIndex++]), y = FromHex(value[charIndex++]); - if (x < 0 || y < 0) return null; - tmp[i] = (byte)((x << 4) | y); - } - return tmp; - } - return null; - } - private static int FromHex(char c) - { - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - if (c >= 'A' && c <= 'F') return c - 'A' + 10; - return -1; - } - // note that top-level error messages still get handled by SetResult, but nested errors - // (is that a thing?) will be wrapped in the RedisResult - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.BulkString: - var asciiHash = result.GetBlob(); - if (asciiHash == null || asciiHash.Length != 40) return false; - - byte[] hash = null; - if (!message.IsInternalCall) - { - hash = ParseSHA1(asciiHash); // external caller wants the hex bytes, not the ascii bytes - } - var sl = message as RedisDatabase.ScriptLoadMessage; - if (sl != null) - { - connection.Bridge.ServerEndPoint.AddScript(sl.Script, asciiHash); - } - SetResult(message, hash); - return true; - } - return false; - } - } - - internal sealed class SortedSetEntryArrayProcessor : ValuePairInterleavedProcessorBase - { - protected override SortedSetEntry Parse(RawResult first, RawResult second) - { - double val; - return new SortedSetEntry(first.AsRedisValue(), second.TryGetDouble(out val) ? val : double.NaN); - } - } - - internal sealed class HashEntryArrayProcessor : ValuePairInterleavedProcessorBase - { - protected override HashEntry Parse(RawResult first, RawResult second) - { - return new HashEntry(first.AsRedisValue(), second.AsRedisValue()); - } - } - - internal abstract class ValuePairInterleavedProcessorBase : ResultProcessor - { - static readonly T[] nix = new T[0]; - - public bool TryParse(RawResult result, out T[] pairs) - { - switch (result.Type) - { - case ResultType.MultiBulk: - var arr = result.GetItems(); - if (arr == null) - { - pairs = null; - } - else - { - int count = arr.Length / 2; - if (count == 0) - { - pairs = nix; - } - else - { - pairs = new T[count]; - int offset = 0; - for (int i = 0; i < pairs.Length; i++) - { - pairs[i] = Parse(arr[offset++], arr[offset++]); - } - } - } - return true; - default: - pairs = null; - return false; - } - } - protected abstract T Parse(RawResult first, RawResult second); - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - T[] arr; - if (TryParse(result, out arr)) - { - SetResult(message, arr); - return true; - } - return false; - } - } - - sealed class AutoConfigureProcessor : ResultProcessor - { - static readonly byte[] READONLY = Encoding.UTF8.GetBytes("READONLY "); - public override bool SetResult(PhysicalConnection connection, Message message, RawResult result) - { - if (result.IsError && result.AssertStarts(READONLY)) - { - var server = connection.Bridge.ServerEndPoint; - server.Multiplexer.Trace("Auto-configured role: slave"); - server.IsSlave = true; - } - return base.SetResult(connection, message, result); - } - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - var server = connection.Bridge.ServerEndPoint; - switch (result.Type) - { - case ResultType.BulkString: - if (message != null && message.Command == RedisCommand.INFO) - { - string info = result.GetString(), line; - if (string.IsNullOrWhiteSpace(info)) - { - SetResult(message, true); - return true; - } - string masterHost = null, masterPort = null; - bool roleSeen = false; - using (var reader = new StringReader(info)) - { - while ((line = reader.ReadLine()) != null) - { - if (string.IsNullOrWhiteSpace(line) || line.StartsWith("# ")) continue; - - string val; - if ((val = Extract(line, "role:")) != null) - { - roleSeen = true; - switch (val) - { - case "master": - server.IsSlave = false; - server.Multiplexer.Trace("Auto-configured role: master"); - break; - case "slave": - server.IsSlave = true; - server.Multiplexer.Trace("Auto-configured role: slave"); - break; - } - } - else if ((val = Extract(line, "master_host:")) != null) - { - masterHost = val; - } - else if ((val = Extract(line, "master_port:")) != null) - { - masterPort = val; - } - else if ((val = Extract(line, "redis_version:")) != null) - { - Version version; - if (Version.TryParse(val, out version)) - { - server.Version = version; - server.Multiplexer.Trace("Auto-configured version: " + version); - } - } - else if ((val = Extract(line, "redis_mode:")) != null) - { - switch (val) - { - case "standalone": - server.ServerType = ServerType.Standalone; - server.Multiplexer.Trace("Auto-configured server-type: standalone"); - break; - case "cluster": - server.ServerType = ServerType.Cluster; - server.Multiplexer.Trace("Auto-configured server-type: cluster"); - break; - case "sentinel": - server.ServerType = ServerType.Sentinel; - server.Multiplexer.Trace("Auto-configured server-type: sentinel"); - break; - } - } - else if ((val = Extract(line, "run_id:")) != null) - { - server.RunId = val; - } - } - if (roleSeen) - { // these are in the same section, if presnt - server.MasterEndPoint = Format.TryParseEndPoint(masterHost, masterPort); - } - } - } - SetResult(message, true); - return true; - case ResultType.MultiBulk: - if (message != null && message.Command == RedisCommand.CONFIG) - { - var arr = result.GetItems(); - int count = arr.Length / 2; - - byte[] timeout = (byte[])RedisLiterals.timeout, - databases = (byte[])RedisLiterals.databases, - slave_read_only = (byte[])RedisLiterals.slave_read_only, - yes = (byte[])RedisLiterals.yes, - no = (byte[])RedisLiterals.no; - - long i64; - for (int i = 0; i < count; i++) - { - var key = arr[i * 2]; - if (key.IsEqual(timeout) && arr[(i * 2) + 1].TryGetInt64(out i64)) - { - // note the configuration is in seconds - int timeoutSeconds = checked((int)i64), targetSeconds; - if (timeoutSeconds > 0) - { - if (timeoutSeconds >= 60) - { - targetSeconds = timeoutSeconds - 20; // time to spare... - } - else - { - targetSeconds = (timeoutSeconds * 3) / 4; - } - server.Multiplexer.Trace("Auto-configured timeout: " + targetSeconds + "s"); - server.WriteEverySeconds = targetSeconds; - } - } - else if (key.IsEqual(databases) && arr[(i * 2) + 1].TryGetInt64(out i64)) - { - int dbCount = checked((int)i64); - server.Multiplexer.Trace("Auto-configured databases: " + dbCount); - server.Databases = dbCount; - } - else if (key.IsEqual(slave_read_only)) - { - var val = arr[(i * 2) + 1]; - if (val.IsEqual(yes)) - { - server.SlaveReadOnly = true; - server.Multiplexer.Trace("Auto-configured slave-read-only: true"); - } - else if (val.IsEqual(no)) - { - server.SlaveReadOnly = false; - server.Multiplexer.Trace("Auto-configured slave-read-only: false"); - } - - } - } - } - SetResult(message, true); - return true; - } - return false; - } - - static string Extract(string line, string prefix) - { - if (line.StartsWith(prefix)) return line.Substring(prefix.Length).Trim(); - return null; - } - } - sealed class BooleanProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - if (result.IsNull) - { - SetResult(message, false); // lots of ops return (nil) when they mean "no" - return true; - } - switch (result.Type) - { - case ResultType.SimpleString: - if (result.IsEqual(RedisLiterals.BytesOK)) - { - SetResult(message, true); - } - else - { - SetResult(message, result.GetBoolean()); - } - return true; - case ResultType.Integer: - case ResultType.BulkString: - SetResult(message, result.GetBoolean()); - return true; - case ResultType.MultiBulk: - var items = result.GetItems(); - if (items.Length == 1) - { // treat an array of 1 like a single reply (for example, SCRIPT EXISTS) - SetResult(message, items[0].GetBoolean()); - return true; - } - break; - } - return false; - } - } - - sealed class ByteArrayProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.BulkString: - SetResult(message, result.GetBlob()); - return true; - } - return false; - } - } - - sealed class ClusterNodesProcessor : ResultProcessor - { - internal static ClusterConfiguration Parse(PhysicalConnection connection, string nodes) - { - var server = connection.Bridge.ServerEndPoint; - var config = new ClusterConfiguration(connection.Multiplexer.ServerSelectionStrategy, nodes, server.EndPoint); - server.SetClusterConfiguration(config); - return config; - } - - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.BulkString: - string nodes = result.GetString(); - connection.Bridge.ServerEndPoint.ServerType = ServerType.Cluster; - var config = Parse(connection, nodes); - SetResult(message, config); - return true; - } - return false; - } - } - - sealed class ClusterNodesRawProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.Integer: - case ResultType.SimpleString: - case ResultType.BulkString: - string nodes = result.GetString(); - try - { ClusterNodesProcessor.Parse(connection, nodes); } - catch - { /* tralalalala */} - SetResult(message, nodes); - return true; - } - return false; - } - } - - private sealed class ConnectionIdentityProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - SetResult(message, connection.Bridge.ServerEndPoint.EndPoint); - return true; - } - } - - sealed class DateTimeProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - long unixTime, micros; - switch (result.Type) - { - case ResultType.Integer: - if (result.TryGetInt64(out unixTime)) - { - var time = RedisBase.UnixEpoch.AddSeconds(unixTime); - SetResult(message, time); - return true; - } - break; - case ResultType.MultiBulk: - var arr = result.GetItems(); - switch (arr.Length) - { - case 1: - if (arr[0].TryGetInt64(out unixTime)) - { - var time = RedisBase.UnixEpoch.AddSeconds(unixTime); - SetResult(message, time); - return true; - } - break; - case 2: - if (arr[0].TryGetInt64(out unixTime) && arr[1].TryGetInt64(out micros)) - { - var time = RedisBase.UnixEpoch.AddSeconds(unixTime).AddTicks(micros * 10); // datetime ticks are 100ns - SetResult(message, time); - return true; - } - break; - } - break; - } - return false; - } - } - - sealed class DoubleProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.Integer: - long i64; - if (result.TryGetInt64(out i64)) - { - SetResult(message, i64); - return true; - } - break; - case ResultType.SimpleString: - case ResultType.BulkString: - double val; - if (result.TryGetDouble(out val)) - { - SetResult(message, val); - return true; - } - break; - } - return false; - } - } - sealed class ExpectBasicStringProcessor : ResultProcessor - { - private readonly byte[] expected; - public ExpectBasicStringProcessor(string value) - { - expected = Encoding.UTF8.GetBytes(value); - } - public ExpectBasicStringProcessor(byte[] value) - { - expected = value; - } - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - if (result.IsEqual(expected)) - { - SetResult(message, true); - return true; - } - return false; - } - } - - sealed class InfoProcessor : ResultProcessor>[]> - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - if (result.Type == ResultType.BulkString) - { - string category = Normalize(null), line; - var list = new List>>(); - using (var reader = new StringReader(result.GetString())) - { - while ((line = reader.ReadLine()) != null) - { - if (string.IsNullOrWhiteSpace(line)) continue; - if (line.StartsWith("# ")) - { - category = Normalize(line.Substring(2)); - continue; - } - int idx = line.IndexOf(':'); - if (idx < 0) continue; - var pair = new KeyValuePair( - line.Substring(0, idx).Trim(), - line.Substring(idx + 1).Trim()); - list.Add(Tuple.Create(category, pair)); - } - } - var final = list.GroupBy(x => x.Item1, x => x.Item2).ToArray(); - SetResult(message, final); - return true; - } - return false; - } - - static string Normalize(string category) - { - return string.IsNullOrWhiteSpace(category) ? "miscellaneous" : category.Trim(); - } - } - - class Int64Processor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.Integer: - case ResultType.SimpleString: - case ResultType.BulkString: - long i64; - if (result.TryGetInt64(out i64)) - { - SetResult(message, i64); - return true; - } - break; - } - return false; - } - } - class PubSubNumSubProcessor : Int64Processor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - if (result.Type == ResultType.MultiBulk) - { - var arr = result.GetItems(); - long val; - if (arr != null && arr.Length == 2 && arr[1].TryGetInt64(out val)) - { - SetResult(message, val); - return true; - } - } - return base.SetResultCore(connection, message, result); - } - } - - sealed class NullableDoubleProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.Integer: - case ResultType.SimpleString: - case ResultType.BulkString: - if (result.IsNull) - { - SetResult(message, null); - return true; - } - double val; - if (result.TryGetDouble(out val)) - { - SetResult(message, val); - return true; - } - break; - } - return false; - } - } - sealed class NullableInt64Processor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.Integer: - case ResultType.SimpleString: - case ResultType.BulkString: - if (result.IsNull) - { - SetResult(message, null); - return true; - } - long i64; - if (result.TryGetInt64(out i64)) - { - SetResult(message, i64); - return true; - } - break; - } - return false; - } - } - - sealed class RedisChannelArrayProcessor : ResultProcessor - { - private readonly RedisChannel.PatternMode mode; - public RedisChannelArrayProcessor(RedisChannel.PatternMode mode) - { - this.mode = mode; - } - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.MultiBulk: - var arr = result.GetItems(); - RedisChannel[] final; - if (arr.Length == 0) - { - final = RedisChannel.EmptyArray; - } - else - { - final = new RedisChannel[arr.Length]; - byte[] channelPrefix = connection.ChannelPrefix; - for (int i = 0; i < final.Length; i++) - { - final[i] = arr[i].AsRedisChannel(channelPrefix, mode); - } - } - SetResult(message, final); - return true; - } - return false; - } - } - - sealed class RedisKeyArrayProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.MultiBulk: - var arr = result.GetItemsAsKeys(); - SetResult(message, arr); - return true; - } - return false; - } - } - - sealed class RedisKeyProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.Integer: - case ResultType.SimpleString: - case ResultType.BulkString: - SetResult(message, result.AsRedisKey()); - return true; - } - return false; - } - } - - sealed class RedisTypeProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.SimpleString: - case ResultType.BulkString: - string s = result.GetString(); - RedisType value; - if (string.Equals(s, "zset", StringComparison.OrdinalIgnoreCase)) value = Redis.RedisType.SortedSet; - else if (!Enum.TryParse(s, true, out value)) value = global::StackExchange.Redis.RedisType.Unknown; - SetResult(message, value); - return true; - } - return false; - } - } - - sealed class RedisValueArrayProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.MultiBulk: - var arr = result.GetItemsAsValues(); - - SetResult(message, arr); - return true; - } - return false; - } - } - sealed class StringArrayProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.MultiBulk: - var arr = result.GetItemsAsStrings(); - - SetResult(message, arr); - return true; - } - return false; - } - } - - sealed class RedisValueGeoPositionProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.MultiBulk: - var pos = result.GetItemsAsGeoPosition(); - - SetResult(message, pos); - return true; - } - return false; - } - } - sealed class RedisValueGeoPositionArrayProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.MultiBulk: - var arr = result.GetItemsAsGeoPositionArray(); - - SetResult(message, arr); - return true; - } - return false; - } - } - - sealed class GeoRadiusResultArrayProcessor : ResultProcessor - { - private static readonly GeoRadiusResultArrayProcessor[] instances; - private readonly GeoRadiusOptions options; - - static GeoRadiusResultArrayProcessor() - { - instances = new GeoRadiusResultArrayProcessor[8]; - for (int i = 0; i < 8; i++) instances[i] = new GeoRadiusResultArrayProcessor((GeoRadiusOptions)i); - } - public static GeoRadiusResultArrayProcessor Get(GeoRadiusOptions options) - { - int i = (int)options; - if (i < 0 || i >= instances.Length) throw new ArgumentOutOfRangeException(nameof(options)); - return instances[i]; - } - - private GeoRadiusResultArrayProcessor(GeoRadiusOptions options) - { - this.options = options; - } - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.MultiBulk: - var arr = result.GetItemsAsRawResults(); - - GeoRadiusResult[] typed; - if (arr == null) - { - typed = null; - } - else - { - var options = this.options; - typed = new GeoRadiusResult[arr.Length]; - for (int i = 0; i < arr.Length; i++) - { - typed[i] = Parse(options, arr[i]); - } - } - SetResult(message, typed); - return true; - } - return false; - } - - private static GeoRadiusResult Parse(GeoRadiusOptions options, RawResult item) - { - if (options == GeoRadiusOptions.None) - { - // Without any WITH option specified, the command just returns a linear array like ["New York","Milan","Paris"]. - return new GeoRadiusResult(item.AsRedisValue(), null, null, null); - } - // If WITHCOORD, WITHDIST or WITHHASH options are specified, the command returns an array of arrays, where each sub-array represents a single item. - var arr = item.GetArrayOfRawResults(); - - int index = 0; - // the first item in the sub-array is always the name of the returned item. - var member = arr[index++].AsRedisValue(); - - /* The other information is returned in the following order as successive elements of the sub-array. -The distance from the center as a floating point number, in the same unit specified in the radius. -The geohash integer. -The coordinates as a two items x,y array (longitude,latitude). - */ - double? distance = null; - GeoPosition? position = null; - long? hash = null; - if ((options & GeoRadiusOptions.WithDistance) != 0) { distance = (double?)arr[index++].AsRedisValue(); } - if ((options & GeoRadiusOptions.WithGeoHash) != 0) { hash = (long?)arr[index++].AsRedisValue(); } - if ((options & GeoRadiusOptions.WithCoordinates) != 0) - { - var coords = arr[index++].GetArrayOfRawResults(); - double longitude = (double)coords[0].AsRedisValue(), latitude = (double)coords[1].AsRedisValue(); - position = new GeoPosition(longitude, latitude); - } - return new GeoRadiusResult(member, distance, hash, position); - } - } - - sealed class RedisValueProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.Integer: - case ResultType.SimpleString: - case ResultType.BulkString: - SetResult(message, result.AsRedisValue()); - return true; - } - return false; - } - } - private class ScriptResultProcessor : ResultProcessor - { - static readonly byte[] NOSCRIPT = Encoding.UTF8.GetBytes("NOSCRIPT "); - public override bool SetResult(PhysicalConnection connection, Message message, RawResult result) - { - if (result.Type == ResultType.Error && result.AssertStarts(NOSCRIPT)) - { // scripts are not flushed individually, so assume the entire script cache is toast ("SCRIPT FLUSH") - connection.Bridge.ServerEndPoint.FlushScriptCache(); - message.SetScriptUnavailable(); - } - // and apply usual processing for the rest - return base.SetResult(connection, message, result); - } - - // note that top-level error messages still get handled by SetResult, but nested errors - // (is that a thing?) will be wrapped in the RedisResult - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - var value = Redis.RedisResult.TryCreate(connection, result); - if (value != null) - { - SetResult(message, value); - return true; - } - return false; - } - } - - sealed class StringPairInterleavedProcessor : ValuePairInterleavedProcessorBase> - { - protected override KeyValuePair Parse(RawResult first, RawResult second) - { - return new KeyValuePair(first.GetString(), second.GetString()); - } - } - - sealed class StringProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.Integer: - case ResultType.SimpleString: - case ResultType.BulkString: - SetResult(message, result.GetString()); - return true; - case ResultType.MultiBulk: - var arr = result.GetItems(); - if(arr.Length == 1) - { - SetResult(message, arr[0].GetString()); - return true; - } - break; - } - return false; - } - } - private class TracerProcessor : ResultProcessor - { - static readonly byte[] - authRequired = Encoding.UTF8.GetBytes("NOAUTH Authentication required."), - authFail = Encoding.UTF8.GetBytes("ERR operation not permitted"), - loading = Encoding.UTF8.GetBytes("LOADING "); - - private readonly bool establishConnection; - - public TracerProcessor(bool establishConnection) - { - this.establishConnection = establishConnection; - } - public override bool SetResult(PhysicalConnection connection, Message message, RawResult result) - { - var final = base.SetResult(connection, message, result); - if (result.IsError) - { - if (result.IsEqual(authFail) || result.IsEqual(authRequired)) - { - connection.RecordConnectionFailed(ConnectionFailureType.AuthenticationFailure, new Exception(result.ToString() + " Verify if the Redis password provided is correct.")); - } - else if (result.AssertStarts(loading)) - { - connection.RecordConnectionFailed(ConnectionFailureType.Loading); - } - else - { - connection.RecordConnectionFailed(ConnectionFailureType.ProtocolFailure); - } - } - return final; - } - - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - bool happy; - switch (message.Command) - { - case RedisCommand.ECHO: - happy = result.Type == ResultType.BulkString && (!establishConnection || result.IsEqual(connection.Multiplexer.UniqueId)); - break; - case RedisCommand.PING: - happy = result.Type == ResultType.SimpleString && result.IsEqual(RedisLiterals.BytesPONG); - break; - case RedisCommand.TIME: - happy = result.Type == ResultType.MultiBulk && result.GetItems().Length == 2; - break; - case RedisCommand.EXISTS: - happy = result.Type == ResultType.Integer; - break; - default: - happy = true; - break; - } - if (happy) - { - if (establishConnection) connection.Bridge.OnFullyEstablished(connection); - SetResult(message, happy); - return true; - } - else - { - connection.RecordConnectionFailed(ConnectionFailureType.ProtocolFailure); - return false; - } - } - } - - #region Sentinel - - sealed class SentinelGetMasterAddressByNameProcessor : ResultProcessor - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - switch (result.Type) - { - case ResultType.MultiBulk: - var arr = result.GetItemsAsValues(); - - int port; - if (arr.Length == 2 && int.TryParse(arr[1], out port)) - { - SetResult(message, Format.ParseEndPoint(arr[0], port)); - return true; - } - else if (arr.Length == 0) - { - SetResult(message, null); - return true; - } - break; - case ResultType.SimpleString: - //We don't want to blow up if the master is not found - if (result.IsNull) - return true; - break; - } - return false; - } - } - - sealed class SentinelArrayOfArraysProcessor : ResultProcessor[][]> - { - protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) - { - var innerProcessor = StringPairInterleaved as StringPairInterleavedProcessor; - if (innerProcessor == null) - { - return false; - } - - switch (result.Type) - { - case ResultType.MultiBulk: - var arrayOfArrays = result.GetArrayOfRawResults(); - - var returnArray = new KeyValuePair[arrayOfArrays.Length][]; - - for (int i = 0; i < arrayOfArrays.Length; i++) - { - var rawInnerArray = arrayOfArrays[i]; - KeyValuePair[] kvpArray; - innerProcessor.TryParse(rawInnerArray, out kvpArray); - returnArray[i] = kvpArray; - } - - SetResult(message, returnArray); - return true; - } - return false; - } - } - - #endregion - } - internal abstract class ResultProcessor : ResultProcessor - { - - protected void SetResult(Message message, T value) - { - if (message == null) return; - var box = message.ResultBox as ResultBox; - message.SetResponseReceived(); - - box?.SetResult(value); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ResultType.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ResultType.cs deleted file mode 100644 index 057e0b9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ResultType.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace StackExchange.Redis -{ - internal enum ResultType : byte - { - None = 0, - SimpleString = 1, - Error = 2, - Integer = 3, - BulkString = 4, - MultiBulk = 5 - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SaveType.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SaveType.cs deleted file mode 100644 index 61c086c..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SaveType.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; - -namespace StackExchange.Redis -{ - /// - /// The type of save operation to perform - /// - public enum SaveType - { - /// - /// Instruct Redis to start an Append Only File rewrite process. The rewrite will create a small optimized version of the current Append Only File. - /// - /// http://redis.io/commands/bgrewriteaof - BackgroundRewriteAppendOnlyFile, - /// - /// Save the DB in background. The OK code is immediately returned. Redis forks, the parent continues to serve the clients, the child saves the DB on disk then exits. A client my be able to check if the operation succeeded using the LASTSAVE command. - /// - /// http://redis.io/commands/bgsave - BackgroundSave, - /// - /// Save the DB in foreground. This is almost never a good thing to do, and could cause significant blocking. Only do this if you know you need to save - /// - /// http://redis.io/commands/save - [Obsolete("Saving on the foreground can cause significant blocking; use with extreme caution")] - ForegroundSave - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ScriptParameterMapper.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ScriptParameterMapper.cs deleted file mode 100644 index 428e654..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ScriptParameterMapper.cs +++ /dev/null @@ -1,411 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; -using System.Text; -using System.Text.RegularExpressions; - -namespace StackExchange.Redis -{ - class ScriptParameterMapper - { - public struct ScriptParameters - { - public RedisKey[] Keys; - public RedisValue[] Arguments; - - public static readonly ConstructorInfo Cons = typeof(ScriptParameters).GetConstructor(new[] { typeof(RedisKey[]), typeof(RedisValue[]) }); - public ScriptParameters(RedisKey[] keys, RedisValue[] args) - { - Keys = keys; - Arguments = args; - } - } - - static readonly Regex ParameterExtractor = new Regex(@"@(? ([a-z]|_) ([a-z]|_|\d)*)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - static string[] ExtractParameters(string script) - { - var ps = ParameterExtractor.Matches(script); - if (ps.Count == 0) return null; - - var ret = new HashSet(); - - for (var i = 0; i < ps.Count; i++) - { - var c = ps[i]; - var ix = c.Index - 1; - if (ix >= 0) - { - var prevChar = script[ix]; - - // don't consider this a parameter if it's in the middle of word (ie. if it's preceeded by a letter) - if (char.IsLetterOrDigit(prevChar) || prevChar == '_') continue; - - // this is an escape, ignore it - if (prevChar == '@') continue; - } - - var n = c.Groups["paramName"].Value; - if (!ret.Contains(n)) ret.Add(n); - } - - return ret.ToArray(); - } - - static string MakeOrdinalScriptWithoutKeys(string rawScript, string[] args) - { - var ps = ParameterExtractor.Matches(rawScript); - if (ps.Count == 0) return rawScript; - - var ret = new StringBuilder(); - var upTo = 0; - - for (var i = 0; i < ps.Count; i++) - { - var capture = ps[i]; - var name = capture.Groups["paramName"].Value; - - var ix = capture.Index; - ret.Append(rawScript.Substring(upTo, ix - upTo)); - - var argIx = Array.IndexOf(args, name); - - if (argIx != -1) - { - ret.Append("ARGV["); - ret.Append(argIx + 1); - ret.Append("]"); - } - else - { - var isEscape = false; - var prevIx = capture.Index - 1; - if (prevIx >= 0) - { - var prevChar = rawScript[prevIx]; - isEscape = prevChar == '@'; - } - - if (isEscape) - { - // strip the @ off, so just the one triggering the escape exists - ret.Append(capture.Groups["paramName"].Value); - } - else - { - ret.Append(capture.Value); - } - } - - upTo = capture.Index + capture.Length; - } - - ret.Append(rawScript.Substring(upTo, rawScript.Length - upTo)); - - return ret.ToString(); - } - - static void LoadMember(ILGenerator il, MemberInfo member) - { - // stack starts: - // T(*?) - - var asField = member as FieldInfo; - if (asField != null) - { - il.Emit(OpCodes.Ldfld, asField); // typeof(member) - return; - } - - var asProp = member as PropertyInfo; - if (asProp != null) - { - var getter = asProp.GetGetMethod(); - if (getter.IsVirtual) - { - il.Emit(OpCodes.Callvirt, getter); // typeof(member) - } - else - { - il.Emit(OpCodes.Call, getter); // typeof(member) - } - - return; - } - - throw new Exception("Should't be possible"); - } - - static readonly MethodInfo RedisValue_FromInt = typeof(RedisValue).GetMethod("op_Implicit", new[] { typeof(int) }); - static readonly MethodInfo RedisValue_FromNullableInt = typeof(RedisValue).GetMethod("op_Implicit", new[] { typeof(int?) }); - static readonly MethodInfo RedisValue_FromLong = typeof(RedisValue).GetMethod("op_Implicit", new[] { typeof(long) }); - static readonly MethodInfo RedisValue_FromNullableLong = typeof(RedisValue).GetMethod("op_Implicit", new[] { typeof(long?) }); - static readonly MethodInfo RedisValue_FromDouble= typeof(RedisValue).GetMethod("op_Implicit", new[] { typeof(double) }); - static readonly MethodInfo RedisValue_FromNullableDouble = typeof(RedisValue).GetMethod("op_Implicit", new[] { typeof(double?) }); - static readonly MethodInfo RedisValue_FromString = typeof(RedisValue).GetMethod("op_Implicit", new[] { typeof(string) }); - static readonly MethodInfo RedisValue_FromByteArray = typeof(RedisValue).GetMethod("op_Implicit", new[] { typeof(byte[]) }); - static readonly MethodInfo RedisValue_FromBool = typeof(RedisValue).GetMethod("op_Implicit", new[] { typeof(bool) }); - static readonly MethodInfo RedisValue_FromNullableBool = typeof(RedisValue).GetMethod("op_Implicit", new[] { typeof(bool?) }); - static readonly MethodInfo RedisKey_AsRedisValue = typeof(RedisKey).GetMethod("AsRedisValue", BindingFlags.NonPublic | BindingFlags.Instance); - static void ConvertToRedisValue(MemberInfo member, ILGenerator il, LocalBuilder needsPrefixBool, ref LocalBuilder redisKeyLoc) - { - // stack starts: - // typeof(member) - - var t = member is FieldInfo ? ((FieldInfo)member).FieldType : ((PropertyInfo)member).PropertyType; - - if (t == typeof(RedisValue)) - { - // They've already converted for us, don't do anything - return; - } - - if (t == typeof(RedisKey)) - { - redisKeyLoc = redisKeyLoc ?? il.DeclareLocal(typeof(RedisKey)); - PrefixIfNeeded(il, needsPrefixBool, ref redisKeyLoc); // RedisKey - il.Emit(OpCodes.Stloc, redisKeyLoc); // --empty-- - il.Emit(OpCodes.Ldloca, redisKeyLoc); // RedisKey* - il.Emit(OpCodes.Call, RedisKey_AsRedisValue); // RedisValue - return; - } - - MethodInfo convertOp = null; - if (t == typeof(int)) convertOp = RedisValue_FromInt; - if (t == typeof(int?)) convertOp = RedisValue_FromNullableInt; - if (t == typeof(long)) convertOp = RedisValue_FromLong; - if (t == typeof(long?)) convertOp = RedisValue_FromNullableLong; - if (t == typeof(double)) convertOp = RedisValue_FromDouble; - if (t == typeof(double?)) convertOp = RedisValue_FromNullableDouble; - if (t == typeof(string)) convertOp = RedisValue_FromString; - if (t == typeof(byte[])) convertOp = RedisValue_FromByteArray; - if (t == typeof(bool)) convertOp = RedisValue_FromBool; - if (t == typeof(bool?)) convertOp = RedisValue_FromNullableBool; - - il.Emit(OpCodes.Call, convertOp); - - // stack ends: - // RedisValue - } - - /// - /// Turns a script with @namedParameters into a LuaScript that can be executed - /// against a given IDatabase(Async) object - /// - public static LuaScript PrepareScript(string script) - { - var ps = ExtractParameters(script); - var ordinalScript = MakeOrdinalScriptWithoutKeys(script, ps); - - return new LuaScript(script, ordinalScript, ps); - } - - static readonly HashSet ConvertableTypes = - new HashSet { - typeof(int), - typeof(int?), - typeof(long), - typeof(long?), - typeof(double), - typeof(double?), - typeof(string), - typeof(byte[]), - typeof(bool), - typeof(bool?), - - typeof(RedisKey), - typeof(RedisValue) - }; - - /// - /// Determines whether or not the given type can be used to provide parameters for the given LuaScript. - /// - public static bool IsValidParameterHash(Type t, LuaScript script, out string missingMember, out string badTypeMember) - { - for (var i = 0; i < script.Arguments.Length; i++) - { - var argName = script.Arguments[i]; - var member = t.GetMember(argName).SingleOrDefault(m => m is PropertyInfo || m is FieldInfo); - if (member == null) - { - missingMember = argName; - badTypeMember = null; - return false; - } - - var memberType = member is FieldInfo ? ((FieldInfo)member).FieldType : ((PropertyInfo)member).PropertyType; - if(!ConvertableTypes.Contains(memberType)){ - missingMember = null; - badTypeMember = argName; - return false; - } - } - - missingMember = badTypeMember = null; - return true; - } - - static void PrefixIfNeeded(ILGenerator il, LocalBuilder needsPrefixBool, ref LocalBuilder redisKeyLoc) - { - // top of stack is - // RedisKey - - var getVal = typeof(RedisKey?).GetProperty("Value").GetGetMethod(); - var prepend = typeof(RedisKey).GetMethod("Prepend"); - - var doNothing = il.DefineLabel(); - redisKeyLoc = redisKeyLoc ?? il.DeclareLocal(typeof(RedisKey)); - - il.Emit(OpCodes.Ldloc, needsPrefixBool); // RedisKey bool - il.Emit(OpCodes.Brfalse, doNothing); // RedisKey - il.Emit(OpCodes.Stloc, redisKeyLoc); // --empty-- - il.Emit(OpCodes.Ldloca, redisKeyLoc); // RedisKey* - il.Emit(OpCodes.Ldarga_S, 1); // RedisKey* RedisKey?* - il.Emit(OpCodes.Call, getVal); // RedisKey* RedisKey - il.Emit(OpCodes.Call, prepend); // RedisKey - - - il.MarkLabel(doNothing); // RedisKey - } - - /// - /// Creates a Func that extracts parameters from the given type for use by a LuaScript. - /// - /// Members that are RedisKey's get extracted to be passed in as keys to redis; all members that - /// appear in the script get extracted as RedisValue arguments to be sent up as args. - /// - /// We send all values as arguments so we don't have to prepare the same script for different parameter - /// types. - /// - /// The created Func takes a RedisKey, which will be prefixed to all keys (and arguments of type RedisKey) for - /// keyspace isolation. - /// - public static Func GetParameterExtractor(Type t, LuaScript script) - { - string ignored; - if (!IsValidParameterHash(t, script, out ignored, out ignored)) throw new Exception("Shouldn't be possible"); - - var keys = new List(); - var args = new List(); - - for (var i = 0; i < script.Arguments.Length; i++) - { - var argName = script.Arguments[i]; - var member = t.GetMember(argName).SingleOrDefault(m => m is PropertyInfo || m is FieldInfo); - - var memberType = member is FieldInfo ? ((FieldInfo)member).FieldType : ((PropertyInfo)member).PropertyType; - - if (memberType == typeof(RedisKey)) - { - keys.Add(member); - } - - args.Add(member); - } - - var nullableRedisKeyHasValue = typeof(RedisKey?).GetProperty("HasValue").GetGetMethod(); - - var dyn = new DynamicMethod("ParameterExtractor_" + t.FullName + "_" + script.OriginalScript.GetHashCode(), typeof(ScriptParameters), new[] { typeof(object), typeof(RedisKey?) }, restrictedSkipVisibility: true); - var il = dyn.GetILGenerator(); - - // only init'd if we use it - LocalBuilder redisKeyLoc = null; - var loc = il.DeclareLocal(t); - il.Emit(OpCodes.Ldarg_0); // object -#if !CORE_CLR - if (t.IsValueType) -#else - if (t.GetTypeInfo().IsValueType) -#endif - { - il.Emit(OpCodes.Unbox_Any, t); // T - } - else - { - il.Emit(OpCodes.Castclass, t); // T - } - il.Emit(OpCodes.Stloc, loc); // --empty-- - - var needsKeyPrefixLoc = il.DeclareLocal(typeof(bool)); - - il.Emit(OpCodes.Ldarga_S, 1); // RedisKey?* - il.Emit(OpCodes.Call, nullableRedisKeyHasValue); // bool - il.Emit(OpCodes.Stloc, needsKeyPrefixLoc); // --empty-- - - if (keys.Count == 0) - { - // if there are no keys, don't allocate - il.Emit(OpCodes.Ldnull); // null - } - else - { - il.Emit(OpCodes.Ldc_I4, keys.Count); // int - il.Emit(OpCodes.Newarr, typeof(RedisKey)); // RedisKey[] - } - - for (var i = 0; i < keys.Count; i++) - { - il.Emit(OpCodes.Dup); // RedisKey[] RedisKey[] - il.Emit(OpCodes.Ldc_I4, i); // RedisKey[] RedisKey[] int -#if !CORE_CLR - if (t.IsValueType) -#else - if (t.GetTypeInfo().IsValueType) -#endif - { - il.Emit(OpCodes.Ldloca, loc); // RedisKey[] RedisKey[] int T* - } - else - { - il.Emit(OpCodes.Ldloc, loc); // RedisKey[] RedisKey[] int T - } - LoadMember(il, keys[i]); // RedisKey[] RedisKey[] int RedisKey - PrefixIfNeeded(il, needsKeyPrefixLoc, ref redisKeyLoc); // RedisKey[] RedisKey[] int RedisKey - il.Emit(OpCodes.Stelem, typeof(RedisKey)); // RedisKey[] - } - - if (args.Count == 0) - { - // if there are no args, don't allocate - il.Emit(OpCodes.Ldnull); // RedisKey[] null - } - else - { - il.Emit(OpCodes.Ldc_I4, args.Count); // RedisKey[] int - il.Emit(OpCodes.Newarr, typeof(RedisValue)); // RedisKey[] RedisValue[] - } - - for (var i = 0; i < args.Count; i++) - { - il.Emit(OpCodes.Dup); // RedisKey[] RedisValue[] RedisValue[] - il.Emit(OpCodes.Ldc_I4, i); // RedisKey[] RedisValue[] RedisValue[] int -#if !CORE_CLR - if (t.IsValueType) -#else - if (t.GetTypeInfo().IsValueType) -#endif - { - il.Emit(OpCodes.Ldloca, loc); // RedisKey[] RedisValue[] RedisValue[] int T* - } - else - { - il.Emit(OpCodes.Ldloc, loc); // RedisKey[] RedisValue[] RedisValue[] int T - } - - var member = args[i]; - LoadMember(il, member); // RedisKey[] RedisValue[] RedisValue[] int memberType - ConvertToRedisValue(member, il, needsKeyPrefixLoc, ref redisKeyLoc); // RedisKey[] RedisValue[] RedisValue[] int RedisValue - - il.Emit(OpCodes.Stelem, typeof(RedisValue)); // RedisKey[] RedisValue[] - } - - il.Emit(OpCodes.Newobj, ScriptParameters.Cons); // ScriptParameters - il.Emit(OpCodes.Ret); // --empty-- - - var ret = (Func)dyn.CreateDelegate(typeof(Func)); - - return ret; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerCounters.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerCounters.cs deleted file mode 100644 index 9b9848e..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerCounters.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System.Net; -using System.Text; - -namespace StackExchange.Redis -{ - /// - /// Illustrates the queues associates with this server - /// - public class ServerCounters - { - internal ServerCounters(EndPoint endpoint) - { - EndPoint = endpoint; - Interactive = new ConnectionCounters(ConnectionType.Interactive); - Subscription = new ConnectionCounters(ConnectionType.Subscription); - Other = new ConnectionCounters(ConnectionType.None); - } - - /// - /// The endpoint to which this data relates (this can be null if the data represents all servers) - /// - public EndPoint EndPoint { get; } - - /// - /// Counters associated with the interactive (non pub-sub) connection - /// - public ConnectionCounters Interactive { get; } - - /// - /// Counters associated with other ambient activity - /// - public ConnectionCounters Other { get; } - - /// - /// Counters associated with the subscription (pub-sub) connection - /// - public ConnectionCounters Subscription { get; } - /// - /// Indicates the total number of outstanding items against this server - /// - public long TotalOutstanding => Interactive.TotalOutstanding + Subscription.TotalOutstanding + Other.TotalOutstanding; - - /// - /// See Object.ToString(); - /// - public override string ToString() - { - string prettyName = EndPoint == null ? "Total" : Format.ToString(EndPoint); - var sb = new StringBuilder(prettyName).Append(": int "); - Interactive.Append(sb); - sb.Append("; sub "); - Subscription.Append(sb); - if (Other.Any()) - { - sb.Append("; other "); - Other.Append(sb); - } - return sb.ToString(); - } - - internal void Add(ServerCounters other) - { - if (other == null) return; - Interactive.Add(other.Interactive); - Subscription.Add(other.Subscription); - } - } -} \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerEndPoint.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerEndPoint.cs deleted file mode 100644 index 4bd9a47..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerEndPoint.cs +++ /dev/null @@ -1,727 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Runtime.CompilerServices; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; - -namespace StackExchange.Redis -{ - [Flags] - internal enum UnselectableFlags - { - None = 0, - RedundantMaster = 1, - DidNotRespond = 2, - ServerType = 4 - - } - - internal sealed partial class ServerEndPoint : IDisposable - { - internal volatile ServerEndPoint Master; - internal volatile ServerEndPoint[] Slaves = NoSlaves; - private static readonly Regex nameSanitizer = new Regex("[^!-~]", RegexOptions.Compiled); - private static readonly ServerEndPoint[] NoSlaves = new ServerEndPoint[0]; - private readonly EndPoint endpoint; - - - private readonly Hashtable knownScripts = new Hashtable(StringComparer.Ordinal); - private readonly ConnectionMultiplexer multiplexer; - - private int databases, writeEverySeconds; - - private PhysicalBridge interactive, subscription; - - bool isDisposed; - - ServerType serverType; - - private bool slaveReadOnly, isSlave; - - private volatile UnselectableFlags unselectableReasons; - - private Version version; - - - internal void ResetNonConnected() - { - interactive?.ResetNonConnected(); - subscription?.ResetNonConnected(); - } - public ServerEndPoint(ConnectionMultiplexer multiplexer, EndPoint endpoint, TextWriter log) - { - this.multiplexer = multiplexer; - this.endpoint = endpoint; - var config = multiplexer.RawConfig; - version = config.DefaultVersion; - slaveReadOnly = true; - isSlave = false; - databases = 0; - writeEverySeconds = config.KeepAlive > 0 ? config.KeepAlive : 60; - interactive = CreateBridge(ConnectionType.Interactive, log); - serverType = ServerType.Standalone; - - // overrides for twemproxy - if (multiplexer.RawConfig.Proxy == Proxy.Twemproxy) - { - databases = 1; - serverType = ServerType.Twemproxy; - } - } - - public ClusterConfiguration ClusterConfiguration { get; private set; } - - public int Databases { get { return databases; } set { SetConfig(ref databases, value); } } - - public EndPoint EndPoint => endpoint; - - public bool HasDatabases => serverType == ServerType.Standalone; - - public bool IsConnected - { - get - { - var tmp = interactive; - return tmp != null && tmp.IsConnected; - } - } - - internal Exception LastException - { - get - { - var tmp1 = interactive; - var tmp2 = subscription; - - //check if subscription endpoint has a better lastexception - if (tmp2 != null && tmp2.LastException != null) - { - if (tmp2.LastException.Data.Contains("Redis-FailureType") && !tmp2.LastException.Data["Redis-FailureType"].ToString().Equals(ConnectionFailureType.UnableToConnect.ToString())) - { - return tmp2.LastException; - } - } - return tmp1?.LastException; - } - } - - internal PhysicalBridge.State ConnectionState - { - get - { - var tmp = interactive; - return tmp.ConnectionState; - } - } - - public bool IsSlave { get { return isSlave; } set { SetConfig(ref isSlave, value); } } - - public long OperationCount - { - get - { - long total = 0; - var tmp = interactive; - if (tmp != null) total += tmp.OperationCount; - tmp = subscription; - if (tmp != null) total += tmp.OperationCount; - return total; - } - } - - public bool RequiresReadMode => serverType == ServerType.Cluster && IsSlave; - - public ServerType ServerType { get { return serverType; } set { SetConfig(ref serverType, value); } } - - public bool SlaveReadOnly { get { return slaveReadOnly; } set { SetConfig(ref slaveReadOnly, value); } } - - public bool AllowSlaveWrites { get; set; } - - public Version Version { get { return version; } set { SetConfig(ref version, value); } } - - public int WriteEverySeconds { get { return writeEverySeconds; } set { SetConfig(ref writeEverySeconds, value); } } - internal ConnectionMultiplexer Multiplexer => multiplexer; - - public void ClearUnselectable(UnselectableFlags flags) - { - var oldFlags = unselectableReasons; - if (oldFlags != 0) - { - unselectableReasons &= ~flags; - if (unselectableReasons != oldFlags) - { - multiplexer.Trace(unselectableReasons == 0 ? "Now usable" : ("Now unusable: " + flags), ToString()); - } - } - } - - public void Dispose() - { - isDisposed = true; - var tmp = interactive; - interactive = null; - tmp?.Dispose(); - - tmp = subscription; - subscription = null; - tmp?.Dispose(); - } - - public PhysicalBridge GetBridge(ConnectionType type, bool create = true, TextWriter log = null) - { - if (isDisposed) return null; - switch (type) - { - case ConnectionType.Interactive: - return interactive ?? (create ? interactive = CreateBridge(ConnectionType.Interactive, log) : null); - case ConnectionType.Subscription: - return subscription ?? (create ? subscription = CreateBridge(ConnectionType.Subscription, log) : null); - } - return null; - } - public PhysicalBridge GetBridge(RedisCommand command, bool create = true) - { - if (isDisposed) return null; - switch (command) - { - case RedisCommand.SUBSCRIBE: - case RedisCommand.UNSUBSCRIBE: - case RedisCommand.PSUBSCRIBE: - case RedisCommand.PUNSUBSCRIBE: - return subscription ?? (create ? subscription = CreateBridge(ConnectionType.Subscription, null) : null); - default: - return interactive; - } - } - - public RedisFeatures GetFeatures() - { - return new RedisFeatures(version); - } - - public void SetClusterConfiguration(ClusterConfiguration configuration) - { - - ClusterConfiguration = configuration; - - if (configuration != null) - { - multiplexer.Trace("Updating cluster ranges..."); - multiplexer.UpdateClusterRange(configuration); - multiplexer.Trace("Resolving genealogy..."); - var thisNode = configuration.Nodes.FirstOrDefault(x => x.EndPoint.Equals(this.EndPoint)); - if (thisNode != null) - { - List slaves = null; - ServerEndPoint master = null; - foreach (var node in configuration.Nodes) - { - if (node.NodeId == thisNode.ParentNodeId) - { - master = multiplexer.GetServerEndPoint(node.EndPoint); - } - else if (node.ParentNodeId == thisNode.NodeId) - { - if (slaves == null) slaves = new List(); - slaves.Add(multiplexer.GetServerEndPoint(node.EndPoint)); - } - } - Master = master; - Slaves = slaves?.ToArray() ?? NoSlaves; - } - multiplexer.Trace("Cluster configured"); - } - } - - public void SetUnselectable(UnselectableFlags flags) - { - if (flags != 0) - { - var oldFlags = unselectableReasons; - unselectableReasons |= flags; - if (unselectableReasons != oldFlags) - { - multiplexer.Trace(unselectableReasons == 0 ? "Now usable" : ("Now unusable: " + flags), ToString()); - } - } - } - public override string ToString() - { - return Format.ToString(EndPoint); - } - - public bool TryEnqueue(Message message) - { - var bridge = GetBridge(message.Command); - return bridge != null && bridge.TryEnqueue(message, isSlave); - } - - internal void Activate(ConnectionType type, TextWriter log) - { - GetBridge(type, true, log); - } - - internal void AddScript(string script, byte[] hash) - { - lock (knownScripts) - { - knownScripts[script] = hash; - } - } - - internal void AutoConfigure(PhysicalConnection connection) - { - if (serverType == ServerType.Twemproxy) - { - // don't try to detect configuration; all the config commands are disabled, and - // the fallback master/slave detection won't help - return; - } - - var commandMap = multiplexer.CommandMap; - const CommandFlags flags = CommandFlags.FireAndForget | CommandFlags.HighPriority | CommandFlags.NoRedirect; - - var features = GetFeatures(); - Message msg; - - if (commandMap.IsAvailable(RedisCommand.CONFIG)) - { - if (multiplexer.RawConfig.KeepAlive <= 0) - { - msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, RedisLiterals.timeout); - msg.SetInternalCall(); - WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); - } - msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, RedisLiterals.slave_read_only); - msg.SetInternalCall(); - WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); - msg = Message.Create(-1, flags, RedisCommand.CONFIG, RedisLiterals.GET, RedisLiterals.databases); - msg.SetInternalCall(); - WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); - } - if (commandMap.IsAvailable(RedisCommand.INFO)) - { - lastInfoReplicationCheckTicks = Environment.TickCount; - if (features.InfoSections) - { - msg = Message.Create(-1, flags, RedisCommand.INFO, RedisLiterals.replication); - msg.SetInternalCall(); - WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); - - msg = Message.Create(-1, flags, RedisCommand.INFO, RedisLiterals.server); - msg.SetInternalCall(); - WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); - } - else - { - msg = Message.Create(-1, flags, RedisCommand.INFO); - msg.SetInternalCall(); - WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); - } - } - else if (commandMap.IsAvailable(RedisCommand.SET)) - { - // this is a nasty way to find if we are a slave, and it will only work on up-level servers, but... - RedisKey key = Guid.NewGuid().ToByteArray(); - msg = Message.Create(0, flags, RedisCommand.SET, key, RedisLiterals.slave_read_only, RedisLiterals.PX, 1, RedisLiterals.NX); - msg.SetInternalCall(); - WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.AutoConfigure); - } - if (commandMap.IsAvailable(RedisCommand.CLUSTER)) - { - msg = Message.Create(-1, flags, RedisCommand.CLUSTER, RedisLiterals.NODES); - msg.SetInternalCall(); - WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.ClusterNodes); - } - } - - int _nextReplicaOffset; - internal uint NextReplicaOffset() // used to round-robin between multiple replicas - => (uint) System.Threading.Interlocked.Increment(ref _nextReplicaOffset); - - internal Task Close() - { - var tmp = interactive; - Task result; - if (tmp == null || !tmp.IsConnected || !multiplexer.CommandMap.IsAvailable(RedisCommand.QUIT)) - { - result = CompletedTask.Default(null); - } - else - { - result = QueueDirectAsync(Message.Create(-1, CommandFlags.None, RedisCommand.QUIT), ResultProcessor.DemandOK, bridge: interactive); - } - return result; - } - - internal void FlushScriptCache() - { - lock (knownScripts) - { - knownScripts.Clear(); - } - } - - private string runId; - internal string RunId - { - get { return runId; } - set - { - if (value != runId) // we only care about changes - { - // if we had an old run-id, and it has changed, then the - // server has been restarted; which means the script cache - // is toast - if (runId != null) FlushScriptCache(); - runId = value; - } - } - } - - internal ServerCounters GetCounters() - { - var counters = new ServerCounters(endpoint); - interactive?.GetCounters(counters.Interactive); - subscription?.GetCounters(counters.Subscription); - return counters; - } - - internal int GetOutstandingCount(RedisCommand command, out int inst, out int qu, out int qs, out int qc, out int wr, out int wq, out int @in, out int ar) - { - var bridge = GetBridge(command, false); - if (bridge == null) - { - return inst = qu = qs = qc = wr = wq = @in = ar = 0; - } - - return bridge.GetOutstandingCount(out inst, out qu, out qs, out qc, out wr, out wq, out @in, out ar); - } - - internal string GetProfile() - { - var sb = new StringBuilder(); - sb.Append("Circular op-count snapshot; int:"); - interactive?.AppendProfile(sb); - sb.Append("; sub:"); - subscription?.AppendProfile(sb); - return sb.ToString(); - } - - internal byte[] GetScriptHash(string script, RedisCommand command) - { - var found = (byte[])knownScripts[script]; - if(found == null && command == RedisCommand.EVALSHA) - { - // the script provided is a hex sha; store and re-use the ascii for that - found = Encoding.ASCII.GetBytes(script); - lock(knownScripts) - { - knownScripts[script] = found; - } - } - return found; - } - - internal string GetStormLog(RedisCommand command) - { - var bridge = GetBridge(command); - return bridge?.GetStormLog(); - } - - internal Message GetTracerMessage(bool assertIdentity) - { - // different configurations block certain commands, as can ad-hoc local configurations, so - // we'll do the best with what we have available. - // note that the muxer-ctor asserts that one of ECHO, PING, TIME of GET is available - // see also: TracerProcessor - var map = multiplexer.CommandMap; - Message msg; - const CommandFlags flags = CommandFlags.NoRedirect | CommandFlags.FireAndForget; - if (assertIdentity && map.IsAvailable(RedisCommand.ECHO)) - { - msg = Message.Create(-1, flags, RedisCommand.ECHO, (RedisValue)multiplexer.UniqueId); - } - else if (map.IsAvailable(RedisCommand.PING)) - { - msg = Message.Create(-1, flags, RedisCommand.PING); - } - else if (map.IsAvailable(RedisCommand.TIME)) - { - msg = Message.Create(-1, flags, RedisCommand.TIME); - } - else if (!assertIdentity && map.IsAvailable(RedisCommand.ECHO)) - { - // we'll use echo as a PING substitute if it is all we have (in preference to EXISTS) - msg = Message.Create(-1, flags, RedisCommand.ECHO, (RedisValue)multiplexer.UniqueId); - } - else - { - map.AssertAvailable(RedisCommand.EXISTS); - msg = Message.Create(0, flags, RedisCommand.EXISTS, (RedisValue)multiplexer.UniqueId); - } - msg.SetInternalCall(); - return msg; - } - - internal bool IsSelectable(RedisCommand command) - { - var bridge = unselectableReasons == 0 ? GetBridge(command, false) : null; - return bridge != null && bridge.IsConnected; - } - - internal void OnEstablishing(PhysicalConnection connection, TextWriter log) - { - try - { - if (connection == null) return; - Handshake(connection, log); - } - catch (Exception ex) - { - connection.RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); - } - } - - internal void OnFullyEstablished(PhysicalConnection connection) - { - try - { - if (connection == null) return; - var bridge = connection.Bridge; - if (bridge == subscription) - { - multiplexer.ResendSubscriptions(this); - } - multiplexer.OnConnectionRestored(endpoint, bridge.ConnectionType); - } - catch (Exception ex) - { - connection.RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); - } - } - - internal int LastInfoReplicationCheckSecondsAgo - { - get { return unchecked(Environment.TickCount - VolatileWrapper.Read(ref lastInfoReplicationCheckTicks)) / 1000; } - } - - private EndPoint masterEndPoint; - public EndPoint MasterEndPoint - { - get { return masterEndPoint; } - set { SetConfig(ref masterEndPoint, value); } - } - - - internal bool CheckInfoReplication() - { - lastInfoReplicationCheckTicks = Environment.TickCount; - PhysicalBridge bridge; - if (version >= RedisFeatures.v2_8_0 && multiplexer.CommandMap.IsAvailable(RedisCommand.INFO) - && (bridge = GetBridge(ConnectionType.Interactive, false)) != null) - { - var msg = Message.Create(-1, CommandFlags.FireAndForget | CommandFlags.HighPriority | CommandFlags.NoRedirect, RedisCommand.INFO, RedisLiterals.replication); - msg.SetInternalCall(); - QueueDirectFireAndForget(msg, ResultProcessor.AutoConfigure, bridge); - return true; - } - return false; - } - private int lastInfoReplicationCheckTicks; - - private int _heartBeatActive; - internal void OnHeartbeat() - { - // don't overlap operations on an endpoint - if (Interlocked.CompareExchange(ref _heartBeatActive, 1, 0) == 0) - { - try - { - - - interactive?.OnHeartbeat(false); - subscription?.OnHeartbeat(false); - } - catch (Exception ex) - { - multiplexer.OnInternalError(ex, EndPoint); - } - finally - { - Interlocked.Exchange(ref _heartBeatActive, 0); - } - } - } - - internal Task QueueDirectAsync(Message message, ResultProcessor processor, object asyncState = null, PhysicalBridge bridge = null) - { - var tcs = TaskSource.CreateDenyExecSync(asyncState); - var source = ResultBox.Get(tcs); - message.SetSource(processor, source); - if (bridge == null) bridge = GetBridge(message.Command); - if (!bridge.TryEnqueue(message, isSlave)) - { - ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, multiplexer.IncludePerformanceCountersInExceptions, message.Command, message, this, multiplexer.GetServerSnapshot())); - } - return tcs.Task; - } - - internal void QueueDirectFireAndForget(Message message, ResultProcessor processor, PhysicalBridge bridge = null) - { - if (message != null) - { - message.SetSource(processor, null); - multiplexer.Trace("Enqueue: " + message); - (bridge ?? GetBridge(message.Command)).TryEnqueue(message, isSlave); - } - } - - internal void ReportNextFailure() - { - interactive?.ReportNextFailure(); - subscription?.ReportNextFailure(); - } - - internal Task SendTracer(TextWriter log = null) - { - var msg = GetTracerMessage(false); - msg = LoggingMessage.Create(log, msg); - return QueueDirectAsync(msg, ResultProcessor.Tracer); - } - - internal string Summary() - { - var sb = new StringBuilder(Format.ToString(endpoint)) - .Append(": ").Append(serverType).Append(" v").Append(version).Append(", ").Append(isSlave ? "slave" : "master"); - - - if (databases > 0) sb.Append("; ").Append(databases).Append(" databases"); - if (writeEverySeconds > 0) - sb.Append("; keep-alive: ").Append(TimeSpan.FromSeconds(writeEverySeconds)); - var tmp = interactive; - sb.Append("; int: ").Append(tmp?.ConnectionState.ToString() ?? "n/a"); - tmp = subscription; - if(tmp == null) - { - sb.Append("; sub: n/a"); - } else - { - var state = tmp.ConnectionState; - sb.Append("; sub: ").Append(state); - if(state == PhysicalBridge.State.ConnectedEstablished) - { - sb.Append(", ").Append(tmp.SubscriptionCount).Append(" active"); - } - } - - var flags = unselectableReasons; - if (flags != 0) - { - sb.Append("; not in use: ").Append(flags); - } - return sb.ToString(); - } - internal void WriteDirectOrQueueFireAndForget(PhysicalConnection connection, Message message, ResultProcessor processor) - { - if (message != null) - { - message.SetSource(processor, null); - if (connection == null) - { - multiplexer.Trace("Enqueue: " + message); - GetBridge(message.Command).TryEnqueue(message, isSlave); - } - else - { - multiplexer.Trace("Writing direct: " + message); - connection.Bridge.WriteMessageDirect(connection, message); - } - } - } - - private PhysicalBridge CreateBridge(ConnectionType type, TextWriter log) - { - multiplexer.Trace(type.ToString()); - var bridge = new PhysicalBridge(this, type); - bridge.TryConnect(log); - return bridge; - } - void Handshake(PhysicalConnection connection, TextWriter log) - { - multiplexer.LogLocked(log, "Server handshake"); - if (connection == null) - { - multiplexer.Trace("No connection!?"); - return; - } - Message msg; - string password = multiplexer.RawConfig.Password; - if (!string.IsNullOrWhiteSpace(password)) - { - multiplexer.LogLocked(log, "Authenticating (password)"); - msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.AUTH, (RedisValue)password); - msg.SetInternalCall(); - WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.DemandOK); - } - if (multiplexer.CommandMap.IsAvailable(RedisCommand.CLIENT)) - { - string name = multiplexer.ClientName; - if (!string.IsNullOrWhiteSpace(name)) - { - name = nameSanitizer.Replace(name, ""); - if (!string.IsNullOrWhiteSpace(name)) - { - multiplexer.LogLocked(log, "Setting client name: {0}", name); - msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.CLIENT, RedisLiterals.SETNAME, (RedisValue)name); - msg.SetInternalCall(); - WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.DemandOK); - } - } - } - - var connType = connection.Bridge.ConnectionType; - - if (connType == ConnectionType.Interactive) - { - multiplexer.LogLocked(log, "Auto-configure..."); - AutoConfigure(connection); - } - multiplexer.LogLocked(log, "Sending critical tracer: {0}", connection.Bridge); - var tracer = GetTracerMessage(true); - tracer = LoggingMessage.Create(log, tracer); - WriteDirectOrQueueFireAndForget(connection, tracer, ResultProcessor.EstablishConnection); - - - // note: this **must** be the last thing on the subscription handshake, because after this - // we will be in subscriber mode: regular commands cannot be sent - if (connType == ConnectionType.Subscription) - { - var configChannel = multiplexer.ConfigurationChangedChannel; - if(configChannel != null) - { - msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.SUBSCRIBE, (RedisChannel)configChannel); - WriteDirectOrQueueFireAndForget(connection, msg, ResultProcessor.TrackSubscriptions); - } - } - multiplexer.LogLocked(log, "Flushing outbound buffer"); - connection.Flush(); - } - - private void SetConfig(ref T field, T value, [CallerMemberName] string caller = null) - { - if(!EqualityComparer.Default.Equals(field, value)) - { - multiplexer.Trace(caller + " changed from " + field + " to " + value, "Configuration"); - field = value; - multiplexer.ReconfigureIfNeeded(endpoint, false, caller); - } - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerSelectionStrategy.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerSelectionStrategy.cs deleted file mode 100644 index 6638012..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerSelectionStrategy.cs +++ /dev/null @@ -1,299 +0,0 @@ -using System; -using System.Net; -using System.Threading; - -namespace StackExchange.Redis -{ - internal sealed class ServerSelectionStrategy - { - public const int NoSlot = -1, MultipleSlots = -2; - private const int RedisClusterSlotCount = 16384; - static readonly ushort[] crc16tab = - { - 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, - 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, - 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, - 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, - 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, - 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, - 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, - 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, - 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, - 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, - 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, - 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, - 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, - 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, - 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, - 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, - 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, - 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, - 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, - 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, - 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, - 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, - 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, - 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, - 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, - 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, - 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, - 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, - 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, - 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, - 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, - 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 - }; - - private readonly ConnectionMultiplexer multiplexer; - private int anyStartOffset; - - private ServerEndPoint[] map; - - private ServerType serverType = ServerType.Standalone; - - public ServerSelectionStrategy(ConnectionMultiplexer multiplexer) - { - this.multiplexer = multiplexer; - } - - public ServerType ServerType { get { return serverType; } set { serverType = value; } } - internal int TotalSlots => RedisClusterSlotCount; - - /// - /// Computes the hash-slot that would be used by the given key - /// - public unsafe int HashSlot(RedisKey key) - { - //HASH_SLOT = CRC16(key) mod 16384 - if (key.IsNull) return NoSlot; - unchecked - { - var blob = (byte[])key; - fixed (byte* ptr = blob) - { - int offset = 0, count = blob.Length, start, end; - if ((start = IndexOf(ptr, (byte)'{', 0, count - 1)) >= 0 - && (end = IndexOf(ptr, (byte)'}', start + 1, count)) >= 0 - && --end != start) - { - offset = start + 1; - count = end - start; // note we already subtracted one via --end - } - - uint crc = 0; - for (int i = 0; i < count; i++) - crc = ((crc << 8) ^ crc16tab[((crc >> 8) ^ ptr[offset++]) & 0x00FF]) & 0x0000FFFF; - return (int)(crc % RedisClusterSlotCount); - } - } - } - - public ServerEndPoint Select(Message message) - { - if (message == null) throw new ArgumentNullException(nameof(message)); - int slot = NoSlot; - switch (serverType) - { - case ServerType.Cluster: - case ServerType.Twemproxy: // strictly speaking twemproxy uses a different hashing algo, but the hash-tag behavior is - // the same, so this does a pretty good job of spotting illegal commands before sending them - - slot = message.GetHashSlot(this); - if (slot == MultipleSlots) throw ExceptionFactory.MultiSlot(multiplexer.IncludeDetailInExceptions, message); - break; - - } - return Select(slot, message.Command, message.Flags); - } - - public ServerEndPoint Select(int db, RedisCommand command, RedisKey key, CommandFlags flags) - { - int slot = serverType == ServerType.Cluster ? HashSlot(key) : NoSlot; - return Select(slot, command, flags); - } - - public bool TryResend(int hashSlot, Message message, EndPoint endpoint, bool isMoved) - { - try - { - if (serverType == ServerType.Standalone || hashSlot < 0 || hashSlot >= RedisClusterSlotCount) return false; - - ServerEndPoint server = multiplexer.GetServerEndPoint(endpoint); - if (server != null) - { - bool retry = false; - if ((message.Flags & CommandFlags.NoRedirect) == 0) - { - message.SetAsking(!isMoved); - message.SetNoRedirect(); // once is enough - - // note that everything so far is talking about MASTER nodes; we might be - // wanting a SLAVE, so we'll check - ServerEndPoint resendVia = null; - var command = message.Command; - switch (Message.GetMasterSlaveFlags(message.Flags)) - { - case CommandFlags.DemandMaster: - resendVia = server.IsSelectable(command) ? server : null; - break; - case CommandFlags.PreferMaster: - resendVia = server.IsSelectable(command) ? server : FindSlave(server, command); - break; - case CommandFlags.PreferSlave: - resendVia = FindSlave(server, command) ?? (server.IsSelectable(command) ? server : null); - break; - case CommandFlags.DemandSlave: - resendVia = FindSlave(server, command); - break; - } - if (resendVia == null) - { - multiplexer.Trace("Unable to resend to " + endpoint); - } - else - { - message.PrepareToResend(resendVia, isMoved); - retry = resendVia.TryEnqueue(message); - } - } - - if (isMoved) // update map; note we can still update the map even if we aren't actually goint to resend - { - var arr = MapForMutation(); - var oldServer = arr[hashSlot]; - arr[hashSlot] = server; - if (oldServer != server) - { - multiplexer.OnHashSlotMoved(hashSlot, oldServer?.EndPoint, endpoint); - } - } - - return retry; - } - return false; - } - catch - { - return false; - } - } - - internal int CombineSlot(int oldSlot, int newSlot) - { - if (oldSlot == MultipleSlots || newSlot == NoSlot) return oldSlot; - if (oldSlot == NoSlot) return newSlot; - return oldSlot == newSlot ? oldSlot : MultipleSlots; - } - internal int CombineSlot(int oldSlot, RedisKey key) - { - if (oldSlot == MultipleSlots || key.IsNull) return oldSlot; - - int newSlot = HashSlot(key); - if (oldSlot == NoSlot) return newSlot; - return oldSlot == newSlot ? oldSlot : MultipleSlots; - } - internal int CountCoveredSlots() - { - var arr = map; - if (arr == null) return 0; - int count = 0; - for (int i = 0; i < arr.Length; i++) - if (arr[i] != null) count++; - return count; - } - - internal void UpdateClusterRange(int fromInclusive, int toInclusive, ServerEndPoint server) - { - var arr = MapForMutation(); - for (int i = fromInclusive; i <= toInclusive; i++) - { - arr[i] = server; - } - } - - static unsafe int IndexOf(byte* ptr, byte value, int start, int end) - { - for (int offset = start; offset < end; offset++) - if (ptr[offset] == value) return offset; - return -1; - } - - private ServerEndPoint Any(RedisCommand command, CommandFlags flags) - { - return multiplexer.AnyConnected(serverType, (uint)Interlocked.Increment(ref anyStartOffset), command, flags); - } - - private ServerEndPoint FindMaster(ServerEndPoint endpoint, RedisCommand command) - { - int max = 5; - do - { - if (!endpoint.IsSlave && endpoint.IsSelectable(command)) return endpoint; - - endpoint = endpoint.Master; - } while (endpoint != null && --max != 0); - return null; - } - - private ServerEndPoint FindSlave(ServerEndPoint endpoint, RedisCommand command) - { - if (endpoint.IsSlave && endpoint.IsSelectable(command)) return endpoint; - - var slaves = endpoint.Slaves; - var len = slaves.Length; - uint startOffset = len <= 1 ? 0 : endpoint.NextReplicaOffset(); - for (int i = 0; i < len; i++) - { - endpoint = slaves[(int)(((uint)i + startOffset) % len)]; - if (endpoint.IsSlave && endpoint.IsSelectable(command)) return endpoint; - } - return null; - } - - private ServerEndPoint[] MapForMutation() - { - var arr = map; - if (arr == null) - { - lock (this) - { - if (map == null) map = new ServerEndPoint[RedisClusterSlotCount]; - arr = map; - } - } - return arr; - } - - private ServerEndPoint Select(int slot, RedisCommand command, CommandFlags flags) - { - flags = Message.GetMasterSlaveFlags(flags); // only intersted in master/slave preferences - - ServerEndPoint[] arr; - if (slot == NoSlot || (arr = map) == null) return Any(command, flags); - - ServerEndPoint endpoint = arr[slot], testing; - // but: ^^^ is the MASTER slots; if we want a slave, we need to do some thinking - - if (endpoint != null) - { - switch (flags) - { - case CommandFlags.DemandSlave: - return FindSlave(endpoint, command) ?? Any(command, flags); - case CommandFlags.PreferSlave: - testing = FindSlave(endpoint, command); - if (testing != null) return testing; - break; - case CommandFlags.DemandMaster: - return FindMaster(endpoint, command) ?? Any(command, flags); - case CommandFlags.PreferMaster: - testing = FindMaster(endpoint, command); - if (testing != null) return testing; - break; - } - if (endpoint.IsSelectable(command)) return endpoint; - } - return Any(command, flags); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerType.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerType.cs deleted file mode 100644 index 80072f3..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ServerType.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// Indicates the flavor of a particular redis server - /// - public enum ServerType - { - /// - /// Classic redis-server server - /// - Standalone, - /// - /// Monitoring/configuration redis-sentinel server - /// - Sentinel, - /// - /// Distributed redis-cluster server - /// - Cluster, - /// - /// Distributed redis installation via twemproxy - /// - Twemproxy - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SetOperation.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SetOperation.cs deleted file mode 100644 index fdb1acd..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SetOperation.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// Describes an algebraic set operation that can be performed to combine multiple sets - /// - public enum SetOperation - { - /// - /// Returns the members of the set resulting from the union of all the given sets. - /// - Union, - /// - /// Returns the members of the set resulting from the intersection of all the given sets. - /// - Intersect, - /// - /// Returns the members of the set resulting from the difference between the first set and all the successive sets. - /// - Difference - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ShutdownMode.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ShutdownMode.cs deleted file mode 100644 index e7a10f6..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/ShutdownMode.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// Defines the persistence behaviour of the server during shutdown - /// - public enum ShutdownMode - { - /// - /// The data is persisted if save points are configured - /// - Default, - /// - /// The data is NOT persisted even if save points are configured - /// - Never, - /// - /// The data is persisted even if save points are NOT configured - /// - Always - } - -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SocketManager.NoPoll.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SocketManager.NoPoll.cs deleted file mode 100644 index c260466..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SocketManager.NoPoll.cs +++ /dev/null @@ -1,16 +0,0 @@ -#if !FEATURE_SOCKET_MODE_POLL - -namespace StackExchange.Redis -{ - partial class SocketManager - { - internal const SocketMode DefaultSocketMode = SocketMode.Async; - - private void OnAddRead(System.Net.Sockets.Socket socket, ISocketCallback callback) - { - throw new System.NotSupportedException(); - } - } -} - -#endif \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SocketManager.Poll.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SocketManager.Poll.cs deleted file mode 100644 index 9b573fd..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SocketManager.Poll.cs +++ /dev/null @@ -1,428 +0,0 @@ -#if FEATURE_SOCKET_MODE_POLL -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Net.Sockets; -using System.Runtime.InteropServices; -using System.Threading; - -namespace StackExchange.Redis -{ - partial class SocketManager - { - internal const SocketMode DefaultSocketMode = SocketMode.Poll; - static readonly IntPtr[] EmptyPointers = new IntPtr[0]; - static readonly WaitCallback HelpProcessItems = state => - { - var qdsl = state as QueueDrainSyncLock; - if (qdsl != null && qdsl.Consume()) - { - var mgr = qdsl.Manager; - mgr.ProcessItems(false); - qdsl.Pulse(); - } - }; - - private static ParameterizedThreadStart read = state => ((SocketManager)state).Read(); - - readonly Queue readQueue = new Queue(), errorQueue = new Queue(); - - private readonly Dictionary socketLookup = new Dictionary(); - - private int readerCount; - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")] - [DllImport("ws2_32.dll", SetLastError = true)] - internal static extern int select([In] int ignoredParameter, [In, Out] IntPtr[] readfds, [In, Out] IntPtr[] writefds, [In, Out] IntPtr[] exceptfds, [In] ref TimeValue timeout); - - private static void ProcessItems(Queue queue, CallbackOperation operation) - - { - if (queue == null) return; - while (true) - { - // get the next item (note we could be competing with a worker here, hence lock) - ISocketCallback callback; - lock (queue) - { - if (queue.Count == 0) break; - callback = queue.Dequeue(); - } - if (callback != null) - { - try - { - switch (operation) - { - case CallbackOperation.Read: callback.Read(); break; - case CallbackOperation.Error: callback.Error(); break; - } - } - catch (Exception ex) - { - Trace.WriteLine(ex); - } - } - } - } - - private void OnAddRead(Socket socket, ISocketCallback callback) - { - if (socket == null) throw new ArgumentNullException(nameof(socket)); - if (callback == null) throw new ArgumentNullException(nameof(callback)); - - lock (socketLookup) - { - if (isDisposed) throw new ObjectDisposedException(name); - - var handle = socket.Handle; - if (handle == IntPtr.Zero) throw new ObjectDisposedException("socket"); - socketLookup.Add(handle, new SocketPair(socket, callback)); - if (socketLookup.Count == 1) - { - Monitor.PulseAll(socketLookup); - if (Interlocked.CompareExchange(ref readerCount, 0, 0) == 0) - StartReader(); - } - } - } - - partial void OnDispose() - { - lock (socketLookup) - { - isDisposed = true; - socketLookup.Clear(); - Monitor.PulseAll(socketLookup); - } - } - - partial void OnShutdown(Socket socket) - { - lock (socketLookup) - { - socketLookup.Remove(socket.Handle); - } - } - - private void ProcessItems(bool setState) - { - if(setState) managerState = ManagerState.ProcessReadQueue; - ProcessItems(readQueue, CallbackOperation.Read); - if (setState) managerState = ManagerState.ProcessErrorQueue; - ProcessItems(errorQueue, CallbackOperation.Error); - } - private void Read() - { - bool weAreReader = false; - try - { - weAreReader = Interlocked.CompareExchange(ref readerCount, 1, 0) == 0; - if (weAreReader) - { - managerState = ManagerState.Preparing; - ReadImpl(); - managerState = ManagerState.Inactive; - } - } - catch (Exception ex) - { - if (weAreReader) - { - managerState = ManagerState.Faulted; - } - Debug.WriteLine(ex); - Trace.WriteLine(ex); - } - finally - { - if (weAreReader) Interlocked.Exchange(ref readerCount, 0); - } - } - - internal ManagerState State => managerState; - private volatile ManagerState managerState; - private volatile int lastErrorTicks; - internal string LastErrorTimeRelative() - { - var tmp = lastErrorTicks; - if (tmp == 0) return "never"; - return unchecked(Environment.TickCount - tmp) + "ms ago"; - } - private ISocketCallback GetCallback(IntPtr key) - { - lock(socketLookup) - { - SocketPair pair; - return socketLookup.TryGetValue(key, out pair) ? pair.Callback : null; - } - } - private void ReadImpl() - { - List dead = null, active = new List(); - List activeCallbacks = new List(); - IntPtr[] readSockets = EmptyPointers, errorSockets = EmptyPointers; - long lastHeartbeat = Environment.TickCount; - SocketPair[] allSocketPairs = null; - while (true) - { - managerState = ManagerState.CheckForHeartbeat; - active.Clear(); - activeCallbacks.Clear(); - dead?.Clear(); - - // this check is actually a pace-maker; sometimes the Timer callback stalls for - // extended periods of time, which can cause socket disconnect - long now = Environment.TickCount; - if (unchecked(now - lastHeartbeat) >= 15000) - { - managerState = ManagerState.ExecuteHeartbeat; - lastHeartbeat = now; - lock (socketLookup) - { - if (allSocketPairs == null || allSocketPairs.Length != socketLookup.Count) - allSocketPairs = new SocketPair[socketLookup.Count]; - socketLookup.Values.CopyTo(allSocketPairs, 0); - } - foreach (var pair in allSocketPairs) - { - var callback = pair.Callback; - if (callback != null) try { callback.OnHeartbeat(); } catch { } - } - } - - managerState = ManagerState.LocateActiveSockets; - lock (socketLookup) - { - if (isDisposed) return; - - if (socketLookup.Count == 0) - { - // if empty, give it a few seconds chance before exiting - managerState = ManagerState.NoSocketsPause; - Monitor.Wait(socketLookup, TimeSpan.FromSeconds(20)); - if (socketLookup.Count == 0) return; // nothing new came in, so exit - } - managerState = ManagerState.PrepareActiveSockets; - foreach (var pair in socketLookup) - { - var socket = pair.Value.Socket; - if (socket.Handle == pair.Key && socket.Connected) - if (pair.Value.Socket.Connected) - { - active.Add(pair.Key); - activeCallbacks.Add(pair.Value.Callback); - } - else - { - (dead ?? (dead = new List())).Add(pair.Key); - } - } - if (dead != null && dead.Count != 0) - { - managerState = ManagerState.CullDeadSockets; - foreach (var socket in dead) socketLookup.Remove(socket); - } - } - int pollingSockets = active.Count; - if (pollingSockets == 0) - { - // nobody had actual sockets; just sleep - managerState = ManagerState.NoActiveSocketsPause; - Thread.Sleep(10); - continue; - } - - if (readSockets.Length < active.Count + 1) - { - managerState = ManagerState.GrowingSocketArray; - ConnectionMultiplexer.TraceWithoutContext("Resizing socket array for " + active.Count + " sockets"); - readSockets = new IntPtr[active.Count + 6]; // leave so space for growth - errorSockets = new IntPtr[active.Count + 6]; - } - managerState = ManagerState.CopyingPointersForSelect; - readSockets[0] = errorSockets[0] = (IntPtr)active.Count; - active.CopyTo(readSockets, 1); - active.CopyTo(errorSockets, 1); - int ready; - try - { - var timeout = new TimeValue(1000); - managerState = ManagerState.ExecuteSelect; - ready = select(0, readSockets, null, errorSockets, ref timeout); - managerState = ManagerState.ExecuteSelectComplete; - if (ready <= 0) // -ve typically means a socket was disposed just before; just retry - { - bool hasWorkToDo = false; - if (ready == 0) - { - managerState = ManagerState.CheckForStaleConnections; - foreach (var s in activeCallbacks) - { - if (s.IsDataAvailable) - { - hasWorkToDo = true; - } - else - { -#pragma warning disable 0420 - s.CheckForStaleConnection(ref managerState); -#pragma warning restore 0420 - } - } - managerState = ManagerState.CheckForStaleConnectionsDone; - } - else - { - lastErrorTicks = Environment.TickCount; - } - if (!hasWorkToDo) - { - continue; - } - } - ConnectionMultiplexer.TraceWithoutContext((int)readSockets[0] != 0, "Read sockets: " + (int)readSockets[0]); - ConnectionMultiplexer.TraceWithoutContext((int)errorSockets[0] != 0, "Error sockets: " + (int)errorSockets[0]); - } - catch (Exception ex) - { // this typically means a socket was disposed just before; just retry - Trace.WriteLine(ex.Message); - continue; - } - - bool haveWork = false; - int queueCount = (int)readSockets[0]; - if (queueCount != 0) - { - managerState = ManagerState.EnqueueRead; - lock (readQueue) - { - for (int i = 1; i <= queueCount; i++) - { - var callback = GetCallback(readSockets[i]); - if (callback != null) - { - readQueue.Enqueue(callback); - haveWork = true; - } - } - } - } - queueCount = (int)errorSockets[0]; - if (queueCount != 0) - { - managerState = ManagerState.EnqueueError; - lock (errorQueue) - { - for (int i = 1; i <= queueCount; i++) - { - var callback = GetCallback(errorSockets[i]); - if (callback != null) - { - errorQueue.Enqueue(callback); - haveWork = true; - } - } - } - } - if(!haveWork) - { - // edge case: select is returning 0, but data could still be available - managerState = ManagerState.EnqueueReadFallback; - lock (readQueue) - { - foreach (var callback in activeCallbacks) - { - if(callback.IsDataAvailable) - { - readQueue.Enqueue(callback); - } - } - } - } - - - if (ready >= 5) // number of sockets we should attempt to process by ourself before asking for help - { - // seek help, work in parallel, then synchronize - var obj = new QueueDrainSyncLock(this); - lock (obj) - { - managerState = ManagerState.RequestAssistance; - ThreadPool.QueueUserWorkItem(HelpProcessItems, obj); - managerState = ManagerState.ProcessQueues; - ProcessItems(true); - if (!obj.Consume()) - { // then our worker arrived and picked up work; we need - // to let it finish; note that if it *didn't* get that far - // yet, the Consume() call will mean that it never tries - Monitor.Wait(obj); - } - } - } - else - { - // just do it ourself - managerState = ManagerState.ProcessQueues; - ProcessItems(true); - } - } - } - - private void StartReader() - { - var thread = new Thread(read, 32*1024) // don't need a huge stack - { - Priority = useHighPrioritySocketThreads ? ThreadPriority.AboveNormal : ThreadPriority.Normal, - Name = name + ":Read", - IsBackground = true - }; - thread.Start(this); - } - [StructLayout(LayoutKind.Sequential)] - internal struct TimeValue - { - public int Seconds; - public int Microseconds; - public TimeValue(int microSeconds) - { - Seconds = (int)(microSeconds / 1000000L); - Microseconds = (int)(microSeconds % 1000000L); - } - } - - struct SocketPair - { - public readonly ISocketCallback Callback; - public readonly Socket Socket; - public SocketPair(Socket socket, ISocketCallback callback) - { - Socket = socket; - Callback = callback; - } - } - sealed class QueueDrainSyncLock - { - private int workers; - public QueueDrainSyncLock(SocketManager manager) - { - Manager = manager; - } - public SocketManager Manager { get; } - - internal bool Consume() - { - return Interlocked.CompareExchange(ref workers, 1, 0) == 0; - } - - internal void Pulse() - { - lock (this) - { - Monitor.PulseAll(this); - } - } - } - } -} -#endif \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SocketManager.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SocketManager.cs deleted file mode 100644 index 1620684..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SocketManager.cs +++ /dev/null @@ -1,481 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Net.Sockets; -using System.Threading; -#if CORE_CLR -using System.Runtime.InteropServices; -using System.Threading.Tasks; -#endif - -namespace StackExchange.Redis -{ - internal enum SocketMode - { - Abort, - Poll, - Async - } - /// - /// Allows callbacks from SocketManager as work is discovered - /// - internal partial interface ISocketCallback - { - /// - /// Indicates that a socket has connected - /// - SocketMode Connected(Stream stream, TextWriter log); - /// - /// Indicates that the socket has signalled an error condition - /// - void Error(); - - void OnHeartbeat(); - - /// - /// Indicates that data is available on the socket, and that the consumer should read synchronously from the socket while there is data - /// - void Read(); - /// - /// Indicates that we cannot know whether data is available, and that the consume should commence reading asynchronously - /// - void StartReading(); - - // check for write-read timeout - void CheckForStaleConnection(ref SocketManager.ManagerState state); - - bool IsDataAvailable { get; } - } - - internal struct SocketToken - { - internal readonly Socket Socket; - public SocketToken(Socket socket) - { - Socket = socket; - } - public int Available => Socket?.Available ?? 0; - - public bool HasValue => Socket != null; - } - - /// - /// A SocketManager monitors multiple sockets for availability of data; this is done using - /// the Socket.Select API and a dedicated reader-thread, which allows for fast responses - /// even when the system is under ambient load. - /// - public sealed partial class SocketManager : IDisposable - { - internal enum ManagerState - { - Inactive, - Preparing, - Faulted, - CheckForHeartbeat, - ExecuteHeartbeat, - LocateActiveSockets, - NoSocketsPause, - PrepareActiveSockets, - CullDeadSockets, - NoActiveSocketsPause, - GrowingSocketArray, - CopyingPointersForSelect, - ExecuteSelect, - ExecuteSelectComplete, - CheckForStaleConnections, - - RecordConnectionFailed_OnInternalError, - RecordConnectionFailed_OnDisconnected, - RecordConnectionFailed_ReportFailure, - RecordConnectionFailed_OnConnectionFailed, - RecordConnectionFailed_FailOutstanding, - RecordConnectionFailed_ShutdownSocket, - - CheckForStaleConnectionsDone, - EnqueueRead, - EnqueueError, - EnqueueReadFallback, - RequestAssistance, - ProcessQueues, - ProcessReadQueue, - ProcessErrorQueue, - - } - private static readonly ParameterizedThreadStart writeAllQueues = context => - { - try { ((SocketManager)context).WriteAllQueues(); } catch { } - }; - - private static readonly WaitCallback writeOneQueue = context => - { - - try { ((SocketManager)context).WriteOneQueue(); } catch { } - }; - - private readonly string name; - - private readonly Queue writeQueue = new Queue(); - - bool isDisposed; - private bool useHighPrioritySocketThreads = true; - - /// - /// Creates a new (optionally named) SocketManager instance - /// - public SocketManager(string name = null) : this(name, true) { } - - /// - /// Creates a new SocketManager instance - /// - public SocketManager(string name, bool useHighPrioritySocketThreads) - { - if (string.IsNullOrWhiteSpace(name)) name = GetType().Name; - this.name = name; - this.useHighPrioritySocketThreads = useHighPrioritySocketThreads; - - // we need a dedicated writer, because when under heavy ambient load - // (a busy asp.net site, for example), workers are not reliable enough -#if !CORE_CLR - Thread dedicatedWriter = new Thread(writeAllQueues, 32 * 1024); // don't need a huge stack; - dedicatedWriter.Priority = useHighPrioritySocketThreads ? ThreadPriority.AboveNormal : ThreadPriority.Normal; -#else - Thread dedicatedWriter = new Thread(writeAllQueues); -#endif - dedicatedWriter.Name = name + ":Write"; - dedicatedWriter.IsBackground = true; // should not keep process alive - dedicatedWriter.Start(this); // will self-exit when disposed - } - - private enum CallbackOperation - { - Read, - Error - } - - /// - /// Gets the name of this SocketManager instance - /// - public string Name => name; - - /// - /// Releases all resources associated with this instance - /// - public void Dispose() - { - lock (writeQueue) - { - // make sure writer threads know to exit - isDisposed = true; - Monitor.PulseAll(writeQueue); - } - OnDispose(); - } - - internal SocketToken BeginConnect(EndPoint endpoint, ISocketCallback callback, ConnectionMultiplexer multiplexer, TextWriter log) - { - var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - SetFastLoopbackOption(socket); - socket.NoDelay = true; - try - { - CompletionType connectCompletionType = CompletionType.Any; - this.ShouldForceConnectCompletionType(ref connectCompletionType); - - var formattedEndpoint = Format.ToString(endpoint); - var tuple = Tuple.Create(socket, callback); - if (endpoint is DnsEndPoint) - { - // A work-around for a Mono bug in BeginConnect(EndPoint endpoint, AsyncCallback callback, object state) - DnsEndPoint dnsEndpoint = (DnsEndPoint)endpoint; - -#if CORE_CLR - multiplexer.LogLocked(log, "BeginConnect: {0}", formattedEndpoint); - socket.ConnectAsync(dnsEndpoint.Host, dnsEndpoint.Port).ContinueWith(t => - { - multiplexer.LogLocked(log, "EndConnect: {0}", formattedEndpoint); - EndConnectImpl(t, multiplexer, log, tuple); - multiplexer.LogLocked(log, "Connect complete: {0}", formattedEndpoint); - }); -#else - CompletionTypeHelper.RunWithCompletionType( - cb => { - multiplexer.LogLocked(log, "BeginConnect: {0}", formattedEndpoint); - return socket.BeginConnect(dnsEndpoint.Host, dnsEndpoint.Port, cb, tuple); - }, - ar => { - multiplexer.LogLocked(log, "EndConnect: {0}", formattedEndpoint); - EndConnectImpl(ar, multiplexer, log, tuple); - multiplexer.LogLocked(log, "Connect complete: {0}", formattedEndpoint); - }, - connectCompletionType); -#endif - } - else - { -#if CORE_CLR - multiplexer.LogLocked(log, "BeginConnect: {0}", formattedEndpoint); - socket.ConnectAsync(endpoint).ContinueWith(t => - { - multiplexer.LogLocked(log, "EndConnect: {0}", formattedEndpoint); - EndConnectImpl(t, multiplexer, log, tuple); - }); -#else - CompletionTypeHelper.RunWithCompletionType( - cb => { - multiplexer.LogLocked(log, "BeginConnect: {0}", formattedEndpoint); - return socket.BeginConnect(endpoint, cb, tuple); - }, - ar => { - multiplexer.LogLocked(log, "EndConnect: {0}", formattedEndpoint); - EndConnectImpl(ar, multiplexer, log, tuple); - multiplexer.LogLocked(log, "Connect complete: {0}", formattedEndpoint); - }, - connectCompletionType); -#endif - } - } - catch (NotImplementedException ex) - { - if (!(endpoint is IPEndPoint)) - { - throw new InvalidOperationException("BeginConnect failed with NotImplementedException; consider using IP endpoints, or enable ResolveDns in the configuration", ex); - } - throw; - } - var token = new SocketToken(socket); - return token; - } - internal void SetFastLoopbackOption(Socket socket) - { - // SIO_LOOPBACK_FAST_PATH (http://msdn.microsoft.com/en-us/library/windows/desktop/jj841212%28v=vs.85%29.aspx) - // Speeds up localhost operations significantly. OK to apply to a socket that will not be hooked up to localhost, - // or will be subject to WFP filtering. - const int SIO_LOOPBACK_FAST_PATH = -1744830448; - -#if !CORE_CLR - // windows only - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - { - // Win8/Server2012+ only - var osVersion = Environment.OSVersion.Version; - if (osVersion.Major > 6 || osVersion.Major == 6 && osVersion.Minor >= 2) - { - byte[] optionInValue = BitConverter.GetBytes(1); - socket.IOControl(SIO_LOOPBACK_FAST_PATH, optionInValue, null); - } - } -#else - try - { - // Ioctl is not supported on other platforms at the moment - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - byte[] optionInValue = BitConverter.GetBytes(1); - socket.IOControl(SIO_LOOPBACK_FAST_PATH, optionInValue, null); - } - } - catch (SocketException) - { - } - catch (PlatformNotSupportedException) - { - // Fix for https://github.com/StackExchange/StackExchange.Redis/issues/582 - // Checking the platform can fail on some platforms. However, we don't - // care if the platform check fails because this is for a Windows - // optimization, and checking the platform will not fail on Windows. - } -#endif - } - - internal void RequestWrite(PhysicalBridge bridge, bool forced) - { - if (Interlocked.CompareExchange(ref bridge.inWriteQueue, 1, 0) == 0 || forced) - { - lock (writeQueue) - { - writeQueue.Enqueue(bridge); - if (writeQueue.Count == 1) - { - Monitor.PulseAll(writeQueue); - } - else if (writeQueue.Count >= 2) - { // struggling are we? let's have some help dealing with the backlog - ThreadPool.QueueUserWorkItem(writeOneQueue, this); - } - } - } - } - - internal void Shutdown(SocketToken token) - { - Shutdown(token.Socket); - } - - private void EndConnectImpl(IAsyncResult ar, ConnectionMultiplexer multiplexer, TextWriter log, Tuple tuple) - { - try - { - bool ignoreConnect = false; - ShouldIgnoreConnect(tuple.Item2, ref ignoreConnect); - if (ignoreConnect) return; - var socket = tuple.Item1; - var callback = tuple.Item2; -#if CORE_CLR - multiplexer.Wait((Task)ar); // make it explode if invalid (note: already complete at this point) -#else - socket.EndConnect(ar); -#endif - var netStream = new NetworkStream(socket, false); - var socketMode = callback?.Connected(netStream, log) ?? SocketMode.Abort; - switch (socketMode) - { - case SocketMode.Poll: - multiplexer.LogLocked(log, "Starting poll"); - OnAddRead(socket, callback); - break; - case SocketMode.Async: - multiplexer.LogLocked(log, "Starting read"); - try - { callback.StartReading(); } - catch (Exception ex) - { - ConnectionMultiplexer.TraceWithoutContext(ex.Message); - Shutdown(socket); - } - break; - default: - ConnectionMultiplexer.TraceWithoutContext("Aborting socket"); - Shutdown(socket); - break; - } - } - catch (ObjectDisposedException) - { - multiplexer.LogLocked(log, "(socket shutdown)"); - if (tuple != null) - { - try - { tuple.Item2.Error(); } - catch (Exception inner) - { - ConnectionMultiplexer.TraceWithoutContext(inner.Message); - } - } - } - catch(Exception outer) - { - ConnectionMultiplexer.TraceWithoutContext(outer.Message); - if (tuple != null) - { - try - { tuple.Item2.Error(); } - catch (Exception inner) - { - ConnectionMultiplexer.TraceWithoutContext(inner.Message); - } - } - } - } - - partial void OnDispose(); - partial void OnShutdown(Socket socket); - - partial void ShouldIgnoreConnect(ISocketCallback callback, ref bool ignore); - - partial void ShouldForceConnectCompletionType(ref CompletionType completionType); - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")] - private void Shutdown(Socket socket) - { - if (socket != null) - { - OnShutdown(socket); - try { socket.Shutdown(SocketShutdown.Both); } catch { } -#if !CORE_CLR - try { socket.Close(); } catch { } -#endif - try { socket.Dispose(); } catch { } - } - } - - private void WriteAllQueues() - { - while (true) - { - PhysicalBridge bridge; - lock (writeQueue) - { - if (writeQueue.Count == 0) - { - if (isDisposed) break; // <========= exit point - Monitor.Wait(writeQueue); - if (isDisposed) break; // (woken by Dispose) - if (writeQueue.Count == 0) continue; // still nothing... - } - bridge = writeQueue.Dequeue(); - } - - switch (bridge.WriteQueue(200)) - { - case WriteResult.MoreWork: - case WriteResult.QueueEmptyAfterWrite: - // back of the line! - lock (writeQueue) - { - writeQueue.Enqueue(bridge); - } - break; - case WriteResult.CompetingWriter: - break; - case WriteResult.NoConnection: - Interlocked.Exchange(ref bridge.inWriteQueue, 0); - break; - case WriteResult.NothingToDo: - if (!bridge.ConfirmRemoveFromWriteQueue()) - { // more snuck in; back of the line! - lock (writeQueue) - { - writeQueue.Enqueue(bridge); - } - } - break; - } - } - } - - private void WriteOneQueue() - { - PhysicalBridge bridge; - lock (writeQueue) - { - bridge = writeQueue.Count == 0 ? null : writeQueue.Dequeue(); - } - if (bridge == null) return; - bool keepGoing; - do - { - switch (bridge.WriteQueue(-1)) - { - case WriteResult.MoreWork: - case WriteResult.QueueEmptyAfterWrite: - keepGoing = true; - break; - case WriteResult.NothingToDo: - keepGoing = !bridge.ConfirmRemoveFromWriteQueue(); - break; - case WriteResult.CompetingWriter: - keepGoing = false; - break; - case WriteResult.NoConnection: - Interlocked.Exchange(ref bridge.inWriteQueue, 0); - keepGoing = false; - break; - default: - keepGoing = false; - break; - } - } while (keepGoing); - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SortType.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SortType.cs deleted file mode 100644 index a1a034f..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SortType.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// Specifies how to compare elements for sorting - /// - public enum SortType - { - /// - /// Elements are interpreted as a double-precision floating point number and sorted numerically - /// - Numeric, - /// - /// Elements are sorted using their alphabetic form (Redis is UTF-8 aware as long as the !LC_COLLATE environment variable is set at the server) - /// - Alphabetic - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SortedSetEntry.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SortedSetEntry.cs deleted file mode 100644 index d1e9b12..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/SortedSetEntry.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; - -namespace StackExchange.Redis -{ - - - - - /// - /// Describes a sorted-set element with the corresponding value - /// - public struct SortedSetEntry : IEquatable, IComparable, IComparable - { - internal readonly RedisValue element; - internal readonly double score; - - /// - /// Initializes a SortedSetEntry value - /// - public SortedSetEntry(RedisValue element, double score) - { - this.element = element; - this.score = score; - } - /// - /// The unique element stored in the sorted set - /// - public RedisValue Element => element; - - /// - /// The score against the element - /// - public double Score => score; - - /// - /// The score against the element - /// -#if !CORE_CLR - [Browsable(false)] -#endif - [EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Score", false)] - public double Value { get { return score; } } - - /// - /// The unique element stored in the sorted set - /// -#if !CORE_CLR - [Browsable(false)] -#endif - [EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Element", false)] - public RedisValue Key { get { return element; } } - - /// - /// Converts to a key/value pair - /// - public static implicit operator KeyValuePair(SortedSetEntry value) - { - return new KeyValuePair(value.element, value.score); - } - /// - /// Converts from a key/value pair - /// - public static implicit operator SortedSetEntry(KeyValuePair value) - { - return new SortedSetEntry(value.Key, value.Value); - } - - /// - /// See Object.ToString() - /// - public override string ToString() - { - return element + ": " + score; - } - /// - /// See Object.GetHashCode() - /// - public override int GetHashCode() - { - return element.GetHashCode() ^ score.GetHashCode(); - } - /// - /// Compares two values for equality - /// - public override bool Equals(object obj) - { - return obj is SortedSetEntry && Equals((SortedSetEntry)obj); - } - - /// - /// Compares two values for equality - /// - public bool Equals(SortedSetEntry value) - { - return score == value.score && element == value.element; - } - - /// - /// Compares two values by score - /// - public int CompareTo(SortedSetEntry value) - { - return score.CompareTo(value.score); - } - - /// - /// Compares two values by score - /// - public int CompareTo(object value) - { - return value is SortedSetEntry ? CompareTo((SortedSetEntry)value) : -1; - } - - /// - /// Compares two values for equality - /// - public static bool operator ==(SortedSetEntry x, SortedSetEntry y) - { - return x.score == y.score && x.element == y.element; - } - /// - /// Compares two values for non-equality - /// - public static bool operator !=(SortedSetEntry x, SortedSetEntry y) - { - return x.score != y.score || x.element != y.element; - } - - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/StringSplits.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/StringSplits.cs deleted file mode 100644 index ba52350..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/StringSplits.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace StackExchange.Redis -{ - class StringSplits - { - public static readonly char[] - Space = { ' ' }, - Comma = { ',' }; - - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/TaskSource.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/TaskSource.cs deleted file mode 100644 index d79bc33..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/TaskSource.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System.Threading.Tasks; -#if !PLAT_SAFE_CONTINUATIONS -using System; -using System.Diagnostics; -using System.Reflection; -using System.Reflection.Emit; -#endif - -namespace StackExchange.Redis -{ - /// - /// We want to prevent callers hijacking the reader thread; this is a bit nasty, but works; - /// see http://stackoverflow.com/a/22588431/23354 for more information; a huge - /// thanks to Eli Arbel for spotting this (even though it is pure evil; it is *my kind of evil*) - /// -#if DEBUG - public // for the unit tests in TaskTests.cs -#endif - static class TaskSource - { -#if !PLAT_SAFE_CONTINUATIONS - // on .NET < 4.6, it was possible to have threads hijacked; this is no longer a problem in 4.6 and core-clr 5, - // thanks to the new TaskCreationOptions.RunContinuationsAsynchronously, however we still need to be a little - // "test and react", as we could be targeting 4.5 but running on a 4.6 machine, in which case *it can still - // work the magic* (thanks to over-the-top install) - - /// - /// Indicates whether the specified task will not hijack threads when results are set - /// - public static readonly Func IsSyncSafe; - static TaskSource() - { - try - { - Type taskType = typeof(Task); - FieldInfo continuationField = taskType.GetField("m_continuationObject", BindingFlags.Instance | BindingFlags.NonPublic); - Type safeScenario = taskType.GetNestedType("SetOnInvokeMres", BindingFlags.NonPublic); - if (continuationField != null && continuationField.FieldType == typeof(object) && safeScenario != null) - { - var method = new DynamicMethod("IsSyncSafe", typeof(bool), new[] { typeof(Task) }, typeof(Task), true); - var il = method.GetILGenerator(); - //var hasContinuation = il.DefineLabel(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, continuationField); - Label nonNull = il.DefineLabel(), goodReturn = il.DefineLabel(); - // check if null - il.Emit(OpCodes.Brtrue_S, nonNull); - il.MarkLabel(goodReturn); - il.Emit(OpCodes.Ldc_I4_1); - il.Emit(OpCodes.Ret); - - // check if is a SetOnInvokeMres - if so, we're OK - il.MarkLabel(nonNull); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, continuationField); - il.Emit(OpCodes.Isinst, safeScenario); - il.Emit(OpCodes.Brtrue_S, goodReturn); - - il.Emit(OpCodes.Ldc_I4_0); - il.Emit(OpCodes.Ret); - - IsSyncSafe = (Func)method.CreateDelegate(typeof(Func)); - - // and test them (check for an exception etc) - var tcs = new TaskCompletionSource(); - bool expectTrue = IsSyncSafe(tcs.Task); - tcs.Task.ContinueWith(delegate { }); - bool expectFalse = IsSyncSafe(tcs.Task); - tcs.SetResult(0); - if (!expectTrue || expectFalse) - { - // revert to not trusting /them - IsSyncSafe = null; - } - } - } - catch (Exception) - { - IsSyncSafe = null; - } - if (IsSyncSafe == null) - IsSyncSafe = t => false; // assume: not - } -#endif - /// - /// Create a new TaskCompletion source - /// - public static TaskCompletionSource Create(object asyncState) - { -#if PLAT_SAFE_CONTINUATIONS - return new TaskCompletionSource(asyncState, TaskCreationOptions.RunContinuationsAsynchronously); -#else - return new TaskCompletionSource(asyncState, TaskCreationOptions.None); -#endif - } - - /// - /// Create a new TaskCompletionSource that will not allow result-setting threads to be hijacked - /// - public static TaskCompletionSource CreateDenyExecSync(object asyncState) - { - var source = new TaskCompletionSource(asyncState); - //DenyExecSync(source.Task); - return source; - } - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/When.cs b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/When.cs deleted file mode 100644 index d72deba..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/StackExchange/Redis/When.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace StackExchange.Redis -{ - /// - /// Indicates when this operation should be performed (only some variations are legal in a given context) - /// - public enum When - { - /// - /// The operation should occur whether or not there is an existing value - /// - Always, - /// - /// The operation should only occur when there is an existing value - /// - Exists, - /// - /// The operation should only occur when there is not an existing value - /// - NotExists - } -} diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/build.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/build.cmd deleted file mode 100644 index 7b53987..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StackExchange.Redis/build.cmd +++ /dev/null @@ -1 +0,0 @@ -dotnet msbuild "/t:Restore;Build;Pack" "/p:NuGetBuildTasksPackTargets='000'" "/p:PackageOutputPath=nupkgs" "/p:Configuration=Release" diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StrongName.ps1 b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StrongName.ps1 deleted file mode 100644 index 0def881..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/StrongName.ps1 +++ /dev/null @@ -1,3 +0,0 @@ -$key = Import-StrongNameKeyPair -KeyFile StackExchange.Redis.snk -dir StackExchange.Redis*/bin/Release/StackExchange.Redis.dll | Set-StrongName -KeyPair $key -Verbose -NoBackup -Force -nuget pack StackExchange.Redis.StrongName.nuspec \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/System.IO.dll b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/System.IO.dll new file mode 100644 index 0000000000000000000000000000000000000000..26cd551c3fcf93e045784b5091f9dfd5442bab3a GIT binary patch literal 21144 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 literal 0 HcmV?d00001 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/System.Threading.Tasks.dll b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/System.Threading.Tasks.dll new file mode 100644 index 0000000000000000000000000000000000000000..a60ab265715dca3e129eaf80adcca908b900ddc7 GIT binary patch literal 35016 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 literal 0 HcmV?d00001 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/build.msbuild b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/build.msbuild deleted file mode 100644 index 3f1eeb5..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/build.msbuild +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Basics.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Basics.md deleted file mode 100644 index 4ffe7d1..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Basics.md +++ /dev/null @@ -1,153 +0,0 @@ -Basic Usage -=== - -The central object in StackExchange.Redis is the `ConnectionMultiplexer` class in the `StackExchange.Redis` namespace; this is the object that hides away the details of multiple servers. Because the `ConnectionMultiplexer` does a lot, it is designed to be **shared and reused** between callers. You should not create a `ConnectionMultiplexer` per operation. It is fully thread-safe and ready for this usage. In all the subsequent examples it will be assumed that you have a `ConnectionMultiplexer` instance stored away for re-use. But for now, let's create one. This is done using `ConnectionMultiplexer.Connect` or `ConnectionMultiplexer.ConnectAsync`, passing in either a configuration string or a `ConfigurationOptions` object. The configuration string can take the form of a comma-delimited series of nodes, so let's just connect to an instance on the local machine on the default port (6379): - -```C# -using StackExchange.Redis; -... -ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); -// ^^^ store and re-use this!!! -``` - -Note that `ConnectionMultiplexer` implements `IDisposable` and can be disposed when no longer required. This is deliberately not showing `using` statement usage, because it is exceptionally rare that you would want to use a `ConnectionMultiplexer` briefly, as the idea is to re-use this object. - -A more complicated scenario might involve a master/slave setup; for this usage, simply specify all the desired nodes that make up that logical redis tier (it will automatically identify the master): - -```C# -ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("server1:6379,server2:6379"); -``` - -If it finds both nodes are masters, a tie-breaker key can optionally be specified that can be used to resolve the issue, however such a condition is fortunately very rare. - -Once you have a `ConnectionMultiplexer`, there are 3 main things you might want to do: - -- access a redis database (note that in the case of a cluster, a single logical database may be spread over multiple nodes) -- make use of the [pub/sub](http://redis.io/topics/pubsub) features of redis -- access an individual server for maintenance / monitoring purposes - -Using a redis database ---- - -Accessing a redis database is as simple as: - -```C# -IDatabase db = redis.GetDatabase(); -``` - -The object returned from `GetDatabase` is a cheap pass-thru object, and does not need to be stored. Note that redis supports multiple databases (although this is not supported on "cluster"); this can be optionally specified in the call to `GetDatabase`. Additionally, if you plan to make use of the asynchronous API and you require the [`Task.AsyncState`][2] to have a value, this can also be specified: - -```C# -int databaseNumber = ... -object asyncState = ... -IDatabase db = redis.GetDatabase(databaseNumber, asyncState); -``` - -Once you have the `IDatabase`, it is simply a case of using the [redis API](http://redis.io/commands). Note that all methods have both synchronous and asynchronous implementations. In line with Microsoft's naming guidance, the asynchronous methods all end `...Async(...)`, and are fully `await`-able etc. - -The simplest operation would be to store and retrieve a value: - -```C# -string value = "abcdefg"; -db.StringSet("mykey", value); -... -string value = db.StringGet("mykey"); -Console.WriteLine(value); // writes: "abcdefg" -``` - -Note that the `String...` prefix here denotes the [String redis type](http://redis.io/topics/data-types), and is largely separate to the [.NET String type][3], although both can store text data. However, redis allows raw binary data for both keys and values - the usage is identical: - -```C# -byte[] key = ..., value = ...; -db.StringSet(key, value); -... -byte[] value = db.StringGet(key); -``` - -The entire range of [redis database commands](http://redis.io/commands) covering all redis data types is available for use. - -Using redis pub/sub ----- - -Another common use of redis is as a [pub/sub message](http://redis.io/topics/pubsub) distribution tool; this is also simple, and in the event of connection failure, the `ConnectionMultiplexer` will handle all the details of re-subscribing to the requested channels. - -```C# -ISubscriber sub = redis.GetSubscriber(); -``` - -Again, the object returned from `GetSubscriber` is a cheap pass-thru object that does not need to be stored. The pub/sub API has no concept of databases, but as before we can optionally provide an async-state. Note that all subscriptions are global: they are not scoped to the lifetime of the `ISubscriber` instance. The pub/sub features in redis use named "channels"; channels do not need to be defined in advance on the server (an interesting use here is things like per-user notification channels, which is what drives parts of the realtime updates on [Stack Overflow](http://stackoverflow.com)). As is common in .NET, subscriptions take the form of callback delegates which accept the channel-name and the message: - -```C# -sub.Subscribe("messages", (channel, message) => { - Console.WriteLine((string)message); -}); -``` - -Separately (and often in a separate process on a separate machine) you can publish to this channel: - -```C# -sub.Publish("messages", "hello"); -``` - -This will (virtually instantaneously) write `"hello"` to the console of the subscribed process. As before, both channel-names and messages can be binary. - -Please also see [Pub / Sub Message Order](PubSubOrder) for guidance on sequential versus concurrent message processing. - -Accessing individual servers ---- - -For maintenance purposes, it is sometimes necessary to issue server-specific commands: - -```C# -IServer server = redis.GetServer("localhost", 6379); -``` - -The `GetServer` method will accept an [`EndPoint`](http://msdn.microsoft.com/en-us/library/system.net.endpoint(v=vs.110).aspx) or the name/value pair that uniquely identify the server. As before, the object returned from `GetServer` is a cheap pass-thru object that does not need to be stored, and async-state can be optionally specified. Note that the set of available endpoints is also available: - -```C# -EndPoint[] endpoints = redis.GetEndPoints(); -``` - -From the `IServer` instance, the [Server commands](http://redis.io/commands#server) are available; for example: - -```C# -DateTime lastSave = server.LastSave(); -ClientInfo[] clients = server.ClientList(); -``` - -Sync vs Async vs Fire-and-Forget ---- - -There are 3 primary usage mechanisms with StackExchange.Redis: - -- Synchronous - where the operation completes before the methods returns to the caller (note that while this may block the caller, it absolutely **does not** block other threads: the key idea in StackExchange.Redis is that it aggressively shares the connection between concurrent callers) -- Asynchronous - where the operation completes some time in the future, and a `Task` or `Task` is returned immediately, which can later: - - be `.Wait()`ed (blocking the current thread until the response is available) - - have a continuation callback added ([`ContinueWith`](http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.continuewith(v=vs.110).aspx) in the TPL) - - be *awaited* (which is a language-level feature that simplifies the latter, while also continuing immediately if the reply is already known) -- Fire-and-Forget - where you really aren't interested in the reply, and are happy to continue irrespective of the response - -The synchronous usage is already shown in the examples above. This is the simplest usage, and does not involve the [TPL][1]. - -For asynchronous usage, the key difference is the `Async` suffix on methods, and (typically) the use of the `await` language feature. For example: - -```C# -string value = "abcdefg"; -await db.StringSetAsync("mykey", value); -... -string value = await db.StringGetAsync("mykey"); -Console.WriteLine(value); // writes: "abcdefg" -``` - -The fire-and-forget usage is accessed by the optional `CommandFlags flags` parameter on all methods (defaults to none). In this usage, the method returns the default value immediately (so a method that normally returns a `String` will always return `null`, and a method that normally returns an `Int64` will always return `0`). The operation will continue in the background. A typical use-case of this might be to increment page-view counts: - -```C# -db.StringIncrement(pageKey, flags: CommandFlags.FireAndForget); -``` - - - - - [1]: http://msdn.microsoft.com/en-us/library/dd460717%28v=vs.110%29.aspx - [2]: http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.asyncstate(v=vs.110).aspx - [3]: http://msdn.microsoft.com/en-us/library/system.string(v=vs.110).aspx diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Configuration.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Configuration.md deleted file mode 100644 index 5c9c0fd..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Configuration.md +++ /dev/null @@ -1,195 +0,0 @@ -Configuration -=== - -Because there are lots of different ways to configure redis, StackExchange.Redis offers a rich configuration model, which is invoked when calling `Connect` (or `ConnectAsync`): - -```C# -var conn = ConnectionMultiplexer.Connect(configuration); -``` - -The `configuration` here can be either: - -- a `ConfigurationOptions` instance -- a `string` representing the configuration - -The latter is *basically* a tokenized form of the former. - -Basic Configuration Strings -- - -The *simplest* configuration example is just the host name: - -```C# -var conn = ConnectionMultiplexer.Connect("localhost"); -``` - -This will connect to a single server on the local machine using the default redis port (6379). Additional options are simply appended (comma-delimited). Ports are represented with a colon (`:`) as is usual. Configuration *options* include an `=` after the name. For example: - -```C# -var conn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,allowAdmin=true"); -``` - -An overview of mapping between the `string` and `ConfigurationOptions` representation is shown below, but you can switch between them trivially: - -```C# -ConfigurationOptions options = ConfigurationOptions.Parse(configString); -``` - -or: - -```C# -string configString = options.ToString(); -``` - -A common usage is to store the *basic* details in a string, and then apply specific details at runtime: - -```C# -string configString = GetRedisConfiguration(); -var options = ConfigurationOptions.Parse(configString); -options.ClientName = GetAppName(); // only known at runtime -options.AllowAdmin = true; -conn = ConnectionMultiplexer.Connect(options); -``` - -Microsoft Azure Redis example with password - -```C# -var conn = ConnectionMultiplexer.Connect("contoso5.redis.cache.windows.net,ssl=true,password=..."); -``` - -Configuration Options ---- - -The `ConfigurationOptions` object has a wide range of properties, all of which are fully documented in intellisense. Some of the more common options to use include: - -| Configuration string | `ConfigurationOptions` | Default | Meaning | -| ---------------------- | ---------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------- | -| abortConnect={bool} | `AbortOnConnectFail` | `true` (`false` on Azure) | If true, `Connect` will not create a connection while no servers are available | -| allowAdmin={bool} | `AllowAdmin` | `false` | Enables a range of commands that are considered risky | -| channelPrefix={string} | `ChannelPrefix` | `null` | Optional channel prefix for all pub/sub operations | -| connectRetry={int} | `ConnectRetry` | `3` | The number of times to repeat connect attempts during initial `Connect` | -| connectTimeout={int} | `ConnectTimeout` | `5000` | Timeout (ms) for connect operations | -| configChannel={string} | `ConfigurationChannel` | `__Booksleeve_MasterChanged` | Broadcast channel name for communicating configuration changes | -| defaultDatabase={int} | `DefaultDatabase` | `null` | Default database index, from `0` to `databases - 1` | -| keepAlive={int} | `KeepAlive` | `-1` | Time (seconds) at which to send a message to help keep sockets alive | -| name={string} | `ClientName` | `null` | Identification for the connection within redis | -| password={string} | `Password` | `null` | Password for the redis server | -| proxy={proxy type} | `Proxy` | `Proxy.None` | Type of proxy in use (if any); for example "twemproxy" | -| resolveDns={bool} | `ResolveDns` | `false` | Specifies that DNS resolution should be explicit and eager, rather than implicit | -| serviceName={string} | `ServiceName` | `null` | Not currently implemented (intended for use with sentinel) | -| ssl={bool} | `Ssl` | `false` | Specifies that SSL encryption should be used | -| sslHost={string} | `SslHost` | `null` | Enforces a particular SSL host identity on the server's certificate | -| sslProtocols={enum} | `SslProtocols` | `null` | Ssl/Tls versions supported when using an encrypted connection. Use '\|' to provide multiple values. | -| syncTimeout={int} | `SyncTimeout` | `1000` | Time (ms) to allow for synchronous operations | -| tiebreaker={string} | `TieBreaker` | `__Booksleeve_TieBreak` | Key to use for selecting a server in an ambiguous master scenario | -| version={string} | `DefaultVersion` | (`3.0` in Azure, else `2.0`) | Redis version level (useful when the server does not make this available) | -| writeBuffer={int} | `WriteBuffer` | `4096` | Size of the output buffer | - -Additional code-only options: -- ReconnectRetryPolicy (`IReconnectRetryPolicy`) - Default: `ReconnectRetryPolicy = LinearRetry(ConnectTimeout);` - -Tokens in the configuration string are comma-separated; any without an `=` sign are assumed to be redis server endpoints. Endpoints without an explicit port will use 6379 if ssl is not enabled, and 6380 if ssl is enabled. -Tokens starting with `$` are taken to represent command maps, for example: `$config=cfg`. - -Automatic and Manual Configuration ---- - -In many common scenarios, StackExchange.Redis will automatically configure a lot of settings, including the server type and version, connection timeouts, and master/slave relationships. Sometimes, though, the commands for this have been disabled on the redis server. In this case, it is useful to provide more information: - -```C# -ConfigurationOptions config = new ConfigurationOptions -{ - EndPoints = - { - { "redis0", 6379 }, - { "redis1", 6380 } - }, - CommandMap = CommandMap.Create(new HashSet - { // EXCLUDE a few commands - "INFO", "CONFIG", "CLUSTER", - "PING", "ECHO", "CLIENT" - }, available: false), - KeepAlive = 180, - DefaultVersion = new Version(2, 8, 8), - Password = "changeme" -}; -``` - -Which is equivalent to the command string: - -```config -redis0:6379,redis1:6380,keepAlive=180,version=2.8.8,$CLIENT=,$CLUSTER=,$CONFIG=,$ECHO=,$INFO=,$PING= -``` -Renaming Commands ---- - -A slightly unusual feature of redis is that you can disable and/or rename individual commands. As per the previous example, this is done via the `CommandMap`, but instead of passing a `HashSet` to `Create()` (to indicate the available or unavailable commands), you pass a `Dictionary`. All commands not mentioned in the dictionary are assumed to be enabled and not renamed. A `null` or blank value records that the command is disabled. For example: - -```C# -var commands = new Dictionary { - { "info", null }, // disabled - { "select", "use" }, // renamed to SQL equivalent for some reason -}; -var options = new ConfigurationOptions { - // ... - CommandMap = CommandMap.Create(commands), - // ... -} -``` - -The above is equivalent to (in the connection string): - -```config -$INFO=,$SELECT=use -``` - -Twemproxy ---- - -[Twemproxy](https://github.com/twitter/twemproxy) is a tool that allows multiple redis instances to be used as though it were a single server, with inbuilt sharding and fault tolerance (much like redis cluster, but implemented separately). The feature-set available to Twemproxy is reduced. To avoid having to configure this manually, the `Proxy` option can be used: - -```C# -var options = new ConfigurationOptions -{ - EndPoints = { "my-server" }, - Proxy = Proxy.Twemproxy -}; -``` - -Tiebreakers and Configuration Change Announcements ---- - -Normally StackExchange.Redis will resolve master/slave nodes automatically. However, if you are not using a management tool such as redis-sentinel or redis cluster, there is a chance that occasionally you will get multiple master nodes (for example, while resetting a node for maintenance it may reappear on the network as a master). To help with this, StackExchange.Redis can use the notion of a *tie-breaker* - which is only used when multiple masters are detected (not including redis cluster, where multiple masters are *expected*). For compatibility with BookSleeve, this defaults to the key named `"__Booksleeve_TieBreak"` (always in database 0). This is used as a crude voting mechanism to help determine the *preferred* master, so that work is routed correctly. - -Likewise, when the configuration is changed (especially the master/slave configuration), it will be important for connected instances to make themselves aware of the new situation (via `INFO`, `CONFIG`, etc - where available). StackExchange.Redis does this by automatically subscribing to a pub/sub channel upon which such notifications may be sent. For similar reasons, this defaults to `"__Booksleeve_MasterChanged"`. - -Both options can be customized or disabled (set to `""`), via the `.ConfigurationChannel` and `.TieBreaker` configuration properties. - -These settings are also used by the `IServer.MakeMaster()` method, which can set the tie-breaker in the database and broadcast the configuration change message. The configuration message can also be used separately to master/slave changes simply to request all nodes to refresh their configurations, via the `ConnectionMultiplexer.PublishReconfigure` method. - -ReconnectRetryPolicy ---- -StackExchange.Redis automatically tries to reconnect in the background when the connection is lost for any reason. It keeps retrying until the connection has been restored. It would use ReconnectRetryPolicy to decide how long it should wait between the retries. -ReconnectRetryPolicy can be linear (default), exponential or a custom retry policy. - - -Examples: -```C# -config.ReconnectRetryPolicy = new ExponentialRetry(5000); // defaults maxDeltaBackoff to 10000 ms -//retry# retry to re-connect after time in milliseconds -//1 a random value between 5000 and 5500 -//2 a random value between 5000 and 6050 -//3 a random value between 5000 and 6655 -//4 a random value between 5000 and 8053 -//5 a random value between 5000 and 10000, since maxDeltaBackoff was 10000 ms -//6 a random value between 5000 and 10000 - -config.ReconnectRetryPolicy = new LinearRetry(5000); -//retry# retry to re-connect after time in milliseconds -//1 5000 -//2 5000 -//3 5000 -//4 5000 -//5 5000 -//6 5000 -``` diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Events.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Events.md deleted file mode 100644 index 57c2026..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Events.md +++ /dev/null @@ -1,14 +0,0 @@ -Events -=== - -The `ConnectionMultiplexer` type exposes multiple events that can be used to understand what is happening under the covers. This can be useful in particular for logging purposes. - -- `ConfigurationChanged` - raised when the configuration of a connection is changed from inside the `ConnectionMultiplexer` -- `ConfigurationChangedBroadcast` - raised when a reconfiguration message is received via pub/sub; this is most commonly caused by `IServer.MakeMaster` being used to change a node's replication configuration, which can optionally broadcast such a request to all clients -- `ConnectionFailed` - raised when a connection fails for any reason; note that you will not receive further `ConnectionFailed` notifications for that connection until connectivity has been re-established -- `ConnectionRestored` - raised when connectivity is re-established to a node that previously failed -- `ErrorMessage` - raised when the redis server responds to any user-initiated request with an error message; this is in addition to the regular exception / fault that will be reported to the immediate caller -- `HashSlotMoved` - raised when a "redis cluster" indicates that a hash-slot has been migrated between nodes; note that requests will normally be automatically re-routed, so the user is not required to do anything special here -- `InternalError` - raised when the library fails in some unanticipated way; this is intended primarily for debugging purposes, and most users should have no need of this event - -Note that the pub/sub implementation in StackExchange.Redis works *similarly* to events, with `Subscribe` / `SubscribeAsync` accepting an `Action` callback that is invoked when messages are received. \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/ExecSync.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/ExecSync.md deleted file mode 100644 index 2b3409f..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/ExecSync.md +++ /dev/null @@ -1,5 +0,0 @@ -The Dangers of Synchronous Continuations -=== - -Once, there was more content here; then [a suitably evil workaround was found](http://stackoverflow.com/a/22588431/23354). This page is not -listed in the index, but remains for your curiosity. \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/KeysScan.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/KeysScan.md deleted file mode 100644 index d0af03a..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/KeysScan.md +++ /dev/null @@ -1,61 +0,0 @@ -Where are `KEYS`, `SCAN`, `FLUSHDB` etc? -=== - -Some very common recurring questions are: - -> There doesn't seem to be a `Keys(...)` or `Scan(...)` method? How can I query which keys exist in the database? - -or - -> There doesn't seem to be a `Flush(...)` method? How can I remove all the keys in the database? - -The key word here, oddly enough, is the last one: database. Because StackExchange.Redis aims to target scenarios such as cluster, it is important to know which commands target the *database* (the logical database that could be distributed over multiple nodes), and which commands target the *server*. The following commands all target a single server: - -- `KEYS` / `SCAN` -- `FLUSHDB` / `FLUSHALL` -- `RANDOMKEY` -- `CLIENT` -- `CLUSTER` -- `CONFIG` / `INFO` / `TIME` -- `SLAVEOF` -- `SAVE` / `BGSAVE` / `LASTSAVE` -- `SCRIPT` (not to be confused with `EVAL` / `EVALSHA`) -- `SHUTDOWN` -- `SLOWLOG` -- `PUBSUB` (not to be confused with `PUBLISH` / `SUBSCRIBE` / etc) -- some `DEBUG` operations - -(I've probably missed at least one) Most of these will seem pretty obvious, but the first 3 rows are not so obvious: - -- `KEYS` / `SCAN` only list keys that are on the current server; not the wider logical database -- `FLUSHDB` / `FLUSHALL` only remove keys that are on the current server; not the wider logical database -- `RANDOMKEY` only selects a key that is on the current server; not the wider logical database - -Actually, StackExchange.Redis spoofs the `RANDOMKEY` one on the `IDatabase` API by simply selecting a target server at random, but this is not possible for the others. - -So how do I use them? ---- - -Simple: start from a server, not a database. - -```C# -// get the target server -var server = conn.GetServer(someServer); - -// show all keys in database 0 that include "foo" in their name -foreach(var key in server.Keys(pattern: "*foo*")) { - Console.WriteLine(key); -} - -// completely wipe ALL keys from database 0 -server.FlushDatabase(); -``` - -Note that unlike the `IDatabase` API (where the target database has already been selected in the `GetDatabase()` call), these methods take an optional parameter for the database, or it defaults to `0`. - -The `Keys(...)` method deserves special mention: it is unusual in that it does not have an `*Async` counterpart. The reason for this is that behind the scenes, the system will determine the most appropriate method to use (`KEYS` vs `SCAN`, based on the server version), and if possible will use the `SCAN` approach to hand you back an `IEnumerable` that does all the paging internally - so you never need to see the implementation details of the cursor operations. If `SCAN` is not available, it will use `KEYS`, which can cause blockages at the server. Either way, both `SCAN` and `KEYS` will need to sweep the entire keyspace, so should be avoided on production servers - or at least, targeted at slaves. - -So I need to remember which server I connected to? That sucks! ---- - -No, not quite. You can use `conn.GetEndPoints()` to list the endpoints (either all known, or the ones specified in the original configuration - these are not necessarily the same thing), and iterate with `GetServer()` to find the server you want (for example, selecting a slave). diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/KeysValues.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/KeysValues.md deleted file mode 100644 index 36e5357..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/KeysValues.md +++ /dev/null @@ -1,116 +0,0 @@ -Keys, Values and Channels -=== - -In dealing with redis, there is quite an important distinction between *keys* and *everything else*. A key is the unique name of a piece of data (which could be a String, a List, Hash, or any of the other [redis data types](http://redis.io/topics/data-types)) within a database. Keys are never interpreted as... well, anything: they are simply inert names. Further - when dealing with clustered or sharded systems, it is the key that defines the node (or nodes if there are slaves) that contain this data - so keys are crucial for routing commands. - -This contrasts with *values*; values are the *things that you store* against keys - either individually (for String data) or as groups. Values do not affect command routing (caveat: except for [the `SORT` command](http://redis.io/commands/sort) when `BY` or `GET` is specified, but that is *really* complicated to explain). Likewise, values are often *interpreted* by redis for the purposes of an operation: - -- `incr` (and the various similar commands) interpret String values as numeric data -- sorting can interpret values using either numeric or unicode rules -- and many others - -The key point is that the API needs to understand what is a key and what is a value. This is reflected in the StackExchange.Redis API, but the good news is that **most of the time** you don't need to know about this at all. - -When using pub/sub, we are dealing with *channels*; channels do not affect routing (so they are not keys), but are quite distinct from regular values, so are considered separately. - -Keys ---- - -StackExchange.Redis represents keys by the `RedisKey` type. The good news, though, is that this has implicit conversions to and from both `string` and `byte[]`, allowing both text and binary keys to be used without any complication. For example, the `StringIncrement` method takes a `RedisKey` as the first parameter, but *you don't need to know that*; for example: - -```C# -string key = ... -db.StringIncrement(key); -``` - -or - -```C# -byte[] key = ... -db.StringIncrement(key); -``` - -Likewise, there are operations that *return* keys as `RedisKey` - and again, it simply works: - -```C# -string someKey = db.KeyRandom(); -``` - -Values ---- - -StackExchange.Redis represents values by the `RedisValue` type. As with `RedisKey`, there are implicit conversions in place which mean that most of the time you never see this type, for example: - -```C# -db.StringSet("mykey", "myvalue"); -``` - -However, in addition to text and binary contents, values can also need to represent typed primitive data - most commonly (in .NET terms) `Int32`, `Int64`, `Double` or `Boolean`. Because of this, `RedisValue` provides a lot more conversion support than `RedisKey`: - -```C# -db.StringSet("mykey", 123); // this is still a RedisKey and RedisValue -... -int i = (int)db.StringGet("mykey"); -``` - -Note that while the conversions from primitives to `RedisValue` are implicit, many of the conversions from `RedisValue` to primitives are explicit: this is because it is very possible that these conversions will fail if the data does not have an appropriate value. - -Note additionally that *when treated numerically*, redis treats a non-existent key as zero; for consistency with this, nil responses are treated as zero: - -```C# -db.KeyDelete("abc"); -int i = (int)db.StringGet("abc"); // this is ZERO -``` - -If you need to detect the nil condition, then you can check for that: - -```C# -db.KeyDelete("abc"); -var value = db.StringGet("abc"); -bool isNil = value.IsNull; // this is true -``` - -or perhaps more simply, just use the provided `Nullable` support: - -```C# -db.KeyDelete("abc"); -var value = (int?)db.StringGet("abc"); // behaves as you would expect -``` - -Hashes ---- - -Since the field names in hashes do not affect command routing, they are not keys, but can take both text and binary names; thus they are treated as values for the purposes of the API. - -Channels ---- - -Channel names for pub/sub are represented by the `RedisChannel` type; this is largely identical to `RedisKey`, but is handled independently since while channel-names are rightly first-class elements, they do not affect command routing. - -Scripting ---- - -[Lua scripting in redis](http://redis.io/commands/EVAL) has two notable features: - -- the inputs must keep keys and values separate (which inside the script become `KEYS` and `ARGV`, respectively) -- the return format is not defined in advance: it is specific to your script - -Because of this, the `ScriptEvaluate` method accepts two separate input arrays: one `RedisKey[]` for the keys, one `RedisValue[]` for the values (both are optional, and are assumed to be empty if omitted). This is probably one of the few times that you'll actually need to type `RedisKey` or `RedisValue` in your code, and that is just because of array variance rules: - -```C# -var result = db.ScriptEvaluate(TransferScript, - new RedisKey[] { from, to }, new RedisValue[] { quantity }); -``` - -(where `TransferScript` is some `string` containing Lua, not shown for this example) - -The response uses the `RedisResult` type (this is unique to scripting; usually the API tries to represent the response as directly and clearly as possible). As before, `RedisResult` offers a range of conversion operations - more, in fact than `RedisValue`, because in addition to being interpreted as text, binary, primitives and nullable-primitives, the response can *also* be interpreted as *arrays* of such, for example: - -```C# -string[] items = db.ScriptEvaluate(...); -``` - -Conclusion ---- - -The types used in the API are very deliberately chosen to distinguish redis *keys* from *values*. However, in virtually all cases you will not need to directly refer to the underlying types involved, as conversion operations are provided. diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/PipelinesMultiplexers.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/PipelinesMultiplexers.md deleted file mode 100644 index be4662c..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/PipelinesMultiplexers.md +++ /dev/null @@ -1,110 +0,0 @@ -Pipelines and Multiplexers -=== - -Latency sucks. Modern computers can churn data at an alarming rate, and high speed networking (often with multiple parallel links between important servers) provides enormous bandwidth, but... that damned latency means that computers spend an awful lot of time *waiting for data* and that is one of the several reasons that continuation-based programming is becoming increasingly popular. Let's consider some regular procedural code: - -```C# -string a = db.StringGet("a"); -string b = db.StringGet("b"); -``` - -In terms of steps involved, this looks like: - - [req1] # client: the client library constructs request 1 - [c=>s] # network: request one is sent to the server - [server] # server: the server processes request 1 - [s=>c] # network: response one is sent back to the client - [resp1] # client: the client library parses response 1 - [req2] - [c=>s] - [server] - [s=>c] - [resp2] - -Now let's highlight *just the bits where the client is doing something*: - - [req1] - [====waiting=====] - [resp1] - [req2] - [====waiting=====] - [resp2] - -And keep in mind that this is **not to scale** - if this was scaled by time, it would be *utterly dominated* by `waiting`. - -Pipelining ---- - -Because of this, many redis clients allow you to make use of *pipelining*; this is the process of sending multiple messages down the pipe without waiting on the reply from each - and (typically) processing the replies later when they come in. In .NET, the idea of an operation that can be initiated but is not yet complete, and which may complete or fault later is encapsulated by the [TPL][1] via the [`Task`][2] / [`Task`][3] APIs. Essentially, a `Task` represents a "future possible value of type `T`" (a non-generic `Task` is essentially a `Task`). You can then either: - -- at a later point block (`.Wait()`) until the operation has completed -- schedule a *continuation* (`.ContinueWith(...)` or `await`) to occur when the operation has completed - -For example, to pipeline the two gets using procedural (blocking) code, we could use: - -```C# -var aPending = db.StringGetAsync("a"); -var bPending = db.StringGetAsync("b"); -var a = db.Wait(aPending); -var b = db.Wait(bPending); -``` - -Note that I'm using `db.Wait` here because it will automatically apply the configured synchronous timeout, but you can use `aPending.Wait()` or `Task.WaitAll(aPending, bPending);` if you prefer. Using pipelining allows us to get both requests onto the network immediately, eliminating most of the latency. Additionally, it also helps reduce packet fragmentation: 20 requests sent individually (waiting for each response) will require at least 20 packets, but 20 requests sent in a pipeline could fit into much fewer packets (perhaps even just one). - -Fire and Forget ---- - -A special-case of pipelining is when we expressly don't care about the response from a particular operation, which allows our code to continue immediately while the enqueued operation proceeds in the background. Often, this means that we can put concurrent work on the connection from a single caller. This is achieved using the `flags` parameter: - -```C# -// sliding expiration -db.KeyExpire(key, TimeSpan.FromMinutes(5), flags: CommandFlags.FireAndForget); -var value = (string)db.StringGet(key); -``` - -The `FireAndForget` flag causes the client library to queue the work as normal, but immediately return a default value (since `KeyExpire` returns a `bool`, this will return `false`, because `default(bool)` is `false` - however the return value is meaningless and should be ignored). This works for `*Async` methods too: an already-completed `Task` is returned with the default value (or an already-completed `Task` is returned for `void` methods). - -Multiplexing ---- - -Pipelining is all well and good, but often any single block of code only wants a single value (or maybe wants to perform a few operations, but which depend on each-other). This means that we still have the problem that we spend most of our time waiting for data to transfer between client and server. Now consider a busy application, perhaps a web-server. Such applications are generally inherently concurrent, so if you have 20 parallel application requests all requiring data, you might think of spinning up 20 connections, or you could synchronize access to a single connection (which would mean the last caller would need to wait for the latency of all the other 19 before it even got started). Or as a compromise, perhaps a pool of 5 connections which are leased - no matter how you are doing it, there is going to be a lot of waiting. **StackExchange.Redis does not do this**; instead, it does a *lot* of work for you to make effective use of all this idle time by *multiplexing* a single connection. When used concurrently by different callers, it **automatically pipelines the separate requests**, so regardless of whether the requests use blocking or asynchronous access, the work is all pipelined. So we could have 10 or 20 of our "get a and b" scenario from earlier (from different application requests), and they would all get onto the connection as soon as possible. Essentially, it fills the `waiting` time with work from other callers. - -For this reason, the only redis features that StackExchange.Redis does not offer (and *will not ever offer*) are the "blocking pops" ([BLPOP](http://redis.io/commands/blpop), [BRPOP](http://redis.io/commands/brpop) and [BRPOPLPUSH](http://redis.io/commands/brpoplpush)) - because this would allow a single caller to stall the entire multiplexer, blocking all other callers. The only other time that StackExchange.Redis needs to hold work is when verifying pre-conditions for a transaction, which is why StackExchange.Redis encapsulates such conditions into internally managed `Condition` instances. [Read more about transactions here](Transactions). If you feel you want "blocking pops", then I strongly suggest you consider pub/sub instead: - -```C# -sub.Subscribe(channel, delegate { - string work = db.ListRightPop(key); - if (work != null) Process(work); -}); -//... -db.ListLeftPush(key, newWork, flags: CommandFlags.FireAndForget); -sub.Publish(channel, ""); -``` - -This achieves the same intent without requiring blocking operations. Notes: - -- the *data* is not sent via pub/sub; the pub/sub API is only used to notify workers to check for more work -- if there are no workers, the new items remain buffered in the list; work does not fall on the floor -- only one worker can pop a single value; when there are more consumers than producers, some consumers will be notified and then find there is nothing to do -- when you restart a worker, you should *assume* there is work so that you process any backlog -- but other than that, the semantic is identical to blocking pops - -The multiplexed nature of StackExchange.Redis makes it possible to reach extremely high throughput on a single connection while using regular uncomplicated code. - -Concurrency ---- - -It should be noted that the pipeline / multiplexer / future-value approach also plays very nicely with continuation-based asynchronous code; for example you could write: - -```C# -string value = await db.StringGetAsync(key); -if (value == null) { - value = await ComputeValueFromDatabase(...); - db.StringSet(key, value, flags: CommandFlags.FireAndForget); -} -return value; -``` - - [1]: http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx - [2]: http://msdn.microsoft.com/en-us/library/system.threading.tasks.task(v=vs.110).aspx - [3]: http://msdn.microsoft.com/en-us/library/dd321424(v=vs.110).aspx diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Profiling.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Profiling.md deleted file mode 100644 index f39c824..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Profiling.md +++ /dev/null @@ -1,208 +0,0 @@ -Profiling -=== - -StackExchange.Redis exposes a handful of methods and types to enable performance profiling. Due to its asynchronous and multiplexing -behavior profiling is a somewhat complicated topic. - -Interfaces ---- - -The profiling interface is composed of `IProfiler`, `ConnectionMultiplexer.RegisterProfiler(IProfiler)`, `ConnectionMultiplexer.BeginProfiling(object)`, -`ConnectionMultiplexer.FinishProfiling(object)`, and `IProfiledCommand`. - -You register a single `IProfiler` with a `ConnectionMultiplexer` instance, it cannot be changed. You begin profiling for a given context (ie. Thread, -Http Request, and so on) by calling `BeginProfiling(object)`, and finish by calling `FinishProfiling(object)`. `FinishProfiling(object)` returns -a collection of `IProfiledCommand`s which contain timing information for all commands sent to redis by the configured `ConnectionMultiplexer` between -the `(Begin|Finish)Profiling` calls with the given context. - -What "context" object should be used is application specific. - -Available Timings ---- - -StackExchange.Redis exposes information about: - - - The redis server involved - - The redis DB being queried - - The redis command run - - The flags used to route the command - - The initial creation time of a command - - How long it took to enqueue the command - - How long it took to send the command, after it was enqueued - - How long it took the response from redis to be received, after the command was sent - - How long it took for the response to be processed, after it was received - - If the command was sent in response to a cluster ASK or MOVED response - - If so, what the original command was - -`TimeSpan`s are high resolution, if supported by the runtime. `DateTime`s are only as precise as `DateTime.UtcNow`. - -Choosing Context ---- - -Due to StackExchange.Redis's asynchronous interface, profiling requires outside assistance to group related commands together. This is achieved -by providing context objects when you start and end profiling (via the `BeginProfiling(object)` & `FinishProfiling(object)` methods), and when a -command is sent (via the `IProfiler` interface's `GetContext()` method). - -A toy example of associating commands issued from many different threads together - -```C# -class ToyProfiler : IProfiler -{ - public ConcurrentDictionary Contexts = new ConcurrentDictionary(); - - public object GetContext() - { - object ctx; - if(!Contexts.TryGetValue(Thread.CurrentThread, out ctx)) ctx = null; - - return ctx; - } -} - -// ... - -ConnectionMultiplexer conn = /* initialization */; -var profiler = new ToyProfiler(); -var thisGroupContext = new object(); - -conn.RegisterProfiler(profiler); - -var threads = new List(); - -for (var i = 0; i < 16; i++) -{ - var db = conn.GetDatabase(i); - - var thread = - new Thread( - delegate() - { - var threadTasks = new List(); - - for (var j = 0; j < 1000; j++) - { - var task = db.StringSetAsync("" + j, "" + j); - threadTasks.Add(task); - } - - Task.WaitAll(threadTasks.ToArray()); - } - ); - - profiler.Contexts[thread] = thisGroupContext; - - threads.Add(thread); -} - -conn.BeginProfiling(thisGroupContext); - -threads.ForEach(thread => thread.Start()); -threads.ForEach(thread => thread.Join()); - -IEnumerable timings = conn.FinishProfiling(thisGroupContext); -``` - -At the end, `timings` will contain 16,000 `IProfiledCommand` objects - one for each command issued to redis. - -If instead you did the following: - -```C# -ConnectionMultiplexer conn = /* initialization */; -var profiler = new ToyProfiler(); - -conn.RegisterProfiler(profiler); - -var threads = new List(); - -var perThreadTimings = new ConcurrentDictionary>(); - -for (var i = 0; i < 16; i++) -{ - var db = conn.GetDatabase(i); - - var thread = - new Thread( - delegate() - { - var threadTasks = new List(); - - conn.BeginProfiling(Thread.CurrentThread); - - for (var j = 0; j < 1000; j++) - { - var task = db.StringSetAsync("" + j, "" + j); - threadTasks.Add(task); - } - - Task.WaitAll(threadTasks.ToArray()); - - perThreadTimings[Thread.CurrentThread] = conn.FinishProfiling(Thread.CurrentThread).ToList(); - } - ); - - profiler.Contexts[thread] = thread; - - threads.Add(thread); -} - -threads.ForEach(thread => thread.Start()); -threads.ForEach(thread => thread.Join()); -``` - -`perThreadTimings` would end up with 16 entries of 1,000 `IProfilingCommand`s, keyed by the `Thread` the issued them. - -Moving away from toy examples, here's how you can profile StackExchange.Redis in an MVC5 application. - -First register the following `IProfiler` against your `ConnectionMultiplexer`: - -```C# -public class RedisProfiler : IProfiler -{ - const string RequestContextKey = "RequestProfilingContext"; - - public object GetContext() - { - var ctx = HttpContext.Current; - if (ctx == null) return null; - - return ctx.Items[RequestContextKey]; - } - - public object CreateContextForCurrentRequest() - { - var ctx = HttpContext.Current; - if (ctx == null) return null; - - object ret; - ctx.Items[RequestContextKey] = ret = new object(); - - return ret; - } -} -``` - -Then, add the following to your Global.asax.cs file: - -```C# -protected void Application_BeginRequest() -{ - var ctxObj = RedisProfiler.CreateContextForCurrentRequest(); - if (ctxObj != null) - { - RedisConnection.BeginProfiling(ctxObj); - } -} - -protected void Application_EndRequest() -{ - var ctxObj = RedisProfiler.GetContext(); - if (ctxObj != null) - { - var timings = RedisConnection.FinishProfiling(ctxObj); - - // do what you will with `timings` here - } -} -``` - -This implementation will group all redis commands, including `async/await`-ed ones, with the http request that initiated them. \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/PubSubOrder.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/PubSubOrder.md deleted file mode 100644 index 26321c9..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/PubSubOrder.md +++ /dev/null @@ -1,20 +0,0 @@ -Pub/Sub Message Order -=== - -When using the pub/sub API, there is a decision to be made as to whether messages from the same connection should be processed *sequentially* vs *concurrently*. - -Processing them sequentially means that you don't need to worry (quite as much) about thread-safety, and means that you preserve the order of events - -they will be processed in exactly the same order in which they are received (via a queue) - but as a consequence it means that messages can delay each-other. - -The other option is *concurrent* processing. This makes **no specific guarantees** about the order in which work gets processed, and your code is entirely -responsible for ensuring that concurrent messages don't corrupt your internal state - but it can be significantly faster and much more scalable. -This works *particularly* well if messages are generally unrelated. - -For safety, **the default is sequential**; however, it is strongly recommended that you use concurrent processing whenever possible. This is a simple change: - -```C# -multiplexer.PreserveAsyncOrder = false; -``` - -The reason that this is not a *configuration* option is that whether it is appropriate to do this depends *entirely* on the code that is subscribing to -messages. \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/ReleaseNotes.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/ReleaseNotes.md deleted file mode 100644 index e01d2a1..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/ReleaseNotes.md +++ /dev/null @@ -1,68 +0,0 @@ -# Release Notes - -# Important: .NET 4.0 support is currently **disabled**; if you need .NET 4.0, please stick with 1.2.1 while we keep investigating - -## 1.2.6 - -- fix change to `cluster nodes` output when using cluster-enabled target and 4.0+ (see [redis #4186]https://github.com/antirez/redis/issues/4186) - -## 1.2.5 - -- critical fix: "poll mode" was disabled in the build for net45/net60 - impact: IO jams and lack of reader during high load - -## 1.2.4 - -- fix: incorrect build configuration (#649) - -## 1.2.3 - -- fix: when using `redis-cluster` with multiple replicas, use round-robin when selecting replica (#610) -- add: can specify `NoScriptCache` flag when using `ScriptEvaluate` to bypass all cache features (always uses `EVAL` instead of `SCRIPT LOAD` and `EVALSHA`) (#617) - -## 1.2.2 (preview): - -- **UNAVAILABLE**: .NET 4.0 support is not in this build, due to [a build issue](https://github.com/dotnet/cli/issues/5993) - looking into solutions -- add: make performance-counter tracking opt-in (`IncludePerformanceCountersInExceptions`) as it was causing problems (#587) -- add: can now specifiy allowed SSL/TLS protocols (#603) -- add: track message status in exceptions (#576) -- add: `GetDatabase()` optimization for DB 0 and low numbered databases: `IDatabase` instance is retained and recycled (as long as no `asyncState` is provided) -- improved connection retry policy (#510, #572) -- add `Execute`/`ExecuteAsync` API to support "modules"; [more info](http://blog.marcgravell.com/2017/04/stackexchangeredis-and-redis-40-modules.html) -- fix: timeout link fixed re /docs change (below) -- [`NRediSearch`](https://www.nuget.org/packages/NRediSearch/) added as exploration into "modules" - -Other changes (not library related) - -- (project) refactor /docs for github pages -- improve release note tracking -- rework build process to use csproj - -## 1.2.1 - -- fix: avoid overlapping per-endpoint heartbeats - -## 1.2.0 - -- (same as 1.2.0-alpha1) - -## 1.2.0-alpha1 - -- add: GEO commands (#489) -- add: ZADD support for new NX/XX switches (#520) -- add: core-clr preview support improvements - -## 1.1.608 - -- fix: bug with race condition in servers indexer (related: 1.1.606) - -## 1.1.607 - -- fix: ensure socket-mode polling is enabled (.net) - -## 1.1.606 - -- fix: bug with race condition in servers indexer - -## and the rest - -(I'm happy to take PRs for change history going back in time) \ No newline at end of file diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Scripting.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Scripting.md deleted file mode 100644 index e04b2d1..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Scripting.md +++ /dev/null @@ -1,59 +0,0 @@ -Scripting -=== - -Basic [Lua scripting](http://redis.io/commands/EVAL) is supported by the `IServer.ScriptLoad(Async)`, `IServer.ScriptExists(Async)`, `IServer.ScriptFlush(Async)`, `IDatabase.ScriptEvaluate`, and `IDatabaseAsync.ScriptEvaluateAsync` methods. -These methods expose the basic commands necessary to submit and execute Lua scripts to redis. - -More sophisticated scripting is available through the `LuaScript` class. The `LuaScript` class makes it simpler to prepare and submit parameters along with a script, as well as allowing you to use -cleaner variables names. - -An example use of the `LuaScript`: - -``` - const string Script = "redis.call('set', @key, @value)"; - - using (ConnectionMultiplexer conn = /* init code */) - { - var db = conn.GetDatabase(0); - - var prepared = LuaScript.Prepare(Script); - db.ScriptEvaluate(prepared, new { key = (RedisKey)"mykey", value = 123 }); - } -``` - -The `LuaScript` class rewrites variables in scripts of the form `@myVar` into the appropriate `ARGV[someIndex]` required by redis. If the -parameter passed is of type `RedisKey` it will be sent as part of the `KEYS` collection automatically. - -Any object that exposes field or property members with the same name as @-prefixed variables in the Lua script can be used as a parameter hash to -`Evaluate` calls. Supported member types are the following: - - - int(?) - - long(?) - - double(?) - - string - - byte[] - - bool(?) - - RedisKey - - RedisValue - - -To avoid retransmitting the Lua script to redis each time it is evaluated, `LuaScript` objects can be converted into `LoadedLuaScript`s via `LuaScript.Load(IServer)`. -`LoadedLuaScripts` are evaluated with the [`EVALSHA`](http://redis.io/commands/evalsha), and referred to by hash. - -An example use of `LoadedLuaScript`: - -``` - const string Script = "redis.call('set', @key, @value)"; - - using (ConnectionMultiplexer conn = /* init code */) - { - var db = conn.GetDatabase(0); - var server = conn.GetServer(/* appropriate parameters*/); - - var prepared = LuaScript.Prepare(Script); - var loaded = prepared.Load(server); - loaded.Evaluate(db, new { key = (RedisKey)"mykey", value = 123 }); - } -``` - -All methods on both `LuaScript` and `LoadedLuaScript` have Async alternatives, and expose the actual script submitted to redis as the `ExecutableScript` property. diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Timeouts.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Timeouts.md deleted file mode 100644 index 9bd5b34..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Timeouts.md +++ /dev/null @@ -1,52 +0,0 @@ -Are you getting network or CPU bound? ---------------- -Verify what's the maximum bandwidth supported on your client and on the server where redis-server is hosted. If there are requests that are getting bound by bandwidth, it will take longer for them to complete and thereby can cause timeouts. -Similarly, verify you are not getting CPU bound on client or on the server box which would cause requests to be waiting for CPU time and thereby have timeouts. - -Are there commands taking long time to process on the redis-server? ---------------- -There can be commands that are taking long time to process on the redis-server causing the request to timeout. Few examples of long running commands are mget with large number of keys, keys * or poorly written lua script. You can run the SlowLog command to see if there are requests taking longer than expected. More details regarding the command can be found [here](https://redis.io/commands/slowlog) - -Was there a big request preceding several small requests to the Redis that timed out? ---------------- -The parameter “qs” in the error message tells you how many requests were sent from the client to the server, but have not yet processed a response. For some types of load you might see that this value keeps growing, because StackExchange.Redis uses a single TCP connection and can only read one response at a time. Even though the first operation timed out, it does not stop the data being sent to/from the server, and other requests are blocked until this is finished. Thereby, causing timeouts. One solution is to minimize the chance of timeouts by ensuring that your redis-server cache is large enough for your workload and splitting large values into smaller chunks. Another possible solution is to use a pool of ConnectionMultiplexer objects in your client, and choose the "least loaded" ConnectionMultiplexer when sending a new request. This should prevent a single timeout from causing other requests to also timeout. - - -Are you seeing high number of busyio or busyworker threads in the timeout exception? ---------------- -Let's first understand some details on ThreadPool Growth: - -The CLR ThreadPool has two types of threads - "Worker" and "I/O Completion Port" (aka IOCP) threads. - - - Worker threads are used when for things like processing `Task.Run(…)` or `ThreadPool.QueueUserWorkItem(…)` methods. These threads are also used by various components in the CLR when work needs to happen on a background thread. - - IOCP threads are used when asynchronous IO happens (e.g. reading from the network). - -The thread pool provides new worker threads or I/O completion threads on demand (without any throttling) until it reaches the "Minimum" setting for each type of thread. By default, the minimum number of threads is set to the number of processors on a system. - -Once the number of existing (busy) threads hits the "minimum" number of threads, the ThreadPool will throttle the rate at which is injects new threads to one thread per 500 milliseconds. This means that if your system gets a burst of work needing an IOCP thread, it will process that work very quickly. However, if the burst of work is more than the configured "Minimum" setting, there will be some delay in processing some of the work as the ThreadPool waits for one of two things to happen - 1. An existing thread becomes free to process the work - 2. No existing thread becomes free for 500ms, so a new thread is created. - -Basically, it means that when the number of Busy threads is greater than Min threads, you are likely paying a 500ms delay before network traffic is processed by the application. Also, it is important to note that when an existing thread stays idle for longer than 15 seconds (based on what I remember), it will be cleaned up and this cycle of growth and shrinkage can repeat. - -If we look at an example error message from StackExchange.Redis (build 1.0.450 or later), you will see that it now prints ThreadPool statistics (see IOCP and WORKER details below). - - System.TimeoutException: Timeout performing GET MyKey, inst: 2, mgr: Inactive, - queue: 6, qu: 0, qs: 6, qc: 0, wr: 0, wq: 0, in: 0, ar: 0, - IOCP: (Busy=6,Free=994,Min=4,Max=1000), - WORKER: (Busy=3,Free=997,Min=4,Max=1000) - -In the above example, you can see that for IOCP thread there are 6 busy threads and the system is configured to allow 4 minimum threads. In this case, the client would have likely seen two 500 ms delays because 6 > 4. - -Note that StackExchange.Redis can hit timeouts if growth of either IOCP or WORKER threads gets throttled. - -Recommendation: -Given the above information, it's recommend to set the minimum configuration value for IOCP and WORKER threads to something larger than the default value. We can't give one-size-fits-all guidance on what this value should be because the right value for one application will be too high/low for another application. This setting can also impact the performance of other parts of complicated applications, so you need to fine-tune this setting to your specific needs. A good starting place is 200 or 300, then test and tweak as needed. - -How to configure this setting: - - - In ASP.NET, use the ["minIoThreads" configuration setting](https://msdn.microsoft.com/en-us/library/vstudio/7w2sway1(v=vs.100).aspx) under the `` configuration element in `machine.config`. You could set your server's `machine.config` to allow this overridable per apppool via the method indicated [here](https://stackoverflow.com/questions/1939230/asp-net-processmodel-configuration-optimization#comment2882249_1939245) and set this per Web.Config. Alternativly you can be able to set this programmatically (see below) from your Application_Start method in `Global.asax.cs`. - -> **Important Note:** the value specified in this configuration element is a *per-core* setting. For example, if you have a 4 core machine and want your minIOThreads setting to be 200 at runtime, you would use ``. - - - Outside of ASP.NET, use the [ThreadPool.SetMinThreads(…)](https://msdn.microsoft.com//en-us/library/system.threading.threadpool.setminthreads(v=vs.100).aspx) API. diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Transactions.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Transactions.md deleted file mode 100644 index 7ff22a0..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/Transactions.md +++ /dev/null @@ -1,118 +0,0 @@ -Transactions in Redis -===================== - -Transactions in Redis are not like transactions in, say a SQL database. The [full documentation is here](http://redis.io/topics/transactions), -but to paraphrase: - -A transaction in redis consists of a block of commands placed between `MULTI` and `EXEC` (or `DISCARD` for rollback). Once a `MULTI` -has been encountered, the commands on that connection *are not executed* - they are queued (and the caller gets the reply `QUEUED` -to each). When an `EXEC` is encountered, they are -all applied in a single unit (i.e. without other connections getting time between operations). If a `DISCARD` is seen instead of -a `EXEC`, everything is thrown away. Because the commands inside the transaction are queued, you can't make decisions *inside* -the transaction. For example, in a SQL database you might do the following (pseudo-code - illustrative only): - -```C# -// assign a new unique id only if they don't already -// have one, in a transaction to ensure no thread-races -var newId = CreateNewUniqueID(); // optimistic -using(var tran = conn.BeginTran()) -{ - var cust = GetCustomer(conn, custId, tran); - var uniqueId = cust.UniqueID; - if(uniqueId == null) - { - cust.UniqueId = newId; - SaveCustomer(conn, cust, tran); - } - tran.Complete(); -} -``` - -So how do you do it in Redis? ---- - -This simply isn't possible in redis transactions: once the transaction is open you *can't fetch data* - your -operations are queued. Fortunately, there are two other commands that help us: `WATCH` and `UNWATCH`. - -`WATCH {key}` tells Redis that we are interested in the specified key for the purposes of the transaction. -Redis will automatically keep track of this key, and any changes will essentially doom our transaction to -rollback - `EXEC` does the same as `DISCARD` (the caller can detect this and retry from the start). So what -you *can* do is: `WATCH` a key, check data from that key in the normal way, then `MULTI`/`EXEC` your changes. -If, when you check the data, you discover that you don't actually need the transaction, you can use `UNWATCH` to -forget all the watched keys. Note that watched keys are also reset during `EXEC` and `DISCARD`. So *at the Redis layer*, this is conceptually: - -``` -WATCH {custKey} -HEXISTS {custKey} "UniqueId" -(check the reply, then either:) -MULTI -HSET {custKey} "UniqueId" {newId} -EXEC -(or, if we find there was already an unique-id:) -UNWATCH -``` - -This might look odd - having a `MULTI`/`EXEC` that only spans a single operation - but the important thing -is that we are now also tracking changes to `{custKey}` from all other connections - if anyone else -changes the key, the transaction will be aborted. - -And in StackExchange.Redis? ---- - -This is *further* complicated by the fact that StackExchange.Redis uses a multiplexer approach. We can't simply -let concurrent callers issue `WATCH` / `UNWATCH` / `MULTI` / `EXEC` / `DISCARD`: it would all be jumbled together. So -an additional abstraction is provided - additionally making things simpler to get right: *constraints*. *Constraints* are -basically pre-canned tests involving `WATCH`, some kind of test, and a check on the result. If all the constraints -pass, the `MULTI`/`EXEC` is issued; otherwise `UNWATCH` is issued. This is all done in a way that prevents the commands being -mixed together with other callers. So our example becomes: - -```C# -var newId = CreateNewId(); -var tran = db.CreateTransaction(); -tran.AddCondition(Condition.HashNotExists(custKey, "UniqueID")); -tran.HashSetAsync(custKey, "UniqueID", newId); -bool committed = tran.Execute(); -// ^^^ if true: it was applied; if false: it was rolled back -``` - -Note that the object returned from `CreateTransaction` only has access to the *async* methods - because the result of -each operation will not be known until after `Execute` (or `ExecuteAsync`) has completed. If the operations are not applied, all the `Task`s -will be marked as cancelled - otherwise, *after* the command has executed you can fetch the results of each as normal. - -The set of available *conditions* is not extensive, but covers the most common scenarios; please contact me (or better: submit a pull-request) if -there are additional conditions that you would like to see. - -Inbuilt operations via `When` ---- - -It should also be noted that many common scenarios (in particular: key/hash existence, like in the above) have been anticipated by Redis, and single-operation -atomic commands exist. These are accessed via the `When` parameter - so our previous example can *also* be written as: - -```C# -var newId = CreateNewId(); -bool wasSet = db.HashSet(custKey, "UniqueID", newId, When.NotExists); -``` - -(here, the `When.NotExists` causes the `HSETNX` command to be used, rather than `HSET`) - -Lua ---- - -You should also keep in mind that Redis 2.6 and above [support Lua scripting](http://redis.io/commands/EVAL), a versatile tool for performing multiple operations as a single atomic unit at the server. -Since no other connections are serviced during a Lua script it behaves much like a transaction, but without the complexity of `MULTI` / `EXEC` etc. This also avoids issues such as bandwidth and latency -between the caller and the server, but the trade-off is that it monopolises the server for the duration of the script. - -At the Redis layer (and assuming `HSETNX` did not exist) this could be implemented as: - -``` -EVAL "if redis.call('hexists', KEYS[1], 'UniqueId') then return redis.call('hset', KEYS[1], 'UniqueId', ARGV[1]) else return 0 end" 1 {custKey} {newId} -``` - -This can be used in StackExchange.Redis via: - -```C# -var wasSet = (bool) db.ScriptEvaluate(@"if redis.call('hexists', KEYS[1], 'UniqueId') then return redis.call('hset', KEYS[1], 'UniqueId', ARGV[1]) else return 0 end", - new RedisKey[] { custKey }, new RedisValue[] { newId }); -``` - -(note that the response from `ScriptEvaluate` and `ScriptEvaluateAsync` is variable depending on your exact script; the response can be interpreted by casting - in this case as a `bool`) diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/index.md b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/index.md deleted file mode 100644 index c8ded85..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/docs/index.md +++ /dev/null @@ -1,58 +0,0 @@ -StackExchange.Redis -=================== - -[Release Notes](ReleaseNotes) - -## Overview - -StackExchange.Redis is a high performance general purpose redis client for .NET languages (C# etc). It is the logical successor to [BookSleeve](https://code.google.com/archive/p/booksleeve/), -and is the client developed-by (and used-by) [Stack Exchange](http://stackexchange.com/) for busy sites like [Stack Overflow](http://stackoverflow.com/). For the full reasons -why this library was created (i.e. "What about BookSleeve?") [please see here](http://marcgravell.blogspot.com/2014/03/so-i-went-and-wrote-another-redis-client.html). - -Features --- - -- High performance multiplexed design, allowing for efficient use of shared connections from multiple calling threads -- Abstraction over redis node configuration: the client can silently negotiate multiple redis servers for robustness and availability -- Convenient access to the full redis feature-set -- Full dual programming model both synchronous and asynchronous usage, without requiring "sync over async" usage of the [TPL][1] -- Support for redis "cluster" - -Installation ---- - -StackExchange.Redis can be installed via the nuget UI (as [StackExchange.Redis](https://www.nuget.org/packages/StackExchange.Redis/)), or via the nuget package manager console: - -```PowerShell -PM> Install-Package StackExchange.Redis -``` - -If you require a strong-named package (because your project is strong-named), then you may wish to use instead: - -```PowerShell -PM> Install-Package StackExchange.Redis.StrongName -``` - -([for further reading, see here](http://blog.marcgravell.com/2014/06/snk-we-need-to-talk.html)) - -Documentation ---- - -- [Basic Usage](Basics) - getting started and basic usage -- [Configuration](Configuration) - options available when connecting to redis -- [Pipelines and Multiplexers](PipelinesMultiplexers) - what is a multiplexer? -- [Keys, Values and Channels](KeysValues) - discusses the data-types used on the API -- [Transactions](Transactions) - how atomic transactions work in redis -- [Events](Events) - the events available for logging / information purposes -- [Pub/Sub Message Order](PubSubOrder) - advice on sequential and concurrent processing -- [Where are `KEYS` / `SCAN` / `FLUSH*`?](KeysScan) - how to use server-based commands -- [Profiling](Profiling) - profiling interfaces, as well as how to profile in an `async` world -- [Scripting](Scripting) - running Lua scripts with convenient named parameter replacement - -Questions and Contributions ---- - -If you think you have found a bug or have a feature request, please [report an issue][2], or if appropriate: submit a pull request. If you have a question, feel free to [contact me](https://github.com/mgravell). - - [1]: http://msdn.microsoft.com/en-us/library/dd460717%28v=vs.110%29.aspx - [2]: https://github.com/StackExchange/StackExchange.Redis/issues?state=open diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/monobuild.bash b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/monobuild.bash deleted file mode 100644 index d0154c0..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/monobuild.bash +++ /dev/null @@ -1,11 +0,0 @@ -rm -rf StackExchange.Redis/bin/mono -rm -rf BasicTest/bin/mono -mkdir -p StackExchange.Redis/bin/mono -mkdir -p BasicTest/bin/mono -echo -e "Building StackExchange.Redis.dll ..." -mcs -recurse:StackExchange.Redis/*.cs -out:StackExchange.Redis/bin/mono/StackExchange.Redis.dll -target:library -unsafe+ -o+ -r:System.IO.Compression.dll -echo -e "Building BasicTest.exe ..." -mcs BasicTest/Program.cs -out:BasicTest/bin/mono/BasicTest.exe -target:exe -o+ -r:StackExchange.Redis/bin/mono/StackExchange.Redis.dll -cp StackExchange.Redis/bin/mono/*.* BasicTest/bin/mono/ -echo -e "Running basic test ..." -mono BasicTest/bin/mono/BasicTest.exe 10000 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/monobuild.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/monobuild.cmd deleted file mode 100644 index d31dc08..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/monobuild.cmd +++ /dev/null @@ -1,15 +0,0 @@ -@rd /s /q StackExchange.Redis\bin\mono 1>nul 2>nul -@rd /s /q BasicTest\bin\mono 1>nul 2>nul -@md StackExchange.Redis\bin\mono 1>nul 2>nul -@md BasicTest\bin\mono 1>nul 2>nul -@echo Building StackExchange.Redis.dll ... -@call mcs -recurse:StackExchange.Redis\*.cs -out:StackExchange.Redis\bin\mono\StackExchange.Redis.dll -target:library -unsafe+ -o+ -r:System.IO.Compression.dll -@echo Building BasicTest.exe ... -@call mcs BasicTest\Program.cs -out:BasicTest\bin\mono\BasicTest.exe -target:exe -o+ -r:StackExchange.Redis\bin\mono\StackExchange.Redis.dll -@copy StackExchange.Redis\bin\mono\*.* BasicTest\bin\mono > nul -@echo . -@echo Running basic test (Mono) ... -@call mono BasicTest\bin\mono\BasicTest.exe 100000 -@echo . -@echo Running basic test (.NET) ... -@call BasicTest\bin\mono\BasicTest.exe 100000 diff --git a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/netbuild.cmd b/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/netbuild.cmd deleted file mode 100644 index 698eb27..0000000 --- a/SNETCracker/libs/redis/StackExchange.Redis-1.2.6/netbuild.cmd +++ /dev/null @@ -1,12 +0,0 @@ -@rd /s /q StackExchange.Redis\bin\Release 1>nul 2>nul -@rd /s /q BasicTest\bin\Release 1>nul 2>nul -@md StackExchange.Redis\bin\Release 1>nul 2>nul -@md BasicTest\bin\Release 1>nul 2>nul -@echo Building StackExchange.Redis.dll ... -@call csc /out:StackExchange.Redis\bin\Release\StackExchange.Redis.dll /target:library /unsafe+ /o+ /r:System.IO.Compression.dll /recurse:StackExchange.Redis\*.cs -@echo Building BasicTest.exe ... -@call csc /out:BasicTest\bin\Release\BasicTest.exe /target:exe -o+ /r:StackExchange.Redis\bin\Release\StackExchange.Redis.dll BasicTest\Program.cs -@copy StackExchange.Redis\bin\Release\*.* BasicTest\bin\Release > nul -@echo . -@echo Running basic test (.NET) ... -@call BasicTest\bin\Release\BasicTest.exe 100000 \ No newline at end of file diff --git a/SNETCracker/rdp/RdpClient.cs b/SNETCracker/rdp/RdpClient.cs index 451e0fd..a913598 100644 --- a/SNETCracker/rdp/RdpClient.cs +++ b/SNETCracker/rdp/RdpClient.cs @@ -7,51 +7,55 @@ namespace MyRDP { - public class RdpClient : AxMsRdpClient4NotSafeForScripting + public class RdpClient : AxMsRdpClient4 { - private Server server= null; + private Server server = null; public delegate void OnResponseDelegate(ResponseType type, Server server); public event OnResponseDelegate OnResponse; public System.Timers.Timer timeOutLog = new System.Timers.Timer(); - public ResponseType response =ResponseType.Connecting; + public ResponseType response = ResponseType.Connecting; public RdpClient(Server cserver) - { + { this.server = cserver; this.timeOutLog.Interval = server.timeout * 1000; this.timeOutLog.Elapsed += TimeOut; this.OnConnected += Rdp_OnConnected; this.OnLoginComplete += Rdp_OnLoginComplete; - this.OnLogonError += Rdp_OnLogonError; this.OnFatalError += Rdp_OnFatalError; this.OnDisconnected += Rdp_OnDisconnected; this.OnAuthenticationWarningDisplayed += Rdp_OnAuthenticationWarningDisplayed; this.OnAuthenticationWarningDismissed += Rdp_OnAuthenticationWarningDismissed; - - + this.OnWarning += Rdp_OnWaring; } public object Password { get; internal set; } - private void Finished() { + private void Finished() + { + if (this.IsDisposed == false) + { + this.Disconnect(); + } OnResponse(ResponseType.Finished, server); } - private void TimeOut(object sender, ElapsedEventArgs e) { + private void TimeOut(object sender, ElapsedEventArgs e) + { this.timeOutLog.Stop(); Finished(); } public delegate void deConnect(string ip, int port, string user, string pass); - public void Connect(string ip,int port,string user,string pass) + public void Connect(string ip, int port, string user, string pass) { try { this.timeOutLog.Start(); this.AdvancedSettings.Compress = 1; - this.Height =1; + this.Height = 1; this.Width = 1; this.Password = pass; - this.ColorDepth =8 ; + this.ColorDepth = 1; this.Server = ip; this.UserName = user; this.AdvancedSettings4.EnableMouse = 0; @@ -60,7 +64,7 @@ public void Connect(string ip,int port,string user,string pass) IMsTscNonScriptable secured = (IMsTscNonScriptable)this.GetOcx(); secured.ClearTextPassword = pass; this.Connect(); - + } catch (Exception e) { @@ -71,29 +75,32 @@ public void Connect(string ip,int port,string user,string pass) private void Rdp_OnDisconnected(object sender, IMsTscAxEvents_OnDisconnectedEvent e) { Finished(); - } + } private void Rdp_OnFatalError(object sender, IMsTscAxEvents_OnFatalErrorEvent e) { Finished(); + FileTool.log("RDP_OnFatalError:" + e.errorCode); } - private void Rdp_OnLogonError(object sender, IMsTscAxEvents_OnLogonErrorEvent e) + private void Rdp_OnLoginComplete(object sender, EventArgs e) { + this.server.isSuccess = true; + this.server.banner = this.ProductVersion; Finished(); - } - private void Rdp_OnLoginComplete(object sender, EventArgs e) + private void Rdp_OnWaring(object sender, IMsTscAxEvents_OnWarningEvent e) { - this.server.isSuccess = true; + Finished(); + FileTool.log("RDP_OnWaring:" + e.warningCode); } private void Rdp_OnConnected(object sender, EventArgs e) { this.server.isConnected = true; - + } private void Rdp_OnAuthenticationWarningDismissed(object sender, EventArgs e) @@ -108,4 +115,4 @@ private void Rdp_OnAuthenticationWarningDisplayed(object sender, EventArgs e) } } -} +} \ No newline at end of file