redis源代码分析4–字典(下)

hash表的两个有意思的处理过程为自动调整hash表的大小,在需要时实现增量rehash,其他如查找,删除等不解释。

我们先看看resize的处理逻辑。

dict.c中有个变量dict_can_resize控制着是否允许自动调整hash表的大小,该变量的改变主要靠如下两个函数:

void dictEnableResize(void) {
    dict_can_resize = 1;
}
void dictDisableResize(void) {
    dict_can_resize = 0;
}

总的说来,在系统运行有后台进程时,不允许自动自动调整大小,这是为了为了使得类linux系统的copy-on-write有更好的性能(没有调整大小, 就没有rehash,这样父进程的db没有改变,子进程就不需要真的copy)。在后台子进程退出后,又会允许resize。这里说到的后台子进程主要跟redis的持久化机制有关,在后面的持久化之快照和持久化之aof中会详细介绍其过程。

接下来我们看看自动调整大小的算法。 继续阅读

发表在 redis | 留下评论

redis源代码分析3–字典(上)

字典实现中主要用到如下5个结构体:

typedef struct dictEntry {
    void *key;
    void *val;
    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;

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];
    int rehashidx; /* rehashing not in progress if rehashidx == -1 */
    int iterators; /* number of iterators currently running */
} dict;

typedef struct dictIterator {
    dict *d;
    int table;
    int index;
    dictEntry *entry, *nextEntry;
} dictIterator;

继续阅读

发表在 redis | 4 条评论

redis源代码分析2–动态字符串

redis的字符串号称是二进制安全的,其内部实现其实就是个head+ char*。

typedef char *sds;
struct sdshdr {
	long len;
	long free;
	char buf[];
};

len 表示buf字符数组实际使用的空间大小,free表示buf剩余空间大小,buf所分配的空间大小等于len+free。尽管一开始buf的大小等于 len(当然可以大于),但随着字符串连接、拷贝(C中的字符串函数),buf分配的空间很可能会比len大,此时redis并不会释放多出的内存。

redis源代码分析2–动态字符串

发表在 redis | 标签为 , , | 2 条评论

redis源代码分析1–链表

先简单介绍下redis中用到的链表,是在文件adlist.c和adlist.h中实现的。

实现中主要用到listNode、list、listIter三个结构,listNode代表链表中的每个节点,list指向整个链表,listIter是为了迭代访问整个list,内部其实就是个listNode指针。

typedef struct listNode {
   struct listNode *prev;
   struct listNode *next;
   void *value;
} listNode;

typedef struct listIter {
   listNode *next;
   int direction;
} listIter;

typedef struct list {
   listNode *head;
   listNode *tail;
   void *(*dup)(void *ptr);
   void(*free)(void *ptr);
   int(*match)(void *ptr, void *key);
   unsigned int len;
} list;

继续阅读

发表在 redis | 标签为 , , | 7 条评论

redis相关资料

1  官方文档:

redis源码doc目录中的所有文档

官方网站:http://redis.io/
命令集合:http://redis.io/commands

2  国外分析文档:

redis-from-the-ground-up:
http://blog.mjrusso.com/2010/10/17/redis-from-the-ground-up.html

Redis: under the hood
http://pauladamsmith.com/articles/redis-under-the-hood.html

redis cookbook:
http://www.rediscookbook.org/

redis tutorial:
http://simonwillison.net/static/2010/redis-tutorial/

Redis Virtual Memory: the story and the code:
http://antirez.com/post/redis-virtual-memory-story.html

redis性能测试:
http://jaksprats.wordpress.com/2010/09/22/12/
继续阅读

发表在 redis | 标签为 , , | 3 条评论