modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/lsm1/lsm-test/lsmtest_tdb2.cc (about) 1 2 3 #include "lsmtest.h" 4 #include <stdlib.h> 5 6 #ifdef HAVE_KYOTOCABINET 7 #include "kcpolydb.h" 8 extern "C" { 9 struct KcDb { 10 TestDb base; 11 kyotocabinet::TreeDB* db; 12 char *pVal; 13 }; 14 } 15 16 int test_kc_open(const char *zFilename, int bClear, TestDb **ppDb){ 17 KcDb *pKcDb; 18 int ok; 19 int rc = 0; 20 21 if( bClear ){ 22 char *zCmd = sqlite3_mprintf("rm -rf %s\n", zFilename); 23 system(zCmd); 24 sqlite3_free(zCmd); 25 } 26 27 pKcDb = (KcDb *)malloc(sizeof(KcDb)); 28 memset(pKcDb, 0, sizeof(KcDb)); 29 30 31 pKcDb->db = new kyotocabinet::TreeDB(); 32 pKcDb->db->tune_page(TESTDB_DEFAULT_PAGE_SIZE); 33 pKcDb->db->tune_page_cache( 34 TESTDB_DEFAULT_PAGE_SIZE * TESTDB_DEFAULT_CACHE_SIZE 35 ); 36 ok = pKcDb->db->open(zFilename, 37 kyotocabinet::PolyDB::OWRITER | kyotocabinet::PolyDB::OCREATE 38 ); 39 if( ok==0 ){ 40 free(pKcDb); 41 pKcDb = 0; 42 rc = 1; 43 } 44 45 *ppDb = (TestDb *)pKcDb; 46 return rc; 47 } 48 49 int test_kc_close(TestDb *pDb){ 50 KcDb *pKcDb = (KcDb *)pDb; 51 if( pKcDb->pVal ){ 52 delete [] pKcDb->pVal; 53 } 54 pKcDb->db->close(); 55 delete pKcDb->db; 56 free(pKcDb); 57 return 0; 58 } 59 60 int test_kc_write(TestDb *pDb, void *pKey, int nKey, void *pVal, int nVal){ 61 KcDb *pKcDb = (KcDb *)pDb; 62 int ok; 63 64 ok = pKcDb->db->set((const char *)pKey, nKey, (const char *)pVal, nVal); 65 return (ok ? 0 : 1); 66 } 67 68 int test_kc_delete(TestDb *pDb, void *pKey, int nKey){ 69 KcDb *pKcDb = (KcDb *)pDb; 70 int ok; 71 72 ok = pKcDb->db->remove((const char *)pKey, nKey); 73 return (ok ? 0 : 1); 74 } 75 76 int test_kc_delete_range( 77 TestDb *pDb, 78 void *pKey1, int nKey1, 79 void *pKey2, int nKey2 80 ){ 81 int res; 82 KcDb *pKcDb = (KcDb *)pDb; 83 kyotocabinet::DB::Cursor* pCur = pKcDb->db->cursor(); 84 85 if( pKey1 ){ 86 res = pCur->jump((const char *)pKey1, nKey1); 87 }else{ 88 res = pCur->jump(); 89 } 90 91 while( 1 ){ 92 const char *pKey; size_t nKey; 93 const char *pVal; size_t nVal; 94 95 pKey = pCur->get(&nKey, &pVal, &nVal); 96 if( pKey==0 ) break; 97 98 #ifndef NDEBUG 99 if( pKey1 ){ 100 res = memcmp(pKey, pKey1, MIN((size_t)nKey1, nKey)); 101 assert( res>0 || (res==0 && nKey>nKey1) ); 102 } 103 #endif 104 105 if( pKey2 ){ 106 res = memcmp(pKey, pKey2, MIN((size_t)nKey2, nKey)); 107 if( res>0 || (res==0 && (size_t)nKey2<nKey) ){ 108 delete [] pKey; 109 break; 110 } 111 } 112 pCur->remove(); 113 delete [] pKey; 114 } 115 116 delete pCur; 117 return 0; 118 } 119 120 int test_kc_fetch( 121 TestDb *pDb, 122 void *pKey, 123 int nKey, 124 void **ppVal, 125 int *pnVal 126 ){ 127 KcDb *pKcDb = (KcDb *)pDb; 128 size_t nVal; 129 130 if( pKcDb->pVal ){ 131 delete [] pKcDb->pVal; 132 pKcDb->pVal = 0; 133 } 134 135 pKcDb->pVal = pKcDb->db->get((const char *)pKey, nKey, &nVal); 136 if( pKcDb->pVal ){ 137 *ppVal = pKcDb->pVal; 138 *pnVal = nVal; 139 }else{ 140 *ppVal = 0; 141 *pnVal = -1; 142 } 143 144 return 0; 145 } 146 147 int test_kc_scan( 148 TestDb *pDb, /* Database handle */ 149 void *pCtx, /* Context pointer to pass to xCallback */ 150 int bReverse, /* True for a reverse order scan */ 151 void *pKey1, int nKey1, /* Start of search */ 152 void *pKey2, int nKey2, /* End of search */ 153 void (*xCallback)(void *pCtx, void *pKey, int nKey, void *pVal, int nVal) 154 ){ 155 KcDb *pKcDb = (KcDb *)pDb; 156 kyotocabinet::DB::Cursor* pCur = pKcDb->db->cursor(); 157 int res; 158 159 if( bReverse==0 ){ 160 if( pKey1 ){ 161 res = pCur->jump((const char *)pKey1, nKey1); 162 }else{ 163 res = pCur->jump(); 164 } 165 }else{ 166 if( pKey2 ){ 167 res = pCur->jump_back((const char *)pKey2, nKey2); 168 }else{ 169 res = pCur->jump_back(); 170 } 171 } 172 173 while( res ){ 174 const char *pKey; size_t nKey; 175 const char *pVal; size_t nVal; 176 pKey = pCur->get(&nKey, &pVal, &nVal); 177 178 if( bReverse==0 && pKey2 ){ 179 res = memcmp(pKey, pKey2, MIN((size_t)nKey2, nKey)); 180 if( res>0 || (res==0 && (size_t)nKey2<nKey) ){ 181 delete [] pKey; 182 break; 183 } 184 }else if( bReverse!=0 && pKey1 ){ 185 res = memcmp(pKey, pKey1, MIN((size_t)nKey1, nKey)); 186 if( res<0 || (res==0 && (size_t)nKey1>nKey) ){ 187 delete [] pKey; 188 break; 189 } 190 } 191 192 xCallback(pCtx, (void *)pKey, (int)nKey, (void *)pVal, (int)nVal); 193 delete [] pKey; 194 195 if( bReverse ){ 196 res = pCur->step_back(); 197 }else{ 198 res = pCur->step(); 199 } 200 } 201 202 delete pCur; 203 return 0; 204 } 205 #endif /* HAVE_KYOTOCABINET */ 206 207 #ifdef HAVE_MDB 208 #include "lmdb.h" 209 210 extern "C" { 211 struct MdbDb { 212 TestDb base; 213 MDB_env *env; 214 MDB_dbi dbi; 215 }; 216 } 217 218 int test_mdb_open( 219 const char *zSpec, 220 const char *zFilename, 221 int bClear, 222 TestDb **ppDb 223 ){ 224 MDB_txn *txn; 225 MdbDb *pMdb; 226 int rc; 227 228 if( bClear ){ 229 char *zCmd = sqlite3_mprintf("rm -rf %s\n", zFilename); 230 system(zCmd); 231 sqlite3_free(zCmd); 232 } 233 234 pMdb = (MdbDb *)malloc(sizeof(MdbDb)); 235 memset(pMdb, 0, sizeof(MdbDb)); 236 237 rc = mdb_env_create(&pMdb->env); 238 if( rc==0 ) rc = mdb_env_set_mapsize(pMdb->env, 1*1024*1024*1024); 239 if( rc==0 ) rc = mdb_env_open(pMdb->env, zFilename, MDB_NOSYNC|MDB_NOSUBDIR, 0600); 240 if( rc==0 ) rc = mdb_txn_begin(pMdb->env, NULL, 0, &txn); 241 if( rc==0 ){ 242 rc = mdb_open(txn, NULL, 0, &pMdb->dbi); 243 mdb_txn_commit(txn); 244 } 245 246 *ppDb = (TestDb *)pMdb; 247 return rc; 248 } 249 250 int test_mdb_close(TestDb *pDb){ 251 MdbDb *pMdb = (MdbDb *)pDb; 252 253 mdb_close(pMdb->env, pMdb->dbi); 254 mdb_env_close(pMdb->env); 255 free(pMdb); 256 return 0; 257 } 258 259 int test_mdb_write(TestDb *pDb, void *pKey, int nKey, void *pVal, int nVal){ 260 int rc; 261 MdbDb *pMdb = (MdbDb *)pDb; 262 MDB_val val; 263 MDB_val key; 264 MDB_txn *txn; 265 266 val.mv_size = nVal; 267 val.mv_data = pVal; 268 key.mv_size = nKey; 269 key.mv_data = pKey; 270 271 rc = mdb_txn_begin(pMdb->env, NULL, 0, &txn); 272 if( rc==0 ){ 273 rc = mdb_put(txn, pMdb->dbi, &key, &val, 0); 274 if( rc==0 ){ 275 rc = mdb_txn_commit(txn); 276 }else{ 277 mdb_txn_abort(txn); 278 } 279 } 280 281 return rc; 282 } 283 284 int test_mdb_delete(TestDb *pDb, void *pKey, int nKey){ 285 int rc; 286 MdbDb *pMdb = (MdbDb *)pDb; 287 MDB_val key; 288 MDB_txn *txn; 289 290 key.mv_size = nKey; 291 key.mv_data = pKey; 292 rc = mdb_txn_begin(pMdb->env, NULL, 0, &txn); 293 if( rc==0 ){ 294 rc = mdb_del(txn, pMdb->dbi, &key, 0); 295 if( rc==0 ){ 296 rc = mdb_txn_commit(txn); 297 }else{ 298 mdb_txn_abort(txn); 299 } 300 } 301 302 return rc; 303 } 304 305 int test_mdb_fetch( 306 TestDb *pDb, 307 void *pKey, 308 int nKey, 309 void **ppVal, 310 int *pnVal 311 ){ 312 int rc; 313 MdbDb *pMdb = (MdbDb *)pDb; 314 MDB_val key; 315 MDB_txn *txn; 316 317 key.mv_size = nKey; 318 key.mv_data = pKey; 319 320 rc = mdb_txn_begin(pMdb->env, NULL, MDB_RDONLY, &txn); 321 if( rc==0 ){ 322 MDB_val val = {0, 0}; 323 rc = mdb_get(txn, pMdb->dbi, &key, &val); 324 if( rc==MDB_NOTFOUND ){ 325 rc = 0; 326 *ppVal = 0; 327 *pnVal = -1; 328 }else{ 329 *ppVal = val.mv_data; 330 *pnVal = val.mv_size; 331 } 332 mdb_txn_commit(txn); 333 } 334 335 return rc; 336 } 337 338 int test_mdb_scan( 339 TestDb *pDb, /* Database handle */ 340 void *pCtx, /* Context pointer to pass to xCallback */ 341 int bReverse, /* True for a reverse order scan */ 342 void *pKey1, int nKey1, /* Start of search */ 343 void *pKey2, int nKey2, /* End of search */ 344 void (*xCallback)(void *pCtx, void *pKey, int nKey, void *pVal, int nVal) 345 ){ 346 MdbDb *pMdb = (MdbDb *)pDb; 347 int rc; 348 MDB_cursor_op op = bReverse ? MDB_PREV : MDB_NEXT; 349 MDB_txn *txn; 350 351 rc = mdb_txn_begin(pMdb->env, NULL, MDB_RDONLY, &txn); 352 if( rc==0 ){ 353 MDB_cursor *csr; 354 MDB_val key = {0, 0}; 355 MDB_val val = {0, 0}; 356 357 rc = mdb_cursor_open(txn, pMdb->dbi, &csr); 358 if( rc==0 ){ 359 while( mdb_cursor_get(csr, &key, &val, op)==0 ){ 360 xCallback(pCtx, key.mv_data, key.mv_size, val.mv_data, val.mv_size); 361 } 362 mdb_cursor_close(csr); 363 } 364 } 365 366 return rc; 367 } 368 369 #endif /* HAVE_MDB */ 370