[feat] 新增LPOP,支持Redis7下的列表索引查找,Redis7-版本通过多次LRange遍历实现。close: https://github.com/NewLifeX/NewLife.Redis/issues/137

This commit is contained in:
智能大石头 2025-03-28 17:31:34 +08:00
parent 88f37eccdb
commit d38011a409
3 changed files with 56 additions and 4 deletions

View File

@ -442,6 +442,7 @@ public class RedisReliableQueue<T> : QueueBase, IProducerConsumer<T>, IDisposabl
// 清理已经失去Status的Ack // 清理已经失去Status的Ack
foreach (var key in rds.Search($"{_Key}:Ack:*", 1000)) foreach (var key in rds.Search($"{_Key}:Ack:*", 1000))
{
if (!acks.Contains(key)) if (!acks.Contains(key))
{ {
var queue = rds.GetList<String>(key) as RedisList<String>; var queue = rds.GetList<String>(key) as RedisList<String>;
@ -449,6 +450,7 @@ public class RedisReliableQueue<T> : QueueBase, IProducerConsumer<T>, IDisposabl
XTrace.WriteLine("全局清理死信:{0} {1}", key, msgs.ToJson()); XTrace.WriteLine("全局清理死信:{0} {1}", key, msgs.ToJson());
rds.Remove(key); rds.Remove(key);
} }
}
return count; return count;
} }

View File

@ -68,11 +68,28 @@ public class RedisList<T> : RedisBase, IList<T>
// Redis7支持LPOS // Redis7支持LPOS
if (Redis.Version.Major >= 7) return LPOS(item); if (Redis.Version.Major >= 7) return LPOS(item);
var count = Count; var p = 0;
if (count > 1000) throw new NotSupportedException($"[{Key}]的元素个数过多,不支持!"); var batch = 100;
while (true)
{
var arr = LRange(p, p + batch - 1);
if (arr == null || arr.Length == 0) break;
var arr = GetAll(); var idx = Array.IndexOf(arr, item);
return Array.IndexOf(arr, item); if (idx >= 0) return p + idx;
if (p >= 1_000_000) throw new NotSupportedException($"[{Key}]的元素个数过多,不支持遍历!");
p += batch;
}
return -1;
//var count = Count;
//if (count > 1000)
//var arr = GetAll();
//return Array.IndexOf(arr, item);
} }
/// <summary>在指定位置插入</summary> /// <summary>在指定位置插入</summary>

View File

@ -1,5 +1,6 @@
using NewLife.Caching; using NewLife.Caching;
using NewLife.Log; using NewLife.Log;
using NewLife.Security;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@ -164,6 +165,38 @@ public class ListTests
Assert.Equal(vs3[1], item2); Assert.Equal(vs3[1], item2);
} }
[Fact]
public void List_IndexOf()
{
var key = "lkey_indexof";
// 删除已有
_redis.Remove(key);
var rlist = _redis.GetList<String>(key) as RedisList<String>;
Assert.NotNull(rlist);
// 添加
var vs = Enumerable.Range(0, 1000).Select(e => Rand.NextString(8)).ToArray();
rlist.AddRange(vs);
_redis.SetExpire(key, TimeSpan.FromSeconds(60));
// 索引
var idx = rlist.IndexOf(vs[1]);
Assert.Equal(1, idx);
idx = rlist.IndexOf("abcd2");
Assert.Equal(-1, idx);
idx = rlist.IndexOf(vs[321]);
Assert.Equal(321, idx);
var rs = rlist.Contains(vs[456]);
Assert.True(rs);
_redis.Remove(key);
}
[Fact] [Fact]
public void RPOPLPUSH_Test() public void RPOPLPUSH_Test()
{ {