Redis对象--List类型

98 阅读2分钟

List的编码方式?

List说明

List是双端队列,首部和尾部都可以进入和输出

List常见操作

  • 左右添加元素,返回总元素个数:lpush、rpush
  • 左右移出并返回第一个元素:lpop、rpop

  • 删除list中等于某个value的key,返回个数:lrem

     lrem testList1 0 abcd//0表示删除所有,大于0表示从左往右,小于0表示1从右往左
    
  • 同步删除 del key、异步删除unlike key
  • 返回值 lrange key start stop
  • 返回长度 len key

编码方式

object字段结构体主要有type、encoding、ptr(指向ziplist、linkedlist、quicklist)、refcount(引用指针)

ZIPLIST结构体包含的字段:ZBYTES(总长度)、ZTAIL(尾巴节点) ZLEN(数据节点个数)、 ENTRY1(数据节点1)、 ENTRY2(数据节点2) 、ENTRY3(数据节点3)、ZLEND(结束标志)

ZIPLIST中的ENTRY结构体包括:PRELEN[上一个节点长度,如果上一个节点小于等于254就是1B,如果大于255就是5B{1B标识、4B存储大小}]、ENCODING[编码方式(String,int之类的),包含正向遍历的长度信息]、ENTRY-DATA(数据节点)

当OBJECT的TYPE为LIST时,当长度大于64B或者512个时,变成LINKEDLIST

ZIPLIST有什么优势?

相比于LINKEDLIST,ZIPLIST数据节点存储更加紧凑,更加节约内存,方便一次性分配空间,遍历时空间局部性好

ZIPLIST是如何从前往后和从后往前遍历的?

ZIPLIST从前往后遍历可以根据ENTRY-DATA中的ENCODING中的当前节点长度来从前往后遍历,ZIPLIST从后往前可以根据ZTAIL,ENTRY-DATA中的PRELEN来从后往前遍历。

ZIPLIST查询节点个数时间?

ZIPLIST中有ZLEN字段,可以直接查询节点个数,但这个节点只有2B

ZIPLIST插入时间复杂度是多少?

数组O(N)

ZIPLIST连续更新有什么问题?

ZIPLIST结构体字段的ENTRY-DATA中记录了PRELEN,这里PRELEN如果小于254 就占1B 否则占5B ,所以一旦一个节点长度发生变化,就会一系列地都发生变化

如何解决ZIPLIST连锁更新的问题?

使用LISTPACK结构替代ENTRY-DATA结构体,LISTPACK结构体包含ENCODING-TYPE ,ELEMENT-DATA,ELEMENT-TOT-LEN(整个节点除它自身长度之外的长度,每1B 第一位0结束,1继续)

关键是ELEMENT-TOT-LEN,从后往前找到每个字节第一个为0的字节,计算前面这个节点的长度。