Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add support for testing against mdb.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 51816384756d6c620e991bb4ef81a284d5ef56f3
User & Date: dan 2012-12-03 20:19:24.220
Context
2012-12-17
19:36
Add new files fts5.c and fts5func.c. check-in: bd4efbb2f7 user: dan tags: trunk
2012-12-03
20:19
Add support for testing against mdb. check-in: 5181638475 user: dan tags: trunk
14:22
Add lsmperf.wiki to the links on index.wiki. check-in: 6de140a17f user: dan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to lsm-test/lsmtest.h.
65
66
67
68
69
70
71









72
73
74
75
76
77
78
int test_kc_close(TestDb *);
int test_kc_write(TestDb *, void *, int , void *, int);
int test_kc_delete(TestDb *, void *, int);
int test_kc_fetch(TestDb *, void *, int, void **, int *);
int test_kc_scan(TestDb *, void *, int, void *, int, void *, int,
  void (*)(void *, void *, int , void *, int)
);










/* 
** Functions in wrapper3.c. This file contains the tdb wrapper for lsm.
** The wrapper for lsm is a bit more involved than the others, as it 
** includes code for a couple of different lsm configurations, and for
** various types of fault injection and robustness testing.
*/







>
>
>
>
>
>
>
>
>







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
int test_kc_close(TestDb *);
int test_kc_write(TestDb *, void *, int , void *, int);
int test_kc_delete(TestDb *, void *, int);
int test_kc_fetch(TestDb *, void *, int, void **, int *);
int test_kc_scan(TestDb *, void *, int, void *, int, void *, int,
  void (*)(void *, void *, int , void *, int)
);

int test_mdb_open(const char *zFilename, int bClear, TestDb **ppDb);
int test_mdb_close(TestDb *);
int test_mdb_write(TestDb *, void *, int , void *, int);
int test_mdb_delete(TestDb *, void *, int);
int test_mdb_fetch(TestDb *, void *, int, void **, int *);
int test_mdb_scan(TestDb *, void *, int, void *, int, void *, int,
  void (*)(void *, void *, int , void *, int)
);

