现在的位置: 首页 > 综合 > 正文

astdb内存数据库 内核详解

2013年12月02日 ⁄ 综合 ⁄ 共 1596字 ⁄ 字号 评论关闭

主要数据结构


内存池数据结构:

#define CIRCLEQ_HEAD(name, type)	\
struct name {
	struct type *cqh_first;
	struct type *cqh_last;
}
#define HASHSIZE	256
typedef struct MPOOL{
	CIRCLEQ_HEAD(_lqh, _bkt)lqh;   //lru链
	CIRCLEQ_HEAD(_hqh, _bkt)hqh[HASHSIZE]; //hash表,表中每个元素都是一个循环队列结构
	pgno_t	curcache;  //指向当前缓存页
	pgno_t	maxcache;  //指向最大缓存页
	pgno_t	npages;    //总页数
	u_long	pagesize;  //内存页大小
	
	int fd;           // 内存池对应的文件描述符 一般指的是/var/lib/asterisk/astdb文件
	
	void (*pgin)(void *, pgno_t, void *);  //输入大小端转换
	void (*pgout)(void *, pgno_t, void *);  //输出大小端转换
	void *pgcookie;
}
如图:

hqh

内存页结构:

typedef struct _page{
	pgno_t	pgno;	//当前页号
	pgno_t	prevpg;	//前一页
	pgno_t	nextpg;	//后一页
	u_int32_t	flags;	//页面类型:BINTERNAL, BLEAF, OVERFLOW, RINTERNAL, RLEAF五种类型。
	indx_t	lower;	//当前页空白区域的下限
	indx_t	upper;	//当前页空白区域的上限
	indx_t	linp[1];	//页面存储实际数据的索引起点
}PAGE;


如图

关于内存页需要关注其具体的部署,上述数据结构存储于页面的开始部分,从 linp 到页面结束用于存储实际的数据,同时这部分分为三个部分,靠近页面开始的部分,即 linp 开始的部分是索引区,从页面的最高端,即页面结束的地址,向页面开始方向是数据区,中间的部分是空闲区,空闲区使用 lower 和 upper 划定区间,即如果以 END 标示页面的最高地址 — 结束地址,则 linp-- ( *lower )是索引区,( *lower ) -- ( *upper )是空闲区,( *upper ) --END 是数据区;当向页面中写入数据时,首先按照数据的大小在空闲区分配相应的区间,分配方式是将( *upper )向( *lower )方向移动待存入数据大小的空间,然后,将此事 upper 指向的地址记录下来,即索引的值,这就需要为索引分配一个内存空间,分配的方式是将( *lower )向( *upper )方向移动存放地址的空间。如此完成了对存储数据的分配,对数据的访问通过 linp[] 即可取出对应的 index 的值,从而访问需要的数据。至于访问时如何知道数据的大小,数据的开始 4 个字节构成的无符号整数记录的数据的实际大小。
		//		--摘自 http://blog.csdn.net/missyou03/article/details/5209690

db数据结构:


typedef struct __db{
	DBTYPE type;
	int (*close)(struct __db *);
	int (*del)(const struct __db *, const DBT *, u_int);
	int (*get)(const struct __db *, const DBT *, u_int);
	int (*put)(const struct __db *, DBT *, const DBT *, u_int);
	int (*seq)(const struct __db *, DBT *, DBT *, u_int);
	int (*sync)(const struct __db *, u_int);
	void *internal;     //指向内部存储结构,如B-tree,Hash, Recno
	int (*fd)(const struct __db *);
}DB;


未完待续。。。

【上篇】
【下篇】

抱歉!评论已关闭.