redis源码从main开始10中查看了redis的对象类型,本章来看redis的string类型

11 redis对象之string
// 定义redis对象的结构体
#define REDIS_LRU_BITS 24
typedef struct redisObject {
    // 对象类型 有五种
    // #define REDIS_STRING 0
    // #define REDIS_LIST 1
    // #define REDIS_SET 2
    // #define REDIS_ZSET 3
    // #define REDIS_HASH 4
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
    int refcount;
    void *ptr;
} robj;

/*
 * 创建一个新 robj 对象
 */
robj *createObject(int type, void *ptr) {

    robj *o = zmalloc(sizeof(*o));

    o->type = type;
    o->encoding = REDIS_ENCODING_RAW;
    o->ptr = ptr;
    o->refcount = 1;

    /* Set the LRU to the current lruclock (minutes resolution). */
    o->lru = LRU_CLOCK();
    return o;
}


在redis源码从main开始2中我们讲述了initServer()方法,在初始化redis服务器的时候,创建了大量用于回复的字符串对象

// 例如,创建一个redis对象,类型是REDIS_STRING,这便是常见的字符串类型对象
shared.crlf = createObject(REDIS_STRING, sdsnew("\r\n"));
// 在创建字符串对象的时候我们看到了使用了sdsnew("\r\n"),
// sdsnew返回一个sds, sds是redis的动态字符串的实现,下面我们来看看相关实现

//这是redis声明的别名
typedef char *sds;

// 这是redis保存字符串对象的结构
struct sdshdr {
    int len;  // 使用了buf多大空间
    int free; // 剩余buf空间
    char buf[]; // 存放具体数据的空间
};

// 根据给定的初始化字节 创建一个sds
sds sdsnew(const char *init) {
    size_t initlen = (init == NULL) ? 0 : strlen(init);
    return sdsnewlen(init, initlen);
}

// 根据给定内容和长度,创建sds
sds sdsnewlen(const void *init, size_t initlen) {
    struct sdshdr *sh;
    if (init) {
        // zmalloc 不初始化所分配的内存
        sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
    } else {
        // zcalloc 将分配的内存全部初始化为 0
        sh = zcalloc(sizeof(struct sdshdr)+initlen+1);
    }

    // 分配失败
    if (sh == NULL) return NULL;

    // 已使用长度
    sh->len = initlen;
    // 没有剩余空间
    sh->free = 0;

    // 有初始化的内容
    if (initlen && init)
        memcpy(sh->buf, init, initlen);
    // 以 \0 结尾
    sh->buf[initlen] = '\0';
    // 返回buf部分
    return (char*)sh->buf;
}

// 可以通过sds取到整个结构体
struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));

基于版本3.0.0版本,点击下载https://download.redis.io/releases/redis-3.0.0.tar.gz

本文地址,https://www.ccagml.com/?p=407

发表评论