redis源码从main开始12中我们看了list对象,本章来看set对象

13 redis对象之set

同样的set类型对象也有两种编码方式,一种是哈希表,一种是整数集合
#define REDIS_ENCODING_HT 2      /* Encoded as hash table */
#define REDIS_ENCODING_INTSET 6  /* Encoded as intset */

以下为两种编码方式的set对象的创建方式

//哈希表编码的集合
robj *createSetObject(void) {
    dict *d = dictCreate(&setDictType,NULL);
    robj *o = createObject(REDIS_SET,d);
    o->encoding = REDIS_ENCODING_HT;
    return o;
}

//整数集合编码的集合
robj *createIntsetObject(void) {
    intset *is = intsetNew();
    robj *o = createObject(REDIS_SET,is);
    o->encoding = REDIS_ENCODING_INTSET;
    return o;
}

// 下面先来看编码方式为哈希表的set对象的创建过程

// 第一步,创建一个字典
dict *dictCreate(dictType *type,void *privDataPtr)
{
    dict *d = zmalloc(sizeof(*d));
    _dictInit(d,type,privDataPtr);
    return d;
}

// redis中字典的结构
typedef struct dict {
    dictType *type; // 一个类型函数
    void *privdata; // 私有数据
    dictht ht[2];     // 哈希表,有两个,在重新计算哈希的过程会使用到
    int rehashidx; /* 重新计算哈希 rehashing not in progress if rehashidx == -1 */
    int iterators; /* 当前运行的迭代器数量 */
} dict;

/* 不同类型的哈希表 */
dictType setDictType = {
    dictEncObjHash,            /* hash function */
    NULL,                      /* key dup */
    NULL,                      /* val dup */
    dictEncObjKeyCompare,      /* key compare */
    dictRedisObjectDestructor, /* key destructor */
    NULL                       /* val destructor */
};


//初始化哈希表
int _dictInit(dict *d, dictType *type, void *privDataPtr)
{
    _dictReset(&d->ht[0]); // 初始化属性
    _dictReset(&d->ht[1]); // 初始化属性
    d->type = type;     // 设置类型dictType,不同类型会有不同的哈希函数,键值的复制比较销毁的相关函数
    d->privdata = privDataPtr;     // 哈希表私有数据
    d->rehashidx = -1; // 设置不在重新计算哈希中
    d->iterators = 0; // 设置进行中的迭代器数量
    return DICT_OK;
}

// 第二步, 创建一个set类型对象, 把刚刚创建的哈希表传入
robj *o = createObject(REDIS_SET,d);

// 第三步, 设置编码为哈希表
o->encoding = REDIS_ENCODING_HT;



//下面我们看整数集合的集合
// 第一步,创建整数集合的结构
intset *is = intsetNew();

//创建空的整数集合
intset *intsetNew(void) {
    intset *is = zmalloc(sizeof(intset));
    is->encoding = intrev32ifbe(INTSET_ENC_INT16);     // 设置初始编码
    is->length = 0;     // 初始化元素数量
    return is;
}

// 第二步,创建set对象
robj *o = createObject(REDIS_SET,is);

// 第三步,设置编码类型
o->encoding = REDIS_ENCODING_INTSET;


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

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

发表评论