14 list 相关操作

Posted 蓝风9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了14 list 相关操作相关的知识,希望对你有一定的参考价值。

前言

相关介绍主要围绕着如下的一些常用的命令, 来看看 list 相关操作的具体 api 

如下常用的命令来自于我们常见的教程 : https://www.runoob.com/redis/redis-lists.html 

本文的相关代码 拷贝自 redis-6.2.0  

代码来自于 https://redis.io/ 
 

数据存储

使用的 quicklist 来存储的数据 

BLPOP key1 [key2] timeout - 执行 blpop list 20 

这里可以看出的是 参数的数量要求大于等于 3 个, 可以传递 多个 key 

从给定的 keyList 里面尝试 lpop 一个元素, 如果 keyList 所有的 key 均没有元素, 阻塞 直到有元素 或者 超时 

blpop, brpop, lpop, rpop 都是差不多, 这里只介绍一个 

我们来看一下 blpopCommand 

遍历 keyList, 并确保 key 对应的 value 类型为 List 

如果 value 对应的 List 为空, 跳过 尝试下一个 key 

从 value 对应的 List 的表头 pop 一个元素, 给客户端返回一个数组 两个元素, 一个 key, 一个 lpop 的 value 

如果 keyList 里面所有的 key 都是空的或者不存在, blockForKeys 等待有元素 或者 直到超时 

因为 我们这里 list2 不存在数据, list 中存在 age, name 两个数据, 这里会返回 [list, age] 

最终客户端这边展示的结果如下, list 中已有两个元素, age, name, list2 没有这个元素 

因为 我们这里 list2 不存在数据, list 中存在 age, name 两个数据, 这里会返回 [list, age] 

BRPOPLPUSH source destination timeout - 执行 brpoppush list list2 20 

这里可以看出的是 参数的数量要求等于 4 个 

lmove, blmove 都是差不多, 这里只介绍一个 

我们来看一下 brpoplpushCommand 

pop source 对应的 value 的最后一个元素 value 

吧 value push 到 destination 的第一个元素 

如果 source 对应的 value 里面没有元素了, 移除 source 对应的 key, value 

更新 dirty, 更新命令行参数为 rpoplpush 

最终客户端这边展示的结果如下, list 中已有一个元素, name, 这里相当于是吧 list 中的 name 移动到了 list2 中 

因此操作之后 list2 中存在一个元素, list 中没有元素了 

LINDEX key index - 执行 lindex list 1

这里可以看出的是 参数的数量要求等于 3 个 

我们来看一下 lindexCommand 

获取 key 对应的 entry, 确保 value 为 LIST 

获取客户端传递过来的 index 参数  

从 list 中获取 index 所对应的元素, 返回给客户端 

最终客户端这边展示的结果如下, list 中已有两个元素, age, name, 这里是获取的是 index 为 1 的元素, 这里为 name 

LINSERT key BEFORE|AFTER pivotValue - 执行 linsert list before name hobby 

这里可以看出的是 参数的数量要求等于 5 个 

我们来看一下 linsertCommand 

查询 key 对应的 value, 确保类型为 List 

查询 pivot 对应的 entry, 在该 entry 之前 或者 之后 添加 value 作为元素 

更新 dirty, 如果更新了元素, 发送 更新通知 返回 value 的长度, 否则返回 -1 

最终客户端这边展示的结果如下, list 中已有两个元素, age, name, 这里是在 name 之前增加了一个 hobby 的元素 

所以最终 list 长度为 3, 元素依次为 [age, hobby, name] 

LLEN key - 执行 llen list 

这里可以看出的是 参数的数量要求等于 2 个 

我们来看一下 llenCommand 

获取 key 对应的 entry, 确保 value 类型为 List  

返回给客户端 value 的长度 

listTypeLen 的具体的实现为 如果编码类型为 quicklist, 直接从 quicklist 元数据中获取长度 

