当前位置: 首页 > 工具软件 > Memlink > 使用案例 >

MemLink之mem

程树
2023-12-01

       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;
通过这个单位就把所有的大小相同的放在了统一个Item中管理,而数据块的表示如下:

typedef 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;
}

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

个人理解,欢迎拍砖。
 类似资料: