在《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;
}
在写逻辑代码前,一切都用画图工具设计好了。
一切都是设计出来的!