列表命令
Redis中的List对象的类型为REDIS_LIST,是一种双向链表结构,主要支持以下几种命令:
- LPUSH 向列表左端添加元素,用法:
LPUSH key value
- RPUSH 向列表右端添加元素,用法:
RPUSH key value
- LPOP 从列表左端弹出元素,用法:
LPOP key
- RPOP 从列表右端弹出元素,用法:
RPOP key
- LLEN 获取列表中元素个数,用法:
LLEN key
- LRANGE 获取列表中某一片段的元素,用法:
LRANGE key start stop
,index从0开始,-1表示最后一个元素 - LREM 删除列表中指定的值,用法:
LREM key count value
,删除列表中前count个值为value的元素,当count>0时从左边开始数,count<0时从右边开始数,count=0时会删除所有值为value的元素 - LINDEX 获取指定索引的元素值,用法:
LINDEX key index
- LSET 设置指定索引的元素值,用法:
LSET key index value
- LTRIM 只保留列表指定片段,用法:
LTRIM key start stop
,包含start和stop - LINSERT 像列表中插入元素,用法:
LINSERT key BEFORE|AFTER privot value
,从左边开始寻找值为privot的第一个元素,然后根据第二个参数是BEFORE还是AFTER决定在该元素的前面还是后面插入value - RPOPLPUSH 将元素从一个列表转义到另一个列表,用法:
RPOPLPUSH source destination
除此之外,还有一些阻塞式命令:
BLPOP
BRPOP
BRPOPLPUSH
编码方式
List的相关操作主要定义在t_list.c中。
列表对象支持两种编码方式:
#define REDIS_ENCODING_LINKEDLIST 4
#define REDIS_ENCODING_ZIPLIST 5
即底层列表可以通过ziplist或LinkedList来实现,两种链表的实现分别在ziplist.c和adlist.c中
命令的具体实现
在上一章中,我们已经知道当有一个客户端请求到来时
- server端会调用readQueryFromClient()来进行处理
- 其中首先会调用processInputBuffer()来解析输入请求,并为每一个参数创建一个字符串对象
- 调用processCommand并最终调用call来执行命令
1、push命令 (lpush、rpush、lpushx、rpushx)
1.1、lpush & rpush
eg:LPUSH key value [value …]
lpush将一个或多个值 value 插入到列表 key 的表头,rpush则是插入到表的尾部
当 key 存在但不是列表类型时,返回一个错误
如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作
在调用 lpush key val1 val2 val3时, redis是从前到后依次将每一个value插入到list的头部的。
即先将val1插入到头部,再将val2插入到头部,最后将val3插入到头部,因此最后val3会在list的头部。
即最终在list中的先后顺序是:
表头—>val3—>val2—>val1—>表尾
1.2、lpushx & rpushx
eg:LPUSHX key value
lpushx将v