Redis的“表”怎么设计的?
在《C语言描述能力之——结构体》我曾提到C语言的描述能力,数据库里的“表”这个概念是如何通过C语言来设计的呢?
我们来看一下Redis的实现吧。
robj *createListObject(void) { list *l = listCreate(); robj *o = createObject(REDIS_LIST,l); listSetFreeMethod(l,decrRefCount); o->encoding = REDIS_ENCODING_LINKEDLIST; return o;}这里的Object是一个抽象的封装,Redis支持的所有数据类型都是一个Object。只是不同类型的Object其指向是不同的。
我们来看一下Redis是如何设计这样一个抽象的Object的(类似于RDBMS里的表)。
typedef struct redisObject { unsigned type:4; unsigned storage:2; unsigned encoding:4; unsigned lru:22; /* lru time (relative to server.lruclock) */ int refcount; void *ptr;} robj;Object这个对象的抽象性由“void *ptr”这一行代码实现。也就是说,redisObject这一个对象其实是一个皮包对象,它真正指向的对象是*ptr。设计的其余几个字段只是redis数据类型的通用属性而已。
回到list数据类型,因为list数据类型是直接从heap里索取内存空间,所以这个函数没有参数传入。
这里的list是怎么定义的呢?
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;就是一个很简单的单链表。
list *listCreate(void){ struct list *list; if ((list = zmalloc(sizeof(*list))) == NULL) return NULL; list->head = list->tail = NULL; list->len = 0; list->dup = NULL; list->free = NULL; list->match = NULL; return list;}
在写逻辑代码前,一切都用画图工具设计好了。
一切都是设计出来的!