memcachedb 是 memcached 加了一个存储层,就是用Berkeley DB来存储数据,最新版本是1.20,
分析了一下,感觉就是从网下到的版本就是把memcached 和 Berkeley DB的简单拼装,并没有用到两者紧密的结合起来,之所以会这样,一种可能是网上发布的版本是简化过的,实际使用的版本没有发布
网上公布的memcachedb 1.20 ,并没有用到HASH,每次取数据的时候,也不是从内存取,还是从硬盘取的,只是维护了一个空闲的内存数组,方便分配内存。也没有预先分配空间,每次还是malloc分配。也只用到了memcached 的binary的传输协议。
放的函数,根本没有向内存中缓存
int item_put(char *key, size_t nkey, item *it){
int ret;
DBT dbkey, dbdata;
BDB_CLEANUP_DBT();
dbkey.data = key;
dbkey.size = nkey;
dbdata.data = it;
dbdata.size = ITEM_ntotal(it);
ret = dbp->put(dbp, NULL, &dbkey, &dbdata, 0);
if (ret == 0) {
return 0;
} else {
if (settings.verbose > 1) {
fprintf(stderr, "dbp->put: %s/n", db_strerror(ret));
}
return -1;
}
}
取的函数也是直接从硬盘读的,根本和内存没什么关系。
item *item_get(char *key, size_t nkey){
item *it = NULL;
DBT dbkey, dbdata;
bool stop;
int ret;
/* first, alloc a fixed size */
it = item_alloc2(settings.item_buf_size);
if (it == 0) {
return NULL;
}
BDB_CLEANUP_DBT();
dbkey.data = key;
dbkey.size = nkey;
dbdata.ulen = settings.item_buf_size;
dbdata.data = it;
dbdata.flags = DB_DBT_USERMEM;
stop = false;
/* try to get a item from bdb */
while (!stop) {
switch (ret = dbp->get(dbp, NULL, &dbkey, &dbdata, 0)) {
case DB_BUFFER_SMALL: /* user mem small */
/* free the original smaller buffer */
item_free(it);
/* alloc the correct size */
it = item_alloc2(dbdata.size);
if (it == NULL) {
return NULL;
}
dbdata.ulen = dbdata.size;
dbdata.data = it;
break;
case 0: /* Success. */
stop = true;
break;
case DB_NOTFOUND:
stop = true;
item_free(it);
it = NULL;
break;
default:
/* TODO: may cause bug here, if return DB_BUFFER_SMALL then retun non-zero again
* here 'it' may not a full one. a item buffer larger than item_buf_size may be added to freelist */
stop = true;
item_free(it);
it = NULL;
if (settings.verbose > 1) {
fprintf(stderr, "dbp->get: %s/n", db_strerror(ret));
}
}
}
return it;
}
只用到了下面这个
static item **freeitem;
把释放的元素存入这个空闲数组里,
总之一句话,网上公布的memcachedb根本没有用到memcached的核心思想和技术,和直接使用Berkeley DB的性能差别不大,没什么用处。估计真正的memcachedb没有开源。