1 Redis 是C语言实现的

2 C字符串是 /0 结束的字符数组

3 Redis具体的动态字符串实现

  1. /*
  2. * 保存字符串对象的结构
  3. */
  4. struct sdshdr {
  5.  
  6. // buf 中已占用空间的长度 使求字符串长度操作变成0(1)
  7. int len;
  8.  
  9. // buf 中剩余可用空间的长度 对字符串字符增加修改时 不大于len+free不用重新分配内存(初始化一个字符串时free为0 当修改字符串时会对free进行赋值)
  10. int free;
  11.  
  12. // 数据空间
  13. char buf[];
  14. };
sdshdr
free 5
len 5
buf

--->

'R' 'e' 'd' 'i' 's' '/0'          

4 感觉更像 Java 中的 StringBuffer 的设计

5 源码初始化一个字符串

  1. /*
  2. * 根据给定的初始化字符串 init 和字符串长度 initlen
  3. * 创建一个新的 sds
  4. *
  5. * 参数
  6. * init :初始化字符串指针
  7. * initlen :初始化字符串的长度
  8. *
  9. * 返回值
  10. * sds :创建成功返回 sdshdr 相对应的 sds
  11. * 创建失败返回 NULL
  12. *
  13. * 复杂度
  14. * T = O(N)
  15. */
  16. /* Create a new sds string with the content specified by the 'init' pointer
  17. * and 'initlen'.
  18. * If NULL is used for 'init' the string is initialized with zero bytes.
  19. *
  20. * The string is always null-termined (all the sds strings are, always) so
  21. * even if you create an sds string with:
  22. *
  23. * mystring = sdsnewlen("abc",3");
  24. *
  25. * You can print the string with printf() as there is an implicit \0 at the
  26. * end of the string. However the string is binary safe and can contain
  27. * \0 characters in the middle, as the length is stored in the sds header. */
  28. sds sdsnewlen(const void *init, size_t initlen) {
  29.  
  30. struct sdshdr *sh;
  31.  
  32. // 根据是否有初始化内容,选择适当的内存分配方式
  33. // T = O(N)
  34. if (init) {
  35. // zmalloc 不初始化所分配的内存
  36. sh = zmalloc(sizeof(struct sdshdr)+initlen+);
  37. } else {
  38. // zcalloc 将分配的内存全部初始化为 0
  39. sh = zcalloc(sizeof(struct sdshdr)+initlen+);
  40. }
  41.  
  42. // 内存分配失败,返回
  43. if (sh == NULL) return NULL;
  44.  
  45. // 设置初始化长度
  46. sh->len = initlen;
  47. // 新 sds 不预留任何空间
  48. sh->free = ;
  49. // 如果有指定初始化内容,将它们复制到 sdshdr 的 buf 中
  50. // T = O(N)
  51. if (initlen && init)
  52. memcpy(sh->buf, init, initlen);
  53. // 以 \0 结尾
  54. sh->buf[initlen] = '\0';
  55.  
  56. // 返回 buf 部分,而不是整个 sdshdr
  57. return (char*)sh->buf;
  58. }

6 修改字符串之前对free操作

  1. /*
  2. * 在不释放 SDS 的字符串空间的情况下,
  3. * 重置 SDS 所保存的字符串为空字符串。
  4. *
  5. * 复杂度
  6. * T = O(1)
  7. */
  8. /* Modify an sds string on-place to make it empty (zero length).
  9. * However all the existing buffer is not discarded but set as free space
  10. * so that next append operations will not require allocations up to the
  11. * number of bytes previously available. */
  12. void sdsclear(sds s) {
  13.  
  14. // 取出 sdshdr
  15. struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
  16.  
  17. // 重新计算属性
  18. sh->free += sh->len;
  19. sh->len = ;
  20.  
  21. // 将结束符放到最前面(相当于惰性地删除 buf 中的内容)
  22. sh->buf[] = '\0';
  23. }
  24.  
  25. /* Enlarge the free space at the end of the sds string so that the caller
  26. * is sure that after calling this function can overwrite up to addlen
  27. * bytes after the end of the string, plus one more byte for nul term.
  28. *
  29. * Note: this does not change the *length* of the sds string as returned
  30. * by sdslen(), but only the free buffer space we have. */
  31. /*
  32. * 对 sds 中 buf 的长度进行扩展,确保在函数执行之后,
  33. * buf 至少会有 addlen + 1 长度的空余空间
  34. * (额外的 1 字节是为 \0 准备的)
  35. *
  36. * 返回值
  37. * sds :扩展成功返回扩展后的 sds
  38. * 扩展失败返回 NULL
  39. *
  40. * 复杂度
  41. * T = O(N)
  42. */
  43. sds sdsMakeRoomFor(sds s, size_t addlen) {
  44.  
  45. struct sdshdr *sh, *newsh;
  46.  
  47. // 获取 s 目前的空余空间长度
  48. size_t free = sdsavail(s);
  49.  
  50. size_t len, newlen;
  51.  
  52. // s 目前的空余空间已经足够,无须再进行扩展,直接返回
  53. if (free >= addlen) return s;
  54.  
  55. // 获取 s 目前已占用空间的长度
  56. len = sdslen(s);
  57. sh = (void*) (s-(sizeof(struct sdshdr)));
  58.  
  59. // s 最少需要的长度
  60. newlen = (len+addlen);
  61.  
  62. // 根据新长度,为 s 分配新空间所需的大小
  63. if (newlen < SDS_MAX_PREALLOC)
  64. // 如果新长度小于 SDS_MAX_PREALLOC
  65. // 那么为它分配两倍于所需长度的空间
  66. newlen *= ;
  67. else
  68. // 否则,分配长度为目前长度加上 SDS_MAX_PREALLOC
  69. newlen += SDS_MAX_PREALLOC;
  70. // T = O(N)
  71. newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+);
  72.  
  73. // 内存不足,分配失败,返回
  74. if (newsh == NULL) return NULL;
  75.  
  76. // 更新 sds 的空余长度
  77. newsh->free = newlen - len;
  78.  
  79. // 返回 sds
  80. return newsh->buf;
  81. }