/* 
** Functions in wrapper3.c. This file contains the tdb wrapper for lsm.
** The wrapper for lsm is a bit more involved than the others, as it 
** includes code for a couple of different lsm configurations, and for
** various types of fault injection and robustness testing.
*/
Changes to lsm-test/lsmtest1.c.
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
  int nLookupTest,                /* Number of lookup tests to run */
  int nScanTest,                  /* Number of scan tests to run */
  int *pRc                        /* IN/OUT: Error code */
){
  int j;
  int rc = *pRc;

  if( rc==0 && nScanTest ){
    TestDb *pDb2 = 0;

    /* Open a control db (i.e. one that we assume works) */
    rc = testControlDb(&pDb2);

    for(j=iFirst; rc==0 && j<=iLast; j++){
      void *pKey; int nKey;         /* Database key to insert */







|







159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
  int nLookupTest,                /* Number of lookup tests to run */
  int nScanTest,                  /* Number of scan tests to run */
  int *pRc                        /* IN/OUT: Error code */
){
  int j;
  int rc = *pRc;

  if( 0 && rc==0 && nScanTest ){
    TestDb *pDb2 = 0;

    /* Open a control db (i.e. one that we assume works) */
    rc = testControlDb(&pDb2);

    for(j=iFirst; rc==0 && j<=iLast; j++){
      void *pKey; int nKey;         /* Database key to insert */
Changes to lsm-test/lsmtest_tdb.c.
291
292
293
294
295
296
297






































































298
299
300
301
302
303
304
  return 0;
}
#endif /* HAVE_KYOTOCABINET */
/* 
** End wrapper for Kyoto cabinet.
*************************************************************************/







































































/*************************************************************************
** Begin wrapper for SQLite.
*/

/*
** nOpenTrans:
**   The number of open nested transactions, in the same sense as used







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
  return 0;
}
#endif /* HAVE_KYOTOCABINET */
/* 
** End wrapper for Kyoto cabinet.
*************************************************************************/

#ifdef HAVE_MDB
static int mdb_close(TestDb *pTestDb){
  return test_mdb_close(pTestDb);
}

static int mdb_write(
  TestDb *pTestDb, 
  void *pKey, 
  int nKey, 
  void *pVal, 
  int nVal
){
  return test_mdb_write(pTestDb, pKey, nKey, pVal, nVal);
}

static int mdb_delete(TestDb *pTestDb, void *pKey, int nKey){
  return test_mdb_delete(pTestDb, pKey, nKey);
}

static int mdb_fetch(
  TestDb *pTestDb, 
  void *pKey, 
  int nKey, 
  void **ppVal, 
  int *pnVal
){
  if( pKey==0 ) return LSM_OK;
  return test_mdb_fetch(pTestDb, pKey, nKey, ppVal, pnVal);
}

static int mdb_scan(
  TestDb *pTestDb,
  void *pCtx,
  int bReverse,
  void *pFirst, int nFirst,
  void *pLast, int nLast,
  void (*xCallback)(void *, void *, int , void *, int)
){
  return test_mdb_scan(
      pTestDb, pCtx, bReverse, pFirst, nFirst, pLast, nLast, xCallback
  );
}

static int mdb_open(const char *zFilename, int bClear, TestDb **ppDb){
  static const DatabaseMethods KcdbMethods = {
    mdb_close,
    mdb_write,
    mdb_delete,
    0,
    mdb_fetch,
    mdb_scan,
    error_transaction_function,
    error_transaction_function,
    error_transaction_function
  };

  int rc;
  TestDb *pTestDb = 0;

  rc = test_mdb_open(zFilename, bClear, &pTestDb);
  if( rc!=0 ){
    *ppDb = 0;
    return rc;
  }
  pTestDb->pMethods = &KcdbMethods;
  *ppDb = pTestDb;
  return 0;
}
#endif /* HAVE_MDB */

/*************************************************************************
** Begin wrapper for SQLite.
*/

/*
** nOpenTrans:
**   The number of open nested transactions, in the same sense as used
621
622
623
624
625
626
627
628



629
630
631
632
633
634
635
  { "lsm_mt2",      "testdb.lsm_mt2",   test_lsm_mt2 },
  { "lsm_mt3",      "testdb.lsm_mt3",   test_lsm_mt3 },
#endif
#ifdef HAVE_LEVELDB
  { "leveldb",      "testdb.leveldb",   test_leveldb_open },
#endif
#ifdef HAVE_KYOTOCABINET
  { "kyotocabinet", "testdb.kc",        kc_open }



#endif
};

const char *tdb_system_name(int i){
  if( i<0 || i>=ArraySize(aLib) ) return 0;
  return aLib[i].zName;
}







|
>
>
>







691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
  { "lsm_mt2",      "testdb.lsm_mt2",   test_lsm_mt2 },
  { "lsm_mt3",      "testdb.lsm_mt3",   test_lsm_mt3 },
#endif
#ifdef HAVE_LEVELDB
  { "leveldb",      "testdb.leveldb",   test_leveldb_open },
#endif
#ifdef HAVE_KYOTOCABINET
  { "kyotocabinet", "testdb.kc",        kc_open },
#endif
#ifdef HAVE_MDB
  { "mdb", "./testdb.mdb",        mdb_open }
#endif
};

const char *tdb_system_name(int i){
  if( i<0 || i>=ArraySize(aLib) ) return 0;
  return aLib[i].zName;
}
Changes to lsm-test/lsmtest_tdb2.cc.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158


#include "lsmtest.h"
#include <stdlib.h>

#ifdef HAVE_LEVELDB
#include "leveldb/db.h"
extern "C" {
  struct LevelDb {
    TestDb base;
    leveldb::DB* db;
    std::string *pRes;
  };
}

int test_leveldb_open(const char *zFilename, int bClear, TestDb **ppDb){
  LevelDb *pLevelDb;

  if( bClear ){
    char *zCmd = sqlite3_mprintf("rm -rf %s\n", zFilename);
    system(zCmd);
    sqlite3_free(zCmd);
  }

  pLevelDb = (LevelDb *)malloc(sizeof(LevelDb));
  memset(pLevelDb, 0, sizeof(LevelDb));

  leveldb::Options options;
  options.create_if_missing = 1;
  leveldb::Status s = leveldb::DB::Open(options, zFilename, &pLevelDb->db);

  if( s.ok() ){
    *ppDb = (TestDb *)pLevelDb;
    pLevelDb->pRes = new std::string("");
  }else{
    test_leveldb_close((TestDb *)pLevelDb);
    *ppDb = 0;
    return 1;
  }
  return 0;
}

int test_leveldb_close(TestDb *pDb){
  LevelDb *pLevelDb = (LevelDb *)pDb;
  if( pDb ){
    if( pLevelDb->db ) delete pLevelDb->db;
  }
  free((void *)pDb);
  return 0;
}

int test_leveldb_write(TestDb *pDb, void *pKey, int nKey, void *pVal, int nVal){
  LevelDb *pLevelDb = (LevelDb *)pDb;
  leveldb::Status s = pLevelDb->db->Put(leveldb::WriteOptions(), 
      leveldb::Slice((const char *)pKey, nKey), 
      leveldb::Slice((const char *)pVal, nVal) 
  );
  return !s.ok();
}

int test_leveldb_delete(TestDb *pDb, void *pKey, int nKey){
  LevelDb *pLevelDb = (LevelDb *)pDb;
  leveldb::Status s = pLevelDb->db->Delete(leveldb::WriteOptions(), 
      leveldb::Slice((const char *)pKey, nKey)
  );
  return !s.ok();
}

int test_leveldb_fetch(
  TestDb *pDb, 
  void *pKey, 
  int nKey, 
  void **ppVal, 
  int *pnVal
){
  LevelDb *pLevelDb = (LevelDb *)pDb;
  pLevelDb->pRes->assign("");
  leveldb::Status s = pLevelDb->db->Get(
      leveldb::ReadOptions(), 
      leveldb::Slice((const char *)pKey, nKey), 
      pLevelDb->pRes
  );
  if( s.ok() ){
    *ppVal = (void *)pLevelDb->pRes->data();
    *pnVal = (int)pLevelDb->pRes->length();
  }else{
    *pnVal = -1;
    *ppVal = 0;
  }
  return 0;
}

int test_leveldb_scan(
  TestDb *pDb,                    /* Database handle */
  void *pCtx,                     /* Context pointer to pass to xCallback */
  int bReverse,                   /* True to iterate in reverse order */
  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)
){
  LevelDb *pLevelDb = (LevelDb *)pDb;
  leveldb::Iterator *pIter;

  leveldb::Slice sKey1((const char *)pKey1, nKey1);
  leveldb::Slice sKey2((const char *)pKey2, nKey2);

  pIter = pLevelDb->db->NewIterator(leveldb::ReadOptions());
  if( bReverse==0 ){
    if( pKey1 ){
      pIter->Seek(sKey1);
    }else{
      pIter->SeekToFirst();
    }
  }else{
    if( pKey2 ){
      pIter->Seek(sKey2);
      if( pIter->Valid()==0 ){
        pIter->SeekToLast();
      }else{
        int res = pIter->key().compare(sKey2);
        assert( res>=0 );
        if( res>0 ){
          pIter->Prev();
        }
        assert( pIter->Valid()==0 || pIter->key().compare(sKey2)<=0 );
      }
    }else{
      pIter->SeekToLast();
    }
  }

  while( pIter->Valid() ){
    if( (bReverse==0 && pKey2 && pIter->key().compare(sKey2)>0) ) break;
    if( (bReverse!=0 && pKey1 && pIter->key().compare(sKey1)<0) ) break;

    leveldb::Slice k = pIter->key();
    leveldb::Slice v = pIter->value();
    xCallback(pCtx, (void *)k.data(), k.size(), (void *)v.data(), v.size());

    if( bReverse==0 ){
      pIter->Next();
    }else{
      pIter->Prev();
    }
  }

  delete pIter;
  return LSM_OK;
}
#endif

#ifdef HAVE_KYOTOCABINET
#include "kcpolydb.h"
extern "C" {
  struct KcDb {
    TestDb base;
    kyotocabinet::TreeDB* db;
    char *pVal;





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5


















































































































































6
7
8
9
10
11
12


#include "lsmtest.h"
#include <stdlib.h>



















































































































































#ifdef HAVE_KYOTOCABINET
#include "kcpolydb.h"
extern "C" {
  struct KcDb {
    TestDb base;
    kyotocabinet::TreeDB* db;
    char *pVal;
300
301
302
303
304
305
306































































































































































307
308
      res = pCur->step();
    }
  }

  delete pCur;
  return 0;
}































































































































































#endif








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
      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 *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 */