zoukankan      html  css  js  c++  java
  • Redis设计与实现(一)简单动态字符串

    Redis没有使用C中自带的String,而是自己构建了一个字符串类,名为Simple Dynamic String。缩写为SDS,下文的SDS就是指此玩意。SDS是redis中默认的字符串使用。而Redis是基于C实现的,C内部的自带的String被它作用于log的记录。也就是一个简单的字符串字面量。当Redis在数据库中新建一个对象的时候(set  msg "nb"),KV中的Key是一个SDS,而Value则是Redis自身实现的SDS对象。当redis中使用RPUSH msg "1" "2"这种情况下 key依然是一个SDS,但是value则为一个列表对象,列表里面存储着2个SDS。

    除了用来保存里面的字符串值对象,SDS也会被用来做缓存区,例如AOF中的缓存区,客户端状态中的输入缓冲区。

    那么SDS是什么呢?我们写代码的人应该能感知出来,这个玩意应该就是对基础数据的封装,然后加入了自己需要的特性。

    源码中SDS是一个对象,里面有三个成员变量,int len用来记录已经使用的长度。也就是字符串的长度,int free表示数组中还剩余的空间。char [] buf表示容器用来存储字符串。

     还是很好理解的吧,SDS遵守了C中以空字符结尾的特点,所以最后一位并没有被算入长度中。所以输出的时候完成可以使用c中自带的print来进行。printf("%s",s->buf)。

    自己使用SDS的好处也很明显,就是利用了哨兵的思想,这样的话知道一个字符串的长度的时间复杂度就可以从O(N)直接变成O(1)。

    另外一个好处就是,不会造成缓存的溢出,这一点Java程序员可能感受不到,理解就是一个操作在执行的时候,因为C是用空字符里进行切割的,例如5+5的字符串组合,如何5变成了6的长度,那么就会溢出到下一个字符串,造成了污染。而SDS存储了长度,就会在每一次修改的时候,进行时候的check。保证这种情况不会出现。

    最后一个特点就是使用SDS可以防止空间的重复操作,什么意思,就是字符串变大变小都需要在C里面对空间进行释放。而SDS这种情况就可以通过"空间预分配",通俗点就是每次多给一点空间,"惰性空间分配",在给字符串锁缩短的时候也会保留多出的空间。这样的话就不需要进行重复的数组重分配了。

    SDS同时可以保存C中字符串无法保存的一些数据,因为C中的字符串是不可以有空的,不然会被认为是结尾,这样的话很多的图片什么的都无法进行保存了,但是SDS是通过长度来进行判断的,所有可以保证的一点就是你存入的数据我都会完整的给你。

    至于为什么SDS也是空结尾,这是为了也可以对C中的String做到一点的重用,也可以使用C中的部分函数。

    smartcat.994
  • 相关阅读:
    UVA 10617 Again Palindrome
    UVA 10154 Weights and Measures
    UVA 10201 Adventures in Moving Part IV
    UVA 10313 Pay the Price
    UVA 10271 Chopsticks
    Restore DB後設置指引 for maximo
    每行SQL語句加go換行
    种服务器角色所拥有的权限
    Framework X support IPV6?
    模擬DeadLock
  • 原文地址:https://www.cnblogs.com/SmartCat994/p/14139015.html
Copyright © 2011-2022 走看看