lua-zset
lua-zset copied to clipboard
讨论下是否还需要zset.score的设计
大多数编程语言本身都提供数组类型,并且可以自定义排序。以lua为例
local list = { {name="a", count=1}, {name="b", count=2 }
table.sort(list, function(a, b)
if a.count ~= b.count then
return a.count < b.count
else
return a.name < b.name
end
return false
end)
自定义排序,是为了方便调用端,做复杂的排序比较(复合排序)
redis zset为什么通过score定义排序?按我个人理解,这是为了将多维条件转换成一维条件,去隔离调用端各种乱七八槽的关系,如redis需要支持脚本化编程、两钟语言间据结构转换
谈回贵项目,是想在本地lua环境中提供zsert支持。那么将多维条件转换成一维条件就没必要了,lua业务层不需要老是想着如何转换成一维比较。比较函数可以在zsert.new时定义
local zs = zset.new(function(a, b)
-- todo someting here
end)
我猜测是效率问题,每对比一次要调用一次lua函数。可以写个 benchmark 对比一下试试?
我猜测是效率问题,每对比一次要调用一次lua函数。可以写个 benchmark 对比一下试试?
以上只是初步构想并未实现。如果差别不大,或只是稍微高一丢丢,应该还可以接受。 可以的,我之后可以尝试实现并对比一下。
底层是跳表,排序是在c层实现的,如果通过回调函数支持自定义排序,性能会降低比较多;
这个数据结构本身不是那么通用的,适合用来做排行榜之类,有score的场景。
性能问题是不是可以传个c函数进去,然后用类似 ffi 的方式执行?
性能问题是不是可以传个c函数进去,然后用类似 ffi 的方式执行?
我猜测是效率问题,每对比一次要调用一次lua函数。可以写个 benchmark 对比一下试试
我没实验测试过性能。 你早前提到的很有道理,每次调用一次lua函数会产生的切换消耗,skiplist以海量数据高性能定位的角度,为了高性能还是不传lua回调比较好,不然方向走偏。 后来,我有另一个不成熟的想法,可是我未去偿试实验,看看就好~~! 参考数据库sort接口设计。类似mongodb中的find/sort
-- 格式
db.collection.find(query).sort(sorting_criteria)
-- 样例
db.ranks.find().sort({ score: -1, ts:-1 })
sorting_criteria: 是一个数组,第一个元素的优先级最高
对应地,在skilplist:slInsert就需要开放存放这个数组,而skiplist::slGetRank需要传入sorting_criteria
可是,存放数据又是另外一个新问题~
@lizijie 如果像 mongo 的 sort 的话,可以把 score 改为数组,然后 compare 就不设计为函数,而是一个32位整数就行,这样就支持 score 数组长度就支持最大 32 了。0 和 1 就相当于 mongo sort 里的 1 和 -1 。
local sorting_criteria = {
[1] = 1, -- score
[2] = 0, -- ts
}
local sort_bits = pack_bits(sorting_criteria)
local zs = zset.new(sort_bits)