├── .azure └── pipelines │ ├── CodeCoverage.runsettings │ ├── azure-pipelines-compliance-policheck.yml │ ├── azure-pipelines-compliance.yml │ ├── azure-pipelines-external-release.yml │ ├── azure-pipelines-internal-release.yml │ ├── azure-pipelines-mirror.yml │ ├── azure-pipelines-performance.yml │ ├── azure-pipelines-tsavorite-codecoverage.yml │ ├── azure-pipelines-tsavorite.yml │ ├── azure-pipelines.yml │ ├── createbinaries.ps1 │ ├── credscan-exclusion.json │ ├── extract_version.ps1 │ └── policheck-exclusion.xml ├── .dockerignore ├── .editorconfig ├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml └── workflows │ ├── ci-bdnbenchmark.yml │ ├── ci.yml │ ├── codeql.yml │ ├── deploy-website.yml │ ├── docker-linux.yml │ ├── docker-windows.yml │ ├── helm-chart.yml │ ├── locker.yml │ └── nightly.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── Directory.Build.props ├── Directory.Packages.props ├── Dockerfile ├── Dockerfile.alpine ├── Dockerfile.cbl-mariner ├── Dockerfile.chiseled ├── Dockerfile.nanoserver ├── Dockerfile.ubuntu ├── Garnet.sln ├── Garnet.snk ├── LICENSE ├── NOTICE.md ├── README.md ├── SECURITY.md ├── SUPPORT.md ├── Version.props ├── benchmark ├── BDN.benchmark │ ├── BDN.benchmark.csproj │ ├── Cluster │ │ ├── ClusterContext.cs │ │ ├── ClusterMigrate.cs │ │ ├── ClusterOperations.cs │ │ ├── ClusterParams.cs │ │ └── Request.cs │ ├── Custom │ │ ├── CustomProcSet.cs │ │ └── CustomTxnSet.cs │ ├── Embedded │ │ ├── EmbeddedNetworkHandler.cs │ │ ├── EmbeddedNetworkSender.cs │ │ ├── EmbeddedRespServer.cs │ │ ├── GarnetServerEmbedded.cs │ │ └── Request.cs │ ├── Geo │ │ └── GeoHash.cs │ ├── Json │ │ └── JsonPathQuery.cs │ ├── Lua │ │ ├── LuaParams.cs │ │ ├── LuaRunnerOperations.cs │ │ ├── LuaScriptCacheOperations.cs │ │ ├── LuaScripts.cs │ │ └── LuaTimeouts.cs │ ├── Network │ │ ├── BasicOperations.cs │ │ ├── NetworkBase.cs │ │ ├── NetworkParams.cs │ │ └── RawStringOperations.cs │ ├── Operations │ │ ├── BasicOperations.cs │ │ ├── CustomOperations.cs │ │ ├── HashObjectOperations.cs │ │ ├── JsonOperations.cs │ │ ├── ModuleOperations.cs │ │ ├── ObjectOperations.cs │ │ ├── OperationParams.cs │ │ ├── OperationsBase.cs │ │ ├── PubSubOperations.cs │ │ ├── RawStringOperations.cs │ │ ├── ScriptOperations.cs │ │ ├── SetOperations.cs │ │ └── SortedSetOperations.cs │ ├── Parsing │ │ ├── DoubleToResp.cs │ │ ├── IntegerToResp.cs │ │ └── RespToInteger.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Utils │ │ └── BenchUtils.cs ├── README.md └── Resp.benchmark │ ├── BenchUtils.cs │ ├── BenchmarkLoggerProvider.cs │ ├── ClientTypes.cs │ ├── GeoUtils.cs │ ├── HashUtils.cs │ ├── NumUtils.cs │ ├── OnlineReqGen.cs │ ├── OpType.cs │ ├── Options.cs │ ├── PeriodicCheckpointer.cs │ ├── Program.cs │ ├── RandomGenerator.cs │ ├── ReqGen.cs │ ├── ReqGenLoadBuffers.cs │ ├── ReqGenUtils.cs │ ├── Resp.benchmark.csproj │ ├── RespOnlineBench.cs │ ├── RespPerfBench.cs │ ├── TxnPerfBench.cs │ └── ZipfGenerator.cs ├── charts └── garnet │ ├── .gitignore │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── templates │ ├── _helpers.tpl │ ├── secret.yaml │ ├── service-headless.yaml │ ├── service.yaml │ ├── serviceaccount.yaml │ ├── statefulset.yaml │ └── token.yaml │ └── values.yaml ├── docker-compose.yml ├── hosting └── Windows │ └── Garnet.worker │ ├── Garnet.worker.csproj │ ├── Program.cs │ └── Worker.cs ├── libs ├── client │ ├── ClientSession │ │ ├── AsyncGarnetClientSession.cs │ │ ├── AsyncPool.cs │ │ ├── GarnetClientSession.cs │ │ ├── GarnetClientSessionClusterExtensions.cs │ │ ├── GarnetClientSessionIncremental.cs │ │ ├── GarnetClientSessionMigrationExtensions.cs │ │ ├── GarnetClientSessionReplicationExtensions.cs │ │ └── GarnetClientSessionTcpNetworkHandler.cs │ ├── ClientTcpNetworkSender.cs │ ├── CompletionEvent.cs │ ├── ExceptionTypes.cs │ ├── Garnet.client.csproj │ ├── GarnetClient.cs │ ├── GarnetClientAPI │ │ ├── GarnetClientAdminCommands.cs │ │ ├── GarnetClientBasicRespCommands.cs │ │ ├── GarnetClientClusterCommands.cs │ │ ├── GarnetClientExecuteAPI.cs │ │ ├── GarnetClientListCommands.cs │ │ ├── GarnetClientSortedSetCommands.cs │ │ └── SortedSetPairCollection.cs │ ├── GarnetClientMetrics.cs │ ├── GarnetClientProcessReplies.cs │ ├── GarnetClientTcpNetworkHandler.cs │ ├── LightEpoch.cs │ ├── NetworkWriter.cs │ ├── PageAsyncResultTypes.cs │ ├── PageOffset.cs │ ├── RespReadResponseUtils.cs │ ├── TcsWrapper.cs │ └── Utility.cs ├── cluster │ ├── AssemblyInfo.cs │ ├── ClusterFactory.cs │ ├── CmdStrings.cs │ ├── Garnet.cluster.csproj │ ├── Server │ │ ├── ClusterAuthContainer.cs │ │ ├── ClusterConfig.cs │ │ ├── ClusterConfigSerializer.cs │ │ ├── ClusterManager.cs │ │ ├── ClusterManagerSlotState.cs │ │ ├── ClusterManagerWorkerState.cs │ │ ├── ClusterProvider.cs │ │ ├── ClusterUtils.cs │ │ ├── ConnectionInfo.cs │ │ ├── Failover │ │ │ ├── FailoverManager.cs │ │ │ ├── FailoverSession.cs │ │ │ ├── FailoverStatus.cs │ │ │ ├── PrimaryFailoverSession.cs │ │ │ └── ReplicaFailoverSession.cs │ │ ├── GarnetClientExtensions.cs │ │ ├── GarnetClusterConnectionStore.cs │ │ ├── GarnetServerNode.cs │ │ ├── Gossip.cs │ │ ├── GossipStats.cs │ │ ├── HashSlot.cs │ │ ├── Migration │ │ │ ├── KeyMigrateState.cs │ │ │ ├── MigrateSession.cs │ │ │ ├── MigrateSessionKeyManager.cs │ │ │ ├── MigrateSessionKeys.cs │ │ │ ├── MigrateSessionSend.cs │ │ │ ├── MigrateSessionSlots.cs │ │ │ ├── MigrateSessionTaskStore.cs │ │ │ ├── MigrateState.cs │ │ │ ├── MigratingKeysWorkingSet.cs │ │ │ ├── MigrationDriver.cs │ │ │ ├── MigrationKeyIterationFunctions.cs │ │ │ └── MigrationManager.cs │ │ ├── Replication │ │ │ ├── CheckpointEntry.cs │ │ │ ├── CheckpointFileType.cs │ │ │ ├── CheckpointStore.cs │ │ │ ├── PrimaryOps │ │ │ │ ├── AofSyncTaskInfo.cs │ │ │ │ ├── AofTaskStore.cs │ │ │ │ ├── DisklessReplication │ │ │ │ │ ├── ReplicaSyncSession.cs │ │ │ │ │ ├── ReplicationSnapshotIterator.cs │ │ │ │ │ ├── ReplicationSyncManager.cs │ │ │ │ │ └── SyncStatus.cs │ │ │ │ ├── PrimarySync.cs │ │ │ │ ├── ReplicaSyncSession.cs │ │ │ │ ├── ReplicaSyncSessionTaskStore.cs │ │ │ │ └── ReplicationPrimaryAofSync.cs │ │ │ ├── RecoveryStatus.cs │ │ │ ├── ReplicaOps │ │ │ │ ├── ReceiveCheckpointHandler.cs │ │ │ │ ├── ReplicaDisklessSync.cs │ │ │ │ ├── ReplicaReceiveCheckpoint.cs │ │ │ │ ├── ReplicaReplayTask.cs │ │ │ │ └── ReplicationReplicaAofSync.cs │ │ │ ├── ReplicationCheckpointManagement.cs │ │ │ ├── ReplicationDevice.cs │ │ │ ├── ReplicationHistoryManager.cs │ │ │ ├── ReplicationLogCheckpointManager.cs │ │ │ ├── ReplicationManager.cs │ │ │ ├── ReplicationNetworkBufferSettings.cs │ │ │ └── SyncMetadata.cs │ │ └── Worker.cs │ ├── Session │ │ ├── ClusterCommandInfo.cs │ │ ├── ClusterCommands.cs │ │ ├── ClusterKeyIterationFunctions.cs │ │ ├── ClusterSession.cs │ │ ├── FailoverCommand.cs │ │ ├── MigrateCommand.cs │ │ ├── ReplicaOfCommand.cs │ │ ├── RespClusterBasicCommands.cs │ │ ├── RespClusterFailoverCommands.cs │ │ ├── RespClusterMigrateCommands.cs │ │ ├── RespClusterReplicationCommands.cs │ │ ├── RespClusterSlotManagementCommands.cs │ │ ├── SlotVerification │ │ │ ├── ClusterSlotVerificationResult.cs │ │ │ ├── ClusterSlotVerify.cs │ │ │ ├── RespClusterIterativeSlotVerify.cs │ │ │ └── RespClusterSlotVerify.cs │ │ ├── SlotVerifiedState.cs │ │ └── TransferOption.cs │ └── SessionParseStateExtensions.cs ├── common │ ├── AsciiUtils.cs │ ├── ClientBase.cs │ ├── Collections │ │ ├── ElasticCircularBuffer.cs │ │ └── ReadOptimizedConcurrentSet.cs │ ├── ConvertUtils.cs │ ├── Crc64.cs │ ├── EnumUtils.cs │ ├── ExceptionInjectionHelper.cs │ ├── ExceptionInjectionType.cs │ ├── FailoverOption.cs │ ├── FileUtils.cs │ ├── Format.cs │ ├── Garnet.common.csproj │ ├── GarnetException.cs │ ├── Generator.cs │ ├── HashSlotUtils.cs │ ├── HashUtils.cs │ ├── LightClient.cs │ ├── LightClientRequest.cs │ ├── LightClientTcpNetworkHandler.cs │ ├── Logging │ │ ├── FileLoggerProvider.cs │ │ └── LogFormatter.cs │ ├── Memory │ │ ├── LimitedFixedBufferPool.cs │ │ ├── PoolEntry.cs │ │ └── PoolLevel.cs │ ├── MemoryResult.cs │ ├── Metrics │ │ ├── InfoMetricsType.cs │ │ ├── LatencyMetricsType.cs │ │ └── MetricsItem.cs │ ├── NetworkBufferSettings.cs │ ├── Networking │ │ ├── BatchHeader.cs │ │ ├── BufferSizeUtils.cs │ │ ├── GarnetSaeaBuffer.cs │ │ ├── GarnetTcpNetworkSender.cs │ │ ├── IMessageConsumer.cs │ │ ├── INetworkHandler.cs │ │ ├── INetworkSender.cs │ │ ├── IServerHook.cs │ │ ├── LightConcurrentStack.cs │ │ ├── MaxSizeSettings.cs │ │ ├── NetworkHandler.cs │ │ ├── NetworkHandlerStream.cs │ │ ├── NetworkSenderBase.cs │ │ ├── TaskToApm.cs │ │ ├── TcpNetworkHandler.cs │ │ ├── TcpNetworkHandlerBase.cs │ │ ├── TlsReaderStatus.cs │ │ └── WireFormat.cs │ ├── NumUtils.cs │ ├── Parsing │ │ └── RespParsingException.cs │ ├── RandomUtils.cs │ ├── RespLengthEncodingUtils.cs │ ├── RespMemoryWriter.cs │ ├── RespReadUtils.cs │ ├── RespWriteUtils.cs │ ├── SimpleObjectPool.cs │ ├── SingleWriterMultiReaderLock.cs │ └── StreamProvider.cs ├── host │ ├── Configuration │ │ ├── CommandLineTypes.cs │ │ ├── ConfigProviders.cs │ │ ├── GarnetCustomTransformers.cs │ │ ├── Options.cs │ │ ├── OptionsValidators.cs │ │ ├── PopulateObjectJsonConverter.cs │ │ ├── Redis │ │ │ ├── RedisConfigSerializer.cs │ │ │ ├── RedisOptions.cs │ │ │ └── RedisTypes.cs │ │ └── TypeConverters.cs │ ├── Garnet.host.csproj │ ├── GarnetServer.cs │ ├── MemoryLogger.cs │ ├── ServerSettingsManager.cs │ └── defaults.conf ├── resources │ ├── Garnet.resources.csproj │ ├── ResourceUtils.cs │ ├── RespCommandsDocs.json │ └── RespCommandsInfo.json ├── server │ ├── ACL │ │ ├── ACLException.cs │ │ ├── ACLParser.cs │ │ ├── ACLPassword.cs │ │ ├── AccessControlList.cs │ │ ├── CommandPermissionSet.cs │ │ ├── SecretsUtility.cs │ │ ├── User.cs │ │ └── UserHandle.cs │ ├── AOF │ │ ├── AofEntryType.cs │ │ ├── AofHeader.cs │ │ └── AofProcessor.cs │ ├── API │ │ ├── GarnetApi.cs │ │ ├── GarnetApiObjectCommands.cs │ │ ├── GarnetStatus.cs │ │ ├── GarnetWatchApi.cs │ │ ├── IGarnetAdvancedApi.cs │ │ └── IGarnetApi.cs │ ├── ArgSlice │ │ ├── ArgSlice.cs │ │ ├── ArgSliceComparer.cs │ │ ├── ArgSliceUtils.cs │ │ └── ScratchBufferManager.cs │ ├── Auth │ │ ├── Aad │ │ │ └── IssuerSigningTokenProvider.cs │ │ ├── GarnetACLAuthenticator.cs │ │ ├── GarnetAadAuthenticator.cs │ │ ├── GarnetAclWithAadAuthenticator.cs │ │ ├── GarnetAclWithPasswordAuthenticator.cs │ │ ├── GarnetNoAuthAuthenticator.cs │ │ ├── GarnetPasswordAuthenticator.cs │ │ ├── IGarnetAuthenticator.cs │ │ └── Settings │ │ │ ├── AadAuthenticationSettings.cs │ │ │ ├── AclAuthenticationAadSettings.cs │ │ │ ├── AclAuthenticationPasswordSettings.cs │ │ │ ├── AclAuthenticationSettings.cs │ │ │ ├── AuthenticationSettings.cs │ │ │ ├── ConnectionProtectionOption.cs │ │ │ ├── NoAuthSettings.cs │ │ │ └── PasswordAuthenticationSettings.cs │ ├── ByteArrayWrapper.cs │ ├── ByteArrayWrapperComparer.cs │ ├── ClientType.cs │ ├── Cluster │ │ ├── CheckpointMetadata.cs │ │ ├── ClusterSlotVerificationInput.cs │ │ ├── IClusterFactory.cs │ │ ├── IClusterProvider.cs │ │ ├── IClusterSession.cs │ │ ├── RoleInfo.cs │ │ └── StoreType.cs │ ├── Custom │ │ ├── CommandType.cs │ │ ├── CustomCommandManager.cs │ │ ├── CustomCommandManagerSession.cs │ │ ├── CustomCommandRegistration.cs │ │ ├── CustomCommandType.cs │ │ ├── CustomCommandUtils.cs │ │ ├── CustomObjectBase.cs │ │ ├── CustomObjectCommand.cs │ │ ├── CustomObjectCommandWrapper.cs │ │ ├── CustomObjectFactory.cs │ │ ├── CustomObjectFunctions.cs │ │ ├── CustomProcedureBase.cs │ │ ├── CustomProcedureWrapper.cs │ │ ├── CustomRawStringCommand.cs │ │ ├── CustomRawStringFunctions.cs │ │ ├── CustomRespCommands.cs │ │ ├── CustomTransaction.cs │ │ ├── CustomTransactionProcedure.cs │ │ ├── ExpandableMap.cs │ │ ├── ICustomCommand.cs │ │ └── ObjectInputExtensions.cs │ ├── Databases │ │ ├── DatabaseManagerBase.cs │ │ ├── DatabaseManagerFactory.cs │ │ ├── IDatabaseManager.cs │ │ ├── MultiDatabaseManager.cs │ │ └── SingleDatabaseManager.cs │ ├── ExpireOption.cs │ ├── Garnet.server.csproj │ ├── GarnetDatabase.cs │ ├── GlobUtils.cs │ ├── InputHeader.cs │ ├── LogCompactionType.cs │ ├── Lua │ │ ├── ILuaAllocator.cs │ │ ├── LuaCommands.cs │ │ ├── LuaLimitedManagedAllocator.cs │ │ ├── LuaManagedAllocator.cs │ │ ├── LuaOptions.cs │ │ ├── LuaRunner.Functions.cs │ │ ├── LuaRunner.Loader.cs │ │ ├── LuaRunner.Strings.cs │ │ ├── LuaRunner.cs │ │ ├── LuaStateWrapper.cs │ │ ├── LuaTimeoutManager.cs │ │ ├── LuaTrackedAllocator.cs │ │ ├── NativeMethods.cs │ │ ├── ScratchBufferNetworkSender.cs │ │ ├── ScriptHashKey.cs │ │ └── SessionScriptCache.cs │ ├── Metrics │ │ ├── GarnetServerMetrics.cs │ │ ├── GarnetServerMonitor.cs │ │ ├── GarnetSessionMetrics.cs │ │ ├── IMetrics.cs │ │ ├── Info │ │ │ ├── GarnetInfoMetrics.cs │ │ │ ├── InfoCommand.cs │ │ │ └── InfoHelp.cs │ │ ├── Latency │ │ │ ├── GarnetLatencyMetrics.cs │ │ │ ├── GarnetLatencyMetricsSession.cs │ │ │ ├── LatencyMetricsEntry.cs │ │ │ ├── LatencyMetricsEntrySession.cs │ │ │ ├── RespLatencyCommands.cs │ │ │ └── RespLatencyHelp.cs │ │ ├── Slowlog │ │ │ ├── RespSlowlogCommands.cs │ │ │ ├── RespSlowlogHelp.cs │ │ │ ├── SlowLogContainer.cs │ │ │ └── SlowlogEntry.cs │ │ └── SystemMetrics.cs │ ├── Module │ │ ├── ModuleRegistrar.cs │ │ └── ModuleUtils.cs │ ├── Objects │ │ ├── Hash │ │ │ ├── HashObject.cs │ │ │ └── HashObjectImpl.cs │ │ ├── ItemBroker │ │ │ ├── CollectionItemBroker.cs │ │ │ ├── CollectionItemBrokerEvent.cs │ │ │ ├── CollectionItemObserver.cs │ │ │ └── CollectionItemResult.cs │ │ ├── List │ │ │ ├── ListObject.cs │ │ │ └── ListObjectImpl.cs │ │ ├── Set │ │ │ ├── SetObject.cs │ │ │ └── SetObjectImpl.cs │ │ ├── SortedSet │ │ │ ├── SortedSetObject.cs │ │ │ └── SortedSetObjectImpl.cs │ │ ├── SortedSetComparer.cs │ │ ├── SortedSetGeo │ │ │ ├── GeoHash.cs │ │ │ ├── GeoSearchOptions.cs │ │ │ └── SortedSetGeoObjectImpl.cs │ │ └── Types │ │ │ ├── ByteArrayBinaryObjectSerializer.cs │ │ │ ├── GarnetObject.cs │ │ │ ├── GarnetObjectBase.cs │ │ │ ├── GarnetObjectSerializer.cs │ │ │ ├── GarnetObjectStoreOutput.cs │ │ │ ├── GarnetObjectType.cs │ │ │ ├── IGarnetObject.cs │ │ │ ├── SerializationPhase.cs │ │ │ └── SerializationState.cs │ ├── OperationError.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Providers │ │ ├── GarnetProvider.cs │ │ └── TsavoriteKVProviderBase.cs │ ├── PubSub │ │ ├── PatternSubscriptionEntry.cs │ │ └── SubscribeBroker.cs │ ├── Resp │ │ ├── ACLCommands.cs │ │ ├── AdminCommands.cs │ │ ├── ArrayCommands.cs │ │ ├── AsyncProcessor.cs │ │ ├── BasicCommands.cs │ │ ├── BasicEtagCommands.cs │ │ ├── Bitmap │ │ │ ├── BitmapCommands.cs │ │ │ ├── BitmapManager.cs │ │ │ ├── BitmapManagerBitCount.cs │ │ │ ├── BitmapManagerBitOp.cs │ │ │ ├── BitmapManagerBitPos.cs │ │ │ └── BitmapManagerBitfield.cs │ │ ├── ByteArrayComparer.cs │ │ ├── ClientCommands.cs │ │ ├── CmdStrings.cs │ │ ├── GarnetDatabaseSession.cs │ │ ├── HyperLogLog │ │ │ ├── HyperLogLog.cs │ │ │ └── HyperLogLogCommands.cs │ │ ├── IRespSerializable.cs │ │ ├── KeyAdminCommands.cs │ │ ├── LocalServerSession.cs │ │ ├── Objects │ │ │ ├── HashCommands.cs │ │ │ ├── ListCommands.cs │ │ │ ├── ObjectStoreUtils.cs │ │ │ ├── SetCommands.cs │ │ │ ├── SharedObjectCommands.cs │ │ │ ├── SortedSetCommands.cs │ │ │ └── SortedSetGeoCommands.cs │ │ ├── Parser │ │ │ ├── ParseUtils.cs │ │ │ ├── RespCommand.cs │ │ │ └── SessionParseState.cs │ │ ├── PubSubCommands.cs │ │ ├── PurgeBPCommand.cs │ │ ├── RespCommandAccessor.cs │ │ ├── RespCommandArgument.cs │ │ ├── RespCommandDataCommon.cs │ │ ├── RespCommandDataProvider.cs │ │ ├── RespCommandDocs.cs │ │ ├── RespCommandInfoFlags.cs │ │ ├── RespCommandKeySpecification.cs │ │ ├── RespCommandsInfo.cs │ │ ├── RespEnums.cs │ │ ├── RespServerSession.cs │ │ ├── RespServerSessionSlotVerify.cs │ │ ├── ScriptHashOwner.cs │ │ └── SessionLogger.cs │ ├── ServerConfig.cs │ ├── ServerConfigType.cs │ ├── Servers │ │ ├── GarnetServerBase.cs │ │ ├── GarnetServerOptions.cs │ │ ├── GarnetServerTcp.cs │ │ ├── IGarnetServer.cs │ │ ├── IServerSerializer.cs │ │ ├── MetricsApi.cs │ │ ├── RegisterApi.cs │ │ ├── ServerOptions.cs │ │ ├── ServerTcpNetworkHandler.cs │ │ └── StoreApi.cs │ ├── SessionParseStateExtensions.cs │ ├── Sessions │ │ ├── ISessionProvider.cs │ │ └── ServerSessionBase.cs │ ├── SortedSetAggregateType.cs │ ├── SpanByteFunctionsForServer.cs │ ├── SpanByteServerSerializer.cs │ ├── Storage │ │ ├── Functions │ │ │ ├── EtagState.cs │ │ │ ├── FunctionsState.cs │ │ │ ├── MainStore │ │ │ │ ├── CallbackMethods.cs │ │ │ │ ├── DeleteMethods.cs │ │ │ │ ├── MainSessionFunctions.cs │ │ │ │ ├── PrivateMethods.cs │ │ │ │ ├── RMWMethods.cs │ │ │ │ ├── ReadMethods.cs │ │ │ │ ├── UpsertMethods.cs │ │ │ │ └── VarLenInputMethods.cs │ │ │ └── ObjectStore │ │ │ │ ├── CallbackMethods.cs │ │ │ │ ├── DeleteMethods.cs │ │ │ │ ├── ObjectSessionFunctions.cs │ │ │ │ ├── PrivateMethods.cs │ │ │ │ ├── RMWMethods.cs │ │ │ │ ├── ReadMethods.cs │ │ │ │ ├── UpsertMethods.cs │ │ │ │ └── VarLenInputMethods.cs │ │ ├── Session │ │ │ ├── Common │ │ │ │ ├── ArrayKeyIterationFunctions.cs │ │ │ │ └── MemoryUtils.cs │ │ │ ├── MainStore │ │ │ │ ├── AdvancedOps.cs │ │ │ │ ├── BitmapOps.cs │ │ │ │ ├── CompletePending.cs │ │ │ │ ├── HyperLogLogOps.cs │ │ │ │ └── MainStoreOps.cs │ │ │ ├── Metrics.cs │ │ │ ├── ObjectStore │ │ │ │ ├── AdvancedOps.cs │ │ │ │ ├── Common.cs │ │ │ │ ├── CompletePending.cs │ │ │ │ ├── HashOps.cs │ │ │ │ ├── ListOps.cs │ │ │ │ ├── SetOps.cs │ │ │ │ ├── SortedSetGeoOps.cs │ │ │ │ └── SortedSetOps.cs │ │ │ └── StorageSession.cs │ │ └── SizeTracker │ │ │ └── CacheSizeTracker.cs │ ├── StoreWrapper.cs │ ├── TLS │ │ ├── CertificateUtils.cs │ │ ├── GarnetTlsOptions.cs │ │ ├── IGarnetTlsOptions.cs │ │ └── ServerCertificateSelector.cs │ └── Transaction │ │ ├── TransactionManager.cs │ │ ├── TxnClusterSlotCheck.cs │ │ ├── TxnKeyEntry.cs │ │ ├── TxnKeyEntryComparison.cs │ │ ├── TxnKeyManager.cs │ │ ├── TxnRespCommands.cs │ │ ├── TxnState.cs │ │ ├── TxnWatchedKeysContainer.cs │ │ ├── WatchVersionMap.cs │ │ └── WatchedKeySlice.cs └── storage │ └── Tsavorite │ ├── .gitignore │ ├── README.md │ ├── cc │ ├── CMakeLists.txt │ ├── README.md │ └── src │ │ ├── CMakeLists.txt │ │ └── device │ │ ├── alloc.h │ │ ├── async.h │ │ ├── auto_ptr.h │ │ ├── constants.h │ │ ├── file.h │ │ ├── file_common.h │ │ ├── file_linux.cc │ │ ├── file_linux.h │ │ ├── file_system_disk.h │ │ ├── file_windows.cc │ │ ├── file_windows.h │ │ ├── gc_state.h │ │ ├── guid.h │ │ ├── light_epoch.h │ │ ├── lss_allocator.cc │ │ ├── lss_allocator.h │ │ ├── native_device.h │ │ ├── native_device_wrapper.cc │ │ ├── phase.h │ │ ├── status.h │ │ ├── thread.h │ │ ├── thread_manual.cc │ │ └── utility.h │ └── cs │ ├── README.md │ ├── Tsavorite.sln │ ├── benchmark │ ├── BDN-Tsavorite.Benchmark │ │ ├── BDN-Tsavorite.benchmark.csproj │ │ ├── BenchmarkDotNetTestsApp.cs │ │ ├── InliningTests.cs │ │ └── IterationTests.cs │ └── YCSB.benchmark │ │ ├── ConcurrentDictionaryBenchmark.cs │ │ ├── FixedLenYcsbBenchmark.cs │ │ ├── Input.cs │ │ ├── Key.cs │ │ ├── KeySpanByte.cs │ │ ├── Options.cs │ │ ├── Output.cs │ │ ├── Program.cs │ │ ├── RandomGenerator.cs │ │ ├── SessionFunctions.cs │ │ ├── SessionSpanByteFunctions.cs │ │ ├── SpanByteYcsbBenchmark.cs │ │ ├── TestLoader.cs │ │ ├── TestStats.cs │ │ ├── Value.cs │ │ ├── YCSB.benchmark.csproj │ │ ├── YcsbConstants.cs │ │ ├── ZipfGenerator.cs │ │ └── scripts │ │ ├── compare_runs.ps1 │ │ └── run_benchmark.ps1 │ ├── src │ ├── core │ │ ├── Allocator │ │ │ ├── AllocatorBase.cs │ │ │ ├── AllocatorRecord.cs │ │ │ ├── AllocatorScan.cs │ │ │ ├── AllocatorSettings.cs │ │ │ ├── AsyncIOContext.cs │ │ │ ├── AtomicOwner.cs │ │ │ ├── BlittableAllocator.cs │ │ │ ├── BlittableAllocatorImpl.cs │ │ │ ├── BlittableFrame.cs │ │ │ ├── BlittableScanIterator.cs │ │ │ ├── ErrorList.cs │ │ │ ├── GenericAllocator.cs │ │ │ ├── GenericAllocatorImpl.cs │ │ │ ├── GenericFrame.cs │ │ │ ├── GenericScanIterator.cs │ │ │ ├── IAllocator.cs │ │ │ ├── IAllocatorCallbacks.cs │ │ │ ├── IScanIteratorFunctions.cs │ │ │ ├── IStreamingSnapshotIteratorFunctions.cs │ │ │ ├── ITsavoriteScanIterator.cs │ │ │ ├── MallocFixedPageSize.cs │ │ │ ├── MemoryPageScanIterator.cs │ │ │ ├── PageUnit.cs │ │ │ ├── PendingFlushList.cs │ │ │ ├── ScanCursorState.cs │ │ │ ├── ScanIteratorBase.cs │ │ │ ├── SpanByteAllocator.cs │ │ │ ├── SpanByteAllocatorImpl.cs │ │ │ ├── SpanByteScanIterator.cs │ │ │ ├── WorkQueueFIFO.cs │ │ │ └── WorkQueueLIFO.cs │ │ ├── Async │ │ │ └── CompletePendingAsync.cs │ │ ├── ClientSession │ │ │ ├── BasicContext.cs │ │ │ ├── ClientSession.cs │ │ │ ├── IClientSession.cs │ │ │ ├── ILockableContext.cs │ │ │ ├── ITsavoriteContext.cs │ │ │ ├── IUnsafeContext.cs │ │ │ ├── LockableContext.cs │ │ │ ├── LockableUnsafeContext.cs │ │ │ ├── ManageClientSessions.cs │ │ │ ├── SessionFunctionsWrapper.cs │ │ │ └── UnsafeContext.cs │ │ ├── Compaction │ │ │ ├── CompactionType.cs │ │ │ ├── ICompactionFunctions.cs │ │ │ ├── LogCompactionFunctions.cs │ │ │ └── TsavoriteCompaction.cs │ │ ├── Device │ │ │ ├── AsyncPool.cs │ │ │ ├── Devices.cs │ │ │ ├── IDevice.cs │ │ │ ├── LocalMemoryDevice.cs │ │ │ ├── LocalStorageDevice.cs │ │ │ ├── ManagedLocalStorageDevice.cs │ │ │ ├── NativeStorageDevice.cs │ │ │ ├── NullDevice.cs │ │ │ ├── ShardedStorageDevice.cs │ │ │ ├── StorageDeviceBase.cs │ │ │ ├── TieredStorageDevice.cs │ │ │ └── runtimes │ │ │ │ ├── linux-x64 │ │ │ │ └── native │ │ │ │ │ └── libnative_device.so │ │ │ │ └── win-x64 │ │ │ │ └── native │ │ │ │ ├── native_device.dll │ │ │ │ └── native_device.pdb │ │ ├── Epochs │ │ │ └── LightEpoch.cs │ │ ├── Index │ │ │ ├── CheckpointManagement │ │ │ │ ├── DefaultCheckpointNamingScheme.cs │ │ │ │ ├── DeviceLogCommitCheckpointManager.cs │ │ │ │ ├── ICheckpointNamingScheme.cs │ │ │ │ ├── INamedDeviceFactory.cs │ │ │ │ ├── INamedDeviceFactoryCreator.cs │ │ │ │ ├── LocalStorageNamedDeviceFactory.cs │ │ │ │ ├── LocalStorageNamedDeviceFactoryCreator.cs │ │ │ │ ├── NullNamedDeviceFactory.cs │ │ │ │ ├── NullNamedDeviceFactoryCreator.cs │ │ │ │ └── RecoveryInfo.cs │ │ │ ├── Checkpointing │ │ │ │ ├── Checkpoint.cs │ │ │ │ ├── FoldOverSMTask.cs │ │ │ │ ├── FullCheckpointSM.cs │ │ │ │ ├── HybridLogCheckpointSM.cs │ │ │ │ ├── HybridLogCheckpointSMTask.cs │ │ │ │ ├── IStateMachine.cs │ │ │ │ ├── IStateMachineCallback.cs │ │ │ │ ├── IStateMachineTask.cs │ │ │ │ ├── IncrementalSnapshotCheckpointSMTask.cs │ │ │ │ ├── IndexCheckpointSM.cs │ │ │ │ ├── IndexCheckpointSMTask.cs │ │ │ │ ├── IndexResizeSM.cs │ │ │ │ ├── IndexResizeSMTask.cs │ │ │ │ ├── SnapshotCheckpointSMTask.cs │ │ │ │ ├── StateMachineBase.cs │ │ │ │ ├── StateMachineDriver.cs │ │ │ │ ├── StateTransitions.cs │ │ │ │ ├── StreamingSnapshotCheckpointSM.cs │ │ │ │ ├── StreamingSnapshotCheckpointSMTask.cs │ │ │ │ ├── StreamingSnapshotTsavoriteKV.cs │ │ │ │ ├── TsavoriteStateMachineProperties.cs │ │ │ │ └── VersionChangeSM.cs │ │ │ ├── Common │ │ │ │ ├── AddressInfo.cs │ │ │ │ ├── CheckpointSettings.cs │ │ │ │ ├── CompletedOutput.cs │ │ │ │ ├── ConcurrentCounter.cs │ │ │ │ ├── ExecutionContext.cs │ │ │ │ ├── HeapContainer.cs │ │ │ │ ├── KVSettings.cs │ │ │ │ ├── LogSettings.cs │ │ │ │ ├── LogSizeTracker.cs │ │ │ │ ├── OperationOptions.cs │ │ │ │ ├── OperationStatus.cs │ │ │ │ ├── PendingContext.cs │ │ │ │ ├── ReadCacheSettings.cs │ │ │ │ ├── RecordInfo.cs │ │ │ │ ├── RecordMetadata.cs │ │ │ │ └── SingleWaiterAutoResetEvent.cs │ │ │ ├── Interfaces │ │ │ │ ├── CallbackInfos.cs │ │ │ │ ├── DataContractObjectSerializer.cs │ │ │ │ ├── IKeyComparer.cs │ │ │ │ ├── IObjectSerializer.cs │ │ │ │ ├── ISessionFunctions.cs │ │ │ │ ├── ISessionFunctionsWrapper.cs │ │ │ │ ├── ISessionLocker.cs │ │ │ │ ├── KeyComparers.cs │ │ │ │ ├── ObjectSerializer.cs │ │ │ │ ├── SessionFunctionsBase.cs │ │ │ │ └── TryAddFunctions.cs │ │ │ ├── Recovery │ │ │ │ ├── Checkpoint.cs │ │ │ │ ├── DeltaLog.cs │ │ │ │ ├── FileDescriptor.cs │ │ │ │ ├── ICheckpointManager.cs │ │ │ │ ├── IndexCheckpoint.cs │ │ │ │ ├── IndexRecovery.cs │ │ │ │ └── Recovery.cs │ │ │ ├── StoreFunctions │ │ │ │ ├── DisposeReason.cs │ │ │ │ ├── IRecordDisposer.cs │ │ │ │ ├── IStoreFunctions.cs │ │ │ │ └── StoreFunctions.cs │ │ │ └── Tsavorite │ │ │ │ ├── Constants.cs │ │ │ │ ├── Extensions.cs │ │ │ │ ├── HashBucket.cs │ │ │ │ ├── HashBucketEntry.cs │ │ │ │ ├── Implementation │ │ │ │ ├── BlockAllocate.cs │ │ │ │ ├── ConditionalCopyToTail.cs │ │ │ │ ├── ContainsKeyInMemory.cs │ │ │ │ ├── ContinuePending.cs │ │ │ │ ├── EpochOperations.cs │ │ │ │ ├── FindRecord.cs │ │ │ │ ├── HandleOperationStatus.cs │ │ │ │ ├── HashEntryInfo.cs │ │ │ │ ├── Helpers.cs │ │ │ │ ├── InternalDelete.cs │ │ │ │ ├── InternalLock.cs │ │ │ │ ├── InternalRMW.cs │ │ │ │ ├── InternalRead.cs │ │ │ │ ├── InternalUpsert.cs │ │ │ │ ├── Locking │ │ │ │ │ ├── ILockTable.cs │ │ │ │ │ ├── OverflowBucketLockTable.cs │ │ │ │ │ └── TransientLocking.cs │ │ │ │ ├── ModifiedBitOperation.cs │ │ │ │ ├── OperationStackContext.cs │ │ │ │ ├── ReadCache.cs │ │ │ │ ├── RecordSource.cs │ │ │ │ ├── Revivification │ │ │ │ │ ├── CheckEmptyWorker.cs │ │ │ │ │ ├── FreeRecordPool.cs │ │ │ │ │ ├── RecordLengths.cs │ │ │ │ │ ├── RevivificationManager.cs │ │ │ │ │ ├── RevivificationSettings.cs │ │ │ │ │ └── RevivificationStats.cs │ │ │ │ ├── SplitIndex.cs │ │ │ │ ├── TryCopyToReadCache.cs │ │ │ │ └── TryCopyToTail.cs │ │ │ │ ├── LogAccessor.cs │ │ │ │ ├── Tsavorite.cs │ │ │ │ ├── TsavoriteBase.cs │ │ │ │ ├── TsavoriteIterator.cs │ │ │ │ ├── TsavoriteThread.cs │ │ │ │ └── WriteReason.cs │ │ ├── Tsavorite.core.csproj │ │ ├── TsavoriteLog │ │ │ ├── CommitFailureException.cs │ │ │ ├── CommitInfo.cs │ │ │ ├── ILogCommitManager.cs │ │ │ ├── ILogEnqueueEntry.cs │ │ │ ├── ILogEntryConsumer.cs │ │ │ ├── IReadOnlySpanBatch.cs │ │ │ ├── IStoreInput.cs │ │ │ ├── LogCommitPolicy.cs │ │ │ ├── TsavoriteLog.cs │ │ │ ├── TsavoriteLogIterator.cs │ │ │ ├── TsavoriteLogRecoveryInfo.cs │ │ │ ├── TsavoriteLogScanSingleIterator.cs │ │ │ └── TsavoriteLogSettings.cs │ │ ├── Utilities │ │ │ ├── AsyncCountDown.cs │ │ │ ├── AsyncQueue.cs │ │ │ ├── AsyncResultTypes.cs │ │ │ ├── BufferPool.cs │ │ │ ├── CompletionEvent.cs │ │ │ ├── LockType.cs │ │ │ ├── Native32.cs │ │ │ ├── OverflowPool.cs │ │ │ ├── PageAsyncResultTypes.cs │ │ │ ├── SafeConcurrentDictionary.cs │ │ │ ├── Status.cs │ │ │ ├── StatusCode.cs │ │ │ ├── TsavoriteException.cs │ │ │ └── Utility.cs │ │ └── VarLen │ │ │ ├── IVariableLengthInput.cs │ │ │ ├── SpanByte.cs │ │ │ ├── SpanByteAndMemory.cs │ │ │ ├── SpanByteComparer.cs │ │ │ ├── SpanByteFunctions.cs │ │ │ ├── SpanByteHeapContainer.cs │ │ │ └── UnmanagedMemoryManager.cs │ └── devices │ │ └── AzureStorageDevice │ │ ├── AzureCheckpointNamingScheme.cs │ │ ├── AzureStorageDevice.cs │ │ ├── AzureStorageNamedDeviceFactory.cs │ │ ├── AzureStorageNamedDeviceFactoryCreator.cs │ │ ├── BlobEntry.cs │ │ ├── BlobManager.cs │ │ ├── BlobUtils.cs │ │ ├── BlobUtilsV12.cs │ │ ├── IBlobManager.cs │ │ ├── IStorageErrorHandler.cs │ │ ├── LeaseTimer.cs │ │ ├── StorageErrorHandler.cs │ │ ├── StorageOperations.cs │ │ ├── TrackedThreads.cs │ │ ├── Tsavorite.devices.AzureStorageDevice.csproj │ │ ├── TsavoriteTraceHelper.cs │ │ └── Utils.cs │ └── test │ ├── BasicLockTests.cs │ ├── BasicStorageTests.cs │ ├── BasicTests.cs │ ├── BlittableIterationTests.cs │ ├── BlittableLogCompactionTests.cs │ ├── BlittableLogScanTests.cs │ ├── CancellationTests.cs │ ├── CheckpointManagerTests.cs │ ├── CompletePendingTests.cs │ ├── ComponentRecoveryTests.cs │ ├── ConcurrentCounterTests.cs │ ├── DeltaLogTests.cs │ ├── DeviceLogTests.cs │ ├── DeviceTests.cs │ ├── EnqueueAndWaitForCommit.cs │ ├── EnqueueTests.cs │ ├── EpochProtectedVersionScheme.cs │ ├── ExpirationTests.cs │ ├── FlakyDeviceTests.cs │ ├── FunctionPerSessionTests.cs │ ├── GenericByteArrayTests.cs │ ├── GenericDiskDeleteTests.cs │ ├── GenericIterationTests.cs │ ├── GenericLogCompactionTests.cs │ ├── GenericLogScanTests.cs │ ├── GenericStringTests.cs │ ├── InputOutputParameterTests.cs │ ├── InsertAtTailSpanByteStressTests.cs │ ├── LargeObjectTests.cs │ ├── LockableUnsafeContextTests.cs │ ├── LogAndDeviceConfigTests.cs │ ├── LogFastCommitTests.cs │ ├── LogFormatter.cs │ ├── LogReadAsyncTests.cs │ ├── LogRecoverReadOnlyTests.cs │ ├── LogResumeTests.cs │ ├── LogScanTests.cs │ ├── LogShiftTailStressTest.cs │ ├── LogTests.cs │ ├── LowMemoryTests.cs │ ├── MallocFixedPageSizeTests.cs │ ├── ManagedLocalStorageTests.cs │ ├── MiscTests.cs │ ├── ModifiedBitTests.cs │ ├── MoreLogCompactionTests.cs │ ├── NUnitLoggerProvider.cs │ ├── NameValidator.cs │ ├── NativeReadCacheTests.cs │ ├── NeedCopyUpdateTests.cs │ ├── ObjectReadCacheTests.cs │ ├── ObjectRecoveryTest.cs │ ├── ObjectRecoveryTest2.cs │ ├── ObjectRecoveryTest3.cs │ ├── ObjectRecoveryTestTypes.cs │ ├── ObjectTestTypes.cs │ ├── ObjectTests.cs │ ├── OverflowBucketLockTableTests.cs │ ├── PostOperationsTests.cs │ ├── ReadAddressTests.cs │ ├── ReadCacheChainTests.cs │ ├── RecoverReadOnlyTest.cs │ ├── RecoveryChecks.cs │ ├── RecoveryTestTypes.cs │ ├── RecoveryTests.cs │ ├── ReproReadCacheTest.cs │ ├── RevivificationTests.cs │ ├── SessionTests.cs │ ├── SharedDirectoryTests.cs │ ├── SimpleRecoveryTest.cs │ ├── SimpleTests.cs │ ├── SimpleVersionSchemeTest.cs │ ├── SimulatedFlakyDevice.cs │ ├── SingleWriterTests.cs │ ├── SpanByteIterationTests.cs │ ├── SpanByteLogScanTests.cs │ ├── SpanByteTests.cs │ ├── SpanByteVLVectorTests.cs │ ├── StateMachineDriverTests.cs │ ├── StructWithStringTests.cs │ ├── TestTypes.cs │ ├── TestUtils.cs │ ├── TryEnqueueBasicTests.cs │ ├── Tsavorite.test.csproj │ ├── UnsafeContextTests.cs │ ├── VLVector.cs │ └── WaitForCommit.cs ├── main └── GarnetServer │ ├── Extensions │ ├── DeleteIfMatch.cs │ ├── GetTwoKeysNoTxn.cs │ ├── MGetIfPM.cs │ ├── MSetPx.cs │ ├── MyDictGet.cs │ ├── MyDictObject.cs │ ├── MyDictSet.cs │ ├── ReadWriteTxn.cs │ ├── SampleDeleteTxn.cs │ ├── SampleUpdateTxn.cs │ ├── SetIfPM.cs │ ├── SetStringAndList.cs │ ├── SetWPIfPGT.cs │ └── Sum.cs │ ├── GarnetServer.csproj │ ├── Program.cs │ ├── Properties │ └── PublishProfiles │ │ ├── linux-arm64-based.pubxml │ │ ├── linux-x64-based.pubxml │ │ ├── osx-arm64-based.pubxml │ │ ├── osx-x64-based.pubxml │ │ ├── portable.pubxml │ │ ├── win-arm64-based-readytorun.pubxml │ │ └── win-x64-based-readytorun.pubxml │ ├── README.md │ └── garnet.conf ├── metrics └── HdrHistogram │ ├── .editorconfig │ ├── HdrHistogram.csproj │ ├── HistogramBase.cs │ ├── HistogramExtensions.cs │ ├── IRecorder.cs │ ├── Iteration │ ├── AbstractHistogramEnumerator.cs │ ├── AllValueEnumerable.cs │ ├── AllValuesEnumerator.cs │ ├── HistogramIterationValue.cs │ ├── PercentileEnumerable.cs │ ├── PercentileEnumerator.cs │ ├── RecordedValuesEnumerable.cs │ └── RecordedValuesEnumerator.cs │ ├── LongConcurrentHistogram.cs │ ├── LongHistogram.cs │ ├── OutputScalingFactor.cs │ ├── TimeStamp.cs │ └── Utilities │ ├── AtomicLongArray.cs │ └── WriterReaderPhaser.cs ├── modules ├── GarnetJSON │ ├── GarnetJSON.csproj │ ├── GarnetJsonObject.cs │ ├── JSONPath │ │ ├── ArrayIndexFilter.cs │ │ ├── ArrayMultipleIndexFilter.cs │ │ ├── ArraySliceFilter.cs │ │ ├── FieldFilter.cs │ │ ├── FieldMultipleFilter.cs │ │ ├── JsonExtensions.cs │ │ ├── JsonPath.cs │ │ ├── JsonSelectSettings.cs │ │ ├── PathFilter.cs │ │ ├── QueryExpression.cs │ │ ├── QueryFilter.cs │ │ ├── QueryScanFilter.cs │ │ ├── RootFilter.cs │ │ ├── ScanFilter.cs │ │ └── ScanMultipleFilter.cs │ ├── JsonCmdStrings.cs │ ├── JsonCommands.cs │ ├── JsonModule.cs │ └── RespJsonEnums.cs └── NoOpModule │ ├── DummyObject.cs │ ├── DummyObjectNoOpRMW.cs │ ├── DummyObjectNoOpRead.cs │ ├── NoOpCommandRMW.cs │ ├── NoOpCommandRead.cs │ ├── NoOpModule.cs │ ├── NoOpModule.csproj │ ├── NoOpProc.cs │ └── NoOpTxn.cs ├── playground ├── Bitmap │ ├── BitCount.cs │ ├── BitOp.cs │ ├── Bitmap.csproj │ ├── Common.cs │ ├── MemoryPoolBuffers.cs │ └── Program.cs ├── ClusterStress │ ├── ClusterOptions.cs │ ├── ClusterStress.csproj │ ├── OnlineReqGen.cs │ ├── Program.cs │ ├── ReqGenForCluster.cs │ ├── ReqGenSharded.cs │ ├── ReqGenUtilsCluster.cs │ ├── ShardedRespOnlineBench.cs │ └── ShardedRespPerfBench.cs ├── CommandInfoUpdater │ ├── CommandDocsUpdater.cs │ ├── CommandInfoUpdater.cs │ ├── CommandInfoUpdater.csproj │ ├── CommonUtils.cs │ ├── GarnetCommandsDocs.json │ ├── GarnetCommandsInfo.json │ ├── Options.cs │ ├── Program.cs │ ├── RespCommandDocsParser.cs │ ├── RespCommandInfoParser.cs │ └── SupportedCommand.cs ├── Embedded.perftest │ ├── Embedded.perftest.csproj │ ├── EmbeddedPerformanceTest.cs │ ├── Operation.cs │ ├── Options.cs │ ├── PerformanceTestLoggerProvider.cs │ └── Program.cs ├── GarnetClientStress │ ├── GarnetClientStress.csproj │ ├── Options.cs │ ├── Program.cs │ ├── ProgressBar.cs │ ├── SimpleStressTests.cs │ ├── StressTestUtil.cs │ └── TaskScaling.cs ├── MigrateBench │ ├── BenchmarkLoggerProvider.cs │ ├── Common.cs │ ├── MigrateBench.csproj │ ├── MigrateRequest.cs │ ├── MigrateSlotWalk.cs │ ├── Options.cs │ └── Program.cs ├── SampleModule │ ├── SampleModule.cs │ └── SampleModule.csproj └── TstRunner │ ├── Program.cs │ └── TstRunner.csproj ├── samples ├── ETag │ ├── Caching.cs │ ├── ETag.csproj │ ├── EtagAbstractions.cs │ ├── OccSimulation.cs │ └── Program.cs ├── GarnetClientSample │ ├── GarnetClientSample.csproj │ ├── GarnetClientSamples.cs │ ├── Program.cs │ └── SERedisSamples.cs └── MetricsMonitor │ ├── ClientMonitor.cs │ ├── Configuration.cs │ ├── MetricsMonitor.csproj │ ├── Options.cs │ └── Program.cs ├── test ├── BDNPerfTests │ ├── BDN_Benchmark_Config.json │ └── run_bdnperftest.ps1 ├── Garnet.fuzz │ ├── FuzzOptions.cs │ ├── FuzzTargets.cs │ ├── Garnet.fuzz.csproj │ ├── Program.cs │ └── Targets │ │ ├── GarnetEndToEnd.cs │ │ ├── IFuzzerTarget.cs │ │ ├── LuaScriptCompilation.cs │ │ └── RespCommandParsing.cs ├── Garnet.test.cluster │ ├── ClientClusterConfig.cs │ ├── ClusterAadAuthTests.cs │ ├── ClusterAuthCommsTests.cs │ ├── ClusterConfigTests.cs │ ├── ClusterManagementTests.cs │ ├── ClusterMigrateTLSTests.cs │ ├── ClusterMigrateTests.cs │ ├── ClusterNegativeTests.cs │ ├── ClusterRedirectTests.cs │ ├── ClusterTestContext.cs │ ├── ClusterTestUtils.cs │ ├── Garnet.test.cluster.csproj │ ├── JwtTokenHelpers.cs │ ├── RedirectTests │ │ ├── BaseCommand.cs │ │ ├── ClusterSlotVerificationTests.cs │ │ └── TestClusterProc.cs │ ├── ReplicationTests │ │ ├── ClusterReplicationAsyncReplay.cs │ │ ├── ClusterReplicationBaseTests.cs │ │ ├── ClusterReplicationDisklessSyncTests.cs │ │ └── ClusterReplicationTLS.cs │ └── packages.config ├── Garnet.test │ ├── CacheSizeTrackerTests.cs │ ├── CredentialManager.cs │ ├── CustomRespCommandsDocs.json │ ├── CustomRespCommandsInfo.json │ ├── DeleteTxn.cs │ ├── DocsTests.cs │ ├── Extensions │ │ ├── ProcCustomCmd.cs │ │ ├── RateLimiterTxn.cs │ │ ├── SortedSetCountTxn.cs │ │ └── TxnCustomCmd.cs │ ├── Garnet.test.csproj │ ├── GarnetBitmapTests.cs │ ├── GarnetClientTests.cs │ ├── GarnetJSON │ │ ├── JSONPath │ │ │ ├── JsonAssert.cs │ │ │ ├── JsonPathExecuteTests.cs │ │ │ ├── JsonPathParseTests.cs │ │ │ └── QueryExpressionTests.cs │ │ └── JsonCommandsTest.cs │ ├── GarnetObjectTests.cs │ ├── GarnetServerConfigTests.cs │ ├── GeoHashTests.cs │ ├── HyperLogLogTests.cs │ ├── IndexGrowthTests.cs │ ├── LuaScriptRunnerTests.cs │ ├── LuaScriptTests.cs │ ├── MultiDatabaseTests.cs │ ├── NUnitLoggerProvider.cs │ ├── NetworkTests.cs │ ├── NumUtils.cs │ ├── ObjectExpiryTxn.cs │ ├── ObjectTestsForOutput.cs │ ├── ReadCacheTests.cs │ ├── ReqGen.cs │ ├── Resp │ │ ├── ACL │ │ │ ├── AclConfigurationFileTests.cs │ │ │ ├── AclParserTests.cs │ │ │ ├── AclTest.cs │ │ │ ├── BasicTests.cs │ │ │ ├── DeleteUserTests.cs │ │ │ ├── GetUserTests.cs │ │ │ ├── ParallelTests.cs │ │ │ ├── RespCommandTests.cs │ │ │ ├── SetUserTests.cs │ │ │ └── UserAclResult.cs │ │ ├── GarnetAuthenticatorTests.cs │ │ └── RespReadUtilsTests.cs │ ├── RespAdminCommandsTests.cs │ ├── RespAofAzureTests.cs │ ├── RespAofTests.cs │ ├── RespBlockingCollectionTests.cs │ ├── RespCommandTests.cs │ ├── RespCustomCommandTests.cs │ ├── RespEtagTests.cs │ ├── RespGetLowMemoryTests.cs │ ├── RespHashTests.cs │ ├── RespInfoTests.cs │ ├── RespListGarnetClientTests.cs │ ├── RespListTests.cs │ ├── RespLowMemoryTests.cs │ ├── RespMetricsTest.cs │ ├── RespModuleTests.cs │ ├── RespPubSubTests.cs │ ├── RespScanCommandsTests.cs │ ├── RespSetTest.cs │ ├── RespSlowLogTests.cs │ ├── RespSortedSetGarnetClientTests.cs │ ├── RespSortedSetGeoTests.cs │ ├── RespSortedSetTests.cs │ ├── RespTests.cs │ ├── RespTestsUtils.cs │ ├── RespTlsTests.cs │ ├── RespTransactionProcTests.cs │ ├── ServerCredential.cs │ ├── SortedSetRemoveTxn.cs │ ├── TestProcedureBitmap.cs │ ├── TestProcedureHLL.cs │ ├── TestProcedureHash.cs │ ├── TestProcedureLists.cs │ ├── TestProcedureSet.cs │ ├── TestProcedureSortedSets.cs │ ├── TestProcess.cs │ ├── TestUtils.cs │ ├── TransactionTests.cs │ ├── UnixSocketTests.cs │ ├── WriteWithExpiryTxn.cs │ ├── redis.conf │ ├── runGarnetTests.cmd │ ├── test.bat │ └── test.sh ├── PerfRegressionTesting │ ├── ConfigFiles │ │ ├── CI_Config_Offline_Get_1Thr.json │ │ ├── CI_Config_Offline_Get_MaxThr.json │ │ ├── CI_Config_Offline_ZADDREM_1Thr.json │ │ ├── CI_Config_Offline_ZADDREM_MaxThr.json │ │ ├── CI_Config_Online_GetSet_1Thr.json │ │ ├── CI_Config_Online_GetSet_MaxThr.json │ │ ├── CI_Config_Online_ZADDZREM_1Thr.json │ │ └── CI_Config_Online_ZADDZREM_MaxThr.json │ └── run_benchmark.ps1 └── testcerts │ ├── README.md │ ├── garnet-ca.crt │ ├── garnet-cert.crt │ ├── garnet.key │ └── testcert.pfx └── website ├── .gitignore ├── README.md ├── babel.config.js ├── blog ├── 2024-03-17-a-brief-history-of-garnet.md ├── 2024-03-18-oss-announcement.md ├── 2025-01-18-etag-when-and-how.md └── authors.yml ├── docs ├── benchmarking │ ├── overview.md │ ├── resp-bench.md │ └── results-resp-bench.md ├── cluster │ ├── key-migration.md │ ├── overview.md │ └── replication.md ├── commands │ ├── acl.md │ ├── analytics.md │ ├── api-compatibility.md │ ├── checkpoint.md │ ├── client.md │ ├── cluster.md │ ├── data-structures.md │ ├── garnet-specific.md │ ├── generic-commands.md │ ├── json.md │ ├── overview.md │ ├── raw-string.md │ ├── scripting-and-functions.md │ ├── server.md │ └── transactions.md ├── dev │ ├── cluster.md │ ├── cluster │ │ ├── migration.md │ │ ├── overview.md │ │ └── sharding.md │ ├── code-structure.md │ ├── collection-broker.md │ ├── configuration.md │ ├── contributing.md │ ├── custom-commands.md │ ├── garnet-api.md │ ├── multi-db.md │ ├── network.md │ ├── onboarding.md │ ├── processing.md │ ├── transactions.md │ └── tsavorite │ │ ├── epochprotection.md │ │ ├── intro.md │ │ ├── locking.md │ │ ├── reviv.md │ │ └── storefunctions.md ├── extensions │ ├── module.md │ ├── objects.md │ ├── overview.md │ ├── procedure.md │ ├── raw-strings.md │ └── transactions.md ├── getting-started │ ├── build.md │ ├── compaction.md │ ├── configuration.md │ ├── memory.md │ └── security.md ├── research │ └── papers.md └── welcome │ ├── about-us.md │ ├── compatibility.md │ ├── faq.md │ ├── features.md │ ├── intro.md │ ├── news.md │ ├── releases.md │ └── roadmap.md ├── docusaurus.config.js ├── package.json ├── sidebars.js ├── src ├── components │ └── HomepageFeatures │ │ ├── index.js │ │ └── styles.module.css ├── css │ └── custom.css └── pages │ ├── index.js │ ├── index.module.css │ └── markdown-page.md ├── static ├── .nojekyll └── img │ ├── benchmark │ ├── lat-get-set-batchsize.png │ ├── lat-get-set-threads.png │ ├── tpt-bitop-batchsize.png │ ├── tpt-bitop-threads.png │ ├── tpt-get-batchsize.png │ ├── tpt-get-threads.png │ ├── tpt-getbit-setbit-batchsize.png │ ├── tpt-getbit-setbit-threads.png │ ├── tpt-pfadd-batchsize.png │ ├── tpt-pfadd-few-keys.png │ └── tpt-pfadd-many-keys.png │ ├── favicon.ico │ ├── garnet-bg2-2800x720.jpg │ ├── garnet-bg2-2800x720.png │ ├── garnet-logo-diamond.png │ ├── garnet-logo-inset.png │ ├── garnet-logo.png │ ├── logo_128.png │ ├── undraw_performance_overview_re_mqrq.svg │ ├── undraw_scrum_board_re_wk7v.svg │ └── undraw_secure_login_pdn4.svg └── yarn.lock /.azure/pipelines/credscan-exclusion.json: -------------------------------------------------------------------------------- 1 | { 2 | "tool": "Credential Scanner", 3 | "suppressions": [ 4 | { 5 | "file": "testcert.pfx", 6 | "_justification": "Self-signed certificate used by unit tests." 7 | }, 8 | { 9 | "file": "garnet.key", 10 | "_justification": "Legitimate app certificate file with private key required for the app to function. This is sample test application" 11 | }, 12 | { 13 | "file": "AclConfigurationFileTests.cs", 14 | "_justification": "Passwords and secrets for a test users created and used for only running the tests." 15 | }, 16 | { 17 | "file": "AclTest.cs", 18 | "_justification": "Passwords and secrets for a test users created and used for only running the tests." 19 | }, 20 | { 21 | "file": "redis.key", 22 | "_justification": "Passwords and secrets for a test users created and used for only running the tests." 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /.azure/pipelines/extract_version.ps1: -------------------------------------------------------------------------------- 1 | <#$f 2 | .DESCRIPTION 3 | 4 | This script pulls the version number from Version.props which is located in the root directory. 5 | It then assigns the value to the BuildNumber which can be used in pipeline yml files 6 | #> 7 | 8 | $propsFile = Resolve-Path -Path "$PSScriptRoot/../../Version.props" 9 | [xml]$xml = Get-Content -Path $propsFile 10 | $version = $xml.Project.PropertyGroup.VersionPrefix 11 | Write-Host "##vso[build.updatebuildnumber]$version" -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Directories 2 | **/bin 3 | **/obj 4 | .git 5 | .vs 6 | .vscode 7 | 8 | # Files 9 | .gitignore 10 | **/*.md 11 | docker-compose.yml 12 | docker-compose.*.yml 13 | Dockerfile* 14 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.cs text 7 | *.bat text 8 | *.sh text 9 | *.csproj text 10 | *.conf text 11 | *.cc text 12 | *.h text 13 | 14 | # Declare files that will always have CRLF line endings on checkout. 15 | *.sln text eol=crlf 16 | 17 | # Denote all files that are truly binary and should not be modified. 18 | *.png binary 19 | *.jpg binary -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Recommended by GitHub best practices to have a Code Owner defined especially for .GitHub folder 2 | # NOTE: Order is important; the last matching pattern takes the most precedence. 3 | 4 | # For Workflows used by GitHub Actions 5 | /.github/workflows/ @darrenge @badrishc @TedHartMS @TalZaccai 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Ask a Question 4 | url: https://github.com/microsoft/garnet/discussions/new/choose 5 | about: Please ask and answer questions for garnet here. 6 | - name: Read the Docs 7 | url: https://microsoft.github.io/garnet/ 8 | about: Be sure you've read the docs! -------------------------------------------------------------------------------- /.github/workflows/locker.yml: -------------------------------------------------------------------------------- 1 | name: Locker - Lock stale issues and PRs 2 | on: 3 | schedule: 4 | - cron: '0 9 * * *' # Once per day, early morning PT 5 | 6 | workflow_dispatch: 7 | # Manual triggering through the GitHub UI, API, or CLI 8 | inputs: 9 | daysSinceClose: 10 | required: true 11 | default: "60" 12 | daysSinceUpdate: 13 | required: true 14 | default: "60" 15 | 16 | permissions: 17 | issues: write 18 | pull-requests: write 19 | 20 | jobs: 21 | main: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Checkout Actions 25 | uses: actions/checkout@v4 26 | with: 27 | repository: "microsoft/vscode-github-triage-actions" 28 | path: ./actions 29 | ref: cd16cd2aad6ba2da74bb6c6f7293adddd579a90e # locker action commit sha 30 | - name: Install Actions 31 | run: npm install --production --prefix ./actions 32 | - name: Run Locker 33 | uses: ./actions/locker 34 | with: 35 | daysSinceClose: ${{ fromJson(inputs.daysSinceClose || 60) }} 36 | daysSinceUpdate: ${{ fromJson(inputs.daysSinceUpdate || 60) }} 37 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /Dockerfile.nanoserver: -------------------------------------------------------------------------------- 1 | ARG TAG=ltsc2022 2 | FROM mcr.microsoft.com/dotnet/sdk:9.0-nanoserver-$TAG AS build 3 | 4 | ENV NUGET_PACKAGES=/src/pkg 5 | 6 | WORKDIR /src 7 | 8 | # Copy files 9 | COPY . . 10 | 11 | # Set protected mode to no for Docker images 12 | USER ContainerAdministrator 13 | RUN pwsh -Command "(Get-Content /src/libs/host/defaults.conf) -replace '\""ProtectedMode\"": \"yes\",', '\""ProtectedMode\"": \"no\",' | Set-Content /src/libs/host/defaults.conf" 14 | USER ContainerUser 15 | 16 | WORKDIR /src/main/GarnetServer 17 | 18 | # Restore, build, and publish 19 | RUN dotnet restore && \ 20 | dotnet build -c Release -p:EnableSourceLink=false -p:EnableSourceControlManagerQueries=false && \ 21 | dotnet publish -c Release -o /app -r win-x64 --self-contained false -f net8.0 -p:EnableSourceLink=false -p:EnableSourceControlManagerQueries=false 22 | 23 | # Final stage/image 24 | FROM mcr.microsoft.com/dotnet/runtime:8.0-nanoserver-$TAG AS runtime 25 | WORKDIR /app 26 | COPY --from=build /app . 27 | 28 | # For inter-container communication. 29 | EXPOSE 6379 30 | 31 | ENTRYPOINT ["/app/GarnetServer"] 32 | -------------------------------------------------------------------------------- /Garnet.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/Garnet.snk -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | ## How to file issues and get help 4 | 5 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing 6 | issues before filing new issues to avoid duplicates. For new issues, file your bug or 7 | feature request as a new Issue. 8 | 9 | For help and questions about using this project, please check our [website](https://microsoft.github.io/garnet). 10 | 11 | ## Microsoft Support Policy 12 | 13 | Support for Garnet is limited to the resources listed above. 14 | -------------------------------------------------------------------------------- /Version.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1.0.69 5 | 6 | 7 | -------------------------------------------------------------------------------- /benchmark/BDN.benchmark/Cluster/ClusterParams.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace BDN.benchmark.Cluster 5 | { 6 | /// 7 | /// Cluster parameters 8 | /// 9 | public struct ClusterParams 10 | { 11 | /// 12 | /// Whether to disable slot verification 13 | /// 14 | public bool disableSlotVerification; 15 | 16 | /// 17 | /// Constructor 18 | /// 19 | public ClusterParams(bool disableSlotVerification) 20 | { 21 | this.disableSlotVerification = disableSlotVerification; 22 | } 23 | 24 | /// 25 | /// String representation 26 | /// 27 | public override string ToString() 28 | { 29 | if (!disableSlotVerification) 30 | return "None"; 31 | 32 | var ret = ""; 33 | if (disableSlotVerification) 34 | ret += "DSV"; 35 | return ret; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /benchmark/BDN.benchmark/Cluster/Request.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | namespace BDN.benchmark.Cluster 7 | { 8 | /// 9 | /// Request struct 10 | /// 11 | unsafe struct Request 12 | { 13 | public byte[] buffer; 14 | public byte* ptr; 15 | 16 | public Request(int size) 17 | { 18 | buffer = GC.AllocateArray(size, pinned: true); 19 | ptr = (byte*)Unsafe.AsPointer(ref buffer[0]); 20 | } 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /benchmark/BDN.benchmark/Embedded/Request.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Embedded.server 5 | { 6 | public struct Request 7 | { 8 | public byte[] buffer; 9 | public unsafe byte* bufferPtr; 10 | } 11 | } -------------------------------------------------------------------------------- /benchmark/BDN.benchmark/Geo/GeoHash.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using BenchmarkDotNet.Attributes; 5 | 6 | namespace BDN.benchmark.Geo 7 | { 8 | /// 9 | /// Benchmark for GeoHash 10 | /// 11 | [MemoryDiagnoser] 12 | public class GeoHash 13 | { 14 | private const double Latitude = 47.642219912251285; 15 | private const double Longitude = -122.14205560231471; 16 | 17 | private const long GeoHashInteger = 1557413161902764; 18 | 19 | [Benchmark] 20 | public long GeoToLongValue() => Garnet.server.GeoHash.GeoToLongValue(Latitude, Longitude); 21 | 22 | [Benchmark] 23 | public (double, double) GetCoordinatesFromLong() => Garnet.server.GeoHash.GetCoordinatesFromLong(GeoHashInteger); 24 | 25 | [Benchmark] 26 | public string GetGeoHashCode() => Garnet.server.GeoHash.GetGeoHashCode(GeoHashInteger); 27 | } 28 | } -------------------------------------------------------------------------------- /benchmark/BDN.benchmark/Network/BasicOperations.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using BenchmarkDotNet.Attributes; 5 | using Embedded.server; 6 | 7 | namespace BDN.benchmark.Network 8 | { 9 | /// 10 | /// Benchmark for BasicOperations 11 | /// 12 | [MemoryDiagnoser] 13 | public class BasicOperations : NetworkBase 14 | { 15 | static ReadOnlySpan INLINE_PING => "PING\r\n"u8; 16 | Request ping; 17 | 18 | public override void GlobalSetup() 19 | { 20 | base.GlobalSetup(); 21 | SetupOperation(ref ping, INLINE_PING); 22 | } 23 | 24 | [Benchmark] 25 | public async ValueTask InlinePing() 26 | { 27 | await Send(ping); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /benchmark/BDN.benchmark/Network/NetworkParams.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace BDN.benchmark.Network 5 | { 6 | /// 7 | /// Network parameters 8 | /// 9 | public struct NetworkParams 10 | { 11 | /// 12 | /// Whether to use TLS 13 | /// 14 | public bool useTLS; 15 | 16 | /// 17 | /// Constructor 18 | /// 19 | public NetworkParams(bool useTLS) 20 | { 21 | this.useTLS = useTLS; 22 | } 23 | 24 | /// 25 | /// String representation 26 | /// 27 | public override string ToString() 28 | { 29 | if (!useTLS) 30 | return "None"; 31 | 32 | var ret = ""; 33 | if (useTLS) 34 | ret += "TLS"; 35 | return ret; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /benchmark/BDN.benchmark/Operations/BasicOperations.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using BenchmarkDotNet.Attributes; 5 | using Embedded.server; 6 | 7 | namespace BDN.benchmark.Operations 8 | { 9 | /// 10 | /// Benchmark for BasicOperations 11 | /// 12 | [MemoryDiagnoser] 13 | public unsafe class BasicOperations : OperationsBase 14 | { 15 | static ReadOnlySpan INLINE_PING => "PING\r\n"u8; 16 | Request ping; 17 | 18 | public override void GlobalSetup() 19 | { 20 | base.GlobalSetup(); 21 | SetupOperation(ref ping, INLINE_PING); 22 | } 23 | 24 | [Benchmark] 25 | public void InlinePing() 26 | { 27 | Send(ping); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /benchmark/BDN.benchmark/Operations/ObjectOperations.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using BenchmarkDotNet.Attributes; 5 | using Embedded.server; 6 | 7 | namespace BDN.benchmark.Operations 8 | { 9 | /// 10 | /// Benchmark for ObjectOperations 11 | /// 12 | [MemoryDiagnoser] 13 | public unsafe class ObjectOperations : OperationsBase 14 | { 15 | static ReadOnlySpan LPUSHPOP => "*3\r\n$5\r\nLPUSH\r\n$1\r\nd\r\n$1\r\ne\r\n*2\r\n$4\r\nLPOP\r\n$1\r\nd\r\n"u8; 16 | Request lPushPop; 17 | 18 | public override void GlobalSetup() 19 | { 20 | base.GlobalSetup(); 21 | 22 | SetupOperation(ref lPushPop, LPUSHPOP); 23 | 24 | // Pre-populate data 25 | SlowConsumeMessage("*3\r\n$5\r\nLPUSH\r\n$1\r\nd\r\n$1\r\nf\r\n"u8); 26 | } 27 | 28 | [Benchmark] 29 | public void LPushPop() 30 | { 31 | Send(lPushPop); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /benchmark/BDN.benchmark/Operations/OperationParams.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace BDN.benchmark.Operations 5 | { 6 | /// 7 | /// Operation parameters 8 | /// 9 | public struct OperationParams 10 | { 11 | /// 12 | /// Whether to use ACLs 13 | /// 14 | public bool useACLs; 15 | 16 | /// 17 | /// Whether to use AOF 18 | /// 19 | public bool useAof; 20 | 21 | /// 22 | /// Constructor 23 | /// 24 | public OperationParams(bool useACLs, bool useAof) 25 | { 26 | this.useACLs = useACLs; 27 | this.useAof = useAof; 28 | } 29 | 30 | /// 31 | /// String representation 32 | /// 33 | public override string ToString() 34 | { 35 | if (!useACLs && !useAof) 36 | return "None"; 37 | 38 | var ret = ""; 39 | if (useACLs) 40 | ret += "ACL"; 41 | if (useAof) 42 | ret += (ret.Length > 0 ? "+" : "") + "AOF"; 43 | return ret; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /benchmark/BDN.benchmark/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("Garnet.fuzz" + AssemblyRef.GarnetPublicKey)] -------------------------------------------------------------------------------- /benchmark/BDN.benchmark/Utils/BenchUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Text; 5 | 6 | namespace BDN.benchmark 7 | { 8 | public class BenchUtils 9 | { 10 | static readonly byte[] ascii_chars = Encoding.ASCII.GetBytes("abcdefghijklmnopqrstvuwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); 11 | Random rnd; 12 | 13 | public BenchUtils() 14 | { 15 | rnd = new Random(674386); 16 | } 17 | 18 | public void RandomBytes(ref byte[] data, int startOffset = -1, int endOffset = -1) 19 | { 20 | startOffset = startOffset == -1 ? 0 : startOffset; 21 | endOffset = endOffset == -1 ? data.Length : endOffset; 22 | for (int i = startOffset; i < endOffset; i++) 23 | data[i] = ascii_chars[rnd.Next(ascii_chars.Length)]; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /benchmark/Resp.benchmark/ClientTypes.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Resp.benchmark 5 | { 6 | public enum ClientType : byte 7 | { 8 | LightClient, 9 | SERedis, 10 | GarnetClientSession, 11 | GarnetClient 12 | } 13 | } -------------------------------------------------------------------------------- /benchmark/Resp.benchmark/OpType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Resp.benchmark 5 | { 6 | public enum OpType 7 | { 8 | NONE, MGET, INCR, MSET, SET, SETEX, GET, DEL, PING, PFADD, MPFADD, PFCOUNT, PFMERGE, ZADD, ZREM, ZADDREM, GEOADD, GEOADDREM, ZCARD, ZADDCARD, 9 | SETBIT, GETBIT, BITCOUNT, BITPOS, BITOP_AND, BITOP_OR, BITOP_XOR, BITOP_NOT, 10 | BITFIELD, BITFIELD_GET, BITFIELD_SET, BITFIELD_INCR, 11 | SETIFPM, MYDICTGET, MYDICTSET, 12 | DBSIZE, 13 | READ_TXN, WRITE_TXN, READWRITETX, WATCH_TXN, SAMPLEUPDATETX, SAMPLEDELETETX, 14 | SCRIPTSET, SCRIPTGET, SCRIPTRETKEY, 15 | PUBLISH, SPUBLISH, 16 | READONLY = 8888, 17 | AUTH = 9999, 18 | } 19 | } -------------------------------------------------------------------------------- /benchmark/Resp.benchmark/Resp.benchmark.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 6 | true 7 | 8 | 9 | 10 | 11 | PreserveNewest 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /charts/garnet/.gitignore: -------------------------------------------------------------------------------- 1 | charts/ 2 | -------------------------------------------------------------------------------- /charts/garnet/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /charts/garnet/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: garnet 3 | description: A Helm chart for Microsoft Garnet 4 | type: application 5 | version: 0.2.2 6 | appVersion: Version.props 7 | home: https://github.com/microsoft/garnet 8 | icon: https://avatars.githubusercontent.com/u/6154722?s=200&v=4 9 | 10 | keywords: 11 | - scalable 12 | - key-value 13 | - cache 14 | - cluster 15 | - store 16 | - remote 17 | - persistent 18 | - concurrent 19 | - low-latency 20 | - cache-storage 21 | - hash-table 22 | - larger-the-memory 23 | 24 | sources: 25 | - https://github.com/microsoft/garnet.git 26 | 27 | maintainers: [] 28 | -------------------------------------------------------------------------------- /charts/garnet/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{ template "chart.header" . }} 2 | {{ template "chart.deprecationWarning" . }} 3 | 4 | {{ template "chart.badgesSection" . }} 5 | 6 | {{ template "chart.description" . }} 7 | 8 | {{ template "chart.homepageLine" . }} 9 | 10 | {{ template "chart.maintainersSection" . }} 11 | 12 | {{ template "chart.sourcesSection" . }} 13 | 14 | ## Usage 15 | 16 | [Helm](https://helm.sh) must be installed to use the charts. Please refer to 17 | Helm's [documentation](https://helm.sh/docs) to get started. 18 | 19 | To install the Garnet chart (using an OCI-based registry): 20 | 21 | ```sh 22 | helm upgrade --install garnet oci://ghcr.io/microsoft/helm-charts/garnet 23 | ``` 24 | 25 | To uninstall the chart: 26 | 27 | ```sh 28 | helm delete garnet 29 | ``` 30 | 31 | {{ template "chart.requirementsSection" . }} 32 | 33 | {{ template "chart.valuesSection" . }} 34 | 35 | {{ template "helm-docs.versionFooter" . }} 36 | -------------------------------------------------------------------------------- /charts/garnet/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if and (eq .Values.config.existingSecret "") .Values.config.garnetConf }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ include "garnet.fullname" . }}-config 6 | labels: 7 | {{- include "garnet.labels" . | nindent 4 }} 8 | type: Opaque 9 | data: 10 | garnet.conf: {{ .Values.config.garnetConf | b64enc | quote }} 11 | {{- end }} 12 | -------------------------------------------------------------------------------- /charts/garnet/templates/service-headless.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "garnet.fullname" . }}-headless 5 | labels: 6 | {{- include "garnet.labels" . | nindent 4 }} 7 | {{- with .Values.service.annotations }} 8 | annotations: 9 | {{- toYaml . | nindent 4 }} 10 | {{- end }} 11 | spec: 12 | clusterIP: None 13 | ports: 14 | - port: {{ .Values.service.port }} 15 | targetPort: {{ .Values.containers.port }} 16 | protocol: TCP 17 | name: garnet 18 | selector: 19 | {{- include "garnet.selectorLabels" . | nindent 4 }} 20 | -------------------------------------------------------------------------------- /charts/garnet/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "garnet.fullname" . }} 5 | labels: 6 | {{- include "garnet.labels" . | nindent 4 }} 7 | {{- with .Values.service.annotations }} 8 | annotations: 9 | {{- toYaml . | nindent 4 }} 10 | {{- end }} 11 | spec: 12 | type: {{ .Values.service.type }} 13 | ports: 14 | - port: {{ .Values.service.port }} 15 | targetPort: {{ .Values.containers.port }} 16 | protocol: TCP 17 | name: garnet 18 | selector: 19 | {{- include "garnet.selectorLabels" . | nindent 4 }} 20 | -------------------------------------------------------------------------------- /charts/garnet/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "garnet.serviceAccountName" . }} 6 | labels: 7 | {{- include "garnet.labels" . | nindent 4 }} 8 | {{- with .Values.serviceAccount.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- if and .Values.serviceAccount.token (semverCompare ">=1.24-0" .Capabilities.KubeVersion.GitVersion) }} 13 | secrets: 14 | - name: {{ include "garnet.serviceAccountName" . }}-token 15 | {{- end }} 16 | {{- end }} 17 | -------------------------------------------------------------------------------- /charts/garnet/templates/token.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.serviceAccount.create .Values.serviceAccount.token (semverCompare ">=1.24-0" .Capabilities.KubeVersion.GitVersion) -}} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ include "garnet.serviceAccountName" . }}-token 6 | labels: 7 | {{- include "garnet.labels" . | nindent 4 }} 8 | annotations: 9 | kubernetes.io/service-account.name: {{ include "garnet.serviceAccountName" . }} 10 | {{- with .Values.serviceAccount.annotations }} 11 | {{- toYaml . | nindent 4 }} 12 | {{- end }} 13 | type: kubernetes.io/service-account-token 14 | {{- end }} 15 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | garnet: 3 | image: 'ghcr.io/microsoft/garnet' 4 | ulimits: 5 | memlock: -1 6 | ports: 7 | - "6379:6379" 8 | # To avoid docker NAT, consider `host` mode. 9 | # https://docs.docker.com/compose/compose-file/compose-file-v3/#network_mode 10 | # network_mode: "host" 11 | volumes: 12 | - garnetdata:/data 13 | volumes: 14 | garnetdata: 15 | -------------------------------------------------------------------------------- /hosting/Windows/Garnet.worker/Garnet.worker.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0;net9.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /hosting/Windows/Garnet.worker/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet; 5 | using Microsoft.Extensions.DependencyInjection; 6 | using Microsoft.Extensions.Hosting; 7 | 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | var builder = Host.CreateApplicationBuilder(args); 13 | builder.Services.AddHostedService(_ => new Worker(args)); 14 | 15 | builder.Services.AddWindowsService(options => 16 | { 17 | options.ServiceName = "Microsoft Garnet Server"; 18 | }); 19 | 20 | var host = builder.Build(); 21 | host.Run(); 22 | } 23 | } -------------------------------------------------------------------------------- /libs/client/ClientSession/GarnetClientSessionTcpNetworkHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Net.Sockets; 5 | using Garnet.common; 6 | using Garnet.networking; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace Garnet.client 10 | { 11 | sealed class GarnetClientSessionTcpNetworkHandler : TcpNetworkHandlerBase 12 | { 13 | public GarnetClientSessionTcpNetworkHandler(GarnetClientSession serverHook, Socket socket, NetworkBufferSettings networkBufferSettings, LimitedFixedBufferPool networkPool, bool useTLS, IMessageConsumer messageConsumer, int networkSendThrottleMax = 8, ILogger logger = null) 14 | : base(serverHook, new GarnetTcpNetworkSender(socket, networkBufferSettings, networkPool, networkSendThrottleMax), socket, networkBufferSettings, networkPool, useTLS, messageConsumer: messageConsumer, logger: logger) 15 | { 16 | } 17 | 18 | public byte[] RawTransportBuffer => transportReceiveBuffer; 19 | } 20 | } -------------------------------------------------------------------------------- /libs/client/ExceptionTypes.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | 6 | namespace Garnet.client 7 | { 8 | /// 9 | /// GarnetClient disposed exception 10 | /// 11 | public sealed class GarnetClientDisposedException : ObjectDisposedException 12 | { 13 | internal GarnetClientDisposedException() : base("GarnetClient") 14 | { 15 | } 16 | } 17 | 18 | /// 19 | /// GarnetClient timeout exception 20 | /// 21 | public sealed class GarnetClientTimeoutException : TimeoutException 22 | { 23 | internal GarnetClientTimeoutException() : base("GarnetClient") 24 | { 25 | } 26 | } 27 | 28 | /// 29 | /// GarnetClient socket disposed exception 30 | /// 31 | public sealed class GarnetClientSocketDisposedException : ObjectDisposedException 32 | { 33 | internal GarnetClientSocketDisposedException() : base("GarnetClient Socket") 34 | { 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /libs/client/Garnet.client.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | ../../Garnet.snk 6 | false 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /libs/client/GarnetClientTcpNetworkHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using System.Net.Sockets; 6 | using Garnet.common; 7 | using Garnet.networking; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace Garnet.client 11 | { 12 | sealed class GarnetClientTcpNetworkHandler : TcpNetworkHandlerBase 13 | { 14 | public GarnetClientTcpNetworkHandler(GarnetClient serverHook, Action callback, Socket socket, NetworkBufferSettings networkBufferSettings, LimitedFixedBufferPool networkPool, bool useTLS, IMessageConsumer messageConsumer, int networkSendThrottleMax = 8, ILogger logger = null) 15 | : base(serverHook, new ClientTcpNetworkSender(socket, callback, networkBufferSettings, networkPool, networkSendThrottleMax), socket, networkBufferSettings, networkPool, useTLS, messageConsumer: messageConsumer, logger: logger) 16 | { 17 | } 18 | 19 | public byte[] RawTransportBuffer => transportReceiveBuffer; 20 | } 21 | } -------------------------------------------------------------------------------- /libs/client/PageAsyncResultTypes.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.client 5 | { 6 | class CountWrapper 7 | { 8 | public int count; 9 | public long untilAddress; 10 | } 11 | 12 | /// 13 | /// Page async flush result 14 | /// 15 | class PageAsyncFlushResult 16 | { 17 | public CountWrapper count; 18 | public long page; 19 | internal long fromOffset; 20 | internal long untilOffset; 21 | } 22 | } -------------------------------------------------------------------------------- /libs/cluster/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | [assembly: InternalsVisibleTo("BDN.benchmark" + ClusterAssemblyRef.GarnetPublicKey)] 7 | [assembly: InternalsVisibleTo("Garnet.test.cluster" + ClusterAssemblyRef.GarnetPublicKey)] 8 | 9 | /// 10 | /// Sets public key string for friend assemblies. 11 | /// 12 | static class ClusterAssemblyRef 13 | { 14 | internal const string GarnetPublicKey = ", PublicKey=" + 15 | "0024000004800000940000000602000000240000525341310004000001000100011b1661238d3d" + 16 | "3c76232193c8aa2de8c05b8930d6dfe8cd88797a8f5624fdf14a1643141f31da05c0f67961b0e3" + 17 | "a64c7120001d2f8579f01ac788b0ff545790d44854abe02f42bfe36a056166a75c6a694db8c5b6" + 18 | "609cff8a2dbb429855a1d9f79d4d8ec3e145c74bfdd903274b7344beea93eab86b422652f8dd8e" + 19 | "ecf530d2"; 20 | } -------------------------------------------------------------------------------- /libs/cluster/ClusterFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.server; 5 | using Microsoft.Extensions.Logging; 6 | using Tsavorite.core; 7 | 8 | namespace Garnet.cluster 9 | { 10 | /// 11 | /// Cluster factory 12 | /// 13 | public class ClusterFactory : IClusterFactory 14 | { 15 | /// 16 | public DeviceLogCommitCheckpointManager CreateCheckpointManager(INamedDeviceFactoryCreator deviceFactoryCreator, ICheckpointNamingScheme checkpointNamingScheme, bool isMainStore, ILogger logger = default) 17 | => new ReplicationLogCheckpointManager(deviceFactoryCreator, checkpointNamingScheme, isMainStore, logger: logger); 18 | 19 | /// 20 | public IClusterProvider CreateClusterProvider(StoreWrapper store) 21 | => new ClusterProvider(store); 22 | } 23 | } -------------------------------------------------------------------------------- /libs/cluster/Garnet.cluster.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | ../../Garnet.snk 6 | false 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /libs/cluster/Server/ClusterAuthContainer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.cluster 5 | { 6 | /// 7 | /// Container to hold cluster username and password for backend cluster communications. 8 | /// Having a container allows for atomic switching to a new username and password. 9 | /// 10 | class ClusterAuthContainer 11 | { 12 | public string ClusterUsername; 13 | public string ClusterPassword; 14 | } 15 | } -------------------------------------------------------------------------------- /libs/cluster/Server/ConnectionInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.cluster 5 | { 6 | internal struct ConnectionInfo 7 | { 8 | public long ping; 9 | public long pong; 10 | public bool connected; 11 | public long lastIO; 12 | 13 | public ConnectionInfo() 14 | { 15 | ping = 0; 16 | pong = 0; 17 | connected = false; 18 | lastIO = 0; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /libs/cluster/Server/Migration/MigrateState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.cluster 5 | { 6 | /// 7 | /// MigrateState 8 | /// 9 | internal enum MigrateState : byte 10 | { 11 | /// 12 | /// SUCCESS 13 | /// 14 | SUCCESS = 0x0, 15 | /// 16 | /// FAIL 17 | /// 18 | FAIL, 19 | /// 20 | /// PENDING 21 | /// 22 | PENDING, 23 | /// 24 | /// IMPORT 25 | /// 26 | IMPORT, 27 | /// 28 | /// STABLE 29 | /// 30 | STABLE, 31 | /// 32 | /// NODE 33 | /// 34 | NODE, 35 | } 36 | } -------------------------------------------------------------------------------- /libs/cluster/Server/Replication/PrimaryOps/DisklessReplication/SyncStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.cluster 5 | { 6 | /// 7 | /// Replication attach sync status 8 | /// 9 | enum SyncStatus : byte 10 | { 11 | SUCCESS, 12 | FAILED, 13 | INPROGRESS, 14 | INITIALIZING 15 | } 16 | 17 | /// 18 | /// Replication sync status info 19 | /// 20 | struct SyncStatusInfo 21 | { 22 | public SyncStatus syncStatus; 23 | public string error; 24 | } 25 | } -------------------------------------------------------------------------------- /libs/cluster/Server/Replication/RecoveryStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.cluster 5 | { 6 | /// 7 | /// Recovery status 8 | /// 9 | public enum RecoveryStatus : byte 10 | { 11 | /// 12 | /// No recovery 13 | /// 14 | NoRecovery, 15 | /// 16 | /// Recovery at initialization 17 | /// 18 | InitializeRecover, 19 | /// 20 | /// Recovery at cluster replicate 21 | /// 22 | ClusterReplicate, 23 | /// 24 | /// Recovery at cluster failover 25 | /// 26 | ClusterFailover, 27 | /// 28 | /// Recovery at replica of no one 29 | /// 30 | ReplicaOfNoOne, 31 | /// 32 | /// Replica has recovered the checkpoint after signal from primary 33 | /// 34 | CheckpointRecoveredAtReplica, 35 | } 36 | } -------------------------------------------------------------------------------- /libs/cluster/Session/SlotVerification/ClusterSlotVerificationResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | namespace Garnet.cluster 7 | { 8 | [StructLayout(LayoutKind.Explicit, Size = 3)] 9 | internal struct ClusterSlotVerificationResult 10 | { 11 | [FieldOffset(0)] 12 | public SlotVerifiedState state; 13 | [FieldOffset(1)] 14 | public ushort slot; 15 | 16 | public ClusterSlotVerificationResult(SlotVerifiedState state, ushort slot) 17 | { 18 | this.state = state; 19 | this.slot = slot; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /libs/cluster/Session/SlotVerifiedState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.cluster 5 | { 6 | /// 7 | /// SlotVerifiedState 8 | /// 9 | public enum SlotVerifiedState : byte 10 | { 11 | /// 12 | /// OK to server request 13 | /// 14 | OK, 15 | /// 16 | /// Slot down 17 | /// 18 | CLUSTERDOWN, 19 | /// 20 | /// Slot moved to remote node 21 | /// 22 | MOVED, 23 | /// 24 | /// Ask target node 25 | /// 26 | ASK, 27 | /// 28 | /// Crossslot operation 29 | /// 30 | CROSSSLOT, 31 | /// 32 | /// Used for multi-key operations referring to a collection of keys some of which have migrated 33 | /// 34 | TRYAGAIN 35 | } 36 | } -------------------------------------------------------------------------------- /libs/cluster/Session/TransferOption.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.cluster 5 | { 6 | /// 7 | /// Transfer option supported by MIGRATE 8 | /// 9 | internal enum TransferOption : byte 10 | { 11 | NONE, 12 | /// 13 | /// Transfer all provided keys 14 | /// 15 | KEYS, 16 | /// 17 | /// Transfer all keys in a single slot 18 | /// 19 | SLOTS, 20 | } 21 | } -------------------------------------------------------------------------------- /libs/common/ExceptionInjectionType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.common 5 | { 6 | /// 7 | /// Exception injection types - used only in debug mode for testing 8 | /// 9 | public enum ExceptionInjectionType 10 | { 11 | /// 12 | /// Network failure after GarnetServerTcp handler created 13 | /// 14 | Network_After_GarnetServerTcp_Handler_Created, 15 | /// 16 | /// Network failure after TcpNetworkHandlerBase start server 17 | /// 18 | Network_After_TcpNetworkHandlerBase_Start_Server, 19 | /// 20 | /// Primary replication sync orchestration failure right before background aof stream starts 21 | /// 22 | Replication_Fail_Before_Background_AOF_Stream_Task_Start, 23 | /// 24 | /// Acquire checkpoint entry from memory entries 25 | /// 26 | Replication_Acquire_Checkpoint_Entry_Fail_Condition 27 | } 28 | } -------------------------------------------------------------------------------- /libs/common/Garnet.common.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | ../../Garnet.snk 6 | false 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /libs/common/LightClientTcpNetworkHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Net.Sockets; 5 | using Garnet.common; 6 | using Garnet.networking; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace Garnet.server 10 | { 11 | internal sealed class LightClientTcpNetworkHandler : TcpNetworkHandler 12 | { 13 | public LightClientTcpNetworkHandler(LightClient serverHook, Socket socket, NetworkBufferSettings networkBufferSettings, LimitedFixedBufferPool networkPool, bool useTLS, IMessageConsumer messageConsumer, int networkSendThrottleMax = 8, ILogger logger = null) 14 | : base(serverHook, socket, networkBufferSettings, networkPool, useTLS, messageConsumer, networkSendThrottleMax: networkSendThrottleMax, logger: logger) 15 | { 16 | } 17 | 18 | public byte[] RawTransportBuffer => transportReceiveBuffer; 19 | } 20 | } -------------------------------------------------------------------------------- /libs/common/Logging/LogFormatter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using System.Globalization; 6 | 7 | namespace Garnet.common 8 | { 9 | /// 10 | /// Log formatter primitives 11 | /// 12 | public static class LogFormatter 13 | { 14 | private const string TIME_FORMAT = "HH:mm:ss.ffff"; 15 | private const string DATE_FORMAT = "yyyy-MM-dd " + TIME_FORMAT; 16 | 17 | /// 18 | /// Format date 19 | /// 20 | /// 21 | public static string FormatDate(DateTime dateTime) => dateTime.ToString(DATE_FORMAT, CultureInfo.InvariantCulture); 22 | 23 | /// 24 | /// Format time 25 | /// 26 | /// 27 | public static string FormatTime(DateTime dateTime) => dateTime.ToString(TIME_FORMAT, CultureInfo.InvariantCulture); 28 | } 29 | } -------------------------------------------------------------------------------- /libs/common/Memory/PoolLevel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Concurrent; 5 | 6 | namespace Garnet.common 7 | { 8 | /// 9 | /// Pool level 10 | /// 11 | public class PoolLevel 12 | { 13 | /// 14 | /// Size 15 | /// 16 | public int size; 17 | 18 | /// 19 | /// Items 20 | /// 21 | public readonly ConcurrentQueue items; 22 | 23 | /// 24 | /// Constructor 25 | /// 26 | public PoolLevel() 27 | { 28 | size = 0; 29 | items = new ConcurrentQueue(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /libs/common/Metrics/MetricsItem.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.common 5 | { 6 | /// 7 | /// Metrics item (or row), contains metric name and value 8 | /// 9 | public readonly struct MetricsItem 10 | { 11 | /// 12 | /// Name of metric 13 | /// 14 | public readonly string Name; 15 | 16 | /// 17 | /// Value of metrics 18 | /// 19 | public readonly string Value; 20 | 21 | /// 22 | /// Metrics Item Constructor 23 | /// 24 | /// 25 | /// 26 | public MetricsItem(string Name, string Value) 27 | { 28 | this.Name = Name; 29 | this.Value = Value; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /libs/common/Networking/IMessageConsumer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | 6 | namespace Garnet.networking 7 | { 8 | /// 9 | /// Interface for consumers of messages (from networks), such as sessions 10 | /// 11 | public interface IMessageConsumer : IDisposable 12 | { 13 | /// 14 | /// Consume the message incoming on the wire 15 | /// 16 | /// 17 | /// 18 | /// 19 | unsafe int TryConsumeMessages(byte* reqBuffer, int bytesRead); 20 | } 21 | } -------------------------------------------------------------------------------- /libs/common/Networking/INetworkHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | 6 | namespace Garnet.networking 7 | { 8 | /// 9 | /// Network handler interface 10 | /// 11 | public interface INetworkHandler : IDisposable 12 | { 13 | /// 14 | /// Get session 15 | /// 16 | IMessageConsumer Session { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /libs/common/Networking/IServerHook.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | 6 | namespace Garnet.networking 7 | { 8 | /// 9 | /// Hook for server 10 | /// 11 | public interface IServerHook 12 | { 13 | /// 14 | /// Try creating a message consumer 15 | /// 16 | /// 17 | /// 18 | /// 19 | /// 20 | bool TryCreateMessageConsumer(Span bytesReceived, INetworkSender networkSender, out IMessageConsumer session); 21 | 22 | /// 23 | /// Dispose message consumer 24 | /// 25 | /// 26 | void DisposeMessageConsumer(INetworkHandler session); 27 | 28 | /// 29 | /// Check whether server is disposed 30 | /// 31 | bool Disposed { get; } 32 | } 33 | } -------------------------------------------------------------------------------- /libs/common/Networking/MaxSizeSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.networking 5 | { 6 | /// 7 | /// Settings for max sizes of types 8 | /// 9 | public class MaxSizeSettings 10 | { 11 | /// 12 | /// Max key size 13 | /// 14 | public int MaxKeySize = 4096; 15 | 16 | /// 17 | /// Max value size 18 | /// 19 | public int MaxValueSize = 4096; 20 | 21 | /// 22 | /// Max input size 23 | /// 24 | public int MaxInputSize = 4096; 25 | 26 | /// 27 | /// Max output size 28 | /// 29 | public int MaxOutputSize = 4096; 30 | } 31 | } -------------------------------------------------------------------------------- /libs/common/Networking/TcpNetworkHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Net.Sockets; 5 | using Garnet.networking; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace Garnet.common 9 | { 10 | /// 11 | /// TCP network handler 12 | /// 13 | /// 14 | public abstract class TcpNetworkHandler : TcpNetworkHandlerBase 15 | where TServerHook : IServerHook 16 | { 17 | /// 18 | /// Constructor 19 | /// 20 | public TcpNetworkHandler(TServerHook serverHook, Socket socket, NetworkBufferSettings networkBufferSettings, LimitedFixedBufferPool networkPool, bool useTLS, IMessageConsumer messageConsumer = null, int networkSendThrottleMax = 8, ILogger logger = null) 21 | : base(serverHook, new GarnetTcpNetworkSender(socket, networkBufferSettings, networkPool, networkSendThrottleMax), socket, networkBufferSettings, networkPool, useTLS, messageConsumer: messageConsumer, logger: logger) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /libs/common/Networking/TlsReaderStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.networking 5 | { 6 | /// 7 | /// TLS reader status 8 | /// 9 | enum TlsReaderStatus 10 | { 11 | /// 12 | /// Rest phase, no reader task or work running 13 | /// 14 | Rest, 15 | /// 16 | /// Reader is active, processing TLS data on some thread 17 | /// 18 | Active, 19 | /// 20 | /// Reader is waiting on a semaphore for data to be available 21 | /// 22 | Waiting 23 | } 24 | } -------------------------------------------------------------------------------- /libs/common/Networking/WireFormat.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.networking 5 | { 6 | /// 7 | /// Wire format for a session, you can add custom session types on the server and client side 8 | /// (e.g., one per distinct store and/or function types). 9 | /// 10 | public enum WireFormat : byte 11 | { 12 | /// 13 | /// ASCII wire format, e.g. for RESP 14 | /// 15 | ASCII = 255 16 | } 17 | } -------------------------------------------------------------------------------- /libs/host/Configuration/CommandLineTypes.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet 5 | { 6 | /// 7 | /// Enum to specify boolean variable over command line. 8 | /// 9 | public enum CommandLineBooleanOption 10 | { 11 | False = 0, 12 | No = 0, 13 | True = 1, 14 | Yes = 1 15 | } 16 | } -------------------------------------------------------------------------------- /libs/resources/Garnet.resources.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | ../../Garnet.snk 6 | false 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /libs/resources/ResourceUtils.cs: -------------------------------------------------------------------------------- 1 | namespace Garnet.resources 2 | { 3 | /// 4 | /// Dummy class for externally referencing this assembly 5 | /// 6 | public class ResourceUtils 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /libs/server/API/GarnetStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | /// 7 | /// Garnet API call return status 8 | /// 9 | public enum GarnetStatus : byte 10 | { 11 | /// 12 | /// OK 13 | /// 14 | OK, 15 | /// 16 | /// Not Found 17 | /// 18 | NOTFOUND, 19 | /// 20 | /// Moved 21 | /// 22 | MOVED, 23 | /// 24 | /// Wrong type 25 | /// 26 | WRONGTYPE 27 | } 28 | } -------------------------------------------------------------------------------- /libs/server/ArgSlice/ArgSliceUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | 6 | namespace Garnet.server 7 | { 8 | /// 9 | /// ArgSlice utils 10 | /// 11 | public static class ArgSliceUtils 12 | { 13 | /// 14 | /// Compute hash slot of given ArgSlice 15 | /// 16 | public static unsafe ushort HashSlot(ref ArgSlice argSlice) 17 | => HashSlotUtils.HashSlot(argSlice.ptr, argSlice.Length); 18 | } 19 | } -------------------------------------------------------------------------------- /libs/server/Auth/GarnetNoAuthAuthenticator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using System.Diagnostics; 6 | 7 | namespace Garnet.server.Auth 8 | { 9 | public class GarnetNoAuthAuthenticator : IGarnetAuthenticator 10 | { 11 | public bool IsAuthenticated => true; 12 | 13 | public bool CanAuthenticate => false; 14 | 15 | public bool HasACLSupport => false; 16 | 17 | public bool Authenticate(ReadOnlySpan password, ReadOnlySpan username) 18 | { 19 | Debug.Fail("No auth authenticator should never authenticate."); 20 | return false; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /libs/server/Auth/GarnetPasswordAuthenticator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using Garnet.server.ACL; 6 | 7 | namespace Garnet.server.Auth 8 | { 9 | /// 10 | /// Authenticator that uses a single fixed password. 11 | /// XXX: Deprecated. Should be replaced by ACL authenticator. 12 | /// 13 | class GarnetPasswordAuthenticator : IGarnetAuthenticator 14 | { 15 | public bool IsAuthenticated => _authenticated; 16 | 17 | public bool CanAuthenticate => true; 18 | 19 | public bool HasACLSupport => false; 20 | 21 | private readonly byte[] _pwd; 22 | private bool _authenticated; 23 | 24 | public GarnetPasswordAuthenticator(byte[] pwd) 25 | { 26 | _pwd = pwd; 27 | } 28 | 29 | public bool Authenticate(ReadOnlySpan password, ReadOnlySpan username) 30 | { 31 | _authenticated = SecretsUtility.ConstantEquals(_pwd, password); 32 | return _authenticated; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /libs/server/Auth/IGarnetAuthenticator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | 6 | namespace Garnet.server.Auth 7 | { 8 | /// 9 | /// Garnet authenticator interface 10 | /// 11 | public interface IGarnetAuthenticator 12 | { 13 | /// 14 | /// Is current caller authenticated 15 | /// 16 | bool IsAuthenticated { get; } 17 | 18 | /// 19 | /// Can authenticator authenticate 20 | /// 21 | bool CanAuthenticate { get; } 22 | 23 | /// 24 | /// Whether this authenticator can be used with the ACL 25 | /// 26 | bool HasACLSupport { get; } 27 | 28 | /// 29 | /// Authenticate the incoming username and password from AUTH command. Username is optional 30 | /// 31 | bool Authenticate(ReadOnlySpan password, ReadOnlySpan username); 32 | } 33 | } -------------------------------------------------------------------------------- /libs/server/Auth/Settings/ConnectionProtectionOption.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server.Auth.Settings 5 | { 6 | /// 7 | /// Certain commands can be set at configuration to be limited to a particular connection type. 8 | /// They can be blocked for all connections, allowed only for local connections or be allowed for all connections. 9 | /// 10 | public enum ConnectionProtectionOption 11 | { 12 | /// 13 | /// Block for all connections. 14 | /// 15 | No = 0, 16 | /// 17 | /// Allow only for local connections. 18 | /// 19 | Local = 1, 20 | /// 21 | /// Allow for every connection including remote connections. 22 | /// 23 | Yes = 2 24 | } 25 | } -------------------------------------------------------------------------------- /libs/server/Auth/Settings/NoAuthSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server.Auth.Settings 5 | { 6 | /// 7 | /// No auth settings 8 | /// 9 | public class NoAuthSettings : IAuthenticationSettings 10 | { 11 | /// 12 | /// Creates a no auth authenticator 13 | /// 14 | /// The main store the authenticator will be associated with. 15 | public IGarnetAuthenticator CreateAuthenticator(StoreWrapper storeWrapper) 16 | { 17 | return new GarnetNoAuthAuthenticator(); 18 | } 19 | 20 | /// 21 | /// Dispose 22 | /// 23 | public void Dispose() 24 | { 25 | // No-op 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /libs/server/ByteArrayWrapperComparer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Garnet.server 8 | { 9 | /// 10 | /// Byte array equality comparer 11 | /// 12 | public sealed class ByteArrayWrapperComparer : IEqualityComparer 13 | { 14 | /// 15 | /// The default instance. 16 | /// 17 | /// Used to avoid allocating new comparers. 18 | public static readonly ByteArrayWrapperComparer Instance = new(); 19 | 20 | /// 21 | public bool Equals(ByteArrayWrapper left, ByteArrayWrapper right) 22 | => left.ReadOnlySpan.SequenceEqual(right.ReadOnlySpan); 23 | 24 | private ByteArrayWrapperComparer() { } 25 | 26 | /// 27 | public int GetHashCode(ByteArrayWrapper key) 28 | => key.GetHashCode(); 29 | } 30 | } -------------------------------------------------------------------------------- /libs/server/Cluster/ClusterSlotVerificationInput.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | public struct ClusterSlotVerificationInput 7 | { 8 | /// 9 | /// Whether this is a read only command 10 | /// 11 | public bool readOnly; 12 | 13 | /// 14 | /// Whether ASKING is enabled for this command 15 | /// 16 | public byte sessionAsking; 17 | 18 | /// 19 | /// Offset of first key in the ArgSlice buffer 20 | /// 21 | public int firstKey; 22 | 23 | /// 24 | /// Offset of the last key in the ArgSlice buffer 25 | /// 26 | public int lastKey; 27 | 28 | /// 29 | /// The step, or increment, between the first key and the position of the next key 30 | /// 31 | public int step; 32 | 33 | /// 34 | /// Offset of key num if any 35 | /// 36 | public int keyNumOffset; 37 | } 38 | } -------------------------------------------------------------------------------- /libs/server/Cluster/IClusterFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Microsoft.Extensions.Logging; 5 | using Tsavorite.core; 6 | 7 | namespace Garnet.server 8 | { 9 | /// 10 | /// Cluster factory 11 | /// 12 | public interface IClusterFactory 13 | { 14 | /// 15 | /// Create checkpoint manager 16 | /// 17 | DeviceLogCommitCheckpointManager CreateCheckpointManager(INamedDeviceFactoryCreator deviceFactoryCreator, ICheckpointNamingScheme checkpointNamingScheme, bool isMainStore, ILogger logger = default); 18 | 19 | /// 20 | /// Create cluster provider 21 | /// 22 | IClusterProvider CreateClusterProvider(StoreWrapper store); 23 | } 24 | } -------------------------------------------------------------------------------- /libs/server/Cluster/StoreType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | /// 7 | /// Store type to operate on. Garnet keeps data in two stores, main store 8 | /// for raw strings and object store for data structures such as sorted set, 9 | /// hash, list. 10 | /// 11 | public enum StoreType : byte 12 | { 13 | /// 14 | /// Main (raw string) store 15 | /// 16 | Main = 1, 17 | 18 | /// 19 | /// Object store 20 | /// 21 | Object = 2, 22 | 23 | /// 24 | /// All stores 25 | /// 26 | All = 3, 27 | } 28 | } -------------------------------------------------------------------------------- /libs/server/Custom/CommandType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | /// 7 | /// Type of custom command 8 | /// 9 | public enum CommandType : byte 10 | { 11 | /// 12 | /// Read 13 | /// 14 | Read, 15 | /// 16 | /// Read-modify-write 17 | /// 18 | ReadModifyWrite 19 | } 20 | } -------------------------------------------------------------------------------- /libs/server/Custom/CustomCommandType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | /// 7 | /// Type of custom command 8 | /// 9 | public enum CustomCommandType : byte 10 | { 11 | /// 12 | /// Read 13 | /// 14 | Read, 15 | /// 16 | /// Read-modify-write 17 | /// 18 | ReadModifyWrite 19 | } 20 | } -------------------------------------------------------------------------------- /libs/server/Custom/CustomObjectCommand.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | public class CustomObjectCommand : ICustomCommand 7 | { 8 | public byte[] Name { get; } 9 | 10 | public readonly string NameStr; 11 | public readonly byte id; 12 | public readonly byte subid; 13 | public readonly CommandType type; 14 | public readonly int arity; 15 | public readonly CustomObjectFactory factory; 16 | public readonly CustomObjectFunctions functions; 17 | 18 | internal CustomObjectCommand(string name, byte id, byte subid, CommandType type, int arity, CustomObjectFactory factory, CustomObjectFunctions functions = null) 19 | { 20 | NameStr = name.ToUpperInvariant(); 21 | this.Name = System.Text.Encoding.ASCII.GetBytes(NameStr); 22 | this.id = id; 23 | this.subid = subid; 24 | this.type = type; 25 | this.arity = arity; 26 | this.factory = factory; 27 | this.functions = functions; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /libs/server/Custom/CustomObjectCommandWrapper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | /// 7 | /// Custom object command wrapper 8 | /// 9 | class CustomObjectCommandWrapper 10 | { 11 | static readonly int MinMapSize = 8; 12 | static readonly byte MaxSubId = 31; // RespInputHeader uses the 3 MSBs of SubId, so SubId must fit in the 5 LSBs 13 | 14 | public readonly byte id; 15 | public readonly CustomObjectFactory factory; 16 | public ExpandableMap commandMap; 17 | 18 | public CustomObjectCommandWrapper(byte id, CustomObjectFactory functions) 19 | { 20 | this.id = id; 21 | this.factory = functions; 22 | this.commandMap = new ExpandableMap(MinMapSize, 0, MaxSubId); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /libs/server/Custom/CustomObjectFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.IO; 5 | 6 | namespace Garnet.server 7 | { 8 | /// 9 | /// Base class for creating custom objects 10 | /// 11 | public abstract class CustomObjectFactory 12 | { 13 | /// 14 | /// Create new (empty) instance of custom object 15 | /// 16 | public abstract CustomObjectBase Create(byte type); 17 | 18 | /// 19 | /// Deserialize value object from given reader 20 | /// 21 | /// 22 | /// 23 | public abstract CustomObjectBase Deserialize(byte type, BinaryReader reader); 24 | } 25 | } -------------------------------------------------------------------------------- /libs/server/Custom/CustomRawStringCommand.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | public class CustomRawStringCommand : ICustomCommand 7 | { 8 | public byte[] Name { get; } 9 | 10 | public readonly string NameStr; 11 | public readonly ushort id; 12 | public readonly CommandType type; 13 | public readonly int arity; 14 | public readonly CustomRawStringFunctions functions; 15 | public long expirationTicks; 16 | 17 | internal CustomRawStringCommand(string name, ushort id, CommandType type, int arity, CustomRawStringFunctions functions, long expirationTicks) 18 | { 19 | NameStr = name.ToUpperInvariant(); 20 | this.Name = System.Text.Encoding.ASCII.GetBytes(NameStr); 21 | this.id = id; 22 | this.type = type; 23 | this.arity = arity; 24 | this.functions = functions; 25 | this.expirationTicks = expirationTicks; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /libs/server/Custom/CustomTransaction.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using Garnet.common; 6 | 7 | namespace Garnet.server 8 | { 9 | class CustomTransaction : ICustomCommand 10 | { 11 | public byte[] Name { get; } 12 | 13 | public readonly string NameStr; 14 | public readonly byte id; 15 | public readonly int arity; 16 | public readonly Func proc; 17 | 18 | internal CustomTransaction(string name, byte id, int arity, Func proc) 19 | { 20 | if (name == null) 21 | throw new GarnetException("CustomTransaction name is null"); 22 | NameStr = name.ToUpperInvariant(); 23 | this.Name = System.Text.Encoding.ASCII.GetBytes(NameStr); 24 | this.id = id; 25 | this.arity = arity; 26 | this.proc = proc ?? throw new GarnetException("CustomTransactionProcedure is null"); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /libs/server/Custom/ICustomCommand.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | /// 7 | /// Interface for custom commands 8 | /// 9 | interface ICustomCommand 10 | { 11 | /// 12 | /// Name of command 13 | /// 14 | byte[] Name { get; } 15 | } 16 | } -------------------------------------------------------------------------------- /libs/server/Garnet.server.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | ../../Garnet.snk 6 | false 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /libs/server/Metrics/Latency/LatencyMetricsEntry.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using HdrHistogram; 5 | 6 | namespace Garnet.server 7 | { 8 | struct LatencyMetricsEntry 9 | { 10 | static readonly long HISTOGRAM_LOWER_BOUND = 1; 11 | static readonly long HISTOGRAM_UPPER_BOUND = TimeStamp.Seconds(100); 12 | 13 | public readonly LongHistogram latency; 14 | 15 | public LatencyMetricsEntry() 16 | { 17 | latency = new LongHistogram(HISTOGRAM_LOWER_BOUND, HISTOGRAM_UPPER_BOUND, 2); 18 | } 19 | 20 | public void Return() 21 | => latency.Return(); 22 | } 23 | } -------------------------------------------------------------------------------- /libs/server/Metrics/Latency/RespLatencyHelp.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Garnet.server 7 | { 8 | /// 9 | /// Info on what latency commands are supported 10 | /// 11 | static class RespLatencyHelp 12 | { 13 | /// 14 | /// Get supported latency commands and a short description 15 | /// 16 | /// 17 | public static List GetLatencyCommands() 18 | { 19 | return new List() 20 | { 21 | "LATENCY [ [value] [opt] ...]. Subcommands are:", 22 | "HISTOGRAM [EVENT [EVENT...]]", 23 | "\tReturn latency histogram of one or more classes.", 24 | "\tIf no commands are specified then all histograms are replied", 25 | "RESET [EVENT [EVENT...]]", 26 | "\tReset latency data of one or more classes.", 27 | "\t(default: reset all data for all event classes).", 28 | "HELP", 29 | "\tPrints this help" 30 | }; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /libs/server/Metrics/Slowlog/SlowlogEntry.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | /// 7 | /// Each entry in the slow log 8 | /// 9 | internal struct SlowLogEntry 10 | { 11 | public int Id; 12 | public int Timestamp; 13 | public int Duration; 14 | public RespCommand Command; 15 | public byte[] Arguments; 16 | public string ClientIpPort; 17 | public string ClientName; 18 | } 19 | } -------------------------------------------------------------------------------- /libs/server/Objects/SortedSetComparer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Garnet.server 8 | { 9 | public sealed class SortedSetComparer : IComparer<(double, byte[])> 10 | { 11 | /// 12 | /// The default instance. 13 | /// 14 | /// Used to avoid allocating new comparers. 15 | public static readonly SortedSetComparer Instance = new(); 16 | 17 | /// 18 | public int Compare((double, byte[]) x, (double, byte[]) y) 19 | { 20 | var ret = x.Item1.CompareTo(y.Item1); 21 | if (ret == 0) 22 | return new ReadOnlySpan(x.Item2).SequenceCompareTo(y.Item2); 23 | return ret; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /libs/server/Objects/Types/ByteArrayBinaryObjectSerializer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Tsavorite.core; 5 | 6 | namespace Garnet.server 7 | { 8 | /// 9 | /// Byte array serializer 10 | /// 11 | public sealed class ByteArrayBinaryObjectSerializer : BinaryObjectSerializer 12 | { 13 | /// 14 | public override void Deserialize(out byte[] obj) => obj = reader.ReadBytes(reader.ReadInt32()); 15 | /// 16 | public override void Serialize(ref byte[] obj) 17 | { 18 | writer.Write(obj.Length); 19 | writer.Write(obj); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /libs/server/Objects/Types/SerializationPhase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | enum SerializationPhase : int 7 | { 8 | REST, 9 | SERIALIZING, 10 | SERIALIZED, 11 | DONE 12 | } 13 | } -------------------------------------------------------------------------------- /libs/server/Objects/Types/SerializationState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | namespace Garnet.server 7 | { 8 | [StructLayout(LayoutKind.Explicit, Size = 4)] 9 | struct SerializationState 10 | { 11 | [FieldOffset(0)] 12 | public SerializationPhase phase; 13 | 14 | [FieldOffset(4)] 15 | public int word; 16 | 17 | public static SerializationState Make(SerializationPhase serializationPhase) 18 | { 19 | SerializationState state = default; 20 | state.phase = serializationPhase; 21 | return state; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /libs/server/OperationError.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | /// 7 | /// Operation error type 8 | /// 9 | public enum OperationError : byte 10 | { 11 | /// 12 | /// Operation on data type succeeded 13 | /// 14 | SUCCESS, 15 | /// 16 | /// Operation failed due to incompatible type 17 | /// 18 | INVALID_TYPE 19 | } 20 | } -------------------------------------------------------------------------------- /libs/server/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | [assembly: InternalsVisibleTo("Garnet.test" + AssemblyRef.GarnetPublicKey)] 7 | [assembly: InternalsVisibleTo("Garnet.fuzz" + AssemblyRef.GarnetPublicKey)] 8 | [assembly: InternalsVisibleTo("Embedded.perftest" + AssemblyRef.GarnetPublicKey)] 9 | [assembly: InternalsVisibleTo("BDN.benchmark" + AssemblyRef.GarnetPublicKey)] 10 | 11 | /// 12 | /// Sets public key string for friend assemblies. 13 | /// 14 | static class AssemblyRef 15 | { 16 | internal const string GarnetPublicKey = ", PublicKey=" + 17 | "0024000004800000940000000602000000240000525341310004000001000100011b1661238d3d" + 18 | "3c76232193c8aa2de8c05b8930d6dfe8cd88797a8f5624fdf14a1643141f31da05c0f67961b0e3" + 19 | "a64c7120001d2f8579f01ac788b0ff545790d44854abe02f42bfe36a056166a75c6a694db8c5b6" + 20 | "609cff8a2dbb429855a1d9f79d4d8ec3e145c74bfdd903274b7344beea93eab86b422652f8dd8e" + 21 | "ecf530d2"; 22 | } -------------------------------------------------------------------------------- /libs/server/PubSub/PatternSubscriptionEntry.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using Garnet.common; 6 | 7 | namespace Garnet.server 8 | { 9 | /// 10 | /// Entry in the table of pattern subscriptions. 11 | /// 12 | struct PatternSubscriptionEntry : IEquatable 13 | { 14 | /// 15 | /// The pattern to which the subscriptions are subscribed. 16 | /// 17 | public ByteArrayWrapper pattern; 18 | 19 | /// 20 | /// The set of subscriptions. 21 | /// 22 | public ReadOptimizedConcurrentSet subscriptions; 23 | 24 | bool IEquatable.Equals(PatternSubscriptionEntry other) 25 | => pattern.ReadOnlySpan.SequenceEqual(other.pattern.ReadOnlySpan); 26 | } 27 | } -------------------------------------------------------------------------------- /libs/server/Resp/IRespSerializable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | 6 | namespace Garnet.server 7 | { 8 | /// 9 | /// Interface to define classes that are serializable to RESP format 10 | /// 11 | public interface IRespSerializable 12 | { 13 | /// 14 | /// Serializes the current object to RESP format 15 | /// 16 | /// Serialized value in RESP format 17 | void ToRespFormat(ref RespMemoryWriter writer); 18 | } 19 | } -------------------------------------------------------------------------------- /libs/server/Resp/RespCommandAccessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | /// 7 | /// RESP command accessor 8 | /// 9 | public static class RespCommandAccessor 10 | { 11 | /// 12 | /// MIGRATE 13 | /// 14 | public static ushort MIGRATE => (ushort)RespCommand.MIGRATE; 15 | } 16 | } -------------------------------------------------------------------------------- /libs/server/Resp/RespEnums.cs: -------------------------------------------------------------------------------- 1 | namespace Garnet.server 2 | { 3 | internal enum ExpirationOption : byte 4 | { 5 | None, 6 | EX, 7 | PX, 8 | EXAT, 9 | PXAT, 10 | KEEPTTL 11 | } 12 | 13 | internal enum EtagOption : byte 14 | { 15 | None, 16 | WithETag, 17 | } 18 | 19 | public enum ExistOptions : byte 20 | { 21 | None, 22 | NX, 23 | XX 24 | } 25 | } -------------------------------------------------------------------------------- /libs/server/Resp/ScriptHashOwner.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using System.Buffers; 6 | 7 | namespace Garnet.server 8 | { 9 | /// 10 | /// Owner for memory used to store Lua script hashes on the heap. 11 | /// 12 | internal sealed class ScriptHashOwner : IMemoryOwner 13 | { 14 | private readonly Memory mem; 15 | 16 | /// 17 | public Memory Memory => mem; 18 | 19 | internal ScriptHashOwner(Memory hashMem) 20 | { 21 | mem = hashMem; 22 | } 23 | 24 | /// 25 | public void Dispose() 26 | { 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /libs/server/Resp/SessionLogger.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using System.Diagnostics; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace Garnet.server 9 | { 10 | class SessionLogger : ILogger 11 | { 12 | private readonly ILogger _logger; 13 | private readonly string _sessionIdPrefix; 14 | 15 | public SessionLogger(ILogger logger, string sessionId) 16 | { 17 | Debug.Assert(logger != null); 18 | _logger = logger; 19 | _sessionIdPrefix = sessionId; 20 | } 21 | 22 | public IDisposable BeginScope(TState state) 23 | => _logger.BeginScope(state); 24 | 25 | public bool IsEnabled(LogLevel logLevel) 26 | => _logger.IsEnabled(logLevel); 27 | 28 | public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) 29 | { 30 | _logger.Log(logLevel, eventId, state, exception, (s, ex) => _sessionIdPrefix + formatter(state, exception)); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /libs/server/ServerConfigType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | internal enum ServerConfigType : int 7 | { 8 | NONE, 9 | ALL, 10 | TIMEOUT, 11 | SAVE, 12 | APPENDONLY, 13 | SLAVE_READ_ONLY, 14 | DATABASES, 15 | CLUSTER_NODE_TIMEOUT 16 | } 17 | } -------------------------------------------------------------------------------- /libs/server/Servers/ServerTcpNetworkHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Net.Sockets; 5 | using Garnet.common; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace Garnet.server 9 | { 10 | internal sealed class ServerTcpNetworkHandler : TcpNetworkHandler 11 | { 12 | public ServerTcpNetworkHandler(GarnetServerTcp serverHook, Socket socket, NetworkBufferSettings networkBufferSettings, LimitedFixedBufferPool networkPool, bool useTLS, int networkSendThrottleMax = 8, ILogger logger = null) 13 | : base(serverHook, socket, networkBufferSettings, networkPool, useTLS, null, networkSendThrottleMax: networkSendThrottleMax, logger: logger) 14 | { 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /libs/server/Sessions/ISessionProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.networking; 5 | 6 | namespace Garnet.server 7 | { 8 | /// 9 | /// Interface to provides server-side session processing logic 10 | /// 11 | public interface ISessionProvider 12 | { 13 | /// 14 | /// Given messages of wire format type and a networkSender, returns a session that handles that wire format. If no provider is configured 15 | /// for the given wire format, an exception is thrown. 16 | /// 17 | /// Wire format 18 | /// Socket connection 19 | /// Server session 20 | IMessageConsumer GetSession(WireFormat wireFormat, INetworkSender networkSender); 21 | 22 | /// 23 | /// 24 | /// 25 | /// 26 | MaxSizeSettings GetMaxSizeSettings { get; } 27 | } 28 | } -------------------------------------------------------------------------------- /libs/server/SortedSetAggregateType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | /// 7 | /// Specifies the type of aggregation to be used in sorted set operations. 8 | /// 9 | public enum SortedSetAggregateType : byte 10 | { 11 | /// 12 | /// Sum the values. 13 | /// 14 | Sum, 15 | /// 16 | /// Use the minimum value. 17 | /// 18 | Min, 19 | /// 20 | /// Use the maximum value. 21 | /// 22 | Max 23 | } 24 | } -------------------------------------------------------------------------------- /libs/server/Storage/Functions/MainStore/CallbackMethods.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Tsavorite.core; 5 | 6 | namespace Garnet.server 7 | { 8 | /// 9 | /// Callback functions for main store 10 | /// 11 | public readonly unsafe partial struct MainSessionFunctions : ISessionFunctions 12 | { 13 | /// 14 | public void ReadCompletionCallback(ref SpanByte key, ref RawStringInput input, ref SpanByteAndMemory output, long ctx, Status status, RecordMetadata recordMetadata) 15 | { 16 | } 17 | 18 | /// 19 | public void RMWCompletionCallback(ref SpanByte key, ref RawStringInput input, ref SpanByteAndMemory output, long ctx, Status status, RecordMetadata recordMetadata) 20 | { 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /libs/server/Storage/Functions/MainStore/MainSessionFunctions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Tsavorite.core; 5 | 6 | namespace Garnet.server 7 | { 8 | /// 9 | /// Callback functions for main store 10 | /// 11 | public readonly unsafe partial struct MainSessionFunctions : ISessionFunctions 12 | { 13 | readonly FunctionsState functionsState; 14 | 15 | /// 16 | /// Constructor 17 | /// 18 | /// 19 | internal MainSessionFunctions(FunctionsState functionsState) 20 | { 21 | this.functionsState = functionsState; 22 | } 23 | 24 | /// 25 | public void ConvertOutputToHeap(ref RawStringInput input, ref SpanByteAndMemory output) 26 | { 27 | // TODO: Inspect input to determine whether we're in a context requiring ConvertToHeap. 28 | //output.ConvertToHeap(); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /libs/server/Storage/Functions/ObjectStore/CallbackMethods.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Tsavorite.core; 5 | 6 | namespace Garnet.server 7 | { 8 | /// 9 | /// Object store functions 10 | /// 11 | public readonly unsafe partial struct ObjectSessionFunctions : ISessionFunctions 12 | { 13 | /// 14 | public void ReadCompletionCallback(ref byte[] key, ref ObjectInput input, ref GarnetObjectStoreOutput output, long ctx, Status status, RecordMetadata recordMetadata) 15 | { 16 | } 17 | 18 | /// 19 | public void RMWCompletionCallback(ref byte[] key, ref ObjectInput input, ref GarnetObjectStoreOutput output, long ctx, Status status, RecordMetadata recordMetadata) 20 | { 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /libs/server/Storage/Functions/ObjectStore/ObjectSessionFunctions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Tsavorite.core; 5 | 6 | namespace Garnet.server 7 | { 8 | /// 9 | /// Object store functions 10 | /// 11 | public readonly unsafe partial struct ObjectSessionFunctions : ISessionFunctions 12 | { 13 | readonly FunctionsState functionsState; 14 | 15 | /// 16 | /// Constructor 17 | /// 18 | internal ObjectSessionFunctions(FunctionsState functionsState) 19 | { 20 | this.functionsState = functionsState; 21 | } 22 | 23 | /// 24 | public void ConvertOutputToHeap(ref ObjectInput input, ref GarnetObjectStoreOutput output) 25 | { 26 | // TODO: Inspect input to determine whether we're in a context requiring ConvertToHeap. 27 | //output.ConvertToHeap(); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /libs/server/Storage/Functions/ObjectStore/VarLenInputMethods.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | using Tsavorite.core; 6 | 7 | namespace Garnet.server 8 | { 9 | /// 10 | /// Object store functions 11 | /// 12 | public readonly unsafe partial struct ObjectSessionFunctions : ISessionFunctions 13 | { 14 | /// 15 | public int GetRMWModifiedValueLength(ref IGarnetObject value, ref ObjectInput input) 16 | { 17 | throw new GarnetException("GetRMWModifiedValueLength is not available on the object store"); 18 | } 19 | 20 | /// 21 | public int GetRMWInitialValueLength(ref ObjectInput input) 22 | { 23 | throw new GarnetException("GetRMWInitialValueLength is not available on the object store"); 24 | } 25 | 26 | public int GetUpsertValueLength(ref IGarnetObject value, ref ObjectInput input) 27 | { 28 | throw new GarnetException("GetUpsertInitialValueLength is not available on the object store"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /libs/server/Storage/Session/Metrics.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | 6 | namespace Garnet.server 7 | { 8 | sealed partial class StorageSession 9 | { 10 | public GarnetLatencyMetricsSession latencyMetrics => LatencyMetrics; 11 | readonly GarnetSessionMetrics sessionMetrics; 12 | readonly GarnetLatencyMetricsSession LatencyMetrics; 13 | 14 | public void incr_session_found() 15 | => sessionMetrics?.incr_total_found(); 16 | 17 | public void incr_session_notfound() 18 | => sessionMetrics?.incr_total_notfound(); 19 | 20 | public void incr_session_pending() 21 | => sessionMetrics?.incr_total_pending(); 22 | 23 | public void StartPendingMetrics() 24 | { 25 | sessionMetrics?.incr_total_pending(); 26 | latencyMetrics?.Start(LatencyMetricsType.PENDING_LAT); 27 | } 28 | 29 | public void StopPendingMetrics() 30 | { 31 | latencyMetrics?.Stop(LatencyMetricsType.PENDING_LAT); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /libs/server/TLS/IGarnetTlsOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Net.Security; 5 | 6 | namespace Garnet.server.TLS 7 | { 8 | /// 9 | /// Interface to provide Garnet TLS options 10 | /// 11 | public interface IGarnetTlsOptions 12 | { 13 | /// 14 | /// TLS server options 15 | /// 16 | SslServerAuthenticationOptions TlsServerOptions { get; } 17 | 18 | /// 19 | /// TLS client options, used by cluster clients 20 | /// 21 | SslClientAuthenticationOptions TlsClientOptions { get; } 22 | 23 | /// 24 | /// Update certificate file 25 | /// 26 | /// 27 | /// 28 | /// The ASCII error message if the method returned ; otherwise 29 | /// 30 | bool UpdateCertFile(string certFileName, string certPassword, out string errorMessage); 31 | } 32 | } -------------------------------------------------------------------------------- /libs/server/Transaction/TxnState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Garnet.server 5 | { 6 | /// 7 | /// Transaction state enum 8 | /// 9 | public enum TxnState : byte 10 | { 11 | /// 12 | /// None 13 | /// 14 | None, 15 | /// 16 | /// Started 17 | /// 18 | Started, 19 | /// 20 | /// Running 21 | /// 22 | Running, 23 | /// 24 | /// Aborted 25 | /// 26 | Aborted, 27 | } 28 | } -------------------------------------------------------------------------------- /libs/server/Transaction/WatchedKeySlice.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | namespace Garnet.server 7 | { 8 | [StructLayout(LayoutKind.Explicit, Size = 29)] 9 | struct WatchedKeySlice 10 | { 11 | [FieldOffset(0)] 12 | public long version; 13 | 14 | [FieldOffset(8)] 15 | public ArgSlice slice; 16 | 17 | [FieldOffset(20)] 18 | public long hash; 19 | 20 | [FieldOffset(28)] 21 | public StoreType type; 22 | } 23 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cc/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Build the native_device library. 2 | 3 | set (NATIVE_DEVICE_HEADERS 4 | device/alloc.h 5 | device/async.h 6 | device/auto_ptr.h 7 | device/constants.h 8 | device/file.h 9 | device/file_common.h 10 | device/file_system_disk.h 11 | device/gc_state.h 12 | device/guid.h 13 | device/light_epoch.h 14 | device/lss_allocator.h 15 | device/native_device.h 16 | device/phase.h 17 | device/status.h 18 | device/thread.h 19 | device/utility.h 20 | ) 21 | 22 | if (MSVC) 23 | set (NATIVE_DEVICE_HEADERS ${NATIVE_DEVICE_HEADERS} 24 | device/file_windows.h 25 | ) 26 | else() 27 | set (FNATIVE_DEVICE_HEADERS ${NATIVE_DEVICE_HEADERS} 28 | device/file_linux.h 29 | ) 30 | endif() 31 | 32 | set (NATIVE_DEVICE_SOURCES 33 | device/lss_allocator.cc 34 | device/native_device_wrapper.cc 35 | device/thread_manual.cc 36 | ) 37 | 38 | if (MSVC) 39 | set (NATIVE_DEVICE_SOURCES ${NATIVE_DEVICE_SOURCES} 40 | device/file_windows.cc 41 | ) 42 | else() 43 | set (NATIVE_DEVICE_SOURCES ${NATIVE_DEVICE_SOURCES} 44 | device/file_linux.cc 45 | ) 46 | endif() 47 | 48 | add_library(native_device SHARED ${NATIVE_DEVICE_SOURCES} ${NATIVE_DEVICE_HEADERS}) 49 | if (UNIX) 50 | target_link_libraries(native_device PRIVATE stdc++fs aio) 51 | endif() 52 | -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cc/src/device/alloc.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #ifdef _WIN32 9 | #include 10 | #endif 11 | 12 | namespace FASTER { 13 | namespace core { 14 | 15 | /// Windows and standard C++/Linux have incompatible implementations of aligned malloc(). (Windows 16 | /// defines a corresponding aligned free(), while Linux relies on the ordinary free().) 17 | inline void* aligned_alloc(size_t alignment, size_t size) { 18 | #ifdef _WIN32 19 | return _aligned_malloc(size, alignment); 20 | #else 21 | return ::aligned_alloc(alignment, size); 22 | #endif 23 | } 24 | 25 | inline void aligned_free(void* ptr) { 26 | #ifdef _WIN32 27 | _aligned_free(ptr); 28 | #else 29 | ::free(ptr); 30 | #endif 31 | } 32 | 33 | } 34 | } // namespace FASTER::core 35 | 36 | -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cc/src/device/constants.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace FASTER { 9 | namespace core { 10 | 11 | struct Constants { 12 | /// Size of cache line in bytes 13 | static constexpr uint32_t kCacheLineBytes = 64; 14 | 15 | /// We issue 256 writes to disk, to checkpoint the hash table. 16 | static constexpr uint32_t kNumMergeChunks = 256; 17 | }; 18 | 19 | } 20 | } // namespace FASTER::cire -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cc/src/device/file.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #pragma once 5 | 6 | #ifdef _WIN32 7 | #include "file_windows.h" 8 | #else 9 | #include "file_linux.h" 10 | #endif 11 | -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cc/src/device/gc_state.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | namespace FASTER { 10 | namespace core { 11 | 12 | /// State of the active garbage-collection call. 13 | class GcState { 14 | public: 15 | typedef void(*truncate_callback_t)(uint64_t offset); 16 | typedef void(*complete_callback_t)(void); 17 | 18 | GcState() 19 | : truncate_callback{ nullptr } 20 | , complete_callback{ nullptr } 21 | , num_chunks{ 0 } 22 | , next_chunk{ 0 } { 23 | } 24 | 25 | void Initialize(truncate_callback_t truncate_callback_, complete_callback_t complete_callback_, 26 | uint64_t num_chunks_) { 27 | truncate_callback = truncate_callback_; 28 | complete_callback = complete_callback_; 29 | num_chunks = num_chunks_; 30 | next_chunk = 0; 31 | } 32 | 33 | truncate_callback_t truncate_callback; 34 | complete_callback_t complete_callback; 35 | uint64_t num_chunks; 36 | std::atomic next_chunk; 37 | }; 38 | 39 | } 40 | } // namespace FASTER::core 41 | -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cc/src/device/status.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #pragma once 5 | #include 6 | 7 | namespace FASTER { 8 | namespace core { 9 | 10 | enum class Status : uint8_t { 11 | Ok = 0, 12 | Pending = 1, 13 | NotFound = 2, 14 | OutOfMemory = 3, 15 | IOError = 4, 16 | Corruption = 5, 17 | Aborted = 6, 18 | }; 19 | 20 | enum class InternalStatus : uint8_t { 21 | Ok, 22 | RETRY_NOW, 23 | RETRY_LATER, 24 | RECORD_ON_DISK, 25 | SUCCESS_UNMARK, 26 | CPR_SHIFT_DETECTED 27 | }; 28 | 29 | } 30 | } // namespace FASTER::core 31 | -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cc/src/device/thread_manual.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #include "thread.h" 5 | 6 | namespace FASTER { 7 | namespace core { 8 | 9 | /// The first thread will have index 0. 10 | std::atomic Thread::next_index_{ 0 }; 11 | 12 | /// No thread IDs have been used yet. 13 | std::atomic Thread::id_used_[kMaxNumThreads] = {}; 14 | 15 | #ifdef COUNT_ACTIVE_THREADS 16 | std::atomic Thread::current_num_threads_ { 0 }; 17 | #endif 18 | 19 | /// Give the new thread an invalid ID. 20 | thread_local Thread::ThreadId Thread::id_{ Thread::ThreadId::kInvalidId }; 21 | 22 | // Track global thread id - used only with native device (thread_manual) for now 23 | thread_local uint32_t Thread::thread_index_{ Thread::next_index_++ }; 24 | } 25 | } // namespace FASTER::core 26 | -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/README.md: -------------------------------------------------------------------------------- 1 | ## Tsavorite 2 | 3 | Tsavorite is a fork of the FASTER C# library (https://github.com/microsoft/FASTER) that we have significantly extended and optimized to support Garnet's requirements. 4 | 5 | ### Privacy 6 | 7 | [Microsoft Privacy Statement](https://go.microsoft.com/fwlink/?LinkId=521839) 8 | -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/benchmark/BDN-Tsavorite.Benchmark/BDN-Tsavorite.benchmark.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | enable 6 | true 7 | ../../../../../../Garnet.snk 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/benchmark/BDN-Tsavorite.Benchmark/BenchmarkDotNetTestsApp.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | using BenchmarkDotNet.Running; 5 | 6 | namespace BenchmarkDotNetTests 7 | { 8 | public class BenchmarkDotNetTestsApp 9 | { 10 | public static string TestDirectory => Path.Combine(Path.GetDirectoryName(typeof(BenchmarkDotNetTestsApp).Assembly.Location), "Tests"); 11 | 12 | public static void Main(string[] args) 13 | { 14 | // Check for debugging a test 15 | if (args[0].ToLower() == "cursor") 16 | { 17 | var test = new IterationTests 18 | { 19 | FlushAndEvict = true 20 | }; 21 | test.SetupPopulatedStore(); 22 | test.Cursor(); 23 | test.TearDown(); 24 | return; 25 | } 26 | 27 | // Do regular invocation. 28 | BenchmarkSwitcher.FromAssembly(typeof(BenchmarkDotNetTestsApp).Assembly).Run(args); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/benchmark/YCSB.benchmark/Input.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #pragma warning disable 1591 5 | 6 | namespace Tsavorite.benchmark 7 | { 8 | public struct Input 9 | { 10 | public long value; 11 | } 12 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/benchmark/YCSB.benchmark/Key.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | using Tsavorite.core; 7 | 8 | namespace Tsavorite.benchmark 9 | { 10 | [StructLayout(LayoutKind.Explicit, Size = 8)] 11 | public struct Key 12 | { 13 | [FieldOffset(0)] 14 | public long value; 15 | 16 | public override string ToString() => "{ " + value + " }"; 17 | 18 | public struct Comparer : IKeyComparer 19 | { 20 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 21 | public readonly long GetHashCode64(ref Key key) => Utility.GetHashCode(key.value); 22 | 23 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 24 | public bool Equals(ref Key key1, ref Key key2) => key1.value == key2.value; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/benchmark/YCSB.benchmark/KeySpanByte.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | namespace Tsavorite.benchmark 7 | { 8 | [StructLayout(LayoutKind.Explicit, Size = SpanByteYcsbBenchmark.kKeySize)] 9 | public struct KeySpanByte 10 | { 11 | [FieldOffset(0)] 12 | public int length; 13 | [FieldOffset(4)] 14 | public long value; 15 | } 16 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/benchmark/YCSB.benchmark/Output.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #pragma warning disable 1591 5 | 6 | using System.Runtime.InteropServices; 7 | 8 | namespace Tsavorite.benchmark 9 | { 10 | [StructLayout(LayoutKind.Explicit)] 11 | public struct Output 12 | { 13 | [FieldOffset(0)] 14 | public Value value; 15 | } 16 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/benchmark/YCSB.benchmark/SessionSpanByteFunctions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Tsavorite.core; 5 | 6 | namespace Tsavorite.benchmark 7 | { 8 | public sealed class SessionSpanByteFunctions : SpanByteFunctions 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/benchmark/YCSB.benchmark/Value.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #define EIGHT_BYTE_VALUE 5 | //#define FIXED_SIZE_VALUE 6 | //#define FIXED_SIZE_VALUE_WITH_LOCK 7 | 8 | using System.Runtime.InteropServices; 9 | 10 | namespace Tsavorite.benchmark 11 | { 12 | [StructLayout(LayoutKind.Explicit, Size = 8)] 13 | public struct Value 14 | { 15 | public const int Size = 8; 16 | 17 | [FieldOffset(0)] 18 | public long value; 19 | } 20 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/benchmark/YCSB.benchmark/YCSB.benchmark.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | ../../../../../../Garnet.snk 6 | false 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Allocator/AllocatorRecord.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member 7 | 8 | namespace Tsavorite.core 9 | { 10 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 11 | public struct AllocatorRecord 12 | { 13 | public RecordInfo info; 14 | public TKey key; 15 | public TValue value; 16 | 17 | public override string ToString() 18 | { 19 | var keyString = key?.ToString() ?? "null"; 20 | if (keyString.Length > 20) 21 | keyString = keyString.Substring(0, 20) + "..."; 22 | var valueString = value?.ToString() ?? "null"; ; 23 | if (valueString.Length > 20) 24 | valueString = valueString.Substring(0, 20) + "..."; 25 | return $"{keyString} | {valueString} | {info}"; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Allocator/PageUnit.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | namespace Tsavorite.core 7 | { 8 | struct PageUnit 9 | { 10 | public byte[] value; 11 | public long pointer; 12 | } 13 | 14 | [StructLayout(LayoutKind.Explicit)] 15 | internal struct FullPageStatus 16 | { 17 | [FieldOffset(0)] 18 | public long LastFlushedUntilAddress; 19 | [FieldOffset(8)] 20 | public long Dirty; 21 | } 22 | 23 | [StructLayout(LayoutKind.Explicit)] 24 | internal struct PageOffset 25 | { 26 | [FieldOffset(0)] 27 | public int Offset; 28 | [FieldOffset(4)] 29 | public int Page; 30 | [FieldOffset(0)] 31 | public long PageAndOffset; 32 | } 33 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Allocator/ScanCursorState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.core 5 | { 6 | internal sealed class ScanCursorState 7 | { 8 | internal IScanIteratorFunctions functions; 9 | internal long acceptedCount; // Number of records pushed to and accepted by the caller 10 | internal bool endBatch; // End the batch (but return a valid cursor for the next batch, as if "count" records had been returned) 11 | internal bool retryLastRecord; // Retry the last record when returning a valid cursor 12 | internal bool stop; // Stop the operation (as if all records in the db had been returned) 13 | 14 | internal void Initialize(IScanIteratorFunctions scanIteratorFunctions) 15 | { 16 | functions = scanIteratorFunctions; 17 | acceptedCount = 0; 18 | endBatch = false; 19 | retryLastRecord = false; 20 | stop = false; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/ClientSession/IClientSession.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.core 5 | { 6 | class SessionInfo 7 | { 8 | public bool isActive; 9 | public IClientSession session; 10 | } 11 | 12 | internal interface IClientSession 13 | { 14 | void MergeRevivificationStatsTo(ref RevivificationStats globalStats, bool reset); 15 | 16 | void ResetRevivificationStats(); 17 | } 18 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/ClientSession/IUnsafeContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.core 5 | { 6 | /// 7 | /// Manual epoch control functions. Useful when doing generic operations across diverse 8 | /// and 9 | /// specializations. 10 | /// 11 | public interface IUnsafeContext 12 | { 13 | /// 14 | /// Resume session on current thread. IMPORTANT: Call before any async op. 15 | /// 16 | void BeginUnsafe(); 17 | 18 | /// 19 | /// Suspend session on current thread 20 | /// 21 | void EndUnsafe(); 22 | } 23 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Compaction/CompactionType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.core 5 | { 6 | /// 7 | /// Type of log compaction 8 | /// 9 | public enum CompactionType 10 | { 11 | /// 12 | /// Scan from untilAddress to read-only address to check for record liveness checking 13 | /// 14 | Scan, 15 | 16 | /// 17 | /// Lookup each record in compaction range, for record liveness checking using hash chain 18 | /// 19 | Lookup, 20 | } 21 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Device/runtimes/linux-x64/native/libnative_device.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/libs/storage/Tsavorite/cs/src/core/Device/runtimes/linux-x64/native/libnative_device.so -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Device/runtimes/win-x64/native/native_device.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/libs/storage/Tsavorite/cs/src/core/Device/runtimes/win-x64/native/native_device.dll -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Device/runtimes/win-x64/native/native_device.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/libs/storage/Tsavorite/cs/src/core/Device/runtimes/win-x64/native/native_device.pdb -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/CheckpointManagement/INamedDeviceFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Tsavorite.core 7 | { 8 | /// 9 | /// Factory for getting IDevice instances for checkpointing. The factory is specific to a particular base path or container. 10 | /// 11 | public interface INamedDeviceFactory 12 | { 13 | /// 14 | /// Get IDevice instance for given file info 15 | /// 16 | /// File info 17 | /// 18 | IDevice Get(FileDescriptor fileInfo); 19 | 20 | /// 21 | /// Delete IDevice for given file info 22 | /// 23 | /// File info 24 | /// 25 | void Delete(FileDescriptor fileInfo); 26 | 27 | /// 28 | /// List path contents, in order of preference 29 | /// 30 | /// 31 | IEnumerable ListContents(string path); 32 | } 33 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/CheckpointManagement/INamedDeviceFactoryCreator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.core 5 | { 6 | /// 7 | /// Factory creator for getting IDevice instances for checkpointing 8 | /// 9 | public interface INamedDeviceFactoryCreator 10 | { 11 | /// 12 | /// Create factory for creating IDevice instances, for the given base name or container 13 | /// 14 | /// Base name or container 15 | /// 16 | INamedDeviceFactory Create(string baseName); 17 | } 18 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/CheckpointManagement/NullNamedDeviceFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Tsavorite.core 7 | { 8 | /// 9 | /// Null device factory 10 | /// 11 | public class NullNamedDeviceFactory : INamedDeviceFactory 12 | { 13 | static readonly NullDevice nullDevice = new(); 14 | 15 | /// 16 | /// Create instance of factory 17 | /// 18 | public NullNamedDeviceFactory() { } 19 | 20 | /// 21 | public void Delete(FileDescriptor fileInfo) { } 22 | 23 | /// 24 | public IDevice Get(FileDescriptor fileInfo) => nullDevice; 25 | 26 | /// 27 | public void Initialize(string baseName) { } 28 | 29 | /// 30 | public IEnumerable ListContents(string path) 31 | { 32 | yield break; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/CheckpointManagement/NullNamedDeviceFactoryCreator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.core 5 | { 6 | /// 7 | /// Creator of factory for getting null device instances 8 | /// 9 | public class NullNamedDeviceFactoryCreator : INamedDeviceFactoryCreator 10 | { 11 | static readonly NullNamedDeviceFactory nullNamedDeviceFactory = new(); 12 | 13 | public INamedDeviceFactory Create(string baseName) 14 | { 15 | return nullNamedDeviceFactory; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/Checkpointing/IStateMachine.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.core 5 | { 6 | /// 7 | /// State machine API 8 | /// 9 | public interface IStateMachine : IStateMachineTask 10 | { 11 | /// 12 | /// Returns the next state given the current state 13 | /// 14 | /// Current state 15 | /// Next state 16 | public SystemState NextState(SystemState currentState); 17 | } 18 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/Checkpointing/IStateMachineCallback.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.core 5 | { 6 | /// 7 | /// Encapsulates custom logic to be executed as part of Tsavorite's state machine logic 8 | /// 9 | public interface IStateMachineCallback 10 | { 11 | /// 12 | /// Invoked immediately before every state transition. 13 | /// 14 | void BeforeEnteringState(SystemState next); 15 | } 16 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/Checkpointing/IStateMachineTask.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.core 5 | { 6 | /// 7 | /// Interface for tasks that are executed as part of the state machine 8 | /// 9 | public interface IStateMachineTask 10 | { 11 | /// 12 | /// Called before we move to nextState. All participant threads will be in previousState. 13 | /// 14 | /// 15 | /// 16 | public void GlobalBeforeEnteringState(SystemState nextState, StateMachineDriver stateMachineDriver); 17 | 18 | /// 19 | /// Called after we move to nextState. All participant threads will be in nextState. 20 | /// 21 | /// 22 | /// 23 | public void GlobalAfterEnteringState(SystemState nextState, StateMachineDriver stateMachineDriver); 24 | } 25 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/Common/HeapContainer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | 6 | namespace Tsavorite.core 7 | { 8 | /// 9 | /// Heap container to store keys and values when they go pending 10 | /// 11 | /// 12 | public interface IHeapContainer : IDisposable 13 | { 14 | /// 15 | /// Get a reference to the contained object 16 | /// 17 | ref T Get(); 18 | } 19 | 20 | /// 21 | /// Heap container for standard C# objects (non-variable-length) 22 | /// 23 | /// 24 | internal sealed class StandardHeapContainer : IHeapContainer 25 | { 26 | private T obj; 27 | 28 | public StandardHeapContainer(ref T obj) 29 | { 30 | this.obj = obj; 31 | } 32 | 33 | public ref T Get() => ref obj; 34 | 35 | public void Dispose() { } 36 | } 37 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/Common/ReadCacheSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #pragma warning disable IDE1006 // Naming Styles 5 | 6 | namespace Tsavorite.core 7 | { 8 | /// 9 | /// Configuration settings for hybrid log 10 | /// 11 | internal class ReadCacheSettings 12 | { 13 | /// 14 | /// Size of a segment (group of pages), in bits 15 | /// 16 | public int PageSizeBits = 25; 17 | 18 | /// 19 | /// Total size of in-memory part of log, in bits 20 | /// 21 | public int MemorySizeBits = 34; 22 | 23 | /// 24 | /// Fraction of log head (in memory) used for second chance 25 | /// copy to tail. This is (1 - MutableFraction) for the 26 | /// underlying log 27 | /// 28 | public double SecondChanceFraction = 0.1; 29 | } 30 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/Common/RecordMetadata.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.core 5 | { 6 | /// 7 | /// A structure carrying metadata about a record in the log. 8 | /// 9 | public readonly struct RecordMetadata 10 | { 11 | /// 12 | /// The header of the record. 13 | /// 14 | public readonly RecordInfo RecordInfo; 15 | 16 | /// 17 | /// The logical address of the record. 18 | /// 19 | public readonly long Address; 20 | 21 | internal RecordMetadata(RecordInfo recordInfo, long address = Constants.kInvalidAddress) 22 | { 23 | RecordInfo = recordInfo; 24 | Address = address; 25 | } 26 | 27 | /// 28 | public override string ToString() => $"ri {RecordInfo}, addr {Address}"; 29 | } 30 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/Interfaces/IKeyComparer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Tsavorite.core 7 | { 8 | /// 9 | /// Defines methods to support the comparison of Tsavorite keys for equality. 10 | /// 11 | /// The type of keys to compare. 12 | /// This comparer differs from the built-in in that it implements a 64-bit hash code 13 | public interface IKeyComparer 14 | { 15 | /// 16 | /// Get 64-bit hash code 17 | /// 18 | long GetHashCode64(ref T key); 19 | 20 | /// 21 | /// Equality comparison 22 | /// 23 | /// Left side 24 | /// Right side 25 | bool Equals(ref T k1, ref T k2); 26 | } 27 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/Recovery/FileDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.core 5 | { 6 | /// 7 | /// Complete specification of file with path, for local and cloud files 8 | /// 9 | public struct FileDescriptor 10 | { 11 | /// 12 | /// Relative directory name or path 13 | /// 14 | public string directoryName; 15 | /// 16 | /// Actual file or blob name 17 | /// 18 | public string fileName; 19 | 20 | /// 21 | /// Create FileInfo instance 22 | /// 23 | /// 24 | /// 25 | public FileDescriptor(string directoryName, string fileName) 26 | { 27 | this.directoryName = directoryName; 28 | this.fileName = fileName; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Index/Tsavorite/WriteReason.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.core 5 | { 6 | /// 7 | /// The reason a SingleWriter was performed 8 | /// 9 | public enum WriteReason : byte 10 | { 11 | /// A new record appended by Upsert 12 | Upsert, 13 | 14 | /// Copying a read from disk to the tail of the log 15 | CopyToTail, 16 | 17 | /// Copying a read from disk to the read cache 18 | CopyToReadCache, 19 | 20 | /// The user called Compact() 21 | Compaction 22 | } 23 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/TsavoriteLog/CommitFailureException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #pragma warning disable 0162 5 | 6 | namespace Tsavorite.core 7 | { 8 | /// 9 | /// Exception thrown when commit fails 10 | /// 11 | public sealed class CommitFailureException : TsavoriteException 12 | { 13 | /// 14 | /// Commit info and next commit task in chain 15 | /// 16 | public LinkedCommitInfo LinkedCommitInfo { get; private set; } 17 | 18 | internal CommitFailureException(LinkedCommitInfo linkedCommitInfo, string message) 19 | : base(message) 20 | => LinkedCommitInfo = linkedCommitInfo; 21 | } 22 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/TsavoriteLog/CommitInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #pragma warning disable 0162 5 | 6 | using System.Threading.Tasks; 7 | 8 | namespace Tsavorite.core 9 | { 10 | /// 11 | /// Info contained in task associated with commit 12 | /// 13 | public struct CommitInfo 14 | { 15 | /// 16 | /// From address of commit range 17 | /// 18 | public long FromAddress; 19 | 20 | /// 21 | /// Until address of commit range 22 | /// 23 | public long UntilAddress; 24 | 25 | /// 26 | /// Error code (0 = success) 27 | /// 28 | public uint ErrorCode; 29 | } 30 | 31 | /// 32 | /// Linked list (chain) of commit info 33 | /// 34 | public struct LinkedCommitInfo 35 | { 36 | /// 37 | /// Commit info 38 | /// 39 | public CommitInfo CommitInfo; 40 | 41 | /// 42 | /// Next task in commit chain 43 | /// 44 | public Task NextTask; 45 | } 46 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/TsavoriteLog/ILogEnqueueEntry.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | 6 | namespace Tsavorite.core 7 | { 8 | /// 9 | /// Represents a entry that can be serialized directly onto TsavoriteLog when enqueuing 10 | /// 11 | public interface ILogEnqueueEntry 12 | { 13 | /// 14 | /// the size in bytes after serialization onto TsavoriteLog 15 | public int SerializedLength { get; } 16 | 17 | /// 18 | /// Serialize the entry onto TsavoriteLog. 19 | /// 20 | /// Memory buffer of TsavoriteLog to serialize onto. Guaranteed to have at least SerializedLength() many bytes 21 | public void SerializeTo(Span dest); 22 | } 23 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/TsavoriteLog/IReadOnlySpanBatch.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | 6 | namespace Tsavorite.core 7 | { 8 | /// 9 | /// Interface to provide a batch of ReadOnlySpan[byte] data to Tsavorite 10 | /// 11 | public interface IReadOnlySpanBatch 12 | { 13 | /// 14 | /// Number of entries in provided batch 15 | /// 16 | /// Number of entries 17 | int TotalEntries(); 18 | 19 | /// 20 | /// Retrieve batch entry at specified index 21 | /// 22 | /// Index 23 | /// 24 | ReadOnlySpan Get(int index); 25 | } 26 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/Utilities/AsyncResultTypes.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #define CALLOC 5 | 6 | namespace Tsavorite.core 7 | { 8 | internal struct AsyncGetFromDiskResult 9 | { 10 | public TContext context; 11 | } 12 | 13 | internal unsafe struct HashIndexPageAsyncFlushResult 14 | { 15 | public int chunkIndex; 16 | public SectorAlignedMemory mem; 17 | } 18 | 19 | internal unsafe struct HashIndexPageAsyncReadResult 20 | { 21 | public int chunkIndex; 22 | } 23 | 24 | internal struct OverflowPagesFlushAsyncResult 25 | { 26 | public SectorAlignedMemory mem; 27 | } 28 | 29 | internal struct OverflowPagesReadAsyncResult 30 | { 31 | } 32 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/core/VarLen/SpanByteHeapContainer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | namespace Tsavorite.core 7 | { 8 | /// 9 | /// Heap container for structs 10 | /// 11 | internal sealed class SpanByteHeapContainer : IHeapContainer 12 | { 13 | readonly SectorAlignedMemory mem; 14 | 15 | public unsafe SpanByteHeapContainer(ref SpanByte obj, SectorAlignedBufferPool pool) 16 | { 17 | mem = pool.Get(obj.TotalSize); 18 | obj.CopyTo(mem.GetValidPointer()); 19 | } 20 | 21 | public unsafe ref SpanByte Get() => ref Unsafe.AsRef(mem.GetValidPointer()); 22 | 23 | public void Dispose() => mem.Return(); 24 | } 25 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/devices/AzureStorageDevice/Tsavorite.devices.AzureStorageDevice.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Tsavorite.devices 5 | true 6 | ../../../../../../../Garnet.snk 7 | false 8 | true 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/src/devices/AzureStorageDevice/Utils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Tsavorite.devices 5 | { 6 | using System; 7 | 8 | /// 9 | /// Utility methods 10 | /// 11 | public static class Utils 12 | { 13 | /// 14 | /// Returns true or false whether an exception is considered fatal 15 | /// 16 | public static bool IsFatal(Exception exception) 17 | { 18 | if (exception is OutOfMemoryException || exception is StackOverflowException) 19 | { 20 | return true; 21 | } 22 | 23 | return false; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/test/LogFormatter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | using System.Globalization; 6 | 7 | namespace Tsavorite.test 8 | { 9 | /// 10 | /// Log formatter primitives 11 | /// 12 | public static class LogFormatter 13 | { 14 | private const string TIME_FORMAT = "HH:mm:ss.ffff"; 15 | private const string DATE_FORMAT = "yyyy-MM-dd " + TIME_FORMAT; 16 | 17 | /// 18 | /// Format date 19 | /// 20 | /// 21 | public static string FormatDate(DateTime dateTime) => dateTime.ToString(DATE_FORMAT, CultureInfo.InvariantCulture); 22 | 23 | /// 24 | /// Format time 25 | /// 26 | /// 27 | public static string FormatTime(DateTime dateTime) => dateTime.ToString(TIME_FORMAT, CultureInfo.InvariantCulture); 28 | } 29 | } -------------------------------------------------------------------------------- /libs/storage/Tsavorite/cs/test/Tsavorite.test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | ../../../../../Garnet.snk 6 | false 7 | 8 | 9 | 10 | 1701;1702;1591;IDE0130;IDE0065;IDE0007;IDE0048 11 | 12 | 13 | 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /main/GarnetServer/Extensions/MyDictGet.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Diagnostics; 5 | using Garnet.common; 6 | using Garnet.server; 7 | using Tsavorite.core; 8 | 9 | namespace Garnet 10 | { 11 | public class MyDictGet : CustomObjectFunctions 12 | { 13 | public override bool Reader(ReadOnlyMemory key, ref ObjectInput input, IGarnetObject value, ref RespMemoryWriter writer, ref ReadInfo readInfo) 14 | { 15 | Debug.Assert(value is MyDict); 16 | 17 | var entryKey = GetFirstArg(ref input); 18 | 19 | var dictObject = (MyDict)value; 20 | if (dictObject.TryGetValue(entryKey.ToArray(), out var result)) 21 | writer.WriteBulkString(result); 22 | else 23 | writer.WriteNull(); 24 | 25 | return true; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /main/GarnetServer/Extensions/MyDictSet.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Diagnostics; 5 | using Garnet.common; 6 | using Garnet.server; 7 | using Tsavorite.core; 8 | 9 | namespace Garnet 10 | { 11 | public class MyDictSet : CustomObjectFunctions 12 | { 13 | public override bool NeedInitialUpdate(ReadOnlyMemory key, ref ObjectInput input, ref RespMemoryWriter writer) => true; 14 | 15 | public override bool Updater(ReadOnlyMemory key, ref ObjectInput input, IGarnetObject value, ref RespMemoryWriter writer, ref RMWInfo rmwInfo) 16 | { 17 | Debug.Assert(value is MyDict); 18 | 19 | var offset = 0; 20 | var keyArg = GetNextArg(ref input, ref offset).ToArray(); 21 | var valueArg = GetNextArg(ref input, ref offset).ToArray(); 22 | 23 | _ = ((MyDict)value).Set(keyArg, valueArg); 24 | return true; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /main/GarnetServer/Extensions/SetStringAndList.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | using Garnet.server; 6 | 7 | namespace Garnet 8 | { 9 | class SetStringAndList : CustomProcedure 10 | { 11 | public override bool Execute(TGarnetApi garnetApi, ref CustomProcedureInput procInput, ref MemoryResult output) 12 | { 13 | var offset = 0; 14 | var key = GetNextArg(ref procInput, ref offset); 15 | var value = GetNextArg(ref procInput, ref offset); 16 | garnetApi.SET(key, value); 17 | 18 | // Create an object and set it 19 | var objKey = GetNextArg(ref procInput, ref offset); 20 | var objValue = GetNextArg(ref procInput, ref offset); 21 | garnetApi.ListRightPush(objKey, [objValue], out _); 22 | 23 | WriteSimpleString(ref output, "OK"); 24 | return true; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /main/GarnetServer/Extensions/Sum.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | using Garnet.server; 6 | 7 | namespace Garnet 8 | { 9 | class Sum : CustomProcedure 10 | { 11 | public override bool Execute(TGarnetApi garnetApi, ref CustomProcedureInput procInput, ref MemoryResult output) 12 | { 13 | var offset = 0; 14 | var sum = 0; 15 | ArgSlice key; 16 | 17 | while ((key = GetNextArg(ref procInput, ref offset)).Length > 0) 18 | { 19 | if (garnetApi.GET(key, out var value) == GarnetStatus.OK) 20 | { 21 | // Sum the values 22 | if (int.TryParse(value.ToString(), out var intValue)) 23 | { 24 | sum += intValue; 25 | } 26 | } 27 | } 28 | 29 | WriteSimpleString(ref output, sum.ToString()); 30 | return true; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /main/GarnetServer/Properties/PublishProfiles/linux-arm64-based.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | FileSystem 10 | <_TargetId>Folder 11 | net8.0;net9.0 12 | linux-arm64 13 | false 14 | true 15 | 16 | 17 | 18 | bin\Release\net8.0\publish\linux-arm64\ 19 | 20 | 21 | 22 | bin\Release\net9.0\publish\linux-arm64\ 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /main/GarnetServer/Properties/PublishProfiles/linux-x64-based.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | bin\Release\net8.0\publish\linux-x64\ 10 | FileSystem 11 | <_TargetId>Folder 12 | net8.0;net9.0 13 | linux-x64 14 | false 15 | true 16 | 17 | 18 | 19 | bin\Release\net8.0\publish\linux-x64\ 20 | 21 | 22 | 23 | bin\Release\net9.0\publish\linux-x64\ 24 | 25 | -------------------------------------------------------------------------------- /main/GarnetServer/Properties/PublishProfiles/osx-arm64-based.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | FileSystem 10 | <_TargetId>Folder 11 | net8.0;net9.0 12 | osx-arm64 13 | false 14 | true 15 | 16 | 17 | 18 | bin\Release\net8.0\publish\osx-arm64\ 19 | 20 | 21 | 22 | bin\Release\net9.0\publish\osx-arm64\ 23 | 24 | -------------------------------------------------------------------------------- /main/GarnetServer/Properties/PublishProfiles/osx-x64-based.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | FileSystem 10 | <_TargetId>Folder 11 | net8.0;net9.0 12 | osx-x64 13 | false 14 | true 15 | 16 | 17 | 18 | bin\Release\net8.0\publish\osx-x64\ 19 | 20 | 21 | 22 | bin\Release\net9.0\publish\osx-x64\ 23 | 24 | -------------------------------------------------------------------------------- /main/GarnetServer/Properties/PublishProfiles/portable.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | FileSystem 10 | <_TargetId>Folder 11 | net8.0;net9.0 12 | false 13 | 14 | 15 | 16 | bin\Release\net8.0\publish\portable\ 17 | 18 | 19 | 20 | bin\Release\net9.0\publish\portable\ 21 | 22 | -------------------------------------------------------------------------------- /main/GarnetServer/Properties/PublishProfiles/win-arm64-based-readytorun.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | FileSystem 10 | <_TargetId>Folder 11 | net8.0;net9.0 12 | win-arm64 13 | false 14 | true 15 | true 16 | 17 | 18 | 19 | bin\Release\net8.0\publish\win-arm64\ 20 | 21 | 22 | 23 | bin\Release\net9.0\publish\win-arm64\ 24 | 25 | -------------------------------------------------------------------------------- /main/GarnetServer/README.md: -------------------------------------------------------------------------------- 1 | # garnet-server 2 | 3 | `garnet-server` is a .NET global tool that provides the [`Microsoft.Garnet`](https://www.nuget.org/packages/Microsoft.Garnet) RESP server. 4 | 5 | The `garnet-server` by itself will create a Garnet server using the default port; for full options, see `garnet-server --help`. 6 | 7 | - [Full Garnet documentation](https://microsoft.github.io/garnet/) 8 | - [Garnet GitHub repository](https://github.com/microsoft/garnet.git) -------------------------------------------------------------------------------- /metrics/HdrHistogram/.editorconfig: -------------------------------------------------------------------------------- 1 | # All files 2 | [*] 3 | generated_code = true 4 | file_header_template = unset 5 | dotnet_analyzer_diagnostic.category-Style.severity = none 6 | dotnet_diagnostic.IDE0005.severity = none -------------------------------------------------------------------------------- /metrics/HdrHistogram/HdrHistogram.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | ../../Garnet.snk 6 | false 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /metrics/HdrHistogram/Iteration/RecordedValuesEnumerable.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a .NET port of the original Java version, which was written by 3 | * Gil Tene as described in 4 | * https://github.com/HdrHistogram/HdrHistogram 5 | * and released to the public domain, as explained at 6 | * http://creativecommons.org/publicdomain/zero/1.0/ 7 | */ 8 | 9 | using System.Collections; 10 | using System.Collections.Generic; 11 | 12 | namespace HdrHistogram.Iteration 13 | { 14 | /// 15 | /// An enumerator of through the histogram using a 16 | /// 17 | internal sealed class RecordedValuesEnumerable : IEnumerable 18 | { 19 | private readonly HistogramBase _histogram; 20 | 21 | public RecordedValuesEnumerable(HistogramBase histogram) 22 | { 23 | _histogram = histogram; 24 | } 25 | 26 | public IEnumerator GetEnumerator() 27 | { 28 | return new RecordedValuesEnumerator(_histogram); 29 | } 30 | 31 | IEnumerator IEnumerable.GetEnumerator() 32 | { 33 | return GetEnumerator(); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /modules/GarnetJSON/GarnetJSON.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | ../../Garnet.snk 6 | false 7 | 8 | 9 | 10 | true 11 | enable 12 | enable 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /modules/GarnetJSON/JSONPath/JsonSelectSettings.cs: -------------------------------------------------------------------------------- 1 | namespace GarnetJSON.JSONPath 2 | { 3 | /// 4 | /// Specifies the settings used when selecting JSON. 5 | /// 6 | public class JsonSelectSettings 7 | { 8 | /// 9 | /// Gets or sets a timeout that will be used when executing regular expressions. 10 | /// 11 | /// The timeout that will be used when executing regular expressions. 12 | public TimeSpan? RegexMatchTimeout { get; set; } 13 | 14 | /// 15 | /// Gets or sets a flag that indicates whether an error should be thrown if 16 | /// no tokens are found when evaluating part of the expression. 17 | /// 18 | /// 19 | /// A flag that indicates whether an error should be thrown if 20 | /// no tokens are found when evaluating part of the expression. 21 | /// 22 | public bool ErrorWhenNoMatch { get; set; } 23 | } 24 | } -------------------------------------------------------------------------------- /modules/GarnetJSON/JsonCmdStrings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace GarnetJSON 5 | { 6 | /// 7 | /// Json Command strings for RESP protocol 8 | /// 9 | public static class JsonCmdStrings 10 | { 11 | public static ReadOnlySpan INDENT => "INDENT"u8; 12 | public static ReadOnlySpan NEWLINE => "NEWLINE"u8; 13 | public static ReadOnlySpan SPACE => "SPACE"u8; 14 | 15 | public static ReadOnlySpan RESP_NEW_OBJECT_AT_ROOT => "ERR new objects must be created at the root"u8; 16 | public static ReadOnlySpan RESP_WRONG_STATIC_PATH => "Err wrong static path"u8; 17 | } 18 | } -------------------------------------------------------------------------------- /modules/GarnetJSON/RespJsonEnums.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace GarnetJSON 5 | { 6 | /// 7 | /// Represents the result of a JSON.SET operation. 8 | /// 9 | public enum SetResult : byte 10 | { 11 | /// 12 | /// The operation was successful. 13 | /// 14 | Success, 15 | 16 | /// 17 | /// The condition for the operation was not met. 18 | /// 19 | ConditionNotMet, 20 | 21 | /// 22 | /// An error occurred during the operation. 23 | /// 24 | Error 25 | } 26 | } -------------------------------------------------------------------------------- /modules/NoOpModule/DummyObjectNoOpRMW.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | using Garnet.server; 6 | using Tsavorite.core; 7 | 8 | namespace NoOpModule 9 | { 10 | /// 11 | /// Represents a no-op RMW operation on a dummy object 12 | /// 13 | public class DummyObjectNoOpRMW : CustomObjectFunctions 14 | { 15 | /// 16 | public override bool NeedInitialUpdate(ReadOnlyMemory key, ref ObjectInput input, 17 | ref RespMemoryWriter writer) => true; 18 | 19 | /// 20 | public override bool Updater(ReadOnlyMemory key, ref ObjectInput input, IGarnetObject value, 21 | ref RespMemoryWriter writer, ref RMWInfo rmwInfo) 22 | { 23 | return true; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /modules/NoOpModule/DummyObjectNoOpRead.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | using Garnet.server; 6 | using Tsavorite.core; 7 | 8 | namespace NoOpModule 9 | { 10 | /// 11 | /// Represents a no-op read operation on a dummy object 12 | /// 13 | public class DummyObjectNoOpRead : CustomObjectFunctions 14 | { 15 | /// 16 | public override bool Reader(ReadOnlyMemory key, ref ObjectInput input, IGarnetObject value, 17 | ref RespMemoryWriter writer, ref ReadInfo readInfo) 18 | { 19 | return true; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /modules/NoOpModule/NoOpModule.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | ../../Garnet.snk 6 | false 7 | 8 | 9 | 10 | true 11 | enable 12 | enable 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /modules/NoOpModule/NoOpProc.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | using Garnet.server; 6 | 7 | namespace NoOpModule 8 | { 9 | /// 10 | /// Represents a no-op procedure 11 | /// 12 | public class NoOpProc : CustomProcedure 13 | { 14 | /// 15 | public override bool Execute(TGarnetApi garnetApi, ref CustomProcedureInput procInput, 16 | ref MemoryResult output) 17 | { 18 | return true; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /modules/NoOpModule/NoOpTxn.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | using Garnet.server; 6 | 7 | namespace NoOpModule 8 | { 9 | /// 10 | /// Represents a no-op transaction 11 | /// 12 | public class NoOpTxn : CustomTransactionProcedure 13 | { 14 | /// 15 | public override bool Prepare(TGarnetReadApi api, ref CustomProcedureInput procInput) 16 | { 17 | return true; 18 | } 19 | 20 | /// 21 | public override void Main(TGarnetApi api, ref CustomProcedureInput procInput, ref MemoryResult output) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /playground/Bitmap/Bitmap.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /playground/Bitmap/Common.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System; 5 | 6 | namespace Bitmap 7 | { 8 | public static class Common 9 | { 10 | public static void PrintElapsedTime(TimeSpan tspan, int iter, long bytes, String msg) 11 | { 12 | double elapsedSeconds = tspan.TotalSeconds; 13 | double elapsedTimeMillis = tspan.TotalMilliseconds; 14 | double bytesAccessed = iter * bytes; 15 | double bytesPerSecond = (((double)(bytesAccessed) / (1024L * 1024L)) / elapsedSeconds); 16 | 17 | Console.WriteLine($"Total number of iterations: {iter}"); 18 | Console.WriteLine("Total time:{0}", tspan); 19 | Console.WriteLine("Total time:{0} ms for {1}", elapsedTimeMillis, msg); 20 | Console.WriteLine("Total time:{0} s for {1}", elapsedSeconds, msg); 21 | Console.WriteLine($"Throughtput: {bytesPerSecond} MB/s"); 22 | Console.WriteLine($"Operations: {iter / elapsedSeconds} Op/s"); 23 | Console.WriteLine("Average latency: {0} ms", elapsedTimeMillis / (double)iter); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /playground/Bitmap/MemoryPoolBuffers.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Buffers; 5 | 6 | namespace Bitmap 7 | { 8 | public unsafe class MemoryPoolBuffers 9 | { 10 | private IMemoryOwner memoryBuffer = null; 11 | private MemoryHandle memoryBufferHandle; 12 | 13 | public MemoryPoolBuffers(int numRecords) 14 | { 15 | memoryBuffer = MemoryPool.Shared.Rent(numRecords); 16 | memoryBufferHandle = memoryBuffer.Memory.Pin(); 17 | } 18 | 19 | public void Dispose() 20 | { 21 | if (memoryBuffer != null) 22 | { 23 | memoryBufferHandle.Dispose(); 24 | memoryBuffer.Dispose(); 25 | } 26 | } 27 | 28 | public byte* GetValidPointer() 29 | { 30 | return (byte*)memoryBufferHandle.Pointer; 31 | } 32 | 33 | 34 | } 35 | } -------------------------------------------------------------------------------- /playground/Bitmap/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Bitmap 5 | { 6 | public unsafe class Program 7 | { 8 | static void Main(string[] args) 9 | { 10 | //BitCount.RunBitCountBenchmark(); 11 | BitOp.RunBitOpBenchmark(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /playground/ClusterStress/ClusterOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using CommandLine; 5 | 6 | namespace Resp.benchmark 7 | { 8 | public partial class Options 9 | { 10 | [Option("cluster", Required = false, Default = false, HelpText = "Cluster mode benchmark enable")] 11 | public bool Cluster { get; set; } 12 | 13 | [Option("shard", Required = false, Default = -1, HelpText = "Restrict benchmark to specific shard")] 14 | public int Shard { get; set; } 15 | 16 | [Option("replica-reads", Required = false, Default = false, HelpText = "Allow replica reads for cluster mode.")] 17 | public bool ReplicaReads { get; set; } 18 | 19 | [Option("migrate-freq", Required = false, Default = 0, HelpText = "Used to control frequency of a task that issues migrate command (Only for cluster option).")] 20 | public int MigrateSlotsFreq { get; set; } 21 | 22 | [Option("migrate-batch", Required = false, Default = 100, HelpText = "Max number of slots picked to migrate from one node to another from background task that executes migrate (Only for cluster option).")] 23 | public int MigrateBatch { get; set; } 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /playground/CommandInfoUpdater/CommandInfoUpdater.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | True 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /playground/CommandInfoUpdater/Options.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using CommandLine; 5 | 6 | namespace CommandInfoUpdater 7 | { 8 | public class Options 9 | { 10 | [Option('p', "port", Required = false, Default = 6379, HelpText = "RESP server port to query")] 11 | public int RespServerPort { get; set; } 12 | 13 | [Option('h', "host", Required = false, Default = "127.0.0.1", HelpText = "RESP server host to query")] 14 | public string RespServerHost { get; set; } 15 | 16 | [Option('o', "output", Required = false, HelpText = "Output directory for updated JSON files")] 17 | public string OutputDir { get; set; } 18 | 19 | [Option('f', "force", Required = false, Default = false, HelpText = "Force overwrite existing commands info")] 20 | public bool Force { get; set; } 21 | 22 | [Option('i', "ignore", Required = false, Separator = ',', HelpText = "Command names to ignore (comma separated)")] 23 | public IEnumerable IgnoreCommands { get; set; } 24 | } 25 | } -------------------------------------------------------------------------------- /playground/Embedded.perftest/Operation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | namespace Embedded.perftest 5 | { 6 | /// 7 | /// Garnet operations to execute in the benchmark 8 | /// 9 | public enum OperationType : byte 10 | { 11 | PING, DBSIZE, CLIENT, ECHO, SET, GET 12 | } 13 | } -------------------------------------------------------------------------------- /playground/GarnetClientStress/GarnetClientStress.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | enable 6 | 7 | 8 | 9 | 10 | PreserveNewest 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /playground/GarnetClientStress/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Threading; 5 | using CommandLine; 6 | 7 | namespace GarnetClientStress 8 | { 9 | public class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | ParserResult result = Parser.Default.ParseArguments(args); 14 | if (result.Tag == ParserResultType.NotParsed) return; 15 | var opts = result.MapResult(o => o, xs => new Options()); 16 | 17 | ConfigureGlobalRuntimeSettings(); 18 | 19 | StressTestUtils stressTestUtils = new(opts); 20 | stressTestUtils.RunTest(); 21 | } 22 | 23 | private static void ConfigureGlobalRuntimeSettings() 24 | { 25 | ThreadPool.SetMinThreads(workerThreads: 1000, completionPortThreads: 1000); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /playground/MigrateBench/Common.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Microsoft.Extensions.Logging; 5 | 6 | namespace MigrateBench 7 | { 8 | public static class Common 9 | { 10 | public static bool Validate(int[] slots, ILogger logger = null) 11 | { 12 | if ((slots.Length & 0x1) > 0) 13 | { 14 | logger?.LogError("Malformed SLOTSRANGES input; please provide pair of ranges"); 15 | return false; 16 | } 17 | return true; 18 | } 19 | 20 | public static List GetSingleSlots(Options opts, ILogger logger = null) 21 | { 22 | var slots = opts.Slots.ToArray(); 23 | if (!Validate(slots, logger)) 24 | return null; 25 | 26 | var _slots = new List(); 27 | for (var i = 0; i < slots.Length; i += 2) 28 | { 29 | var startSlot = slots[i]; 30 | var endSlot = slots[i + 1]; 31 | for (var j = startSlot; j <= endSlot; j++) 32 | _slots.Add(j); 33 | } 34 | 35 | return _slots; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /playground/MigrateBench/MigrateBench.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | disable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /playground/SampleModule/SampleModule.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet; 5 | using Garnet.server; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace SampleModule 9 | { 10 | public class SampleModule : ModuleBase 11 | { 12 | public override void OnLoad(ModuleLoadContext context, string[] args) 13 | { 14 | var status = context.Initialize("SampleModule", 1); 15 | if (status != ModuleActionStatus.Success) 16 | { 17 | context.Logger?.LogError("Failed to initialize SampleModule. Error {status}", status); 18 | return; 19 | } 20 | 21 | context.RegisterCommand("SampleModule.SETIFPM", new SetIfPMCustomCommand()); 22 | 23 | context.RegisterTransaction("SampleModule.READWRITETX", () => new ReadWriteTxn()); 24 | 25 | var factory = new MyDictFactory(); 26 | context.RegisterType(factory); 27 | 28 | context.RegisterCommand("SampleModule.MYDICTSET", factory, new MyDictSet()); 29 | context.RegisterCommand("SampleModule.MYDICTGET", factory, new MyDictGet(), CommandType.Read); 30 | 31 | context.RegisterProcedure("SampleModule.SUM", () => new Sum()); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /playground/SampleModule/SampleModule.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /playground/TstRunner/TstRunner.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | PreserveNewest 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /samples/ETag/ETag.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | disable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /samples/ETag/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace ETag; 4 | 5 | class Program 6 | { 7 | static async Task Main(string[] args) 8 | { 9 | // Uncomment whichever example you want to run 10 | 11 | await OccSimulation.RunSimulation(); 12 | // await Caching.RunSimulation(); 13 | } 14 | } -------------------------------------------------------------------------------- /samples/GarnetClientSample/GarnetClientSample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | true 6 | 7 | 8 | 9 | 10 | PreserveNewest 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /samples/GarnetClientSample/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Net; 5 | using System.Threading.Tasks; 6 | 7 | namespace GarnetClientSample 8 | { 9 | /// 10 | /// Use Garnet with GarnetClient and StackExchange.Redis clients 11 | /// 12 | class Program 13 | { 14 | static readonly EndPoint endpoint = new IPEndPoint(IPAddress.Loopback, 6379); 15 | 16 | static readonly bool useTLS = false; 17 | 18 | static async Task Main() 19 | { 20 | await new GarnetClientSamples(endpoint, useTLS).RunAll(); 21 | 22 | // await new SERedisSamples(address, port).RunAll(); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /samples/MetricsMonitor/MetricsMonitor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | true 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /samples/MetricsMonitor/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using CommandLine; 5 | 6 | namespace MetricsMonitor 7 | { 8 | public class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | ParserResult result = Parser.Default.ParseArguments(args); 13 | if (result.Tag == ParserResultType.NotParsed) return; 14 | var opts = result.MapResult(o => o, xs => new Options()); 15 | 16 | ClientMonitor cm = new(opts); 17 | cm.StartMonitor(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /test/Garnet.fuzz/FuzzOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.IO; 5 | using CommandLine; 6 | 7 | namespace Garnet.fuzz 8 | { 9 | internal sealed class FuzzOptions 10 | { 11 | [Option('t', "fuzz-target", HelpText = "Class name to run fuzz input against.", Required = true)] 12 | public required FuzzTargets FuzzTarget { get; set; } 13 | 14 | [Option('f', "input-file", HelpText = "Read fuzz input from given file.", Group = "input")] 15 | public FileInfo? InputFile { get; set; } 16 | 17 | [Option('d', "input-directory", HelpText = "Read fuzz inputs from files in given directory.", Group = "input")] 18 | public DirectoryInfo? InputDirectory { get; set; } 19 | 20 | [Option('i', "stdin", HelpText = "Read fuzz input from standard input.", Group = "input")] 21 | public bool UseStandardIn { get; set; } 22 | 23 | [Option('c', "run-count", HelpText = "Number of times to run fuzzer for input (default=1)")] 24 | public int? RepeatCount { get; set; } 25 | 26 | [Option('q', "quiet", HelpText = "Suppress output.")] 27 | public bool Quiet { get; set; } 28 | } 29 | } -------------------------------------------------------------------------------- /test/Garnet.fuzz/FuzzTargets.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Embedded.server; 5 | using Garnet.server; 6 | 7 | namespace Garnet.fuzz 8 | { 9 | /// 10 | /// Different known fuzz targets. 11 | /// 12 | internal enum FuzzTargets 13 | { 14 | /// 15 | /// Fuzz parsing of requests into s. 16 | /// 17 | RespCommandParsing, 18 | 19 | /// 20 | /// Fuzz compilation of Lua scripts in . 21 | /// 22 | LuaScriptCompilation, 23 | 24 | /// 25 | /// Fuzz Garnet accepting resp commands, using . 26 | /// 27 | GarnetEndToEnd, 28 | } 29 | } -------------------------------------------------------------------------------- /test/Garnet.fuzz/Garnet.fuzz.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | enable 6 | true 7 | ../../Garnet.snk 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /test/Garnet.test.cluster/ReplicationTests/ClusterReplicationAsyncReplay.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using NUnit.Framework; 5 | 6 | namespace Garnet.test.cluster 7 | { 8 | [NonParallelizable] 9 | public class ClusterReplicationAsyncReplay : ClusterReplicationBaseTests 10 | { 11 | [SetUp] 12 | public override void Setup() 13 | { 14 | asyncReplay = true; 15 | base.Setup(); 16 | } 17 | 18 | [TearDown] 19 | public override void TearDown() 20 | { 21 | base.TearDown(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /test/Garnet.test.cluster/ReplicationTests/ClusterReplicationTLS.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using NUnit.Framework; 5 | 6 | namespace Garnet.test.cluster 7 | { 8 | [NonParallelizable] 9 | public class ClusterReplicationTLS : ClusterReplicationBaseTests 10 | { 11 | [SetUp] 12 | public override void Setup() 13 | { 14 | useTLS = true; 15 | base.Setup(); 16 | } 17 | 18 | [TearDown] 19 | public override void TearDown() 20 | { 21 | base.TearDown(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /test/Garnet.test.cluster/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /test/Garnet.test/DeleteTxn.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | using Garnet.server; 6 | using Tsavorite.core; 7 | 8 | namespace Garnet 9 | { 10 | /// 11 | /// Functions to implement custom transaction Delete key/object 12 | /// 13 | /// Format: DeleteTxn 1 key 14 | /// 15 | /// Description: Delete key 16 | /// 17 | sealed class DeleteTxn : CustomTransactionProcedure 18 | { 19 | public override bool Prepare(TGarnetReadApi api, ref CustomProcedureInput procInput) 20 | { 21 | var offset = 0; 22 | AddKey(GetNextArg(ref procInput.parseState, ref offset), LockType.Exclusive, false); 23 | return true; 24 | } 25 | 26 | public override void Main(TGarnetApi api, ref CustomProcedureInput procInput, ref MemoryResult output) 27 | { 28 | var offset = 0; 29 | var key = GetNextArg(ref procInput.parseState, ref offset); 30 | api.DELETE(key, StoreType.Main); 31 | WriteSimpleString(ref output, "SUCCESS"); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /test/Garnet.test/Extensions/ProcCustomCmd.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | using Garnet.server; 6 | 7 | namespace Garnet 8 | { 9 | class ProcCustomCmd : CustomProcedure 10 | { 11 | public override unsafe bool Execute(TGarnetApi garnetApi, ref CustomProcedureInput procInput, ref MemoryResult output) 12 | { 13 | var offset = 0; 14 | var key = GetNextArg(ref procInput, ref offset); 15 | 16 | var args = new ArgSlice[2]; 17 | args[0] = GetNextArg(ref procInput, ref offset); // value to set 18 | args[1] = GetNextArg(ref procInput, ref offset); // prefix to match 19 | 20 | if (!ParseCustomRawStringCommand("SETIFPM", out var rawStringCommand)) 21 | return false; 22 | 23 | ExecuteCustomRawStringCommand(garnetApi, rawStringCommand, key, args, out var _output); 24 | 25 | return true; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /test/Garnet.test/Extensions/SortedSetCountTxn.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using Garnet.common; 5 | using Garnet.server; 6 | using Tsavorite.core; 7 | 8 | namespace Garnet 9 | { 10 | sealed class SortedSetCountTxn : CustomTransactionProcedure 11 | { 12 | public override bool Prepare(TGarnetReadApi api, ref CustomProcedureInput input) 13 | { 14 | int offset = 0; 15 | AddKey(GetNextArg(ref input, ref offset), LockType.Shared, true); 16 | return true; 17 | } 18 | 19 | public override unsafe void Main(TGarnetApi api, ref CustomProcedureInput input, ref MemoryResult output) 20 | { 21 | int offset = 0; 22 | var key = GetNextArg(ref input, ref offset); 23 | var minScore = GetNextArg(ref input, ref offset); 24 | var maxScore = GetNextArg(ref input, ref offset); 25 | 26 | var status = api.SortedSetCount(key, minScore, maxScore, out int numElements); 27 | 28 | WriteSimpleString(ref output, numElements.ToString()); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /test/Garnet.test/ServerCredential.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | 7 | namespace Garnet.test 8 | { 9 | /// 10 | /// Server credential instance, used to generate ACL file or interact with server. 11 | /// 12 | public struct ServerCredential(string user, string password, bool IsAdmin, bool UsedForClusterAuth, bool IsClearText) 13 | { 14 | public string user = user; 15 | public string password = password; 16 | public byte[] hash = SHA256.HashData(Encoding.ASCII.GetBytes(password)); 17 | public bool IsAdmin = IsAdmin; 18 | public bool UsedForClusterAuth = UsedForClusterAuth; 19 | public bool IsClearText = IsClearText; 20 | } 21 | } -------------------------------------------------------------------------------- /test/Garnet.test/runGarnetTests.cmd: -------------------------------------------------------------------------------- 1 | REM Usage: \runGarnetTests.cmd 100 Debug ClusterUseTLSReplicationTests 2 | 3 | echo off 4 | setlocal enabledelayedexpansion 5 | 6 | SET numCount=%1 7 | SET config=%2 8 | SET filter=%3 9 | 10 | echo [Test Configuration] 11 | echo Iteration: %numCount% 12 | echo Configuration: %config% 13 | dotnet build -c !config!&& cd ../../../ 14 | 15 | echo [==================] 16 | FOR /L %%A IN (1,1,%numCount%) DO ( 17 | echo [============================= Running iteration number %%A out of %numCount%, started on %time% =============================] 18 | cd .\Garnet\test\Garnet.test\ && dotnet test -c !config! --logger:"console;verbosity=detailed" --filter !filter! --no-build && cd ../../../ 19 | echo [============================= Ended iteration number %%A out of %numCount%, completed on %time% ===============================] 20 | ) -------------------------------------------------------------------------------- /test/Garnet.test/test.bat: -------------------------------------------------------------------------------- 1 | :loop 2 | dotnet test -c Debug --logger:"console;verbosity=detailed" --filter Cluster 3 | goto loop -------------------------------------------------------------------------------- /test/Garnet.test/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | testname=ClusterTLSRPrimaryCheckpointRetrieve 4 | config=Release 5 | framework=net8.0 6 | 7 | # First run does build 8 | dotnet test -c $config --logger:"console;verbosity=detailed" --framework:$framework --filter $testname 9 | 10 | while dotnet test --no-build -c $config --logger:"console;verbosity=detailed" --framework:$framework --filter $testname; do 11 | echo "Tests passed. Running again..." 12 | done 13 | 14 | echo "Tests failed." -------------------------------------------------------------------------------- /test/PerfRegressionTesting/ConfigFiles/CI_Config_Offline_Get_1Thr.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "To get proper expected results, the ExpectedCoresToTestOn needs to match the number of cores on test machine.", 3 | "ExpectedCoresToTestOn_win": 48, 4 | "ExpectedCoresToTestOn_linux": 48, 5 | "op": "GET", 6 | "threads": "1", 7 | "dbsize": 268435456, 8 | "runtime": 30, 9 | "expectedMSETThroughputValue_linux": 4800000, 10 | "expectedGETThroughputValue_linux": 2000000, 11 | "expectedMSETThroughputValue_win": 6200000, 12 | "expectedGETThroughputValue_win": 1580000, 13 | "acceptableGETThroughputRange": 10, 14 | "acceptableMSETThroughputRange": 15 15 | } 16 | -------------------------------------------------------------------------------- /test/PerfRegressionTesting/ConfigFiles/CI_Config_Offline_Get_MaxThr.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "Note: MAX is actually total number of cores / 2", 3 | "_comment2": "To get proper expected results, the ExpectedCoresToTestOn needs to match the number of cores on test machine.", 4 | "ExpectedCoresToTestOn_win": 48, 5 | "ExpectedCoresToTestOn_linux": 48, 6 | "op": "GET", 7 | "threads": "MAX", 8 | "dbsize": 268435456, 9 | "runtime": 30, 10 | "expectedMSETThroughputValue_linux": 5500000, 11 | "expectedGETThroughputValue_linux": 44000000, 12 | "expectedMSETThroughputValue_win": 6300000, 13 | "expectedGETThroughputValue_win": 34600000, 14 | "acceptableGETThroughputRange": 10, 15 | "acceptableMSETThroughputRange": 15 16 | } 17 | -------------------------------------------------------------------------------- /test/PerfRegressionTesting/ConfigFiles/CI_Config_Offline_ZADDREM_1Thr.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "To get proper expected results, the ExpectedCoresToTestOn needs to match the number of cores on test machine.", 3 | "ExpectedCoresToTestOn_win": 48, 4 | "ExpectedCoresToTestOn_linux": 48, 5 | "op": "ZADDREM", 6 | "threads": "1", 7 | "expectedGETThroughputValue_linux": 710000, 8 | "expectedGETThroughputValue_win": 620000, 9 | "acceptableGETThroughputRange": 10, 10 | "acceptableMSETThroughputRange": 10 11 | } 12 | -------------------------------------------------------------------------------- /test/PerfRegressionTesting/ConfigFiles/CI_Config_Offline_ZADDREM_MaxThr.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "Note: MAX is actually total number of cores / 2", 3 | "_comment2": "To get proper expected results, the ExpectedCoresToTestOn needs to match the number of cores on test machine.", 4 | "ExpectedCoresToTestOn_win": 48, 5 | "ExpectedCoresToTestOn_linux": 48, 6 | "op": "ZADDREM", 7 | "threads": "MAX", 8 | "expectedGETThroughputValue_linux": 7800000, 9 | "expectedGETThroughputValue_win": 9400000, 10 | "acceptableGETThroughputRange": 10, 11 | "acceptableMSETThroughputRange": 10 12 | 13 | } 14 | -------------------------------------------------------------------------------- /test/PerfRegressionTesting/ConfigFiles/CI_Config_Online_GetSet_1Thr.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "To get proper expected results, the ExpectedCoresToTestOn needs to match the number of cores on test machine.", 3 | "ExpectedCoresToTestOn_win": 48, 4 | "ExpectedCoresToTestOn_linux": 48, 5 | "op_workload": "GET,SET", 6 | "onlineMode": "--online", 7 | "batchsize": 1, 8 | "threads": "1", 9 | "op_percent": "90,10", 10 | "client": "GarnetClientSession", 11 | "expectedMedianValue_linux": 52, 12 | "expectedMedianValue_win": 110, 13 | "acceptableRangeMedian": 10, 14 | 15 | "expected99Value_linux": 70, 16 | "expected99Value_win": 145, 17 | "acceptableRange99": 10, 18 | 19 | "expected99_9Value_linux": 95, 20 | "expected99_9Value_win": 225, 21 | "acceptableRange99_9": 10, 22 | 23 | "expectedTPTValue_linux": 19, 24 | "expectedTPTValue_win": 10, 25 | "acceptableRangeTPT": 20 26 | } 27 | -------------------------------------------------------------------------------- /test/PerfRegressionTesting/ConfigFiles/CI_Config_Online_GetSet_MaxThr.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "Note: MAX is actually total number of cores / 2", 3 | "_comment2": "To get proper expected results, the ExpectedCoresToTestOn needs to match the number of cores on test machine.", 4 | "ExpectedCoresToTestOn_win": 48, 5 | "ExpectedCoresToTestOn_linux": 48, 6 | "op_workload": "GET,SET", 7 | "onlineMode": "--online", 8 | "batchsize": 1, 9 | "threads": "MAX", 10 | "op_percent": "90,10", 11 | "client": "GarnetClientSession", 12 | "expectedMedianValue_linux": 68, 13 | "expectedMedianValue_win": 230, 14 | "acceptableRangeMedian": 20, 15 | 16 | "expected99Value_linux": 94, 17 | "expected99Value_win": 285, 18 | "acceptableRange99": 10, 19 | 20 | "expected99_9Value_linux": 120, 21 | "expected99_9Value_win": 380, 22 | "acceptableRange99_9": 10, 23 | 24 | "expectedTPTValue_linux": 352, 25 | "expectedTPTValue_win": 105, 26 | "acceptableRangeTPT": 20 27 | } 28 | -------------------------------------------------------------------------------- /test/PerfRegressionTesting/ConfigFiles/CI_Config_Online_ZADDZREM_1Thr.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "To get proper expected results, the ExpectedCoresToTestOn needs to match the number of cores on test machine.", 3 | "ExpectedCoresToTestOn_win": 48, 4 | "ExpectedCoresToTestOn_linux": 48, 5 | "op_workload": "ZADD,ZREM", 6 | "onlineMode": "--online", 7 | "batchsize": 1, 8 | "threads": "1", 9 | "op_percent": "50,50", 10 | "client": "GarnetClientSession", 11 | "keyLength": 8, 12 | "sscardinality": 1024, 13 | "expectedMedianValue_linux": 55, 14 | "expectedMedianValue_win": 115, 15 | "acceptableRangeMedian": 10, 16 | 17 | "expected99Value_linux": 77, 18 | "expected99Value_win": 145, 19 | "acceptableRange99": 10, 20 | 21 | "expected99_9Value_linux": 102, 22 | "expected99_9Value_win": 210, 23 | "acceptableRange99_9": 10, 24 | 25 | "expectedTPTValue_linux": 18, 26 | "expectedTPTValue_win": 9, 27 | "acceptableRangeTPT": 20 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /test/PerfRegressionTesting/ConfigFiles/CI_Config_Online_ZADDZREM_MaxThr.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "Note: MAX is actually total number of cores / 2", 3 | "_comment2": "To get proper expected results, the ExpectedCoresToTestOn needs to match the number of cores on test machine.", 4 | "ExpectedCoresToTestOn_win": 48, 5 | "ExpectedCoresToTestOn_linux": 48, 6 | "op_workload": "ZADD,ZREM", 7 | "onlineMode": "--online", 8 | "batchsize": 1, 9 | "threads": "MAX", 10 | "op_percent": "50,50", 11 | "client": "GarnetClientSession", 12 | "keyLength": 8, 13 | "sscardinality": 1024, 14 | "expectedMedianValue_linux": 66, 15 | "expectedMedianValue_win": 225, 16 | "acceptableRangeMedian": 15, 17 | 18 | "expected99Value_linux": 97, 19 | "expected99Value_win": 300, 20 | "acceptableRange99": 10, 21 | 22 | "expected99_9Value_linux": 130, 23 | "expected99_9Value_win": 375, 24 | "acceptableRange99_9": 10, 25 | 26 | "expectedTPTValue_linux": 360, 27 | "expectedTPTValue_win": 105, 28 | "acceptableRangeTPT": 20 29 | } 30 | -------------------------------------------------------------------------------- /test/testcerts/garnet-ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBvTCCAWMCFFgb14wFKV8baUGozmPAgMS1FXLvMAoGCCqGSM49BAMCMGExCzAJ 3 | BgNVBAYTAlVTMRMwEQYDVQQIDApTb21lLVN0YXRlMQswCQYDVQQKDAJNUzEPMA0G 4 | A1UEAwwGR2FybmV0MR8wHQYJKoZIhvcNAQkBFhBlbWFpbEBnYXJuZXQuY29tMB4X 5 | DTIzMTAwNTIzMDIzMVoXDTI2MTAwNDIzMDIzMVowYTELMAkGA1UEBhMCVVMxEzAR 6 | BgNVBAgMClNvbWUtU3RhdGUxCzAJBgNVBAoMAk1TMQ8wDQYDVQQDDAZHYXJuZXQx 7 | HzAdBgkqhkiG9w0BCQEWEGVtYWlsQGdhcm5ldC5jb20wWTATBgcqhkjOPQIBBggq 8 | hkjOPQMBBwNCAASn0/D2LA2Hd/lYl1FzFmBFqP3dfaMQNHEPKaXzKqC4gn2Wk/gU 9 | HsFqs75TrRLZ0/HgjCdJjnnT0lncI1I8i1SXMAoGCCqGSM49BAMCA0gAMEUCIF80 10 | 6bGMHFOYQ8JZ3mAZa/YYTkJjPHV2/A+2rBXUG2hMAiEAsH9zhA8OrM1ivUluKCV9 11 | vCfFx1Ds99rjFGG5Q0CBCI4= 12 | -----END CERTIFICATE----- 13 | -------------------------------------------------------------------------------- /test/testcerts/garnet-cert.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBxTCCAWsCFCWgngWAWpmiGEM3Kvw8U1pCunIKMAoGCCqGSM49BAMCMGExCzAJ 3 | BgNVBAYTAlVTMRMwEQYDVQQIDApTb21lLVN0YXRlMQswCQYDVQQKDAJNUzEPMA0G 4 | A1UEAwwGR2FybmV0MR8wHQYJKoZIhvcNAQkBFhBlbWFpbEBnYXJuZXQuY29tMB4X 5 | DTIzMTAwNTIzMDgwMVoXDTI2MTAwNDIzMDgwMVowaTELMAkGA1UEBhMCQVUxEzAR 6 | BgNVBAgMClNvbWUtU3RhdGUxCzAJBgNVBAoMAk1TMRMwEQYDVQQDDApHYXJuZXRU 7 | ZXN0MSMwIQYJKoZIhvcNAQkBFhRlbWFpbEBnYXJuZXR0ZXN0LmNvbTBZMBMGByqG 8 | SM49AgEGCCqGSM49AwEHA0IABOmdueERFVRHQ7JahNn/c7x2I9DguY3E6ECc8X6t 9 | JLNfiPaEZDUXh1uhaxQ/VFjkxnGOzSudlRoCKY4++UCfzK0wCgYIKoZIzj0EAwID 10 | SAAwRQIhAJ+u4TpAJhOuectsZZLtVXNRDtt+ay/5eP8i3WypZSM4AiBdwDGNIqql 11 | SBPwuioAvuL6zeoJ7LVnPmWtGsICf0s/Bw== 12 | -----END CERTIFICATE----- 13 | -------------------------------------------------------------------------------- /test/testcerts/garnet.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BggqhkjOPQMBBw== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MHcCAQEEID+aO836a4e9jO4SwyvVhU3QOR7lV+HAK+GtMDB51Dd/oAoGCCqGSM49 6 | AwEHoUQDQgAE6Z254REVVEdDslqE2f9zvHYj0OC5jcToQJzxfq0ks1+I9oRkNReH 7 | W6FrFD9UWOTGcY7NK52VGgIpjj75QJ/MrQ== 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /test/testcerts/testcert.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/test/testcerts/testcert.pfx -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /website/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ``` 8 | $ yarn 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ``` 14 | $ yarn start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ### Build 20 | 21 | ``` 22 | $ yarn build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ### Deployment 28 | 29 | Using SSH: 30 | 31 | ``` 32 | $ USE_SSH=true yarn deploy 33 | ``` 34 | 35 | Not using SSH: 36 | 37 | ``` 38 | $ GIT_USER= yarn deploy 39 | ``` 40 | 41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 42 | -------------------------------------------------------------------------------- /website/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /website/blog/2024-03-18-oss-announcement.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: msr-blog-announcement 3 | title: OSS Announcement 4 | authors: badrishc 5 | tags: [garnet, oss, announcement, msr] 6 | --- 7 | 8 | The Microsoft Research Blog has just published a new post introducing Garnet. Check it out [here](https://www.microsoft.com/en-us/research/blog/introducing-garnet-an-open-source-next-generation-faster-cache-store-for-accelerating-applications-and-services/). Have fun! 9 | -------------------------------------------------------------------------------- /website/blog/authors.yml: -------------------------------------------------------------------------------- 1 | badrishc: 2 | name: Badrish Chandramouli 3 | title: Partner Research Manager, Microsoft Research 4 | url: https://badrish.net 5 | image_url: https://badrish.net/assets/icons/badrish4.jpg 6 | 7 | hkhalid: 8 | name: Hamdaan Khalid 9 | title: Software Engineer, Azure Resource Graph 10 | url: https://hamdaan-rails-personal.herokuapp.com/about 11 | image_url: https://hamdaan-rails-personal.herokuapp.com/assets/me-f1fa367c094eedf1c151b0b0dfbc057c2b047dec4e10f3974167ec3f803d81f0.jpg -------------------------------------------------------------------------------- /website/docs/commands/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: overview 3 | sidebar_label: Overview 4 | title: Overview 5 | slug: overview 6 | --- 7 | 8 | # Overview of API Coverage 9 | 10 | Garnet supports a large (and growing) subset of the Redis REST API surface. The list is growing over time, and we would love to hear from you on what APIs you want the most! Also, we want to see you contribute new APIs as well. 11 | 12 | Garnet also supports a powerful custom operator framework whereby you can register custom C# data structures and read-modify-write operations on the server and access them via an extension of RESP. 13 | 14 | View the full list of commands and their support status in the [API Compatibility](api-compatibility.md) section. 15 | Click any of the links to learn more about the commands supported in the different categories. -------------------------------------------------------------------------------- /website/docs/dev/cluster.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: cluster 3 | sidebar_label: Cluster Mode 4 | title: Cluster Mode 5 | --- 6 | 7 | # Cluster Mode 8 | 9 | 10 | 11 | 12 | Throughput: 92,263.32 ops/sec 13 | Throughput: 244,445.78 ops/sec 14 | Throughput: 451,460.24 ops/sec 15 | Throughput: 502,109.25 ops/sec 16 | Throughput: 624,804.31 ops/sec 17 | Throughput: 709,774.95 ops/sec 18 | Throughput: 714,856.42 ops/sec 19 | -------------------------------------------------------------------------------- /website/docs/dev/contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: contributing 3 | sidebar_label: Contributing 4 | title: Contributing 5 | --- 6 | 7 | 8 | # More Information 9 | 10 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 11 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 12 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 13 | 14 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 15 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 16 | provided by the bot. You will only need to do this once across all repos using our CLA. 17 | 18 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 19 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 20 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 21 | 22 | -------------------------------------------------------------------------------- /website/docs/dev/tsavorite/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: intro 3 | sidebar_label: Introduction 4 | title: Introduction 5 | --- 6 | 7 | # Introduction to Tsavorite 8 | 9 | Garnet’s storage layer, called Tsavorite, was forked from our prior open-source project [FASTER](https://github.com/microsoft/FASTER). Tsavorite includes strong database features such as thread scalability, 10 | tiered storage support (memory, SSD, and cloud storage), fast non-blocking checkpointing, recovery, operation logging for durability, multi-key [locking](locking.md) and transaction support, and better 11 | memory management and [space reuse](reviv.md). 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /website/docs/welcome/about-us.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: about-us 3 | sidebar_label: About Us 4 | title: About Us 5 | --- 6 | 7 | # About Us 8 | 9 | Check out our blog post [here](/blog/brief-history) for more details on our history and evolution. 10 | 11 | ## Contributors 12 | 13 | Core Team: 14 | * Badrish Chandramouli, Vasileios Zois, Ted Hart, Tal Zaccai, Darren Gehring. 15 | * Email: garnetteam AT microsoft.com 16 | 17 | Project Partners: 18 | * Hamdaan Khalid, Alan Yang, Pradeep Yadav, Alex Dubinkov, Venugopal Latchupatulla. 19 | * Knut Magne Risvik, Sarah Williamson, Narayanan Subramanian, Saurabh Singh, Padmanabh Gupta. 20 | * Kevin Montrose, Matt Tremblay, Kevin Bowersox, Marc Gravell. 21 | * Open-source contributors, including @PaulusParssinen, @Vijay-Nirmal, @babykart, @nightroman, and @prvyk. 22 | * Prior contributors: Lukas Maas, Yoganand Rajasekaran. 23 | -------------------------------------------------------------------------------- /website/src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /website/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS files with the .module.css suffix will be treated as CSS modules 3 | * and scoped locally. 4 | */ 5 | 6 | .heroBanner { 7 | padding: 4rem 0; 8 | text-align: center; 9 | position: relative; 10 | overflow: hidden; 11 | } 12 | 13 | @media screen and (max-width: 996px) { 14 | .heroBanner { 15 | padding: 2rem; 16 | } 17 | } 18 | 19 | .buttons { 20 | display: flex; 21 | align-items: center; 22 | justify-content: center; 23 | } 24 | -------------------------------------------------------------------------------- /website/src/pages/markdown-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Markdown page example 3 | --- 4 | 5 | # Markdown page example 6 | 7 | You don't need React to write simple standalone pages. 8 | -------------------------------------------------------------------------------- /website/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/.nojekyll -------------------------------------------------------------------------------- /website/static/img/benchmark/lat-get-set-batchsize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/benchmark/lat-get-set-batchsize.png -------------------------------------------------------------------------------- /website/static/img/benchmark/lat-get-set-threads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/benchmark/lat-get-set-threads.png -------------------------------------------------------------------------------- /website/static/img/benchmark/tpt-bitop-batchsize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/benchmark/tpt-bitop-batchsize.png -------------------------------------------------------------------------------- /website/static/img/benchmark/tpt-bitop-threads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/benchmark/tpt-bitop-threads.png -------------------------------------------------------------------------------- /website/static/img/benchmark/tpt-get-batchsize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/benchmark/tpt-get-batchsize.png -------------------------------------------------------------------------------- /website/static/img/benchmark/tpt-get-threads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/benchmark/tpt-get-threads.png -------------------------------------------------------------------------------- /website/static/img/benchmark/tpt-getbit-setbit-batchsize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/benchmark/tpt-getbit-setbit-batchsize.png -------------------------------------------------------------------------------- /website/static/img/benchmark/tpt-getbit-setbit-threads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/benchmark/tpt-getbit-setbit-threads.png -------------------------------------------------------------------------------- /website/static/img/benchmark/tpt-pfadd-batchsize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/benchmark/tpt-pfadd-batchsize.png -------------------------------------------------------------------------------- /website/static/img/benchmark/tpt-pfadd-few-keys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/benchmark/tpt-pfadd-few-keys.png -------------------------------------------------------------------------------- /website/static/img/benchmark/tpt-pfadd-many-keys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/benchmark/tpt-pfadd-many-keys.png -------------------------------------------------------------------------------- /website/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/favicon.ico -------------------------------------------------------------------------------- /website/static/img/garnet-bg2-2800x720.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/garnet-bg2-2800x720.jpg -------------------------------------------------------------------------------- /website/static/img/garnet-bg2-2800x720.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/garnet-bg2-2800x720.png -------------------------------------------------------------------------------- /website/static/img/garnet-logo-diamond.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/garnet-logo-diamond.png -------------------------------------------------------------------------------- /website/static/img/garnet-logo-inset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/garnet-logo-inset.png -------------------------------------------------------------------------------- /website/static/img/garnet-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/garnet-logo.png -------------------------------------------------------------------------------- /website/static/img/logo_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/garnet/529942b0a0af41cc2183a3026a5225b5276ae14d/website/static/img/logo_128.png --------------------------------------------------------------------------------