ZipList:压缩列表,为了节省内存而设计的一种数据结构
ZipList是一种特殊的双端链表,是由一系列的特殊编码的连续内存块组成,不需要通过指针来进行寻址来找到各个节点,可以在任意一端进行压入或者是弹出操作,并且该操作的时间复杂度是O(1);
dict底层是依靠依靠哈希表来实现的,虽然查询性能比较高,但是一个指针要占用8个字节,大量使用指针寻址(因为内存不连续,要通过指针寻址)会浪费内存,况且这种链式存储方式极其容易产生内存碎片;
因为在压缩列表中,存放不同的数据所占用的内存是不一样的Entry值越大,占用字节数越大
在ZipList中,Entry并不像普通链表一样进行记录前后点的指针,因为每记录两个指针要占用16个字节,浪费内存,而是使用了下面的结构
1)previous_entry_length:前一个结点的长度,占用1个字节或者是5个字节
1.1)如果前一个结点的长度小于254个字节,那么就采用1个字节来保存这个长度值;
1.2)如果前一个结点的长度大于254个字节,那么就采用5个字节来保存这个长度的值,第一个字节是OXFE,后四个字节才是真实的长度数据;
2)encoding:编码属性,记录content的数据类型字符串还是整数以及长度,Encoding本身的长度占用1个,2个或者是5个字节,况且只是存在这两个值;
ZipListEntry中的encoding编码分为字符串和整数两种
1)字符串:如果Encoding是以00或者01或者是10来进行开头的那么证明content是字符串类型下面的p和q是用来记录字符串的长度的;
假设现在要保存"ab"和"bc"这两个字符串
第一部分是表示前一个字符串的长度,第二部分是表示采用00编码,并且所存储的字符串长度是4,第三部分是实际存储的字符串的ASCIL值;
整个压缩列表的结构:
2)整数:如果encoding是以11开头,那么就证明content是整数,况且encoding固定只是使用1个字节,来记录四种字节数