memlink之mem

       memlink按照天涯的人说是一个灰常牛的key-List系统,比Redis要快很多倍,下面就来一点点看它的代码。在内存中的Block也是通过一个池来管理的,用到的数据结构大致有三个DataBlock、MemItem、MemPool。MemPool的结构如下:

typedef struct _mempool{
MemItem *freemem; // 数组
int size;     // 数组的大小
int used;     // 正在用的MemItem的大小
int blocks;   // 内存池中的数目
}MemPool;

在一个内存池中管理的有各种大小的Block,而相同大小的Block就被放在统一个MemItem中来管理,该结构如下:

typedef struct _mem_item{
int      memsize;     // 管理的块的大小
unsigned int block_count; // 块的数目
unsigned int total;   // 用的空闲的块的总数
DataBlock    *data;   // 相当于一个链表头
}MemItem;

而存放数据的DataBlock的结构如下:

ypedef struct _data_block
{
unsigned short data_count;    // 小块的数目
unsigned short visible_count; // visible item count
unsigned short tagdel_count;   // tag delete item count, invisible
struct _data_block *prev;
struct _data_block *next;
char data[0];
}DataBlock;

该结构在内存中通过双向链表来保存,链表的头保存在MemItem中,关于是否内存和申请内存的操作都很普通。这里用内存池显然是为了减少分配释放带来的开销,那为什在expend的时候不用改变内存大小的系统调用?这样的话可能减少一次分配和一次拷贝和一次释放,代码如下:

int mempool_expand(MemPool *mp){
int newnum = mp->size * 2;
MemItem *newitems = (MemItem*)zz_malloc(sizeof(MemItem) * newnum);
if (NULL == newitems) {
DERROR("malloc error!\n");
MEMLINK_EXIT;
return -1;
}
memcpy(newitems, mp->freemem, sizeof(MemItem) * mp->used);
zz_free(mp->freemem);
mp->freemem = newitems;
mp->size = newnum;
return 0;
}

-------------------------------------------

个人理解欢迎拍砖。

原文地址:https://www.cnblogs.com/ggzwtj/p/2245798.html