ydb的内存模型
2009-09-10 00:00:00 来源:WEB开发网2 然后通过index_item结构来存取每个索引,并进行合法性校验。
3 最后将通过校验的item插入到红黑树。
PS:这里觉得它做了两个数据结构不太好,
Java代码
int tree_open(struct tree *tree, char *fname, int *last_record_logno, u64 *last_record_offset, int flags) {
char buf[256];
tree->fname = strdup(fname);
tree->refcnt = rarr_new();
///防止索引文件丢失。进行备份。
snprintf(buf, sizeof(buf), "%s.old", fname);
tree->fname_old = strdup(buf);
snprintf(buf, sizeof(buf), "%s.new", fname);
tree->fname_new = strdup(buf);
///红黑树的根结点赋值。
tree->root = RB_ROOT;
///加载索引文件到红黑树
return tree_load_index(tree, last_record_logno, last_record_offset, flags);
}
然后是loglist_open函数。它的主要流程是:
1 搜索top_dir目录,找到所有的数据文件。
2遍历这些文件,生成log数据结构,以文件的numbet(文件名中包含的)为索引插入到loglist中。
3 最后打开最后一个数据文件(也就是将要写的那个文件),并将它的相关属性赋值给loglist.
Java代码
int loglist_open(struct loglist *llist, char *top_dir, u64 min_log_size, int max_descriptors) {
llist->min_log_size = min_log_size;
llist->logs = rarr_new();
llist->top_dir = strdup(top_dir);
char unlink_base[256];
snprintf(unlink_base, sizeof(unlink_base), "%s%s%s%s.old",
top_dir, PATH_DELIMITER, DATA_FNAME, DATA_EXT);
llist->unlink_base = strdup(unlink_base);
....................................
/* Load data files */
///系统调用,用来搜索满足glob_str模式的文件。
glob(glob_str, 0, NULL, &globbuf);
for(off=globbuf.gl_pathv; off && *off; off++) {
///通过文件名得到logno
int logno = logno_from_fname(*off, prefix_len, suffix_len);
log_info("Opening log: %s (%04i)", *off, logno);
///生成log,并插入到数组。
if(log_open(llist, logno) < 0) {
log_error("Unable to open log %5i/0x%04x", logno, logno);
continue;
}
max_logno = MAX(max_logno, logno);
}
globfree(&globbuf);
if(max_logno < 0) { /* empty directory yet*/
if(log_create(llist, 0) < 0)
return(-1);
max_logno = 0;
}
///打开writer。
if(log_open_writer(llist, max_logno) < 0)
return(-1);
return(0);
}
它的get其实很简单,就是根据传递进来的key,在红黑树中得到相应的item结构,然后通过item的logno在loglist得到对应的数据文件,然后通过offset和传递进来的buf_sz从文件中read到需要的数据。
Java代码
/* Retrieve a value for selected key */
int ydb_get(YDB ydb, char *key, unsigned short key_sz,
char *buf, unsigned int buf_sz);
最后来看下ydb_add的实现:
Java代码
/* Add/modify a key */
int ydb_add(YDB ydb, char *key, unsigned short key_sz,
char *value, unsigned int value_sz);
这里我们暂时略过ydb的gc处理。在ydb-add中,主要调用了db_add方法。
它的主要流程是:
1 调用loglist_append,来将数据写入到对应的log文件,并更新loglist的对应域
2 调用tree_add,来新建或者修改一个item,并加入到索引树中。
Java代码
int db_add(struct db *db, char *key, u16 key_sz, char *value, u32 value_sz) {
/* TODO: error handling on write? */
struct append_info af;
af = loglist_append(&db->loglist, key, key_sz, value, value_sz, FLAG_SET);
tree_add(&db->tree, key, key_sz, af.logno,
af.value_offset, value_sz, af.record_offset);
return 1;
}
更多精彩
赞助商链接