美文网首页Redis源码学习笔记
Redis源码学习基本数据结构之动态字符串sds

Redis源码学习基本数据结构之动态字符串sds

作者: lixin_karl | 来源:发表于2019-04-02 17:04 被阅读0次
一、sds是什么

字符串是Redis中最为常见的数据存储类型,其底层实现是简单动态字符串sds(simple dynamic string),是可以修改的字符串。它的内存管理模式类似于c++中的vector,它采用预分配冗余空间的方式来减少内存的频繁分配。关联源码sds.c/sds.h

typedef char *sds 

sds实际上就是一个char指针。它来自于跟它相关的结构体的一部分,其中一共有5个结构体相关根据以下5个值判断属于哪个结构体

#define SDS_TYPE_5  0
#define SDS_TYPE_8  1
#define SDS_TYPE_16 2
#define SDS_TYPE_32 3
#define SDS_TYPE_64 4

其中,SDS_TYPE_5 目前没有用,会用SDS_TYPE_8来代替。它是根据数据的长度来决定使用什么结构体的,对于SDS_TYPE_8 对应的结构体为

struct sdshdr8{
    uint8_t len; /*使用了多少 即数据长度 类似vector size()*/
    uint8_t alloc; /* 申请了多少内存 类似于vector capacity()*/
    unsigned char flags; /* 具体的sdshdr类型 可以节省内存*/
    char buf[];/* 实际数据也是sds开始的地址 */
}

二、sds特点

  • SDS是在C字符串的基础上进行了一些包装,使得它更符合Redis的使用场景。sds获取长度的时间复杂度为O(1)。
  • 减少修改字符串时内存重分配的次数,其内存增加模式类似与c++的vector每次增长两倍但是每次最多增长1024*1024字节。
  • SDS对于存储的数据没有任何限制,二进制安全。 普通的c字符串与到'\0'则结束。所以sds是可以存储任意类型的数据的。
    三 sds.h/sds.c源码
sds sdsnewlen(const void *init, size_t initlen);//申请内存申请内存的长度为(对应结构体的长度+1+initlen) 最后一个字节会赋值'\0',这点可以保证对普通字符串的兼容
sds sdsnew(const char *init);//根据一个普通字符串在创建sds
sds sdsempty(void);//创建一个空的sds
sds sdsdup(const sds s);//复制一个sds 重新申请内存

void sdsfree(sds s);//释放申请出来的内存

sds sdsgrowzero(sds s, size_t len);//sds动态空间增加到特定的长度,最多申请SDS_MAX_PREALLOC
sds sdscatlen(sds s, const void *t, size_t len);//字符串拼接
sds sdscat(sds s, const char *t);//字符串拼接
sds sdscatsds(sds s, const sds t);//sds拼接
sds sdscpylen(sds s, const char *t, size_t len);//sds复制
sds sdscpy(sds s, const char *t);//sds复制
sds sdscatvprintf(sds s, const char *fmt, va_list ap);//字符串拼接
sds sdscatfmt(sds s, char const *fmt, ...);//字符串拼接

sds sdstrim(sds s, const char *cset);//移除s中是 cset中的字符

void sdsrange(sds s, ssize_t start, ssize_t end);//sds子字符串

void sdsupdatelen(sds s);//字符串实际长度

void sdsclear(sds s);//字符串清理,相关数据赋值为0

int sdscmp(const sds s1, const sds s2);//字符串比较
sds *sdssplitlen(const char *s, ssize_t len, const char *sep, int seplen, int *count);//s中以sep为分隔标志,返回分隔后的sds数组

void sdsfreesplitres(sds *tokens, int count);//将分隔出来的字符串数组释放掉内存

void sdstolower(sds s);//都变成小写字符
void sdstoupper(sds s);//都变成大写字符

sds sdsfromlonglong(long long value);//longlong变成sds

sds sdscatrepr(sds s, const char *p, size_t len);//一些特殊字符的拼接
sds *sdssplitargs(const char *line, int *argc);//将line分割argc个sds数组

sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);//把sds中出现在from中的字符替换为to中的对应位置的字符
sds sdsjoin(char **argv, int argc, char *sep);//字符串连接
sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);//字符串连接

/* 底层用户调用api */
sds sdsMakeRoomFor(sds s, size_t addlen);//重新申请内存
void sdsIncrLen(sds s, ssize_t incr);
sds sdsRemoveFreeSpace(sds s);//移除冗余的空间,增加内存的效率
size_t sdsAllocSize(sds s);//返回总的申请的内存
void *sdsAllocPtr(sds s);//返回最初申请的一段内存的起始位置


void *sds_malloc(size_t size);///申请内存
void *sds_realloc(void *ptr, size_t size);//重新申请内存
void sds_free(void *ptr);//释放内存

相关文章

  • redis基本数据结构

    redis 基本数据结构. redis的基本数据结构主要有: SDS动态字符串,链表,字典,哈希表,跳跃表,整数集...

  • redis

    redis Redis 数据结构和底层实现string:简单动态字符串SDS,Redis 的字符串是动态字符串,是...

  • Redis 数据结构之SDS

    Redis 数据结构之SDS 简单动态字符串 为了实现对于字符串的高效操作,Redis 自己构建的一种名为简单动态...

  • 深挖 Redis 6.0 源码—SDS

    SDS(Simple Dynamic Strings, 简单动态字符串)是 Redis 的一种基本数据结构,主要是...

  • 聊一聊Redis之数据结构

    基本数据结构 简单动态字符串 Redis中的字符串使用“简单动态字符串”(SDS)表示,无论是字符串值还是键底层都...

  • Redis底层数据结构

    Redis底层数据结构类型 简单动态字符串(simple dynamic string)SDS Redis 没有直...

  • redis数据结构--SDS

    redis底层存储字符串的数据结构叫做简单动态字符串(simple dynamic string)。 SDS定义 ...

  • Redis源码

    一、Redis数据结构: SDS SDS(动态字符串)包含字符数组buf[],字符数组现有长度len,字符数组分配...

  • Redis字符串与C字符串区别

    一、数据结构 redis的字符串底层数据结构是sds(simple dynamic string),即简单动态字符...

  • redis数据结构

    redis数据结构列表:简单动态字符串(sds)链表(list)字典(dict)跳跃表(skiplist)整数集合...

网友评论

    本文标题:Redis源码学习基本数据结构之动态字符串sds

    本文链接:https://www.haomeiwen.com/subject/eguwbqtx.html