zoukankan      html  css  js  c++  java
  • redis_简单动态字符串

    在redis中,C字符串(以''结尾的字符数组)只用在一些无需对字符串值进行修改的地方,比如打印日志。其他情况,redis使用SDS - SimpleDynamicString 简单动态字符串,来做。

    比如

    127.0.0.1:6379> set testKey "testValue"
    OK

    键,是一个字符串对象,底层是一个保存着字符串"testKey"的SDS

    值也是一个字符串对象,底层是一个保存着字符串"testValue"的SDS

    SDS 定义

    struct sdshdr {
        // 记录buf数组中已使用的字节数,等同于字符串长度(不包括结尾的)
        int len;
        // 记录buf数组中未使用的字节数
        int free;
        // 实际保存字符串的字节数组
        char buf[];
    }

    比如一个字符串"test":

      len = 4

      free = 0(这个不一定,初始时为0,后续说明)

      buf[] = 't'、'e'、's'、't'、'',注意结尾与C相同,也存在'',不记入字符串长度

    这样做的优势

    1. 常数复杂度获取字符串长度

    1. C字符串不记录长度,只能遍历,到得到长度,时间复杂度O(n),SDS可以直接记录len为长度,时间复杂度O(1)

    2. 兼容部分C字符串的函数

    • 都遵循C字符串以结尾的方式,可以重用一部分C字符串函数库的方法

    3. 减少修改字符串时带来的内存重分配次数

    • 通过每次增长或减短字符串时,设置free,使字符串预留出一部分空间,而不是每次都精确到字符串的长度。在频繁修改字符串的环境中可以减少内存重新分配的操作
    • 具体涉及到两种情况:变长、变短。
    • 变长:空间预分配
      • 如果修改后的字符串长度小于 1MB,则程序分配大小和len相同的未使用空间给free
        • 比如"test"修改为"testAgain",则len=9、free=9、buf[] 数组大小为 9+9+1()=19字节
      • 如果修改后的字符串长度大于等于 1MB,则程序分配固定的 1MB给free
        • 比如一个0.7MB的字符串扩成了7MB,则len=7MB、free=1MB、buf[] 数组大小为 9MB + 9MB + 1B
      • 如果修改后的字符串长度能被len+free放下,则此次修改字符串就不需要重新分配空间了
    • 变短:惰性空间释放
      • 变短后的字符串,变短的长度被保存在free中,未来如果有变长操作,则可以直接使用。
        • 比如"test"修改为"t",则len=1、free=3、buf[] 数组大小为 1+3+1=5字节,与变短之前的4+0+1相同

    同时SDS提供实时释放未使用空间的api

    其他特点

    SDS的api都是二进制安全的,所有SDS的api都会用处理二进制的方式处理buf[]中的数据,不会特殊处理。

    比如一个字符串内容为"testandmore",其内容不会因为有而被截断

    micheal.li > 阿智
    micheal.li > mikeve@163.com
  • 相关阅读:
    How to using X++ code achieve copying records
    How to using x++ code achieve Lookup files list with entire folder
    Using X++ code create and Read XML file.
    Using X++ Code Create master table form
    When you are finished renamed the Item number Jobs
    Visual Studio.NET 简介
    Visual C++中的异常处理浅析
    最常见的20种VC++编译错误信息
    开发WDM型的USB设备驱动程序
    C++中内存管理
  • 原文地址:https://www.cnblogs.com/loveCheery/p/9133343.html
Copyright © 2011-2022 走看看