Redis-6379-压缩列表-列表键和哈希键的底层实现之一

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38375620/article/details/88951580

压缩列表

压缩列表(ziplist)是列表键和哈希键的底层实现之一。

当一个列表键只包含少量列表项, 并且每个列表项要么就是小整数值, 要么就是长度比较短的字符串, 那么 Redis 就会使用压缩列表来做列表键的底层实现。

当一个哈希键只包含少量键值对, 并且每个键值对的键和值要么就是小整数值, 要么就是长度比较短的字符串, 那么 Redis 就会使用压缩列表来做哈希键的底层实现。

举个例子, 执行以下命令将创建一个压缩列表实现的哈希键:

redis> HMSET profile "name" "Jack" "age" 28 "job" "Programmer" 
OK

因为哈希键里面包含的所有键和值都是小整数值或者短字符串。

HMSET key field value [field value ...]

时间复杂度:O(N) where N is the number of fields being set.

设置 key 指定的哈希集中指定字段的值。该命令将重写所有在哈希集中存在的字段。如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key 关联

返回值

simple-string-reply

例子

redis> HMSET myhash field1 "Hello" field2 "World"
OK
redis> HGET myhash field1
"Hello"
redis> HGET myhash field2
"World"
redis> 

HSET key field value

时间复杂度:O(1)

设置 key 指定的哈希集中指定字段的值。

如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key 关联。

如果字段在哈希集中存在,它将被重写。

返回值

integer-reply:含义如下

  • 1如果field是一个新的字段
  • 0如果field原来在map里面已经存在

例子

redis> HSET myhash field1 "Hello"
(integer) 1
redis> HGET myhash field1
"Hello"
redis> 



压缩列表的构成

压缩列表是 Redis 为了节约内存而开发的, 由一系列特殊编码的连续内存块组成的顺序型(sequential)数据结构。

一个压缩列表可以包含任意多个节点(entry), 每个节点可以保存一个字节数组或者一个整数值。

压缩列表的各个组成部分, 表 7-1 则记录了各个组成部分的类型、长度、以及用途。

digraph {      label = "\n 图 7-1    压缩列表的各个组成部分";      node [shape = record];      ziplist [label = " zlbytes | zltail | zllen | entry1 | entry2 | ... | entryN | zlend "];  }


压缩列表各个组成部分的详细说明

属性 类型 长度 用途
zlbytes uint32_t 4 字节 记录整个压缩列表占用的内存字节数:在对压缩列表进行内存重分配, 或者计算 zlend 的位置时使用。
zltail uint32_t 4 字节 记录压缩列表表尾节点距离压缩列表的起始地址有多少字节: 通过这个偏移量,程序无须遍历整个压缩列表就可以确定表尾节点的地址。
zllen uint16_t 2 字节 记录了压缩列表包含的节点数量: 当这个属性的值小于 UINT16_MAX65535)时, 这个属性的值就是压缩列表包含节点的数量; 当这个值等于 UINT16_MAX 时, 节点的真实数量需要遍历整个压缩列表才能计算得出。
entryX 列表节点 不定 压缩列表包含的各个节点,节点的长度由节点保存的内容决定。
zlend uint8_t 1 字节 特殊值 0xFF (十进制 255 ),用于标记压缩列表的末端。

压缩列表示例:

  • 列表 zlbytes 属性的值为 0xd2 (十进制 210), 表示压缩列表的总长为 210 字节。
  • 列表 zltail 属性的值为 0xb3 (十进制 179), 这表示如果我们有一个指向压缩列表起始地址的指针 p , 那么只要用指针 p 加上偏移量 179 , 就可以计算出表尾节点 entry5 的地址。
  • 列表 zllen 属性的值为 0x5 (十进制 5), 表示压缩列表包含五个节点。

digraph {      label = "\n 图 7-3    包含五个节点的压缩列表";      rankdir = BT;      node [shape = record];      ziplist [label = " <zlbytes> zlbytes \n 0xd2 | zltail \n 0xb3 | zllen \n 0x5 | entry1 | entry2 | entry3 | entry4 | <entry5> entry5 | zlend \n 0xFF "];      node [shape = plaintext];      p [label = "p"];      p -> ziplist:zlbytes;      tail [label = "p + 179"];      tail -> ziplist:entry5;  }

猜你喜欢

转载自blog.csdn.net/qq_38375620/article/details/88951580