Redis中的字符串是可以修改的字符串,在内存中它是以字节数组的形式存在的。我们知道C语言里面的字符串标准形式是以NULL(即0x\0)作为结束符,但是在Redis里面,字符串不是这么表示的。因为要获取以NULL结尾的字符串的长度使用的是strlen标准库函数,这个函数的算法复杂度是O(n),它需要对字节数组进行遍历扫描,作为单线程的Redis表示承受不起。
Redis的字符串叫做"SDS",也就是simple dynamic string(简单动态字符串)。它的结构是一个带长度信息的字节数组。
Struct SDS<T> {
T capacity; //数组容量
T len; //数组长度
byte flags; //特殊标志位,不用理睬
byte[] content; //数组内容
}
如代码所示,content里面存储了真正的字符串内容,那么其中的capacity和len表示什么意思呢?
其有点儿类似于java语言中的ArrayList结构,需要比实际的内容长度多分配一些冗余空间。capacity表示所分配数组的长度,len表示字符串的实际长度。字符串是可以修改的动态字符串,它要支持append操作。如果数组没有冗余空间,那么追加操作必然涉及分配新数组,然后将旧内容复制过来,再append新内容,如果字符串的长度非常长,内存的分配和复制开销就会非常大。
上面的SDS结构使用了泛型T.为什么不直接用Int呢?因为当字符串比较短时,len和capacity可以使用byte和short来表示,Redis为了对内存做极致的优化,不同长度的字符串使用不同的结构体来表示。