Exemple #1
0
        /// <summary>
        /// 获取键键值列表
        /// </summary>
        /// <param name="keys"></param>
        /// <returns></returns>
        public byte[][] GetByteKeys(params string[] keys)
        {
            if (keys.Length == 0)
            {
                throw new ArgumentException("keys");
            }

            using (var redisWriter = new RedisWriter(this, keys.Length + 1, "MGET"))
            {
                foreach (var key in keys)
                {
                    redisWriter.WriteArgument(key);
                }
                this.Connection.SendCommand(redisWriter);
            }
            return(this.Connection.ExpectMultiBulkReply());
        }
Exemple #2
0
        /// <summary>
        /// 设置当前要操作的DB
        /// </summary>
        /// <param name="dbIndex"></param>
        /// <returns></returns>
        public bool Select(int dbIndex)
        {
            //SET key value
            using (var redisWriter = new RedisWriter(this, 2, "SELECT"))
            {
                redisWriter.WriteArgument(dbIndex.ToString());
                this.Connection.SendCommand(redisWriter);
            }

            var result = this.Connection.ExpectSuccess();

            if (result)
            {
                this.db = dbIndex;
            }
            return(result);
        }
Exemple #3
0
        /// <summary>
        /// 在指定位置添加元素
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="before">元素前后,true before,false after</param>
        /// <param name="pivot">位置元素</param>
        /// <returns>添加后元素数</returns>
        public int LInsert(string key, string value, string pivot, bool before)
        {
            //Integer reply: the length of the list after the insert operation, or -1 when the value pivot was not found.
            //LINSERT mylist BEFORE "World" "There"
            //LINSERT key BEFORE|AFTER pivot value
            using (var w = new RedisWriter(this.client, 5, "LINSERT"))
            {
                w.WriteArgument(key);
                w.WriteArgument(before ? "BEFORE" : "AFTER");
                w.WriteArgument(pivot);
                w.WriteArgument(value);

                this.connection.SendCommand(w);
            }

            return(this.connection.ExpectInt());
        }
Exemple #4
0
        /// <summary>
        /// 自加一个数值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public int Increment(string key, int count)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }


            using (var redisWriter = new RedisWriter(this, 3, "INCRBY"))
            {
                redisWriter.WriteArgument(key);
                redisWriter.WriteArgument(count.ToString());
                this.Connection.SendCommand(redisWriter);
            }

            return(this.Connection.ExpectInt());
        }
Exemple #5
0
        /// <summary>
        /// 获取所有键列表
        /// </summary>
        public string[] GetKeys()
        {
            using (var redisWriter = new RedisWriter(this, 2, "KEYS"))
            {
                redisWriter.WriteArgument("*");
                this.Connection.SendCommand(redisWriter);
            }

            var keys = this.Connection.ExpectToStringArray();

            return(keys);

            //var r = this.Connection.ExpectBulkReply();
            //if (r.Length == 0)
            //    return new string[0];

            //return this.Encoding.GetString(r).Split(' ');
        }
Exemple #6
0
        /// <summary>
        /// 返回多个集合差集
        /// </summary>
        /// <param name="keys"></param>
        /// <returns></returns>
        public string[] SDIFF(params string[] keys)
        {
            if (keys.Length == 0)
            {
                throw new ArgumentNullException("keys");
            }

            using (var w = new RedisWriter(this.client, keys.Length + 1, "SDIFF"))
            {
                foreach (var key in keys)
                {
                    w.WriteArgument(key);
                }

                this.connection.SendCommand(w);
            }
            return(this.connection.ExpectToStringArray(this.connection.ExpectMultiBulkReply()));
        }
Exemple #7
0
        /// <summary>
        /// 删除一批键
        /// </summary>
        /// <param name="keys"></param>
        /// <returns>返回删除的个数</returns>
        public int Remove(params string[] keys)
        {
            if (keys == null)
            {
                throw new ArgumentNullException("args");
            }

            using (var redisWriter = new RedisWriter(this, keys.Length + 1, "DEL"))
            {
                foreach (var key in keys)
                {
                    redisWriter.WriteArgument(key);
                }
                this.Connection.SendCommand(redisWriter);
            }

            return(this.Connection.ExpectInt());
        }
