redis为什么要使用skiplist跳表

1.什么是skiplist跳表

跳表是一种特殊的链表,特殊的点在于其可以进行二分查找。普通的链表要查找元素只能挨个遍历链表中的所有元素,而跳表则利用了空间换时间的策略,在原来有序链表的基础上面增加了多级索引,然后利用类似二分查找的思路来快速实现查找功能。跳表可以支持快速的查找,插入,删除等操作,时间复杂度为O(logn),空间复杂度为O(n)。

2.随机层数的计算

跳表在节点插入时候,会随机出一个层数,依靠这个随机数操作构建的多层链表结构,能保证一个比较好的查找性能。这个随机层数不是一个普通的服从均匀分布的随机数,具体的计算逻辑如下

1.首先,每个节点肯定都有第1层指针(每个节点都在第1层链表里)。
2.如果一个节点有第i层(i>=1)指针(即节点已经在第1层到第i层链表中),那么它有第(i+1)层指针的概率为p。
3.节点最大的层数不允许超过一个最大值,记为MaxLevel。

伪代码如下

randomLevel()
    level := 1
    // random()返回一个[0...1)的随机数
    while random() < p and level < MaxLevel do
        level := level + 1
    return level

randomLevel逻辑中包含有两个参数,一个是概率p,一个是最大层数MaxLevel。在redis的实现中,这两个参数分别为

p = 1/4
MaxLevel = 32

该部分内容来自于如下文档:

skiplist的算法性能分析

关于跳表本身更详细的讲解可以参考上述文档。

3.redis为什么要使用跳表

经常会有人问这个问题,redis中为什么要使用跳表?

这个问题,redis作者已经给出过明确答案

  1. They are not very memory intensive. It’s up to you basically. Changing parameters about the probability of a node to have a given number of levels will make then less memory intensive than btrees.

  2. A sorted set is often target of many ZRANGE or ZREVRANGE operations, that is, traversing the skip list as a linked list. With this operation the cache locality of skip lists is at least as good as with other kind of balanced trees.

  3. They are simpler to implement, debug, and so forth. For instance thanks to the skip list simplicity I received a patch (already in Redis master) with augmented skip lists implementing ZRANK in O(log(N)). It required little changes to the code.

按照我自己的理解,稍微翻译一下就是
1.跳表不是非常吃内存,并且基本是取决于你自己。你可以通过改变参数p(第二部分中提到的),从而达到比btree消耗更少内存的目的。

2.redis中的zset结构经常会使用ZRANGE或者ZREVRANGE这种操作,这个时候遍历跳表就相当于遍历一个普通的链表。这种情况下,跳表的表现跟btree一样优秀。

3.很多人认为这一点是最重要的原因。跳表实现起来更容易,只需要一点点代码就能达到效果,修改起来也很方便。

### 在 Unreal Engine 5 中实现纹理旋转 在 Unreal Engine 5 (UE5) 中,可以通过材质编辑器(Material Editor)来调整纹理的旋转。具体来说,在材质节点中可以找到用于控制纹理变换的各种参数,其中包括缩放(Scale),平移(Pan),以及旋转(Rotate)[^1]。 对于希望动态改变纹理方向的情况,开发者通常会利用蓝图(Blueprints)或者C++编写自定义逻辑,通过修改材质实例常量(Material Instance Constants, MICs)中的旋转属性值达到预期效果[^2]。 另外值得注意的是,如果涉及到动画图表内的骨骼控制器影响网格物体表面贴图,则可能涉及到了新增加的支持累加标志(additive flag)到旋转乘数骨控制器节点(rotation multiplier bone controller node)的功能特性。不过此功能更偏向于角色动画领域而非简单的静态或随时间变化的UV映射操作。 为了更好地理解如何应用这些概念并实际动手实践,请参考官方文档有关创建和编辑材质(Create/Edit Materials)部分下的“Transforming Texture Coordinates”章节获取更多细节说明;同时也可以探索社区论坛及第三方资源寻找针对性的教学案例学习。 ```cpp // C++ 示例:设置材质实例常量的旋转变换 UMaterialInstanceDynamic* MID = UMaterialInstanceDynamic::Create(BaseMaterial, nullptr); MID->SetScalarParameterValue(FName("RotationAngle"), RotationValue); // 假设有一个名为 'RotationAngle' 的标量参数用来表示角度 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值