summaryrefslogtreecommitdiffstats
path: root/ext/lsm1/lsm-test/lsmtest_tdb2.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ext/lsm1/lsm-test/lsmtest_tdb2.cc')
-rw-r--r--ext/lsm1/lsm-test/lsmtest_tdb2.cc369
1 files changed, 369 insertions, 0 deletions
diff --git a/ext/lsm1/lsm-test/lsmtest_tdb2.cc b/ext/lsm1/lsm-test/lsmtest_tdb2.cc
new file mode 100644
index 0000000..86ebb49
--- /dev/null
+++ b/ext/lsm1/lsm-test/lsmtest_tdb2.cc
@@ -0,0 +1,369 @@
+
+
+#include "lsmtest.h"
+#include <stdlib.h>
+
+#ifdef HAVE_KYOTOCABINET
+#include "kcpolydb.h"
+extern "C" {
+ struct KcDb {
+ TestDb base;
+ kyotocabinet::TreeDB* db;
+ char *pVal;
+ };
+}
+
+int test_kc_open(const char *zFilename, int bClear, TestDb **ppDb){
+ KcDb *pKcDb;
+ int ok;
+ int rc = 0;
+
+ if( bClear ){
+ char *zCmd = sqlite3_mprintf("rm -rf %s\n", zFilename);
+ system(zCmd);
+ sqlite3_free(zCmd);
+ }
+
+ pKcDb = (KcDb *)malloc(sizeof(KcDb));
+ memset(pKcDb, 0, sizeof(KcDb));
+
+
+ pKcDb->db = new kyotocabinet::TreeDB();
+ pKcDb->db->tune_page(TESTDB_DEFAULT_PAGE_SIZE);
+ pKcDb->db->tune_page_cache(
+ TESTDB_DEFAULT_PAGE_SIZE * TESTDB_DEFAULT_CACHE_SIZE
+ );
+ ok = pKcDb->db->open(zFilename,
+ kyotocabinet::PolyDB::OWRITER | kyotocabinet::PolyDB::OCREATE
+ );
+ if( ok==0 ){
+ free(pKcDb);
+ pKcDb = 0;
+ rc = 1;
+ }
+
+ *ppDb = (TestDb *)pKcDb;
+ return rc;
+}
+
+int test_kc_close(TestDb *pDb){
+ KcDb *pKcDb = (KcDb *)pDb;
+ if( pKcDb->pVal ){
+ delete [] pKcDb->pVal;
+ }
+ pKcDb->db->close();
+ delete pKcDb->db;
+ free(pKcDb);
+ return 0;
+}
+
+int test_kc_write(TestDb *pDb, void *pKey, int nKey, void *pVal, int nVal){
+ KcDb *pKcDb = (KcDb *)pDb;
+ int ok;
+
+ ok = pKcDb->db->set((const char *)pKey, nKey, (const char *)pVal, nVal);
+ return (ok ? 0 : 1);
+}
+
+int test_kc_delete(TestDb *pDb, void *pKey, int nKey){
+ KcDb *pKcDb = (KcDb *)pDb;
+ int ok;
+
+ ok = pKcDb->db->remove((const char *)pKey, nKey);
+ return (ok ? 0 : 1);
+}
+
+int test_kc_delete_range(
+ TestDb *pDb,
+ void *pKey1, int nKey1,
+ void *pKey2, int nKey2
+){
+ int res;
+ KcDb *pKcDb = (KcDb *)pDb;
+ kyotocabinet::DB::Cursor* pCur = pKcDb->db->cursor();
+
+ if( pKey1 ){
+ res = pCur->jump((const char *)pKey1, nKey1);
+ }else{
+ res = pCur->jump();
+ }
+
+ while( 1 ){
+ const char *pKey; size_t nKey;
+ const char *pVal; size_t nVal;
+
+ pKey = pCur->get(&nKey, &pVal, &nVal);
+ if( pKey==0 ) break;
+
+#ifndef NDEBUG
+ if( pKey1 ){
+ res = memcmp(pKey, pKey1, MIN((size_t)nKey1, nKey));
+ assert( res>0 || (res==0 && nKey>nKey1) );
+ }
+#endif
+
+ if( pKey2 ){
+ res = memcmp(pKey, pKey2, MIN((size_t)nKey2, nKey));
+ if( res>0 || (res==0 && (size_t)nKey2<nKey) ){
+ delete [] pKey;
+ break;
+ }
+ }
+ pCur->remove();
+ delete [] pKey;
+ }
+
+ delete pCur;
+ return 0;
+}
+
+int test_kc_fetch(
+ TestDb *pDb,
+ void *pKey,
+ int nKey,
+ void **ppVal,
+ int *pnVal
+){
+ KcDb *pKcDb = (KcDb *)pDb;
+ size_t nVal;
+
+ if( pKcDb->pVal ){
+ delete [] pKcDb->pVal;
+ pKcDb->pVal = 0;
+ }
+
+ pKcDb->pVal = pKcDb->db->get((const char *)pKey, nKey, &nVal);
+ if( pKcDb->pVal ){
+ *ppVal = pKcDb->pVal;
+ *pnVal = nVal;
+ }else{
+ *ppVal = 0;
+ *pnVal = -1;
+ }
+
+ return 0;
+}
+
+int test_kc_scan(
+ TestDb *pDb, /* Database handle */
+ void *pCtx, /* Context pointer to pass to xCallback */
+ int bReverse, /* True for a reverse order scan */
+ void *pKey1, int nKey1, /* Start of search */
+ void *pKey2, int nKey2, /* End of search */
+ void (*xCallback)(void *pCtx, void *pKey, int nKey, void *pVal, int nVal)
+){
+ KcDb *pKcDb = (KcDb *)pDb;
+ kyotocabinet::DB::Cursor* pCur = pKcDb->db->cursor();
+ int res;
+
+ if( bReverse==0 ){
+ if( pKey1 ){
+ res = pCur->jump((const char *)pKey1, nKey1);
+ }else{
+ res = pCur->jump();
+ }
+ }else{
+ if( pKey2 ){
+ res = pCur->jump_back((const char *)pKey2, nKey2);
+ }else{
+ res = pCur->jump_back();
+ }
+ }
+
+ while( res ){
+ const char *pKey; size_t nKey;
+ const char *pVal; size_t nVal;
+ pKey = pCur->get(&nKey, &pVal, &nVal);
+
+ if( bReverse==0 && pKey2 ){
+ res = memcmp(pKey, pKey2, MIN((size_t)nKey2, nKey));
+ if( res>0 || (res==0 && (size_t)nKey2<nKey) ){
+ delete [] pKey;
+ break;
+ }
+ }else if( bReverse!=0 && pKey1 ){
+ res = memcmp(pKey, pKey1, MIN((size_t)nKey1, nKey));
+ if( res<0 || (res==0 && (size_t)nKey1>nKey) ){
+ delete [] pKey;
+ break;
+ }
+ }
+
+ xCallback(pCtx, (void *)pKey, (int)nKey, (void *)pVal, (int)nVal);
+ delete [] pKey;
+
+ if( bReverse ){
+ res = pCur->step_back();
+ }else{
+ res = pCur->step();
+ }
+ }
+
+ delete pCur;
+ return 0;
+}
+#endif /* HAVE_KYOTOCABINET */
+
+#ifdef HAVE_MDB
+#include "lmdb.h"
+
+extern "C" {
+ struct MdbDb {
+ TestDb base;
+ MDB_env *env;
+ MDB_dbi dbi;
+ };
+}
+
+int test_mdb_open(
+ const char *zSpec,
+ const char *zFilename,
+ int bClear,
+ TestDb **ppDb
+){
+ MDB_txn *txn;
+ MdbDb *pMdb;
+ int rc;
+
+ if( bClear ){
+ char *zCmd = sqlite3_mprintf("rm -rf %s\n", zFilename);
+ system(zCmd);
+ sqlite3_free(zCmd);
+ }
+
+ pMdb = (MdbDb *)malloc(sizeof(MdbDb));
+ memset(pMdb, 0, sizeof(MdbDb));
+
+ rc = mdb_env_create(&pMdb->env);
+ if( rc==0 ) rc = mdb_env_set_mapsize(pMdb->env, 1*1024*1024*1024);
+ if( rc==0 ) rc = mdb_env_open(pMdb->env, zFilename, MDB_NOSYNC|MDB_NOSUBDIR, 0600);
+ if( rc==0 ) rc = mdb_txn_begin(pMdb->env, NULL, 0, &txn);
+ if( rc==0 ){
+ rc = mdb_open(txn, NULL, 0, &pMdb->dbi);
+ mdb_txn_commit(txn);
+ }
+
+ *ppDb = (TestDb *)pMdb;
+ return rc;
+}
+
+int test_mdb_close(TestDb *pDb){
+ MdbDb *pMdb = (MdbDb *)pDb;
+
+ mdb_close(pMdb->env, pMdb->dbi);
+ mdb_env_close(pMdb->env);
+ free(pMdb);
+ return 0;
+}
+
+int test_mdb_write(TestDb *pDb, void *pKey, int nKey, void *pVal, int nVal){
+ int rc;
+ MdbDb *pMdb = (MdbDb *)pDb;
+ MDB_val val;
+ MDB_val key;
+ MDB_txn *txn;
+
+ val.mv_size = nVal;
+ val.mv_data = pVal;
+ key.mv_size = nKey;
+ key.mv_data = pKey;
+
+ rc = mdb_txn_begin(pMdb->env, NULL, 0, &txn);
+ if( rc==0 ){
+ rc = mdb_put(txn, pMdb->dbi, &key, &val, 0);
+ if( rc==0 ){
+ rc = mdb_txn_commit(txn);
+ }else{
+ mdb_txn_abort(txn);
+ }
+ }
+
+ return rc;
+}
+
+int test_mdb_delete(TestDb *pDb, void *pKey, int nKey){
+ int rc;
+ MdbDb *pMdb = (MdbDb *)pDb;
+ MDB_val key;
+ MDB_txn *txn;
+
+ key.mv_size = nKey;
+ key.mv_data = pKey;
+ rc = mdb_txn_begin(pMdb->env, NULL, 0, &txn);
+ if( rc==0 ){
+ rc = mdb_del(txn, pMdb->dbi, &key, 0);
+ if( rc==0 ){
+ rc = mdb_txn_commit(txn);
+ }else{
+ mdb_txn_abort(txn);
+ }
+ }
+
+ return rc;
+}
+
+int test_mdb_fetch(
+ TestDb *pDb,
+ void *pKey,
+ int nKey,
+ void **ppVal,
+ int *pnVal
+){
+ int rc;
+ MdbDb *pMdb = (MdbDb *)pDb;
+ MDB_val key;
+ MDB_txn *txn;
+
+ key.mv_size = nKey;
+ key.mv_data = pKey;
+
+ rc = mdb_txn_begin(pMdb->env, NULL, MDB_RDONLY, &txn);
+ if( rc==0 ){
+ MDB_val val = {0, 0};
+ rc = mdb_get(txn, pMdb->dbi, &key, &val);
+ if( rc==MDB_NOTFOUND ){
+ rc = 0;
+ *ppVal = 0;
+ *pnVal = -1;
+ }else{
+ *ppVal = val.mv_data;
+ *pnVal = val.mv_size;
+ }
+ mdb_txn_commit(txn);
+ }
+
+ return rc;
+}
+
+int test_mdb_scan(
+ TestDb *pDb, /* Database handle */
+ void *pCtx, /* Context pointer to pass to xCallback */
+ int bReverse, /* True for a reverse order scan */
+ void *pKey1, int nKey1, /* Start of search */
+ void *pKey2, int nKey2, /* End of search */
+ void (*xCallback)(void *pCtx, void *pKey, int nKey, void *pVal, int nVal)
+){
+ MdbDb *pMdb = (MdbDb *)pDb;
+ int rc;
+ MDB_cursor_op op = bReverse ? MDB_PREV : MDB_NEXT;
+ MDB_txn *txn;
+
+ rc = mdb_txn_begin(pMdb->env, NULL, MDB_RDONLY, &txn);
+ if( rc==0 ){
+ MDB_cursor *csr;
+ MDB_val key = {0, 0};
+ MDB_val val = {0, 0};
+
+ rc = mdb_cursor_open(txn, pMdb->dbi, &csr);
+ if( rc==0 ){
+ while( mdb_cursor_get(csr, &key, &val, op)==0 ){
+ xCallback(pCtx, key.mv_data, key.mv_size, val.mv_data, val.mv_size);
+ }
+ mdb_cursor_close(csr);
+ }
+ }
+
+ return rc;
+}
+
+#endif /* HAVE_MDB */