Exemple #8
0
        //public void SendCommand(string cmd, params object[] args)
        //{
        //    var s = args.Length > 0 ? String.Format(cmd, args) : cmd;
        //    byte[] r = this.client.Encoding.GetBytes(s);
        //    try
        //    {
        //        this.socket.Send(r);
        //    }
        //    catch (SocketException)
        //    {
        //        // timeout;
        //        socket.Close();
        //        socket = null;

        //        throw new IOException("Unable to connect");
        //    }
        //}

        public void SendCommand(RedisWriter redisWriter)
        {
            var data  = redisWriter.GetBuffer();
            var count = (int)redisWriter.Length;

            try
            {
                this.socket.Send(data, 0, count, SocketFlags.None);
            }
            catch (SocketException)
            {
                // timeout;
                socket.Close();
                socket = null;

                throw new IOException("Unable to connect");
            }
        }
Exemple #9
0
        /// <summary>
        /// 设置一组数据(MSET)
        /// </summary>
        /// <param name="dict"></param>
        public bool Set(IDictionary <string, byte[]> dict)
        {
            if (dict == null)
            {
                throw new ArgumentNullException("dict");
            }

            //MSET key1 value1 key2 value2
            using (var w = new RedisWriter(this, dict.Count * 2 + 1, "MSET"))
            {
                foreach (var item in dict)
                {
                    w.WriteArgument(item.Key);
                    w.WriteArgument(item.Value);
                }
                this.Connection.SendCommand(w);
            }
            return(this.Connection.ExpectSuccess());
        }
Exemple #10
0
        /// <summary>
        /// 返回给定的分值范围元素列表
        /// </summary>
        /// <param name="key"></param>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <param name="offset">取出偏移量,需设置count有效</param>
        /// <param name="count">设置数量则offset有产效</param>
        /// <returns></returns>
        public SortedList <double, string> ZRANGEBYSCORE(string key, double min, double max, int offset, int count)
        {
            //ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
            var size = 5;

            if (count > 0)
            {
                size += 3;
            }

            using (var w = new RedisWriter(this.client, size, "ZRANGEBYSCORE"))
            {
                w.WriteArgument(key);
                w.WriteArgument(min.ToString());
                w.WriteArgument(max.ToString());
                w.WriteArgument("WITHSCORES");
                if (count > 0)
                {
                    w.WriteArgument("LIMIT");
                    w.WriteArgument(offset.ToString());
                    w.WriteArgument(count.ToString());
                }

                this.connection.SendCommand(w);
            }

            var b = this.connection.ExpectMultiBulkReply();

            if (b.Length < 2)
            {
                return(new SortedList <double, string>(0));
            }

            var r = new SortedList <double, string>(b.Length / 2);
            var d = 0d;

            for (int i = 0, l = b.Length; i < l; i += 2)
            {
                double.TryParse(this.client.Encoding.GetString(b[i + 1]), out d);
                r[d] = this.client.Encoding.GetString(b[i]);
            }
            return(r);
        }
Exemple #11
0
        /// <summary>
        /// 重命名一个键
        /// </summary>
        /// <param name="oldKeyname"></param>
        /// <param name="newKeyname"></param>
        /// <returns></returns>
        public bool Rename(string oldKeyname, string newKeyname)
        {
            if (oldKeyname == null)
            {
                throw new ArgumentNullException("oldKeyname");
            }
            if (newKeyname == null)
            {
                throw new ArgumentNullException("newKeyname");
            }

            using (var redisWriter = new RedisWriter(this, 3, "RENAME"))
            {
                redisWriter.WriteArgument(oldKeyname);
                redisWriter.WriteArgument(newKeyname);
                this.Connection.SendCommand(redisWriter);
            }
            return(this.Connection.ExpectSuccess());
        }
Exemple #12
0
        /// <summary>
        /// 获取元素的键项列表
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string[] HKEYS(string key)
        {
            //HKEYS myhash

            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            using (var w = new RedisWriter(this.client, 2, "HKEYS"))
            {
                w.WriteArgument(key);

                this.connection.SendCommand(w);
            }

            //Array reply
            return(this.connection.ExpectToStringArray(this.connection.ExpectMultiBulkReply()));
        }
