redis源码剖析(七)—— Redis 数据结构dict.c

文章目录

dict.h


//定义错误相关的码
#define DICT_OK 0
#define DICT_ERR 1

//实际存放数据的地方
typedef struct dictEntry {
   
    void *key;
    void *val;
    struct dictEntry *next;
} dictEntry;

//哈希表的定义
typedef struct dict {
   
    //指向实际的哈希表记录(用数组+开链的形式进行保存)
    dictEntry **table;
    //type中包含一系列哈希表需要用到的函数
    dictType *type;
    //size表示哈希表的大小,为2的指数
    unsigned long size;
    //sizemask=size-1,方便哈希值根据size取模
    unsigned long sizemask;
    //used记录了哈希表中有多少记录
    unsigned long used;
    void *privdata;
} dict;

//对Hash表进行迭代遍历时使用的迭代器
typedef struct dictIterator {
   
    dict *ht;
    int index;
    dictEntry *entry, *nextEntry;
} dictIterator;

/* This is the initial size of every hash table */
//每个Hash表的初始大小
#define DICT_HT_INITIAL_SIZE     4

dict.c

#include "fmacros.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <limits.h>

#include "dict.h"
#include "zmalloc.h"

/* ---------------------------- Utility funcitons --------------------------- */

/**
 * 打印出系统的崩溃信息
 * C语言中的可变参数的使用va_start va_end
 */
static void _dictPanic(const char *fmt, ...)
{
   
    va_list ap;
    va_start(ap, fmt);
    fprintf(stderr, "\nDICT LIBRARY PANIC: ");
    vfprintf(stderr, fmt, ap);
    fprintf(stderr, "\n\n");
    va_end(ap);
}

/* ------------------------- Heap Management Wrappers------------------------ */
/** 
 *  堆分配函数
 */
static void *_dictAlloc(size_t size)
{
   
    void *p = zmalloc(size);
    if (p == NULL)
        _dictPanic("Out of memory");
    return p;
}

/**
 * 堆释放函数
 */
static void _dictFree(void *ptr) {
   
    zfree(ptr);
}

/* -------------------------- private prototypes ---------------------------- */

static int _dictExpandIfNeeded(dict *ht);
static unsigned long _dictNextPower(unsigned long size);
static int _dictKeyIndex(dict *ht, const void *key);
static int _dictInit(dict *ht, dictType *type, void *privDataPtr);

/* -------------------------- hash functions -------------------------------- */

/* Thomas Wang's 32 bit Mix Function */
/**
 * 求Hash的键值,可以促使均匀分布
 */
unsigned int dictIntHashFunction(unsigned int key)
{
   
    key += ~(key << 15);
    key ^=  (key >> 10);
    key +=  (key << 3);
    key ^=  (key >> 6);
    key += ~(key << 11);
    key ^=  (key >> 16);
    return key;
}

/**
 * 直接将整数key作为Hash的键值
 */
/* Identity hash function for integer keys */
unsigned int dictIdentityHashFunction(unsigned int key)
{
   
    return key;
}

/* Generic hash function (a popular one from Bernstein).
 * I tested a few and this was the best. */
//Hash函数(通用目的Hash函数)
unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
   
    unsigned int hash = 5381;

    while (len--)
        hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */
    return hash;
}

/* ----------------------------- API implementation ------------------------- */

/* Reset an hashtable already initialized with ht_init().
 * NOTE: This function should only called by ht_destroy(). */
/**
 * 重设Hash表
 * 各种值都设置为0
 */
static void _dictReset(dict *ht)
{
   
    ht->table = NULL;
    ht->size = 0;
    ht->sizemask = 0;
    ht->used = 0;
}

/**
 * 创建一个新的Hash表
 * type为可用于Hash表上面的相应函数
 */
/* Create a new hash table */
dict *dictCreate(dictType *type,
        void *privDataPtr)
{
   
    dict *ht = _dictAlloc(sizeof(*ht));

    _dictInit(ht,type,privDataPtr)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值