sds(简单动态字符串)是redis底层的字符串表示,它具有字符串对象化和替代char*的作用。数据库中的值类型包括字符串,哈希表,列表,集合和有序集合,但是键类型却总是字符串。
typedef char *sds; struct sdshdr { // buf 已占用长度 int len; // buf 剩余可用长度 int free; // 实际保存字符串数据的地方 char buf[]; };
redis构建了自己的类型系统,所有的键、值、参数都是有类型的,在redis中用redisObject结构表示:
/* * Redis 对象 */ typedef struct redisObject { // 类型 unsigned type:4; // 对齐位 unsigned notused:2; // 编码方式 unsigned encoding:4; // LRU 时间(相对于server.lruclock) unsigned lru:22; // 引用计数 int refcount; // 指向对象的值 void *ptr; } robj;
string类型的每个具体值都由一个redisObject进行描述,它可以表示一个字符串或整数,分别使用REDIS_ENCODING_INT 和REDIS_ENCODING_RAW 两种编码(redis不直接存储数据结构而是通过编码转化成内存映射模型使用)。前者用于保存long类型数据,后者用来保存sds/char*,long long,long double,double类型数据。字符串类型基本上就是通过sds数据结构的操作函数来实现的,这里仅举个简单例子,其它没啥好说的。
/* * 在指定字符串后追加字符串并指明增加的内存空间 */ sds sdscatlen(sds s, const void *t, size_t len) { //申明字符串sh struct sdshdr *sh; //获取参数s的长度 size_t curlen = sdslen(s); //为s新增内存空间 s = sdsMakeRoomFor(s,len); //未分配成功则返回null if (s == NULL) return NULL; //使sh指向重新分配内存后的s的基址 sh = (void*) (s-(sizeof(struct sdshdr))); //将t复制到s的结尾 memcpy(s+curlen, t, len); //设置sh的长度变量和剩余可用长度 sh->len = curlen+len; sh->free = sh->free-len; //末尾添加‘\0’结尾符 s[curlen+len] = '\0'; return s; }
时间: 2024-10-22 14:41:25