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 相关操作的主要内容,如果未能解决你的问题,请参考以下文章
用java代码操作Redis进行相关的Hash,String,Set,List操作