Exemple #13
0
        /// <summary>
        /// 返回有序集 key 中, score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员。有序集成员按 score 值递减(从大到小)的次序排列。
        /// 具有相同 score 值的成员按字典序的逆序(reverse lexicographical order )排列。
        /// 除了成员按 score 值递减的次序排列这一点外, ZREVRANGEBYSCORE 命令的其他方面和 ZRANGEBYSCORE 命令一样
        /// </summary>
        /// <param name="key"></param>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <param name="withscores">是否返回分值</param>
        /// <param name="count">设置数量则offset有产效</param>
        /// <param name="offset">取出偏移量,需设置count有效</param>
        /// <returns></returns>
        private byte[][] ZREVRANGEBYSCOREByte(string key, double min, double max, bool withscores, int offset, int count)
        {
            //ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]

            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            //Array reply: list of elements in the specified score range (optionally with their scores).

            var size = 4;

            if (withscores)
            {
                size++;
            }
            if (count > 0)
            {
                size += 3;
            }

            using (var w = new RedisWriter(this.client, size, "ZREVRANGEBYSCORE"))
            {
                w.WriteArgument(key);
                w.WriteArgument(max.ToString());
                w.WriteArgument(min.ToString());
                if (withscores)
                {
                    w.WriteArgument("WITHSCORES");
                }
                if (count > 0)
                {
                    w.WriteArgument("LIMIT");
                    w.WriteArgument(offset.ToString());
                    w.WriteArgument(count.ToString());
                }

                this.connection.SendCommand(w);
            }

            return(this.connection.ExpectMultiBulkReply());
        }
Exemple #14
0
        /// <summary>
        /// 获取哈希表元素个数
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public int HLEN(string key)
        {
            //HLEN key

            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            using (var w = new RedisWriter(this.client, 2, "HLEN"))
            {
                w.WriteArgument(key);

                this.connection.SendCommand(w);
            }

            //Integer reply: number of fields in the hash, or 0 when key does not exist.
            return(this.connection.ExpectInt());
        }
Exemple #15
0
        /// <summary>
        /// 设置一个值,当键已存在时则忽略
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetNX(string key, byte[] value)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            if (value.Length > 1073741824)
            {
                throw new ArgumentException("value exceeds 1G", "value");
            }

            using (var redisWriter = new RedisWriter(this, 3, "SETNX"))
            {
                redisWriter.WriteArgument(key);
                redisWriter.WriteArgument(value);
                this.Connection.SendCommand(redisWriter);
            }

            //Set key to hold string value if key does not exist. In that case, it is equal to SET. When key already holds a value, no operation is performed. SETNX is short for "SET if N ot e X ists".
            //Return value
            //Integer reply, specifically:
            //1 if the key was set
            //0 if the key was not set
            var r = this.Connection.ExpectInt();

            if (r == 1)
            {
                return(true);
            }
            if (r == 0)
            {
                return(false);
            }

            throw new InvalidOperationException(string.Format("Unknown Result '{0}'", r));
        }
Exemple #16
0
 /// <summary>
 /// 将多个 HyperLogLog 合并为一个 HyperLogLog ,合并后的 HyperLogLog 的基数估算值.
 /// </summary>
 /// <param name="destkey"></param>
 /// <param name="sourcekeys"></param>
 /// <returns></returns>
 public bool PFMERGE(string destkey, params string[] sourcekeys)
 {
     if (string.IsNullOrEmpty(destkey))
     {
         throw new ArgumentNullException("destkey");
     }
     if (sourcekeys.Length == 0)
     {
         throw new ArgumentNullException("sourcekeys");
     }
     using (var w = new RedisWriter(this.client, sourcekeys.Length + 2, "PFMERGE"))
     {
         w.WriteArgument(destkey);
         foreach (var member in sourcekeys)
         {
             w.WriteArgument(member);
         }
         this.connection.SendCommand(w);
     }
     return(this.connection.ExpectSuccess());
 }
Exemple #17
0
 /// <summary>
 /// 将所有元素参数添加到 HyperLogLog 数据结构中
 /// </summary>
 /// <param name="key"></param>
 /// <param name="value"></param>
 /// <returns>"OK" 添加成功</returns>
 public int PFADD(string key, params string[] value)
 {
     if (string.IsNullOrEmpty(key))
     {
         throw new ArgumentNullException("key");
     }
     if (value == null || value.Length == 0)
     {
         throw new ArgumentNullException("value");
     }
     using (var w = new RedisWriter(this.client, value.Length + 2, "PFADD"))
     {
         w.WriteArgument(key);
         foreach (var member in value)
         {
             w.WriteArgument(member);
         }
         this.connection.SendCommand(w);
     }
     return(this.connection.ExpectInt());
 }
Exemple #18
0
        /// <summary>
        /// 删除一个积分范围元素
        /// </summary>
        /// <param name="key"></param>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        public int ZREMRANGEBYSCORE(string key, double min, double max)
        {
            //ZREMRANGEBYSCORE key min max

            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            //Integer reply: the number of elements removed.
            using (var w = new RedisWriter(this.client, 4, "ZREMRANGEBYRANK"))
            {
                w.WriteArgument(key);
                w.WriteArgument(min.ToString());
                w.WriteArgument(max.ToString());

                this.connection.SendCommand(w);
            }

            return(this.connection.ExpectInt());
        }