最终客户端这边展示的结果如下, list 中已有三个元素, age, hobby, name, 这里返回的是 list 中元素的数量, 这里为 3 

LPUSH key value1 [value2] - 执行 lpush list head 

这里可以看出的是 参数的数量要求大于等于 3 个 

lpush, rpush, lpushx, rpushx 都是差不多, 这里只介绍一个 

我们来看一下 lpushCommand 

查询 key 对应的 value, 确保类型为 List 

如果 x系列命令, 并且 key 对应的 entry 不存在, 直接返回 0, 否则 如果 entry 不存在, 创建一个 list, 添加到 db->dict 里面 

依次 lpush 各个需要添加元素 

更新 dirty, 返回给客户端 value 中元素的数量, 发送更新通知 

最终客户端这边展示的结果如下, list 中已有三个元素, age, hobby, name, 新增一个 head 到 list 左边, 返回的是 list 中元素的数量, 这里为 4 

LRANGE key start stop - 执行 lrange list 1 3

这里可以看出的是 参数的数量要求等于 4 个 

我们来看一下 lrangeCommand 

获取 key 对应的 value, 确保类型为 List, 获取 start, end, 并校验数据类型 

返回 value 中 [start, end] 区间的所有的元素给客户端 

具体的 lrange 的处理方式为, 从 start, end 开始迭代元素, 并返回给客户端 

最终客户端这边展示的结果如下, list 中已有三个元素, head, age, hobby, name, 在 range 为 [1, 3] 范围内的元素为 [age, hobby, name] 这三个元素 

LREM key count value - 执行 lrem list 1 head 

这里可以看出的是 参数的数量要求等于 4 个 

我们来看一下 lremCommand 

约束 toRemove 大于小于零, 为遍历方向, 向前遍历删除, 还是向后遍历删除 

获取 key 对应的 entry, 并确保类型为 List 

迭代遍历 list, 删除 匹配待删除元素的 entry, 删除 count 个 

更新 dirty, 发送更新通知 

如果 value 中没有元素了, 删除 entry 

返回给客户端 移除元素的数量 

最终客户端这边展示的结果如下, list 中已有四个元素, head, age, hobby, name, 从表头遍历删除 2 个 "head" 元素 

但是实际 list 中只有一个 "head", 因此会遍历完 list, 最终删除 一个 "head" 元素 

LSET key index value - 执行 lset list 0 head 

这里可以看出的是 参数的数量要求等于 4 个 

我们来看一下 lsetCommand 

获取 key 对应的 entry, 并确保类型为 List 

设置 value 中 index 所在的元素为 value 

如果 index 越界, 返回 outofrangeerr, 否则 返回 ok, 更新 dirty, 发送更新通知 

最终客户端这边展示的结果如下, list 中已有三个元素, age, hobby, name, 设置索引为 1 的元素为 head 

因此 更新之后 list 中的元素为 [head, hobby, name] 

LTRIM key start stop - 执行 ltrim list 1 2

这里可以看出的是 参数的数量要求等于 4 个 

我们来看一下 ltrimCommand 

从参数中获取 start, end 并确保类型正确 

获取 key 对应的 entry, 确保 value 为 List 

转换 start, end[start, end 的小于0的约束] 

删除 [0, start), (end, llen] 这部分区间的数据, 使得只保留下 [start, end] 区间的数据 

更新 dirty, 发送更新通知, 响应给客户端 ok 

最终客户端这边展示的结果如下, list 中已有三个元素, head, hobby, name, 只保留 [1, 2] 区间的元素, 会删除掉 head 

完 

以上是关于14 list 相关操作的主要内容,如果未能解决你的问题,请参考以下文章

线性表的相关操作

list操作相关总结

用java代码操作Redis进行相关的Hash,String,Set,List操作

python List的一些相关操作

client-go gin的简单整合二(list列表相关进一步操作)

大数据之Redis:Redis数据类型List及相关的命令行操作