C语言15天玩转redis —— 第肆篇 哈希对象类型

C语言 1

实际上在redis的那一个规模,它世代唯有三个键,3个值,这么些键永远都以字符串对象,也正是SDS对象,而值的类型就多了,有字符串对象,有队列对象,

<1> dictEntry **table;

与此同时也很精细,redis为啥会这样做呢???仔细钻探你大概会了然,扩大体积有两种形式,要么叁遍性扩大容积,要么渐进性扩大体积,前面那种扩容是什

前面几篇小说作者都不曾选取一个艺术仔细讲解,其实也没怎么好教学的,就好似C#中的3个类的一个措施而已,知道传递一些什么参数就OK了,就比如要

typedef struct dictEntry {
    void *key;
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next;
} dictEntry;

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;

/* This is our hash table structure. Every dictionary has two of this as we
 * implement incremental rehashing, for the old to the new 0. */
typedef struct dictht {
    dictEntry **table;
    unsigned long size;
    unsigned long sizemask;
    unsigned long used;
} dictht;

typedef struct dict {
    dictType *type;
    void *privdata;
    dictht ht[2];
    long rehashidx; /* rehashing not in progress if rehashidx == -1 */
    int iterators; /* number of iterators currently running */
} dict;

/* If safe is set to 1 this is a safe iterator, that means, you can call
 * dictAdd, dictFind, and other functions against the dictionary even while
 * iterating. Otherwise it is a non safe iterator, and only dictNext()
 * should be called while iterating. */
typedef struct dictIterator {
    dict *d;
    long index;
    int table, safe;
    dictEntry *entry, *nextEntry;
    /* unsafe iterator fingerprint for misuse detection. */
    long long fingerprint;
} dictIterator;

 

<2> dictht ht[2]

调用方法就是这般的简易,关键在于时不时的急需你看一看手册,其实最首要的是询问下它在redis源码中的原理就好了。

[administrator@localhost redis-3.0.5]$ src/redis-cli
127.0.0.1:6379> clear

127.0.0.1:6379> hset person name jack
(integer) 1
127.0.0.1:6379> hset person age 20
(integer) 1
127.0.0.1:6379> hset person sex famale
(integer) 1
127.0.0.1:6379> hgetall person
1) "name"
2) "jack"
3) "age"
4) "20"
5) "sex"
6) "famale"
127.0.0.1:6379> hkeys person
1) "name"
2) "age"
3) "sex"
127.0.0.1:6379> hvals person
1) "jack"
2) "20"
3) "famale"
127.0.0.1:6379> 

 

  hash的源代码是在dict.h源代码里面,枚举如下:

1. dict结构

么意思呢?正是小编在扩大体量的同时不影响前端的CU大切诺基D,笔者渐渐的把多少从ht[0]转移到ht[1]中,同时rehashindex来记录转移的情景,当一切变换

好了,就此打住,去集团了。

  
能够观望它的体系是dictType,从地点你也足以见到,它是有枚举结构定义的,如下:

 

 

说的HSet,它的格式如下:

其一布局是hash的实在的最底层数据结构,能够看出里边有多少个属性。

       从地点这些结构体中,你能够观看1个格外首要的习性: dictEntry
**table, 个中table是1个数组,数组类型是dictEntry,既然是3个数组,

  1. dicth结构

    1 typedef struct dictht {
    2 dictEntry **table;
    3 unsigned long size;
    4 unsigned long sizemask;
    5 unsigned long used;
    6 } dictht;

 

     
 你只怕会疑窦,为何那性子格是2个大小的数组呢,其实正真使用的是ht[0],而ht[1]是用来扩大容积hash表时的暂存数组,那或多或少也很奇葩,

完了未来,将ht[1]改成ht[0]应用,就那样容易。

C语言 2

C语言 3

 

从地方那么些数据结构中你能够见到里边都是一些情势,可是有3个可怜主要的方法,那正是首先个hashFunction,能够看来它正是计量hash值的,

首先个正是:   *key:它就是hash表中的key。

1 typedef struct dict {
2     dictType *type;
3     void *privdata;
4     dictht ht[2];
5     long rehashidx; /* rehashing not in progress if rehashidx == -1 */
6     int iterators; /* number of iterators currently running */
7 } dict;

二:探索规律

  只假设八个数据结构,最基础的恒久是CUQashqaiD,redis中的insert和update,永远只须求set来替代,比如下边包车型地铁Hset,如下图:

的装逼方法。

那前边的多少个属性就好明白了,size是数组的高低,sizemask和数组求模有关,used记录数组中已利用的大小,以往我们把注意力放在dictEntry那

其次个就是:    union的*val 就是hash的value。

Dictionary存放的话,能够依据气象优先考虑下redis哦,起码能够装装逼嘛,今后自身默许你早已有装逼的欢腾了,打开redis手册,看看有怎样大家用赢得

1 typedef struct dictType {
2     unsigned int (*hashFunction)(const void *key);
3     void *(*keyDup)(void *privdata, const void *key);
4     void *(*valDup)(void *privdata, const void *obj);
5     int (*keyCompare)(void *privdata, const void *key1, const void *key2);
6     void (*keyDestructor)(void *privdata, void *key);
7     void (*valDestructor)(void *privdata, void *obj);
8 } dictType;

接下去自个儿在CentOS里面操作一下,

地点便是大家利用hash的源代码数据结构,接下去自身来撸一撸当中的逻辑关系。

1 var person=new Dictionary<string,string>();
2 person.Add("name","jack");
3 ....

C语言 4

一:常用方法

 

 

还有那篇的hash对象,将来的雷打不动聚集对象等等,要是您还不明了的话,转化为C#语言正是。

个数组实体类型方面。

  redis中的hash也是我们选用中的高频数据结构,它的协会基本上和编制程序语言中的HashTable,Dictionary丽水小异,假使大家以往有怎样逻辑必要用

C语言 5

跟C#中的dictionary中求hash值一样同等的。

 

  1. dictEntry结构

    1 typedef struct dictEntry {
    2 void key;
    3 union {
    4 void
    val;
    5 uint64_t u64;
    6 int64_t s64;
    7 double d;
    8 } v;
    9 struct dictEntry *next;
    10 } dictEntry;

从那个数据结构下面你可以看出有多个大属性。

其四个正是:    *next就是为了防范hash冲突选拔的挂链手段。

<1> dictType *type

 

也许有人看了下边包车型地铁console有好几迷惑,那正是前方有多少个参数,比如person,name啦,然后才是value,假设您看了第①篇的话,你差不多就精晓了,

本条原理和C#中的Dictionary依然一如既往同样的。

不明了你看懂了没有,如若总计地点描述的话,作者可以画出如下的hash结构图。