Redis list的實現爲一個雙向鏈表,便可以支持反向查找和遍歷,更方便操做,不過帶來了部分額外的內存開銷,api
/// <summary> /// Redis list的實現爲一個雙向鏈表,便可以支持反向查找和遍歷,更方便操做,不過帶來了部分額外的內存開銷, /// Redis內部的不少實現,包括髮送緩衝隊列等也都是用的這個數據結構。 /// </summary> public class RedisListService : RedisBase { #region 賦值 /// <summary> /// 從左側向list中添加值 /// </summary> public void LPush(string key, string value) { base.iClient.PushItemToList(key, value); } /// <summary> /// 從左側向list中添加值,並設置過時時間 /// </summary> public void LPush(string key, string value, DateTime dt) { base.iClient.PushItemToList(key, value); base.iClient.ExpireEntryAt(key, dt); } /// <summary> /// 從左側向list中添加值,設置過時時間 /// </summary> public void LPush(string key, string value, TimeSpan sp) { base.iClient.PushItemToList(key, value); base.iClient.ExpireEntryIn(key, sp); } /// <summary> /// 從右側向list中添加值 /// </summary> public void RPush(string key, string value) { base.iClient.PrependItemToList(key, value); } /// <summary> /// 從右側向list中添加值,並設置過時時間 /// </summary> public void RPush(string key, string value, DateTime dt) { base.iClient.PrependItemToList(key, value); base.iClient.ExpireEntryAt(key, dt); } /// <summary> /// 從右側向list中添加值,並設置過時時間 /// </summary> public void RPush(string key, string value, TimeSpan sp) { base.iClient.PrependItemToList(key, value); base.iClient.ExpireEntryIn(key, sp); } /// <summary> /// 添加key/value /// </summary> public void Add(string key, string value) { base.iClient.AddItemToList(key, value); } /// <summary> /// 添加key/value ,並設置過時時間 /// </summary> public void Add(string key, string value, DateTime dt) { base.iClient.AddItemToList(key, value); base.iClient.ExpireEntryAt(key, dt); } /// <summary> /// 添加key/value。並添加過時時間 /// </summary> public void Add(string key, string value, TimeSpan sp) { base.iClient.AddItemToList(key, value); base.iClient.ExpireEntryIn(key, sp); } /// <summary> /// 爲key添加多個值 /// </summary> public void Add(string key, List<string> values) { base.iClient.AddRangeToList(key, values); } /// <summary> /// 爲key添加多個值,並設置過時時間 /// </summary> public void Add(string key, List<string> values, DateTime dt) { base.iClient.AddRangeToList(key, values); base.iClient.ExpireEntryAt(key, dt); } /// <summary> /// 爲key添加多個值,並設置過時時間 /// </summary> public void Add(string key, List<string> values, TimeSpan sp) { base.iClient.AddRangeToList(key, values); base.iClient.ExpireEntryIn(key, sp); } #endregion #region 獲取值 /// <summary> /// 獲取list中key包含的數據數量 /// </summary> public long Count(string key) { return base.iClient.GetListCount(key); } /// <summary> /// 獲取key包含的全部數據集合 /// </summary> public List<string> Get(string key) { return base.iClient.GetAllItemsFromList(key); } /// <summary> /// 獲取key中下標爲star到end的值集合 /// </summary> public List<string> Get(string key, int star, int end) { return base.iClient.GetRangeFromList(key, star, end); } #endregion #region 阻塞命令 /// <summary> /// 阻塞命令:從list爲key的尾部移除一個值,並返回移除的值,阻塞時間爲sp /// </summary> public string BlockingPopItemFromList(string key, TimeSpan? sp) { return base.iClient.BlockingPopItemFromList(key, sp); } /// <summary> /// 阻塞命令:從多個list中尾部移除一個值,並返回移除的值&key,阻塞時間爲sp /// </summary> public ItemRef BlockingPopItemFromLists(string[] keys, TimeSpan? sp) { return base.iClient.BlockingPopItemFromLists(keys, sp); } /// <summary> /// 阻塞命令:從list中keys的尾部移除一個值,並返回移除的值,阻塞時間爲sp /// </summary> public string BlockingDequeueItemFromList(string key, TimeSpan? sp) { return base.iClient.BlockingDequeueItemFromList(key, sp); } /// <summary> /// 阻塞命令:從多個list中尾部移除一個值,並返回移除的值&key,阻塞時間爲sp /// </summary> public ItemRef BlockingDequeueItemFromLists(string[] keys, TimeSpan? sp) { return base.iClient.BlockingDequeueItemFromLists(keys, sp); } /// <summary> /// 阻塞命令:從list中一個fromkey的尾部移除一個值,添加到另一個tokey的頭部,並返回移除的值,阻塞時間爲sp /// </summary> public string BlockingPopAndPushItemBetweenLists(string fromkey, string tokey, TimeSpan? sp) { return base.iClient.BlockingPopAndPushItemBetweenLists(fromkey, tokey, sp); } #endregion #region 刪除 /// <summary> /// 從尾部移除數據,返回移除的數據 /// </summary> public string PopItemFromList(string key) { var sa = base.iClient.CreateSubscription(); return base.iClient.PopItemFromList(key); } /// <summary> /// 從尾部移除數據,返回移除的數據 /// </summary> public string DequeueItemFromList(string key) { return base.iClient.DequeueItemFromList(key); } /// <summary> /// 移除list中,key/value,與參數相同的值,並返回移除的數量 /// </summary> public long RemoveItemFromList(string key, string value) { return base.iClient.RemoveItemFromList(key, value); } /// <summary> /// 從list的尾部移除一個數據,返回移除的數據 /// </summary> public string RemoveEndFromList(string key) { return base.iClient.RemoveEndFromList(key); } /// <summary> /// 從list的頭部移除一個數據,返回移除的值 /// </summary> public string RemoveStartFromList(string key) { return base.iClient.RemoveStartFromList(key); } #endregion #region 其它 /// <summary> /// 從一個list的尾部移除一個數據,添加到另一個list的頭部,並返回移動的值 /// </summary> public string PopAndPushItemBetweenLists(string fromKey, string toKey) { return base.iClient.PopAndPushItemBetweenLists(fromKey, toKey); } public void TrimList(string key, int start, int end) { base.iClient.TrimList(key, start, end); } #endregion #region 發佈訂閱 public void Publish(string channel, string message) { base.iClient.PublishMessage(channel, message); } public void Subscribe(string channel, Action<string, string, IRedisSubscription> actionOnMessage) { var subscription = base.iClient.CreateSubscription(); subscription.OnSubscribe = c => { Console.WriteLine($"訂閱頻道{c}"); Console.WriteLine(); }; //取消訂閱 subscription.OnUnSubscribe = c => { Console.WriteLine($"取消訂閱 {c}"); Console.WriteLine(); }; subscription.OnMessage += (c, s) => { actionOnMessage(c, s, subscription); }; Console.WriteLine($"開始啓動監聽 {channel}"); subscription.SubscribeToChannels(channel); //blocking } public void UnSubscribeFromChannels(string channel) { var subscription = base.iClient.CreateSubscription(); subscription.UnSubscribeFromChannels(channel); } #endregion }
我在這裏將註解添加上去,有不正確之處,歡迎指正、服務器
//尾部追加數據 client.PushItemToList(listId, value); //設置過時時間 client.ExpireEntryAt(key, expireAt); //設置滑動過時時間 client.ExpireEntryIn(key, expireIn); client.PrependItemToList(listId, value); client.AddItemToList(listId, value); client.AddRangeToList(listId, values); //獲取listId包含的數據數量 client.GetListCount(listId); //獲取listId包含的全部數據集合 client.GetAllItemsFromList(listId); //獲取listId中下標爲startingFrom到endingAt的值集合 client.GetRangeFromList(listId, startingFrom, endingAt); // 阻塞命令:從listId的頭部移除一個值,並返回移除的值,阻塞時間爲sp client.BlockingPopItemFromList(listId, timeOut); // 阻塞命令:從多個listId的尾部移除一個值,並返回移除的值,阻塞時間爲sp client.BlockingPopItemFromLists(listIds, timeOut); // 阻塞命令:從listId的尾部移除一個值,並返回移除的值,阻塞時間爲sp client.BlockingDequeueItemFromList(listId, timeOut); // 阻塞命令:從多個listId的尾部移除一個值,並返回移除的值,阻塞時間爲sp client.BlockingDequeueItemFromLists(listIds, timeOut); //阻塞命令:從一個fromListId的頭部移除一個值,添加到另一個toListId的頭部,並返回移除的值,阻塞時間爲sp client.BlockingPopAndPushItemBetweenLists(fromListId, toListId, timeOut); //從尾部移除數據,返回移除的數據 client.PopItemFromList(listId); // 從尾部移除數據,返回移除的數據 client.DequeueItemFromList(listId); //移除listId中,與value相同的值的數據,並返回移除的數量 client.RemoveItemFromList(listId, value); // 從list的尾部移除一個數據,返回移除的數據 client.RemoveEndFromList(listId); //從list的頭部移除一個數據,返回移除的數據 client.RemoveStartFromList(listId); //從一個list的尾部移除一個數據,添加到另一個list的頭部,並返回移動的值 client.PopAndPushItemBetweenLists(fromListId, toListId);
//1. 添加 //1.1 client.PushItemToList("group1", "你好1"); client.PushItemToList("group1", "你好2"); client.PushItemToList("group1", "你好3"); client.PushItemToList("group1", "你好4"); client.PushItemToList("group1", "你好5"); //1.2 client.PrependItemToList("group2", "早上1"); client.PrependItemToList("group2", "早上2"); client.PrependItemToList("group2", "早上3"); client.PrependItemToList("group2", "早上4"); client.PrependItemToList("group2", "早上5"); //1.3 client.AddItemToList("group3", "中午1"); client.AddItemToList("group3", "中午2"); client.AddItemToList("group3", "中午3"); client.AddItemToList("group3", "中午4"); client.AddItemToList("group3", "中午5"); //1.4 List<string> values1 = new List<string>() { "晚上1", "晚上2", "晚上3", "晚上4", "晚上5" }; client.AddRangeToList("group4",values1);
//2.插入 //2.1尾部插入 client.PushItemToList("group3", "a1"); client.PushItemToList("group3", "a2"); client.PushItemToList("group3", "a3"); //2.2頭部插入 client.PrependItemToList("group3", "b1"); client.PrependItemToList("group3", "b2"); client.PrependItemToList("group3", "b3");
從效果圖看,Push方式是往鏈表的尾部逐步插入數據,Prepend是往鏈表的頭部逐步插入數據數據結構
//3.刪除 client.PopItemFromList("group1"); client.PopItemFromList("group1"); client.PopItemFromList("group1"); client.DequeueItemFromList("group3"); client.DequeueItemFromList("group3"); client.RemoveEndFromList("group4"); client.RemoveStartFromList("group4"); client.RemoveStartFromList("group4");
對比先後的數據變化,能夠得出Pop、Dequeue方法效果都是同樣,刪除鏈表尾部數據。RemoveEnd 刪除鏈表尾部數據、RemoveStart刪除鏈表頭部數據ide
//4.發佈訂閱 //4.1(服務器)發佈消息 client.PublishMessage(toChanner, message); //4.2 (客戶端)訂閱 var subscription= client.CreateSubscription(); //4.2.1(客戶端)訂閱頻道 subscription.SubscribeToChannels(channels); //4.2.2 (客戶端)取消頻道 subscription.UnSubscribeFromChannels(channels);
其它的一些api方法,就不作數據效果展現了~spa