redis 学习笔记二 (简单动态字符串)
2014-10-30 19:37
148 查看
redis的基本数据结构是动态数组
一、[b]c语言动态数组[/b]
先看下一般的动态数组结构
这是个广泛使用的常见技巧,常用来构成缓冲区。比起指针,用空数组有这样的优势:
这个数组不占用任何内存,意味着这样的结构节省空间;
该数组的内存地址就和他后面的元素的地址相同,意味着无需初始化,数组名就是后面元素的地址,直接就能当做指针使用。
这样的写法最适合制作动态buffer。因为可以这样分配空间:
malloc(sizeof(struct XXX)+ buff_len);
看出来好处没有?直接就把buffer的结构体和缓冲区一块分配了。用起来也非常方便,因为现在空数组其实变成了buff_len长度的数组了。
这样的好处是:
一次分配解决问题,省了不少麻烦。大家知道为了防止内存泄漏,如果是分两次分配(结构体和缓冲区),那么要是第二次malloc失败了,必须回滚释放第一个分配的结构体。这样带来了编码麻烦。
其次,分配了第二个缓冲区以后,如果结构里面用的是指针,还要为这个指针赋值。同样,在free这个buffer的时候,用指针也要两次free。如果用空数组,所有问题一次解决。
其次,大家知道小内存的管理是非常困难的,如果用指针,这个buffer的struct部分就是小内存了,在系统内存在多了势必严重影响内存管理的性能。要是用空数组把struct和实际数据缓冲区一次分配大块问题,就没有这个问题。
如此看来,用空数组既简化编码,又解决了小内存碎片问题提高了性能,何乐不为?应该广泛采用。
二、[b]Redis数据类型定义[/b]
sds(Simple Dynamic Strings)是 Redis中最基本的底层数据结构, 它既是 Redis 的 String 类型的底层实现, 也是实现 Hash 、 List 和 Set 等复合类型的基石。
除此之外,sds 还是 Redis 内部实现所使用的字符串类型,
sds.c中有很多函数对sdshdr结构体的处理,这里就不多说明了,具体看代码
但是其中sds有空间预分配策略和惰性空间释放 两个优化策略
1)空间预分配策略
主要是针对分配空间时,预留一部分空间。小于1Mz那么程序分配和预留空间同样大小。
2)惰性空间释放
主要针对截断字符串时候,并不释放空间,而是把截断的位置赋值为'\0'
这里可以看看《Redis设计与实现》 里面有对源码分析,看源码配合着书一起看 还是很容易理解的
一、[b]c语言动态数组[/b]
先看下一般的动态数组结构
struct MyData { int nLen; char data[0]; };
这是个广泛使用的常见技巧,常用来构成缓冲区。比起指针,用空数组有这样的优势:
1.不需要初始化,数组名直接就是所在的偏移
2.不占任何空间,指针需要占用
int
长度空间,空数组不占任何空间。
这个数组不占用任何内存,意味着这样的结构节省空间;
该数组的内存地址就和他后面的元素的地址相同,意味着无需初始化,数组名就是后面元素的地址,直接就能当做指针使用。
这样的写法最适合制作动态buffer。因为可以这样分配空间:
malloc(sizeof(struct XXX)+ buff_len);
看出来好处没有?直接就把buffer的结构体和缓冲区一块分配了。用起来也非常方便,因为现在空数组其实变成了buff_len长度的数组了。
这样的好处是:
一次分配解决问题,省了不少麻烦。大家知道为了防止内存泄漏,如果是分两次分配(结构体和缓冲区),那么要是第二次malloc失败了,必须回滚释放第一个分配的结构体。这样带来了编码麻烦。
其次,分配了第二个缓冲区以后,如果结构里面用的是指针,还要为这个指针赋值。同样,在free这个buffer的时候,用指针也要两次free。如果用空数组,所有问题一次解决。
其次,大家知道小内存的管理是非常困难的,如果用指针,这个buffer的struct部分就是小内存了,在系统内存在多了势必严重影响内存管理的性能。要是用空数组把struct和实际数据缓冲区一次分配大块问题,就没有这个问题。
如此看来,用空数组既简化编码,又解决了小内存碎片问题提高了性能,何乐不为?应该广泛采用。
二、[b]Redis数据类型定义[/b]
sds(Simple Dynamic Strings)是 Redis中最基本的底层数据结构, 它既是 Redis 的 String 类型的底层实现, 也是实现 Hash 、 List 和 Set 等复合类型的基石。
除此之外,sds 还是 Redis 内部实现所使用的字符串类型,
//与 sds 实现有关的数据类型有两个,一个是 sds : // 字符串类型的别名 typedef char *sds; //另一个是 sdshdr : // 持有 sds 的结构 struct sdshdr { int len; // buf 中已被使用的字符串空间数量 int free; // buf 中预留字符串空间数量 char buf[]; // 实际储存字符串的地方 };
sds.c中有很多函数对sdshdr结构体的处理,这里就不多说明了,具体看代码
但是其中sds有空间预分配策略和惰性空间释放 两个优化策略
1)空间预分配策略
主要是针对分配空间时,预留一部分空间。小于1Mz那么程序分配和预留空间同样大小。
2)惰性空间释放
主要针对截断字符串时候,并不释放空间,而是把截断的位置赋值为'\0'
这里可以看看《Redis设计与实现》 里面有对源码分析,看源码配合着书一起看 还是很容易理解的
相关文章推荐
- redis学习笔记二(简单动态字符串)
- redis 学习笔记二 (简单动态字符串)
- (一)redis源码学习之简单动态字符串(SDS)
- 学习笔记-Redis设计与实现-简单动态对象(simple dynamic string, SDS)
- 结合redis设计与实现的redis源码学习-2-SDS(简单动态字符串)
- redis 笔记01 简单动态字符串、链表、字典、跳跃表、整数集合、压缩列表
- Redis源码学习——简单动态字符串SDS(Simple Dynamic String)
- Redis源码阅读笔记(1)——简单动态字符串sds实现原理
- Redis源码分析(五)——简单动态字符串(sds)
- javascript学习笔记—简单的动态选择收件人/联系人
- Redis中的简单动态字符串
- redis源码分析笔记2- redis的数据类型-动态字符串sds
- Redis的简单动态字符串——Simple Dynamic String
- Redis数据结构(一)简单动态字符串
- Redis源码学习之【动态字符串】
- PHP 学习笔记 - - - 简单方法的使用 (字符串与数字)
- Redis学习笔记---字符串类型
- Redis内部数据结构详解之简单动态字符串(sds)
- Redis源码学习之【动态字符串】
- redis数据结构-简单动态字符串(sds)