/// <summary> /// Computes the hash-slot that would be used by the given key /// </summary> public unsafe int HashSlot(RedisKey key) { //HASH_SLOT = CRC16(key) mod 16384 if (key.IsNull) return NoSlot; unchecked { var blob = (byte[])key; fixed (byte* ptr = blob) { int offset = 0, count = blob.Length, start, end; if ((start = IndexOf(ptr, (byte)'{', 0, count - 1)) >= 0 && (end = IndexOf(ptr, (byte)'}', start + 1, count)) >= 0 && --end != start) { offset = start + 1; count = end - start; // note we already subtracted one via --end } uint crc = 0; for (int i = 0; i < count; i++) crc = ((crc << 8) ^ crc16tab[((crc >> 8) ^ ptr[offset++]) & 0x00FF]) & 0x0000FFFF; return (int)(crc % RedisClusterSlotCount); } } }
public object Eval(string script, string[] keyArgs, object[] valueArgs) { RedisKey[] redisKeyArgs = new RedisKey[keyArgs.Length]; RedisValue[] redisValueArgs = new RedisValue[valueArgs.Length]; int i = 0; foreach (string key in keyArgs) { redisKeyArgs[i] = key; i++; } i = 0; foreach (object val in valueArgs) { if (val.GetType() == typeof(byte[])) { // User data is always in bytes redisValueArgs[i] = (byte[])val; } else { // Internal data like session timeout and indexes are stored as strings redisValueArgs[i] = val.ToString(); } i++; } return RetryLogic(() => _connection.ScriptEvaluate(script, redisKeyArgs, redisValueArgs)); }
/// <summary> /// Creates a new <see cref="IDatabase"/> instance that provides an isolated key space /// of the specified underyling database instance. /// </summary> /// <param name="database"> /// The underlying database instance that the returned instance shall use. /// </param> /// <param name="keyPrefix"> /// The prefix that defines a key space isolation for the returned database instance. /// </param> /// <returns> /// A new <see cref="IDatabase"/> instance that invokes the specified underlying /// <paramref name="database"/> but prepends the specified <paramref name="keyPrefix"/> /// to all key paramters and thus forms a logical key space isolation. /// </returns> /// <remarks> /// <para> /// The following methods are not supported in a key space isolated database and /// will throw an <see cref="NotSupportedException"/> when invoked: /// </para> /// <list type="bullet"> /// <item><see cref="IDatabaseAsync.KeyRandomAsync(CommandFlags)"/></item> /// <item><see cref="IDatabase.KeyRandom(CommandFlags)"/></item> /// </list> /// <para> /// Please notice that keys passed to a script are prefixed (as normal) but care must /// be taken when a script returns the name of a key as that will (currently) not be /// "unprefixed". /// </para> /// </remarks> public static IDatabase WithKeyPrefix(this IDatabase database, RedisKey keyPrefix) { if (database == null) { throw new ArgumentNullException("database"); } if (keyPrefix.IsNull) { throw new ArgumentNullException("keyPrefix"); } if (keyPrefix.IsEmpty) { return database; // fine - you can keep using the original, then } if(database is DatabaseWrapper) { // combine the key in advance to minimize indirection var wrapper = (DatabaseWrapper)database; keyPrefix = wrapper.ToInner(keyPrefix); database = wrapper.Inner; } return new DatabaseWrapper(database, keyPrefix.AsPrefix()); }
public RedisSchtickWrapper(Func<IDatabase> getRedisDb, string machineName = null, string keyPrefix = "schyntax") { _getRedisDb = getRedisDb; _keyPrefix = keyPrefix; _lastKey = keyPrefix + "_last"; _machineName = machineName ?? Environment.MachineName; }
public void CanHandleCommands() { RedisServiceFactory.Register<IRedisCommandHandler, TestCommandHandler>(); TestCommandHandler cmdHandler = (TestCommandHandler)RedisServiceFactory.CommandHandlers.First(); bool onExecutingDone = false; bool onExecutedDone = false; RedisKey[] testKeys = new RedisKey[] { "test" }; RedisValue[] testValues = new RedisValue[] { "test value" }; object testResult = (RedisValue)"hello world"; cmdHandler.onExecuting = (command, involvedKeys, involvedValues) => { Assert.AreEqual(RedisCommand.SET, command); Assert.AreEqual(1, testKeys.Intersect(involvedKeys).Count()); Assert.AreEqual(1, testValues.Intersect(involvedValues).Count()); onExecutingDone = true; }; cmdHandler.onExecuted = (RedisCommand command, ref object result, RedisKey[] involvedKeys) => { Assert.AreEqual(RedisCommand.HMSET, command); Assert.AreEqual(1, testKeys.Intersect(involvedKeys).Count()); Assert.AreEqual(testResult, result); onExecutedDone = true; }; RedisServiceFactory.CommandHandlers.ExecuteBeforeHandlers(RedisCommand.SET, new RedisKey[] { "test" }, new RedisValue[] { "test value" }); RedisServiceFactory.CommandHandlers.ExecuteAfterHandlers(RedisCommand.HMSET, new RedisKey[] { "test" }, ref testResult); Assert.IsTrue(onExecutingDone); Assert.IsTrue(onExecutedDone); }
public RedisLock([NotNull]IDatabase redis, [NotNull]RedisKey key, [NotNull]RedisValue owner, [NotNull]TimeSpan timeOut) { _redis = redis; _key = key; _owner = owner; //The comparison below uses timeOut as a max timeSpan in waiting Lock int i = 0; DateTime lockExpirationTime = DateTime.UtcNow +timeOut; while (DateTime.UtcNow < lockExpirationTime) { if (_redis.LockTake(key, owner, timeOut)) return; //assumes that a second call made by the same owner means an extension request var lockOwner = _redis.LockQuery(key); if (lockOwner.Equals(owner)) { //extends the lock only for the remaining time var ttl = redis.KeyTimeToLive(key) ?? TimeSpan.Zero; var extensionTTL = lockExpirationTime - DateTime.UtcNow; if (extensionTTL > ttl) _redis.LockExtend(key, owner, extensionTTL - ttl); isRoot = false; return; } SleepBackOffMultiplier(i); i++; } throw new TimeoutException(string.Format("Lock on {0} with owner identifier {1} Exceeded timeout of {2}", key, owner.ToString(), timeOut)); }
/// <summary> /// Removes the specified fields from the hash stored at key. Non-existing fields are ignored. Non-existing keys /// are treated as empty hashes and this command returns 0. /// </summary> /// <param name="key"> /// The key. /// </param> /// <param name="field"> /// The field. /// </param> /// <remarks> /// http://redis.io/commands/hdel /// </remarks> /// <returns> /// The number of fields that were removed. /// </returns> public static bool Delete(RedisKey key, RedisValue field) { bool result = SharedCache.Instance.GetWriteConnection(key) .GetDatabase(SharedCache.Instance.Db) .HashDelete(key, field); return result; }
/// <summary> /// Removes the specified key. A key is ignored if it does not exist. /// </summary> /// <param name="key"> /// The key. /// </param> /// <returns> /// True if the key was removed. /// </returns> /// <remarks> /// http://redis.io/commands/del /// </remarks> public static bool Delete(RedisKey key) { bool result = SharedCache.Instance.GetWriteConnection(key) .GetDatabase(SharedCache.Instance.Db) .KeyDelete(key); return result; }
/// <summary> /// Removes the specified key. A key is ignored if it does not exist. /// </summary> /// <param name="key"> /// The key. /// </param> /// <returns> /// True if the key was removed. /// </returns> /// <remarks> /// http://redis.io/commands/del /// </remarks> public static Task<bool> DeleteAsync(RedisKey key) { Task<bool> result = SharedCache.Instance.GetWriteConnection(key) .GetDatabase(SharedCache.Instance.Db) .KeyDeleteAsync(key); return result; }
/// <summary> /// If key already exists and is a string, this command appends the value at the end of the string. If key does /// not exist it is created and set as an empty string, so APPEND will be similar to SET in this special case. /// </summary> /// <param name="key"> /// The key. /// </param> /// <param name="value"> /// The value. /// </param> /// <returns> /// the length of the string after the append operation. /// </returns> /// <remarks> /// http://redis.io/commands/append /// </remarks> public static Task<long> AppendAsync(RedisKey key, RedisValue value) { Task<long> result = SharedCache.Instance.GetWriteConnection(key) .GetDatabase(SharedCache.Instance.Db) .StringAppendAsync(key, value); return result; }
public bool Lock(RedisKey resource, TimeSpan ttl, out Lock lockObject) { var task = LockAsync(resource, ttl); task.Wait(); var result = task.Result; lockObject = result.Item2; return result.Item1; }
/// <summary> /// Returns the value associated with field in the hash stored at key. /// </summary> /// <returns> /// the value associated with field, or nil when field is not present in the hash or key does not exist. /// </returns> /// <remarks>http://redis.io/commands/hget</remarks> public static Task<RedisValue> GetString(RedisKey key, RedisValue field) { Task<RedisValue> result = SharedCache.Instance.GetReadConnection(key) .GetDatabase(SharedCache.Instance.Db) .HashGetAsync(key, field); return result; }
public void CommandStart(RedisSettings usedSettings, string command, RedisKey key) { if (TimerStrategy == null) return; this.start = TimerStrategy.Start(); this.usedSettings = usedSettings; this.command = command; this.key = key; }
public async Task<IEnumerable<DeviceToken>> GetUserDeviceTokensAsync(IEnumerable<string> userIds) { var keys = new RedisKey[userIds.Count()]; for (int i = 0; i < userIds.Count(); i++) { keys[i] = userIds.ElementAt(i); } var dtJsons = await pubsubRedis.GetDatabase().StringGetAsync(keys.ToArray(), CommandFlags.PreferSlave); return from item in dtJsons select JsonToDeviceToken(item); }
internal static void SetUniqueVal(RedisKey hashKey, RedisValue hashField, RedisValue value, RedisKey indexKey) { var result = Store.Database.ScriptEvaluate(Script, new {hashKey, hashField, finalVal = value, indexKey}); if ((bool)result) { return; } throw new UniqueConstraintViolatedException(); }
/// <summary> /// Executes all Redis command handlers, running behaviors that must run before some given command is about to get executed. /// </summary> /// <param name="handlers">The sequence of Redis command handlers</param> /// <param name="command">The Redis command</param> /// <param name="involvedKeys">An array of involved Redis keys in the command</param> /// <param name="involvedValues">An array of involved Redis values in the command</param> /// <returns>True if handlers could be executed. Otherwise, false.</returns> public static bool ExecuteBeforeHandlers(this IEnumerable<IRedisCommandHandler> handlers, RedisCommand command, RedisKey[] involvedKeys = null, RedisValue[] involvedValues = null) { bool canExecute = CanExecuteHandlers(handlers, command); if (canExecute) foreach (IRedisCommandHandler handler in handlers) handler.OnExecuting(command, involvedKeys, involvedValues); return canExecute; }
/// <summary> /// Executes all Redis command handlers, running behaviors that must run after some given command has been already executed. /// </summary> /// <typeparam name="TResult">The type of Redis command result</typeparam> /// <param name="handlers">The sequence of Redis command handlers</param> /// <param name="command">The Redis command</param> /// <param name="involvedKeys">An array of involved Redis keys in the command</param> /// <param name="result">The result of the Redis command execution</param> /// <returns>True if handlers could be executed. Otherwise, false.</returns> public static bool ExecuteAfterHandlers(this IEnumerable<IRedisCommandHandler> handlers, RedisCommand command, RedisKey[] involvedKeys, ref object result) { bool canExecute = CanExecuteHandlers(handlers, command); if (canExecute) foreach (IRedisCommandHandler handler in handlers) handler.OnExecuted(command, ref result, involvedKeys); return canExecute; }
public RedisTimelineMessage(RedisSettings usedSettings, string command, RedisKey key, object sentObject, long sentSize, object receivedObject, long receivedSize, bool isError) { UsedSettings = usedSettings; Command = command; Key = key; SentObject = sentObject; SentSize = sentSize; ReceivedObject = receivedObject; ReceivedSize = receivedSize; IsError = isError; }
/// <summary> /// Removes the specified fields from the hash stored at key. Non-existing fields are ignored. Non-existing keys /// are treated as empty hashes and this command returns 0. /// </summary> /// <remarks>http://redis.io/commands/hdel</remarks> /// <returns>The number of fields that were removed.</returns> public static Task<long> Remove(RedisKey key, RedisValue[] fields) { var connections = SharedCache.Instance.GetWriteConnections(key); Task<long> result = null; foreach (var connection in connections) { var task = connection.GetDatabase(SharedCache.Instance.Db) .HashDeleteAsync(key, fields); if (null == result) result = task; } return result; }
/// <summary> /// Removes the specified keys. A key is ignored if it does not exist. /// </summary> /// <param name="keys"> /// The keys. /// </param> /// <returns> /// The number of keys that were removed. /// </returns> /// <remarks> /// http://redis.io/commands/del /// </remarks> public static long Delete(RedisKey[] keys) { var dictionary = SharedCache.Instance.GetWriteConnection(keys); long removed = 0; foreach (KeyValuePair<ConnectionMultiplexer, RedisKey[]> kvp in dictionary) { removed += kvp.Key .GetDatabase(SharedCache.Instance.Db) .KeyDelete(kvp.Value); } return removed; }
public Task ScriptEvaluateAsync(int database, string script, string key, byte[] messageArguments) { if (_connection == null) { throw new InvalidOperationException(Resources.Error_RedisConnectionNotStarted); } var keys = new RedisKey[] { key }; var arguments = new RedisValue[] { messageArguments }; return _connection.GetDatabase(database).ScriptEvaluateAsync(script, keys, arguments); }
/// <summary> /// Returns if field is an existing field in the hash stored at key. /// </summary> /// <returns> /// 1 if the hash contains field. 0 if the hash does not contain field, or key does not exist. /// </returns> /// <remarks>http://redis.io/commands/hexists</remarks> public static Task<bool> Exists(RedisKey key, RedisValue field) { var connections = SharedCache.Instance.GetWriteConnections(key); Task<bool> result = null; foreach (var connection in connections) { var task = connection.GetDatabase(SharedCache.Instance.Db) .HashExistsAsync(key, field); if (null == result) result = task; } return result; }
public static RedisLock AcquireLock(this IDatabase redis, RedisKey key, RedisValue value, TimeSpan timeout) { DateTime enterTime = DateTime.UtcNow; while (DateTime.UtcNow.Subtract(enterTime)<timeout) { //TODO: Should update the timeout on lock if (redis.LockTake(key, value, timeout)) { return new RedisLock(redis, key, value); } } throw new Exception(String.Format("Unable to take the lock key={0} value={1} in {2}, key already exists ?", key, value, timeout)); }
internal static Task SetUniqueValAsync(RedisKey hashKey, RedisValue hashField, RedisValue value, RedisKey indexKey) { return Store.Database .ScriptEvaluateAsync(Script, new {hashKey, hashField, finalVal = value, indexKey}) .ContinueWith(r => { if ((bool) r.Result) { return; } throw new UniqueConstraintViolatedException(); }); }
public bool Lock(RedisKey resource, TimeSpan ttl, out Lock lockObject) { var val = CreateUniqueLockId(); Lock innerLock = null; bool successfull = retry(DefaultRetryCount, DefaultRetryDelay, () => { try { int n = 0; var startTime = DateTime.Now; // Use keys for_each_redis_registered( redis => { if (LockInstance(redis, resource, val, ttl)) n += 1; } ); /* * Add 2 milliseconds to the drift to account for Redis expires * precision, which is 1 milliescond, plus 1 millisecond min drift * for small TTLs. */ var drift = Convert.ToInt32((ttl.TotalMilliseconds * ClockDriveFactor) + 2); var validity_time = ttl - (DateTime.Now - startTime) - new TimeSpan(0, 0, 0, 0, drift); if (n >= Quorum && validity_time.TotalMilliseconds > 0) { innerLock = new Lock(resource, val, validity_time); return true; } else { for_each_redis_registered( redis => { UnlockInstance(redis, resource, val); } ); return false; } } catch (Exception) { return false; } }); lockObject = innerLock; return successfull; }
public void NoErrorWhenNoHandlerIsConfigured() { RedisKey[] testKeys = new RedisKey[] { "test" }; RedisValue[] testValues = new RedisValue[] { "test value" }; object testResult = (RedisValue)"hello world"; Assert.DoesNotThrow ( () => { Assert.IsFalse(RedisServiceFactory.CommandHandlers.ExecuteBeforeHandlers(RedisCommand.SET, new RedisKey[] { "test" }, new RedisValue[] { "test value" })); Assert.IsFalse(RedisServiceFactory.CommandHandlers.ExecuteAfterHandlers(RedisCommand.HMSET, new RedisKey[] { "test" }, ref testResult)); } ); }
public RedisSettings Select(RedisSettings[] settings, RedisKey key) { if (settings.Length == 0) throw new ArgumentException("settings length is 0"); if (settings.Length == 1) return settings[0]; using (var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider()) { var hashBytes = md5.ComputeHash((byte[])key); var preSeed = BitConverter.ToInt32(hashBytes, 0); if (preSeed == int.MinValue) preSeed++; // int.MinValue can't do Abs var seed = System.Math.Abs(preSeed); var index = seed % settings.Length; return settings[index]; } }
public async Task<Tuple<bool, Lock>> LockAsync(RedisKey resource, TimeSpan ttl) { var val = CreateUniqueLockId(); Lock lockObject = null; var successfull = await Retry(DefaultRetryCount, _defaultRetryDelay, async () => { try { var n = 0; var startTime = DateTime.Now; // Use keys await for_each_redis_registered( async connection => { if (await LockInstance(connection, resource, val, ttl)) n += 1; } ); /* * Add 2 milliseconds to the drift to account for Redis expires * precision, which is 1 milliescond, plus 1 millisecond min drift * for small TTLs. */ var drift = Convert.ToInt32((ttl.TotalMilliseconds*ClockDriveFactor) + 2); var validityTime = ttl - (DateTime.Now - startTime) - new TimeSpan(0, 0, 0, 0, drift); if (n >= Quorum && validityTime.TotalMilliseconds > 0) { lockObject = new Lock(resource, val, validityTime); return true; } await for_each_redis_registered(connection => UnlockInstance(connection, resource, val)); return false; } catch (Exception) { return false; } }); return Tuple.Create(successfull, lockObject); }
private static void TestConcurrent(IDatabase db, RedisKey key, int SyncLoop, int Threads) { long value; db.KeyDelete(key, CommandFlags.FireAndForget); var time = RunConcurrent(delegate { for (int i = 0; i < SyncLoop; i++) { db.StringIncrement(key); } }, Threads, timeout: 45000); value = (long)db.StringGet(key); Assert.AreEqual(SyncLoop * Threads, value); Console.WriteLine("Sync: {0} INCR using {1} threads, {2:###,##0}ms, {3} ops/s; final value: {4}", SyncLoop * Threads, Threads, (long)time.TotalMilliseconds, (long)((SyncLoop * Threads) / time.TotalSeconds), value); }
/// <summary> /// 初始化数据库环境、实例化子类中,所有Set属性 /// </summary> public void Initializer() { if (IsInitializer) { return; } _client = new RedisClient(_redisConnection); IsInitializer = true; Connection = new RedisConnection(_client); Hash = new RedisHash(_client); Key = new RedisKey(_client); List = new RedisList(_client); PubSub = new RedisPubSub(_client); Script = new RedisScript(_client); Server = new RedisServer(_client); Set = new RedisSet(_client); SortedSet = new RedisSortedSet(_client); String = new RedisString(_client); Transaction = new RedisTransaction(_client); Bit = new RedisBit(_client); Expire = new RedisExpire(_client); Sort = new RedisSort(_client); Number = new RedisNumber(_client); }
public TimeSpan?KeyTimeToLive(RedisKey key, CommandFlags flags = CommandFlags.None) { return(Inner.KeyTimeToLive(ToInner(key), flags)); }
public void ListSetByIndex(RedisKey key, long index, RedisValue value, CommandFlags flags = CommandFlags.None) { Inner.ListSetByIndex(ToInner(key), index, value, flags); }
public long ListInsertBefore(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None) { return(Inner.ListInsertBefore(ToInner(key), pivot, value, flags)); }
public long ListRemove(RedisKey key, RedisValue value, long count = 0, CommandFlags flags = CommandFlags.None) { return(Inner.ListRemove(ToInner(key), value, count, flags)); }
public RedisValue ListRightPop(RedisKey key, CommandFlags flags = CommandFlags.None) { return(Inner.ListRightPop(ToInner(key), flags)); }
public bool KeyRename(RedisKey key, RedisKey newKey, When when = When.Always, CommandFlags flags = CommandFlags.None) { return(Inner.KeyRename(ToInner(key), ToInner(newKey), when, flags)); }
public long ListRightPush(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) { return(Inner.ListRightPush(ToInner(key), values, flags)); }
public long SetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey[] keys, CommandFlags flags = CommandFlags.None) { return(Inner.SetCombineAndStore(operation, ToInner(destination), ToInner(keys), flags)); }
public long SetAdd(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None) { return(Inner.SetAdd(ToInner(key), values, flags)); }
public bool GeoAdd(RedisKey key, GeoEntry value, CommandFlags flags = CommandFlags.None) { return(Inner.GeoAdd(ToInner(key), value, flags)); }
public bool LockTake(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags = CommandFlags.None) { return(Inner.LockTake(ToInner(key), value, expiry, flags)); }
public bool LockRelease(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) { return(Inner.LockRelease(ToInner(key), value, flags)); }
public RedisType KeyType(RedisKey key, CommandFlags flags = CommandFlags.None) { return(Inner.KeyType(ToInner(key), flags)); }
public long GeoAdd(RedisKey key, GeoEntry[] values, CommandFlags flags = CommandFlags.None) { return(Inner.GeoAdd(ToInner(key), values, flags)); }
public void KeyRestore(RedisKey key, byte[] value, TimeSpan?expiry = null, CommandFlags flags = CommandFlags.None) { Inner.KeyRestore(ToInner(key), value, expiry, flags); }
public bool GeoAdd(RedisKey key, double longitude, double latitude, RedisValue member, CommandFlags flags = CommandFlags.None) { return(Inner.GeoAdd(ToInner(key), longitude, latitude, member, flags)); }
public RedisValue ListRightPopLeftPush(RedisKey source, RedisKey destination, CommandFlags flags = CommandFlags.None) { return(Inner.ListRightPopLeftPush(ToInner(source), ToInner(destination), flags)); }
public bool GeoRemove(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) { return(Inner.GeoRemove(ToInner(key), member, flags)); }
public bool KeyPersist(RedisKey key, CommandFlags flags = CommandFlags.None) { return(Inner.KeyPersist(ToInner(key), flags)); }
public bool SetContains(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) { return(Inner.SetContains(ToInner(key), value, flags)); }
public bool KeyMove(RedisKey key, int database, CommandFlags flags = CommandFlags.None) { return(Inner.KeyMove(ToInner(key), database, flags)); }
public long SetLength(RedisKey key, CommandFlags flags = CommandFlags.None) { return(Inner.SetLength(ToInner(key), flags)); }
public RedisValue[] ListRange(RedisKey key, long start = 0, long stop = -1, CommandFlags flags = CommandFlags.None) { return(Inner.ListRange(ToInner(key), start, stop, flags)); }
public RedisValue[] SetMembers(RedisKey key, CommandFlags flags = CommandFlags.None) { return(Inner.SetMembers(ToInner(key), flags)); }
public long SetCombineAndStore(SetOperation operation, RedisKey destination, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) { return(Inner.SetCombineAndStore(operation, ToInner(destination), ToInner(first), ToInner(second), flags)); }
public long ListRightPush(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None) { return(Inner.ListRightPush(ToInner(key), value, when, flags)); }
public RedisValue[] SetCombine(SetOperation operation, RedisKey first, RedisKey second, CommandFlags flags = CommandFlags.None) { return(Inner.SetCombine(operation, ToInner(first), ToInner(second), flags)); }
public RedisValue ListGetByIndex(RedisKey key, long index, CommandFlags flags = CommandFlags.None) { return(Inner.ListGetByIndex(ToInner(key), index, flags)); }
public void ListTrim(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None) { Inner.ListTrim(ToInner(key), start, stop, flags); }
public RedisValue LockQuery(RedisKey key, CommandFlags flags = CommandFlags.None) { return(Inner.LockQuery(ToInner(key), flags)); }