码迷,mamicode.com
首页 > 其他好文 > 详细

Redis数据类型之字典

时间:2015-07-31 23:36:36      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:redis   哈希   

Redis数据类型之字典

标签(空格分隔): redis


redis的字典

字典又称符号表(symbol table),关联数组(associative array),或者映射(map)。是用于保存键值对的一种抽象数据结构。
字典的key是唯一的,对键值对的操作基本都是基于key来操作的。redis中的数据库底层是使用字典来实现的,对于数据库的增删改查都是基于字典来实现的。redis的哈希键也是基于字典来实现的。

具体的实现是在src下的dict.h和dict.c文件

字典的数据结构

哈希表结点

/*
 * 哈希表节点
 */
typedef struct dictEntry {

    // 键
    void *key;

    // 值
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
    } v;

    // 指向下个哈希表节点,形成链表
    struct dictEntry *next;

} dictEntry;

哈希表的数据结构

/*
 * 哈希表
 */
typedef struct dictht {

    // 哈希表数组
    dictEntry **table;

    // 哈希表大小
    unsigned long size;

    // 哈希表大小掩码,用于计算索引值
    // 总是等于 size - 1
    unsigned long sizemask;

    // 该哈希表已有节点的数量
    unsigned long used;

} dictht;

字典的数据结构

/*
 * 字典
 */
typedef struct dict {

    // 类型特定函数
    dictType *type;

    // 私有数据
    void *privdata;

    // 哈希表
    dictht ht[2];

    // rehash 索引
    // 当 rehash 不在进行时,值为 -1
    int rehashidx; /* rehashing not in progress if rehashidx == -1 */

    // 目前正在运行的安全迭代器的数量
    int iterators; /* number of iterators currently running */

} dict;

其中的dictType是一个struct

/*
 * 字典类型特定函数
 */
typedef struct dictType {

    // 计算哈希值的函数
    unsigned int (*hashFunction)(const void *key);

    // 复制键的函数
    void *(*keyDup)(void *privdata, const void *key);

    // 复制值的函数
    void *(*valDup)(void *privdata, const void *obj);

    // 对比键的函数
    int (*keyCompare)(void *privdata, const void *key1, const void *key2);

    // 销毁键的函数
    void (*keyDestructor)(void *privdata, void *key);

    // 销毁值的函数
    void (*valDestructor)(void *privdata, void *obj);

} dictType;
    // 哈希表
    dictht ht[2];

这里的ht是一个包含两项数据的数组,数组的每一项都是一个dictht哈希表,一般情况下,只使用ht[0],ht[1]是在rehash的情况下使用。

哈希算法

当需要向字典添加一对键值对时,程序首先根据字典的key计算出hash值和索引值,然后根据索引值,将包含新键值对的哈希表结点放到哈希数组指定的索引位置上。

redis计算hash值和索引的方法如下

// 计算给定键的哈希值
#define dictHashKey(d, key) (d)->type->hashFunction(key)
 // 计算索引值
idx = h & d->ht[table].sizemask;

哈希冲突

当两个或者两个以上的键被分配到哈希数组的同一个索引上,被称为哈希冲突。

哈希冲突的解决方法:

  1. 开放定址法(包括线性探查法、线性补偿探测法、随机探测)
  2. 拉链法,又称链地址法

redis如何解决哈希冲突?
链地址法,每个哈希表结点都有一个next指针域,多个哈希表结点可以构成一个单链表,被分配到同一个索引的键可以使用这个next指针连起来,从而解决哈希冲突。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Redis数据类型之字典

标签:redis   哈希   

原文地址:http://blog.csdn.net/weiyongxuan/article/details/47176935

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!