• 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
  • 相关阅读:
    Nbimer族助手 部分控件不能用的解决方法(转)
    jquery中通过全局变量来禁止多次ajax请求
    Three.JS 从世界坐标系转换到屏幕坐标系
    php 判断是手机版还是电脑端
    6个html5页面适配iphone6的技巧
    http://stackoverflow.com/questions/6065169/requestanimationframe-with-this-keyword
    javascript模仿php 函数 trim ltrim rtrim (原创)
    JavaScript中Trim(),TrimStart(),TrimEnd()的实现
    如何定位摄像机,使物体在屏幕上始终具有相同的像素宽度和高度?(threes)
    鸿基台式机安装
  • 原文地址:https://www.cnblogs.com/loveCheery/p/9133343.html
Copyright © 2020-2023  润新知