59 lines
3.4 KiB
C#
59 lines
3.4 KiB
C#
namespace NewLife.Caching;
|
||
|
||
/// <summary>超级基数估算</summary>
|
||
/// <remarks>
|
||
/// HyperLogLog可以使用固定且很少的内存(每个HyperLogLog结构需要12K字节再加上key本身的几个字节)来存储集合的唯一元素。
|
||
/// 返回的可见集合基数并不是精确值, 而是一个带有 0.81% 标准错误(standard error)的近似值。
|
||
/// 例如为了记录一天会执行多少次各不相同的搜索查询, 一个程序可以在每次执行搜索查询时调用一次PFADD, 并通过调用PFCOUNT命令来获取这个记录的近似结果。
|
||
/// 注意: 这个命令的一个副作用是可能会导致HyperLogLog内部被更改,出于缓存的目的,它会用8字节的来记录最近一次计算得到基数,所以PFCOUNT命令在技术上是个写命令。
|
||
/// </remarks>
|
||
public class HyperLogLog : RedisBase
|
||
{
|
||
#region 实例化
|
||
/// <summary>实例化超级基数</summary>
|
||
/// <param name="redis"></param>
|
||
/// <param name="key"></param>
|
||
public HyperLogLog(Redis redis, String key) : base(redis, key) { }
|
||
#endregion
|
||
|
||
/// <summary>添加</summary>
|
||
/// <remarks>
|
||
/// 这个命令的一个副作用是它可能会更改这个HyperLogLog的内部来反映在每添加一个唯一的对象时估计的基数(集合的基数)。
|
||
/// 如果一个HyperLogLog的估计的近似基数在执行命令过程中发了变化, PFADD 返回1,否则返回0,
|
||
/// 如果指定的key不存在,这个命令会自动创建一个空的HyperLogLog结构(指定长度和编码的字符串)。
|
||
/// 如果在调用该命令时仅提供变量名而不指定元素也是可以的,如果这个变量名存在,则不会有任何操作,如果不存在,则会创建一个数据结构(返回1)
|
||
/// </remarks>
|
||
/// <param name="items"></param>
|
||
/// <returns></returns>
|
||
public Int32 Add(params String[] items) => Execute((rc, k) => rc.ExecuteByKey<String, Int32>("PFADD", Key, items), true);
|
||
|
||
/// <summary>近似基数</summary>
|
||
/// <remarks>
|
||
/// 返回存储在HyperLogLog结构体的该变量的近似基数,如果该变量不存在,则返回0。
|
||
/// 当参数为多个key时,返回这些HyperLogLog并集的近似基数,这个值是将所给定的所有key的HyperLoglog结构合并到一个临时的HyperLogLog结构中计算而得到的。
|
||
/// </remarks>
|
||
public Int32 Count => Execute((rc, k) => rc.Execute<Int32>("PFCOUNT", Key), true);
|
||
|
||
/// <summary>合并</summary>
|
||
/// <remarks>
|
||
/// 将多个 HyperLogLog 合并(merge)为一个 HyperLogLog , 合并后的 HyperLogLog 的基数接近于所有输入 HyperLogLog 的可见集合(observed set)的并集。
|
||
/// 合并得出的 HyperLogLog 会被储存在目标变量(第一个参数)里面, 如果该键并不存在, 那么命令在执行之前, 会先为该键创建一个空的。
|
||
/// </remarks>
|
||
/// <param name="keys"></param>
|
||
/// <returns></returns>
|
||
public Boolean Merge(params String[] keys)
|
||
{
|
||
var args = new List<Object>
|
||
{
|
||
Key
|
||
};
|
||
foreach (var item in keys)
|
||
{
|
||
if (Redis is FullRedis rds && !rds.Prefix.IsNullOrEmpty())
|
||
args.Add(item.EnsureStart(rds.Prefix));
|
||
else
|
||
args.Add(item);
|
||
}
|
||
return Execute((rc, k) => rc.Execute<String>("PFMERGE", args.ToArray()), true) == "OK";
|
||
}
|
||
} |