Exemple #19
0
        /// <summary>
        /// 设置一组元素值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dictionary"></param>
        public bool HMSET(string key, IDictionary <string, string> dictionary)
        {
            //HMSET key field value [field value ...]

            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            if (dictionary == null)
            {
                throw new ArgumentNullException("dictionary");
            }

            using (var w = new RedisWriter(this.client, dictionary.Count * 2 + 2, "HMSET"))
            {
                w.WriteArgument(key);

                var e = dictionary.GetEnumerator();
                while (e.MoveNext())
                {
                    if (e.Current.Key == null)
                    {
                        throw new ArgumentNullException("dictionary", "dictionary key contains null, it's not allowed");
                    }
                    if (e.Current.Value == null)
                    {
                        throw new ArgumentNullException("dictionary", "dictionary key " + e.Current.Key + " value is null");
                    }

                    w.WriteArgument(this.client.Encoding.GetBytes(e.Current.Key));
                    w.WriteArgument(this.client.Encoding.GetBytes(e.Current.Value));
                }

                this.connection.SendCommand(w);
            }

            //Simple string reply
            return(this.connection.ExpectSuccess());
        }
Exemple #20
0
        /// <summary>
        /// 获取服务器信息
        /// </summary>
        /// <returns></returns>
        public Dictionary <string, string> GetInfo()
        {
            using (var redisWriter = new RedisWriter(this, 1, "INFO"))
            {
                this.Connection.SendCommand(redisWriter);
            }

            byte[] r = this.Connection.ExpectBulkReply();

            var dict = new Dictionary <string, string>(10);
            var v    = this.Encoding.GetString(r);

            foreach (var line in v.Split('\n'))
            {
                int p = line.IndexOf(':');
                if (p == -1)
                {
                    continue;
                }
                dict.Add(line.Substring(0, p), line.Substring(p + 1));
            }
            return(dict);
        }
Exemple #21
0
        /// <summary>
        /// 添加一个元素
        /// </summary>
        /// <param name="key"></param>
        /// <param name="score"></param>
        /// <param name="member"></param>
        /// <returns>排序</returns>
        public int ZAdd(string key, double score, string member)
        {
            //ZADD myzset 1 "one"

            if (member == null)
            {
                throw new ArgumentNullException("member");
            }

            using (var w = new RedisWriter(this.client, 4, "ZADD"))
            {
                w.WriteArgument(key);
                w.WriteArgument(score.ToString());
                w.WriteArgument(member);

                this.connection.SendCommand(w);
            }

            //Integer reply, specifically:
            //The number of elements added to the sorted sets, not including elements already existing for which the score was updated.

            return(this.connection.ExpectInt());
        }
Exemple #22
0
        /// <summary>
        /// 获取匹配的键列表
        /// </summary>
        /// <param name="pattern">匹配规则</param>
        /// <returns></returns>
        public string[] GetKeys(string pattern)
        {
            if (pattern == null)
            {
                throw new ArgumentNullException("key");
            }

            using (var redisWriter = new RedisWriter(this, 2, "KEYS"))
            {
                redisWriter.WriteArgument(pattern);
                this.Connection.SendCommand(redisWriter);
            }

            var keys = this.Connection.ExpectToStringArray();

            return(keys);

            //var keys = this.Connection.ExpectBulkReply() ;
            //if (keys.Length == 0)
            //    return new string[0];

            //return this.Encoding.GetString(keys).Split(' ');
        }
Exemple #23
0
        /// <summary>
        /// 返回给定的区间元素列表
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <param name="withscores">是否返回分值</param>
        /// <returns></returns>
        private byte[][] ZREVRANGEByte(string key, int start, int stop, bool withscores)
        {
            //ZREVRANGE key start stop [WITHSCORES]

            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            //Array reply: list of elements in the specified range (optionally with their scores).

            if (withscores)
            {
                using (var w = new RedisWriter(this.client, 5, "ZREVRANGE"))
                {
                    w.WriteArgument(key);
                    w.WriteArgument(start.ToString());
                    w.WriteArgument(stop.ToString());
                    w.WriteArgument("WITHSCORES");

                    this.connection.SendCommand(w);
                }
            }
            else
            {
                using (var w = new RedisWriter(this.client, 4, "ZREVRANGE"))
                {
                    w.WriteArgument(key);
                    w.WriteArgument(start.ToString());
                    w.WriteArgument(stop.ToString());

                    this.connection.SendCommand(w);
                }
            }

            return(this.connection.ExpectMultiBulkReply());
        }
