zoukankan      html  css  js  c++  java
  • Redis设计与实现(六)压缩列表

    压缩列表是列表键和哈希键的底层实现之一,当一个列表键只包含少量的列表项,而且每个列表项都是小整数值或者长度比较小的字符串。那么就会使用压缩列表来进行列表键的底层实现。很明显在C的天下里面,int都要分位数,开发的人肯定是个极致思想的老铁。变态的压缩思想都来了,很多时候我们也在尽可能的去调整代码的深度,调前退出循环什么的,为什么Java里面好像不咋说压缩这回事。这个和java的设计有关系。很简单的说就是C站在了巨人的裤腰带上,java站在了巨人的肩膀上。所以导致java看不及下面的空间。

    压缩列表是为了压缩内存而产生的东西。是由一系列特殊编码的连续内存组成的顺序型数据结构。一个列表包含多个节点。每个节点可以保存一个字节数组或者一个整型。

    在设计的时候也是在数组的头上放点标识位.

    zlbytes:是int32位的数据,用来计算整个压缩列表中占有的内存字节数,对压缩列表进行内存重分配。

    zltail:也是int32位的数据,记录压缩列表尾节点距离压缩列表的起始地址有多少字节。这样就可以直接找到尾部。

    zllen:是16位的数据,记录了压缩列表中真实的数据,这边有个bug,就是它是16位的,那最大值只有65536,如果超过了这个,依然会显示65536.

    entry不限制大小,是一个存放数据的地方。

    zlend标识尾巴0xff

    看到这边我就在思考,怎么进行压缩的,你大小不知道,寻址的方法都变得复杂了,本身int就是纯净的数据,数组只是纯净数据的集合,浪费的最多是空间(int 64 放了一个16的数据)。你现在破坏了整体的规范性,寻址公式可能有不能用了 (y = 10x+30).

    别着急往下看看。

    entry肯定也是一种类(java的叫法)。字节数组有以下三种,长度小于等于63的,小于16838的,小于32个2-1的,三种模式,整数可以有以下六种长度,4位长 0-12之间的,1字节长度的有符号数,4字节长度的有符号,int16的整数,32,64.

    每一个节点都是由previous_entry_length,encoding,content组成。

    previous_entry_length表示:前一个数据的长度,以字节为单位,为1字节和5字节。

     这为什么是后存前一个节点的原因我也不明白,偏爱从后往前遍历吗。这其实蛮有意思的,唯一我感觉能解释的就是zltail这个存了尾巴的偏移量。所有这样会方便一点。

     encoding:记录了节点的content属性所保存数据的类型和长度

     现在应该能感受出为什么叫压缩列表了,其实我个人真正意义上愿意叫他是个混合列表。什么都能存入,另外一个特点就是,大量的哨兵位来打破了固化设计。

    压缩列表有个问题就是:连锁更新,什么是连锁更新,就是一个256插入新的压缩列表,导致后面的253的数据都要更新,进行扩容。像火车一样,每个后面的车厢都需要进行更新了。

    这样的话会进行很操蛋的事情。

     

    smartcat.994
  • 相关阅读:
    Codechef EDGEST 树套树 树状数组 线段树 LCA 卡常
    BZOJ4319 cerc2008 Suffix reconstruction 字符串 SA
    Codechef STMINCUT S-T Mincut (CodeChef May Challenge 2018) kruskal
    Codeforces 316G3 Good Substrings 字符串 SAM
    Codechef CHSIGN Change the Signs(May Challenge 2018) 动态规划
    BZOJ1396 识别子串 字符串 SAM 线段树
    CodeForces 516C Drazil and Park 线段树
    CodeForces 516B Drazil and Tiles 其他
    CodeForces 516A Drazil and Factorial 动态规划
    SPOJ LCS2
  • 原文地址:https://www.cnblogs.com/SmartCat994/p/14144780.html
Copyright © 2011-2022 走看看