本文是一个示例,展示了如何直接使用BerkeleyDBmemory pool功能。



BerkeleyDB对外开放了它的memory pool, logging,mutex lock子系统,应用程序开发者可以使用mpool来管理其他文件,按页对那些文件做读写操作,还可以同时使用lock子系统实现互斥。同时你还可以注册你自己的日志读写和恢复函数并且使用logging API写日志或者操纵日志文件和记录,并且使用mutex实现多进程/多线程互斥。有了这几块功能,你就可以使用Berkeley DB的功能写一个Access method,比如你可以写另外一个btree或者list,或者其他的数据访问方法。有兴趣的读者可以探索一下。这块的功能我会在后文当中依次demo一下。





//

// Create an environment object and initialize it for error

// reporting.

//

DbEnv *dbenv = new DbEnv(0);

int pagesize = 1024;

int cachesize = 1024 * 20;

int hits = 50;

int npages = 30;

db_pgno_t pageno, pgno1 = 1, pgno2 = 2, pgno3 = 3;

int cnt, ret;

void *p, *pg1, *pg2, *pg3;

DbMpoolFile *mfp;



dbenv->set_error_stream(&err_stream);

dbenv->set_errpfx("Mpool");

dbenv->set_shm_key(123);

dbenv->set_flags(DB_NOMMAP, 0);

dbenv->set_cachesize(0, 20 * 1024, 0);



// Databases are in a subdirectory.

dbenv->open(home, DB_CREATE | DB_INIT_MPOOL | DB_SYSTEM_MEM, 0);

try

{

if ((ret = dbenv->memp_fcreate(&mfp, 0)) != 0) {

cerr << "Mpool: memp_fcreate failed: "

<< strerror(ret) << "/n";

return;

}



int i = mfp->open("MyMPOOLFile", DB_CREATE, 0644, pagesize);

if (mfp->get(&pgno1, NULL, DB_MPOOL_CREATE, &pg1) != 0 ||

mfp->get(&pgno3, NULL, DB_MPOOL_CREATE, &pg3) != 0)

std::cout<<"/nFailed to create pages in MyMPOOLFile";

/* Now we have pg1 and pg3 to read from. */

else {

mfp->sync();/* MyMPOOLFile is enlarged here to 3 pages. */

std::cout << "retrieve " << hits << " randompages... /n";

/* Put back pg1 and pg3. */

mfp->put(pg1, DB_PRIORITY_UNCHANGED, 0);

mfp->put(pg3, DB_PRIORITY_UNCHANGED, 0);



/*

* So far pg2 is never used, so it's not in mpool, and we should useDB_MPOOL_CREATE. If we

* directly specify DB_MPOOL_DIRTY here, we can't get the page.

*/

mfp->get(&pgno2, NULL, DB_MPOOL_CREATE, &pg2);



/*

* Must put before dirty it otherwise we are self-blocked by our own sharedlatch.

* We can't OR any flags here, any of the 5 flags should be specified separatelyin db5.0, thus

* we have to CREATE pg2, put it back to mpool, then DIRTY it, modify it and putit back again.

*/

mfp->put(pg2, DB_PRIORITY_UNCHANGED, 0);



/*

* We want to write pg2, so must specify DIRTY flag. Without the DIRTY flag, wegot read only pages,

* our changes won't be synced to disk when evicted.

*/

mfp->get(&pgno2, NULL, DB_MPOOL_DIRTY, &pg2);

/* Write bytes to pg2. */

strcpy((char *)pg2 + 60, "hello world!");

/* Put back pg2. */

mfp->put(pg2, DB_PRIORITY_UNCHANGED, 0);

mfp->close(0);

}

}

catch(DbException &e)

{

std::cerr<< "Exception occur: "

<
}



// Close the handle.

dbenv->close(0);

delete dbenv;