Exemple #24
0
        /// <summary>
        /// 订阅指定KEY的消息,使用此方法请确保此实例仅会被当次使用
        /// </summary>
        /// <param name="channels"></param>
        /// <param name="resultCallback"></param>
        public void Subscribe(Action <RedisSubscribeResult> resultCallback, params string[] channels)
        {
            if (channels.Length == 0)
            {
                throw new ArgumentException("channels");
            }

            using (var redisWriter = new RedisWriter(this.client, channels.Length + 1, "SUBSCRIBE"))
            {
                foreach (var key in channels)
                {
                    redisWriter.WriteArgument(key);
                }

                this.connection.SendCommand(redisWriter);
            }

            this.client.PoolAbandon = true; //禁用当前池实例,防止被重用
            while (true)
            {
                var result = this.connection.ExpectSubscribeResult();
                resultCallback(result);
            }
        }
Exemple #25
0
        /// <summary>
        /// 返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从大到小)排序。
        /// 排名以 0 为底,也就是说, score 值最大的成员排名为 0 。
        /// 使用 ZRANK 命令可以获得成员按 score 值递增(从小到大)排列的排名。
        /// </summary>
        /// <param name="key"></param>
        /// <param name="member"></param>
        /// <returns></returns>
        public int?ZREVRANK(string key, string member)
        {
            //ZREVRANK key member
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            if (member == null)
            {
                throw new ArgumentNullException("member");
            }

            //If member exists in the sorted set, Integer reply: the rank of member.
            //If member does not exist in the sorted set or key does not exist, Bulk string reply: nil.
            using (var w = new RedisWriter(this.client, 3, "ZREVRANK"))
            {
                w.WriteArgument(key);
                w.WriteArgument(member);

                this.connection.SendCommand(w);
            }
            return(this.connection.ExpectIntOrNil());
        }
Exemple #26
0
        /// <summary>
        /// 计算给定的一个或多个有序集的并集,其中给定 key 的数量必须以 numkeys 参数指定,并将该并集(结果集)储存到 destination 。
        /// 默认情况下,结果集中某个成员的 score 值是所有给定集下该成员 score 值之 和 。
        /// </summary>
        /// <param name="destinationKey">目标键</param>
        /// <param name="keyWeights">键与乘法因子</param>
        /// <param name="aggregate">聚合方式</param>
        /// <returns>保存到 destination 的结果集的基数</returns>
        public int ZUNIONSTORE(string destinationKey, IDictionary <string, double> keyWeights, RedisAggregate aggregate)
        {
            //ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

            //Integer reply: the number of elements in the resulting sorted set at destination.

            if (string.IsNullOrEmpty(destinationKey))
            {
                throw new ArgumentNullException("destinationKey");
            }

            if (keyWeights == null || keyWeights.Count == 0)
            {
                throw new ArgumentNullException("keyWeights");
            }
            //
            var keys    = new string[keyWeights.Count];
            var weights = new double[keyWeights.Count];
            var i       = 0;
            var e       = keyWeights.GetEnumerator();

            while (e.MoveNext())
            {
                keys[i]    = e.Current.Key;
                weights[i] = e.Current.Value;
                i++;
            }

            //ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
            using (var w = new RedisWriter(this.client, 6 + keyWeights.Count * 2, "ZUNIONSTORE"))
            {
                w.WriteArgument(destinationKey);
                w.WriteArgument(keyWeights.Count.ToString());
                foreach (var key in keys)
                {
                    w.WriteArgument(key);
                }
                w.WriteArgument("WEIGHTS");
                foreach (var weight in weights)
                {
                    w.WriteArgument(weight.ToString());
                }
                w.WriteArgument("AGGREGATE");
                w.WriteArgument(aggregate.ToString());

                this.connection.SendCommand(w);
            }

            return(this.connection.ExpectInt());

            //示例
            //            redis> ZRANGE programmer 0 -1 WITHSCORES
            //1) "peter"
            //2) "2000"
            //3) "jack"
            //4) "3500"
            //5) "tom"
            //6) "5000"

            //redis> ZRANGE manager 0 -1 WITHSCORES
            //1) "herry"
            //2) "2000"
            //3) "mary"
            //4) "3500"
            //5) "bob"
            //6) "4000"

            //redis> ZUNIONSTORE salary 2 programmer manager WEIGHTS 1 3
            //(integer) 6

            //redis> ZRANGE salary 0 -1 WITHSCORES
            //1) "peter"
            //2) "2000"
            //3) "jack"
            //4) "3500"
            //5) "tom"
            //6) "5000"
            //7) "herry"
            //8) "6000"
            //9) "mary"
            //10) "10500"
            //11) "bob"
            //12) "12000"
        }