Redis 设计与实现读书笔记一 Redis字符串的更多相关文章

  1. Redis设计与实现读书笔记——简单动态字符串

    前言 项目里用到了redis数据结构,不想只是简单的调用api,这里对我的读书笔记做一下记录.原文地址: http://www.redisbook.com/en/latest/internal-dat ...

  2. Redis 设计与实现读书笔记一 Redis List

    list结构体 adlist.h/list(源码位置) /* * 双端链表结构 */ typedef struct list { // 表头节点 listNode *head; // 表尾节点 lis ...

  3. Redis设计与实现读书笔记(二) 链表

    链表作为最基础的数据结构,在许多高级语言上已经有了很好的实现.由于redis采用C语言编写,需要自己实现链表,于是redis在adlist.h定义了链表类型.作者对于这部分没什么好说,源码比较简单,如 ...

  4. Redis设计与实现读书笔记(一) SDS

    作为redis最基础的底层数据结构之一,SDS提供了许多C风格字符串所不具备的功能,为之后redis内存管理提供了许多方便.它们分别是: 二进制安全 减少字符串长度获取时间复杂度 杜绝字符串溢出 减少 ...

  5. <<redis设计和实现>>读书笔记

    redis如何实现主从同步的高效率?? 主从复制的同步有一个命令数据的同步文本,然后利用两个不同服务器的偏移量来进行进行同步,避免每次都是全部同步(并非会保存所有的命令数据,而是会有一个缓冲区(比如1 ...

  6. Redis设计与实现读书笔记——双链表

    前言 首先,贴一下参考链接: http://www.redisbook.com/en/latest/internal-datastruct/adlist.html, 另外真赞文章的作者,一个90后的小 ...

  7. Linux内核设计与实现 读书笔记 转

    Linux内核设计与实现  读书笔记: http://www.cnblogs.com/wang_yb/tag/linux-kernel/ <深入理解LINUX内存管理> http://bl ...

  8. 【2018.08.13 C与C++基础】C++语言的设计与演化读书笔记

    先占坑 老实说看这本书的时候,有很多地方都很迷糊,但却说不清楚问题到底在哪里,只能和Effective C++联系起来,更深层次的东西就想不到了. 链接: https://blog.csdn.net/ ...

  9. 【读书笔记】Redis入门

    1:Redis概览 Remote Dictionary Server 远程字典服务 Redis是基于内存的存储 在一台普通的笔记本上,Redis每秒的读取速度可以达到10万 内存读取数据,断电的时候数 ...

随机推荐

  1. jar转dll

    IKVM http://www.cnblogs.com/luckeryin/archive/2012/03/28/2421274.html

  2. Steam和Byte[]之间进行输换

    一. 二进制转换成图片 MemoryStream ms = new MemoryStream(bytes); ms.Position = 0; Image img = Image.FromStream ...

  3. JDE910笔记2--OMW项目建立及简单使用[转]

    1.打开JDE的OBJECT MANAGEMENT WORKBENCH.在工作区中选择ADD,建立项目并选择OMW PROJECT,添加相关信息,如下图所示 其中,ProjectID可以对应不同的数据 ...

  4. LoadRunner 文本检查点使用

    在测试时,我们可以根据文本检查点判断事务是否执行正确.   我们在启动流程时,成功返回:   我们检查这个响应结果是否有. int i=0; i=web_reg_find("Text=\&q ...

  5. HTTP 错误 500.22 - Internal Server Error 检测到在集成的托管管道模式下不适用的 ASP.NET 设置

    答案:在将WebDataHelper升级到VS2013是出现的这个错误,这个程序使用了URL重写的技术, 解决方法是:需要将重写的配置,迁移到system.webServer配置节中

  6. C#入门篇6-9:字符串操作 不值一提的函数【不看也行】

    // 判断输入的是否全是数字:返回结果:true:全是数字:false:有字幕出现 public static bool Isaccord1(string str) { bool bl = true; ...

  7. 在ASP.NET MVC中使用CKEditor和CkFinder

    在你需要使用editor控件的页面头部添加: <head> ... <script type="text/javascript" src="/ckedi ...

  8. 构建之法<第四章>之感悟

    第四章:两人合作内容出处:4.6 两人合作的不同阶段和技巧 本章主要是讲关于合作方面的,文章以刚刚认识的两个人为例!也就是说,他们之前的关系是陌生人,然而在现实当中两人合作也可以有其它的关系,比如说合 ...

  9. Oracle 过程控制语句整理

    分支语句/循环语句 v_case ) :; begin then dbms_output.put_line('条件成立'); elsif then then dbms_output.put_line( ...

  10. QQ2013登录报文简单分析(不可用于非法用途)

    [NO.1 2013-05-08 00:31:16 046 SEND 115字节]02 31 03 08 25 27 B5 88 6F 91 D2 03 00 00 00 0101 01 00 00 ...