tdbTest.cpp 13.0 KB
Newer Older
1
#include <gtest/gtest.h>
H
Hongze Cheng 已提交
2

H
Hongze Cheng 已提交
3
#define ALLOW_FORBID_FUNC
H
Hongze Cheng 已提交
4
#include "os.h"
H
Hongze Cheng 已提交
5
#include "tdb.h"
H
more  
Hongze Cheng 已提交
6

H
Hongze Cheng 已提交
7
#include <string>
H
Hongze Cheng 已提交
8 9
#include <thread>
#include <vector>
H
Hongze Cheng 已提交
10

H
Hongze Cheng 已提交
11 12 13 14 15 16 17
typedef struct SPoolMem {
  int64_t          size;
  struct SPoolMem *prev;
  struct SPoolMem *next;
} SPoolMem;

static SPoolMem *openPool() {
H
Hongze Cheng 已提交
18
  SPoolMem *pPool = (SPoolMem *)taosMemoryMalloc(sizeof(*pPool));
H
Hongze Cheng 已提交
19 20 21 22 23 24 25

  pPool->prev = pPool->next = pPool;
  pPool->size = 0;

  return pPool;
}

H
Hongze Cheng 已提交
26
static void clearPool(SPoolMem *pPool) {
H
Hongze Cheng 已提交
27 28 29 30 31 32 33 34 35 36 37
  SPoolMem *pMem;

  do {
    pMem = pPool->next;

    if (pMem == pPool) break;

    pMem->next->prev = pMem->prev;
    pMem->prev->next = pMem->next;
    pPool->size -= pMem->size;

H
Hongze Cheng 已提交
38
    taosMemoryFree(pMem);
H
Hongze Cheng 已提交
39 40 41
  } while (1);

  assert(pPool->size == 0);
H
Hongze Cheng 已提交
42
}
H
Hongze Cheng 已提交
43

H
Hongze Cheng 已提交
44 45
static void closePool(SPoolMem *pPool) {
  clearPool(pPool);
H
Hongze Cheng 已提交
46
  taosMemoryFree(pPool);
H
Hongze Cheng 已提交
47 48
}

H
Hongze Cheng 已提交
49
static void *poolMalloc(void *arg, size_t size) {
H
Hongze Cheng 已提交
50 51 52 53
  void     *ptr = NULL;
  SPoolMem *pPool = (SPoolMem *)arg;
  SPoolMem *pMem;

H
Hongze Cheng 已提交
54
  pMem = (SPoolMem *)taosMemoryMalloc(sizeof(*pMem) + size);
H
Hongze Cheng 已提交
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
  if (pMem == NULL) {
    assert(0);
  }

  pMem->size = sizeof(*pMem) + size;
  pMem->next = pPool->next;
  pMem->prev = pPool;

  pPool->next->prev = pMem;
  pPool->next = pMem;
  pPool->size += pMem->size;

  ptr = (void *)(&pMem[1]);
  return ptr;
}

static void poolFree(void *arg, void *ptr) {
  SPoolMem *pPool = (SPoolMem *)arg;
  SPoolMem *pMem;

  pMem = &(((SPoolMem *)ptr)[-1]);

  pMem->next->prev = pMem->prev;
  pMem->prev->next = pMem->next;
  pPool->size -= pMem->size;

H
Hongze Cheng 已提交
81
  taosMemoryFree(pMem);
H
Hongze Cheng 已提交
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
}

static int tKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
  int k1, k2;

  std::string s1((char *)pKey1 + 3, kLen1 - 3);
  std::string s2((char *)pKey2 + 3, kLen2 - 3);
  k1 = stoi(s1);
  k2 = stoi(s2);

  if (k1 < k2) {
    return -1;
  } else if (k1 > k2) {
    return 1;
  } else {
    return 0;
  }
}

static int tDefaultKeyCmpr(const void *pKey1, int keyLen1, const void *pKey2, int keyLen2) {
  int mlen;
  int cret;

  ASSERT(keyLen1 > 0 && keyLen2 > 0 && pKey1 != NULL && pKey2 != NULL);

  mlen = keyLen1 < keyLen2 ? keyLen1 : keyLen2;
  cret = memcmp(pKey1, pKey2, mlen);
  if (cret == 0) {
    if (keyLen1 < keyLen2) {
      cret = -1;
    } else if (keyLen1 > keyLen2) {
      cret = 1;
    } else {
      cret = 0;
    }
  }
  return cret;
}
H
more  
Hongze Cheng 已提交
120

H
Hongze Cheng 已提交
121
TEST(tdb_test, simple_insert1) {
H
Hongze Cheng 已提交
122
  int           ret;
H
Hongze Cheng 已提交
123 124
  TDB          *pEnv;
  TTB          *pDb;
H
Hongze Cheng 已提交
125
  tdb_cmpr_fn_t compFunc;
H
Hongze Cheng 已提交
126
  int           nData = 1000000;
H
Hongze Cheng 已提交
127
  TXN           txn;
H
more  
Hongze Cheng 已提交
128

H
Hongze Cheng 已提交
129 130
  taosRemoveDir("tdb");

H
Hongze Cheng 已提交
131
  // Open Env
H
Hongze Cheng 已提交
132
  ret = tdbOpen("tdb", 4096, 64, &pEnv);
H
Hongze Cheng 已提交
133
  GTEST_ASSERT_EQ(ret, 0);
H
Hongze Cheng 已提交
134

H
Hongze Cheng 已提交
135
  // Create a database
H
more  
Hongze Cheng 已提交
136
  compFunc = tKeyCmpr;
H
Hongze Cheng 已提交
137
  ret = tdbTbOpen("db.db", -1, -1, compFunc, pEnv, &pDb);
H
Hongze Cheng 已提交
138
  GTEST_ASSERT_EQ(ret, 0);
H
Hongze Cheng 已提交
139

H
Hongze Cheng 已提交
140
  {
H
Hongze Cheng 已提交
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
    char      key[64];
    char      val[64];
    int64_t   poolLimit = 4096;  // 1M pool limit
    int64_t   txnid = 0;
    SPoolMem *pPool;

    // open the pool
    pPool = openPool();

    // start a transaction
    txnid++;
    tdbTxnOpen(&txn, txnid, poolMalloc, poolFree, pPool, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED);
    tdbBegin(pEnv, &txn);

    for (int iData = 1; iData <= nData; iData++) {
      sprintf(key, "key%d", iData);
      sprintf(val, "value%d", iData);
H
Hongze Cheng 已提交
158
      ret = tdbTbInsert(pDb, key, strlen(key), val, strlen(val), &txn);
H
Hongze Cheng 已提交
159 160 161 162 163 164 165 166 167 168 169 170 171
      GTEST_ASSERT_EQ(ret, 0);

      // if pool is full, commit the transaction and start a new one
      if (pPool->size >= poolLimit) {
        // commit current transaction
        tdbCommit(pEnv, &txn);
        tdbTxnClose(&txn);

        // start a new transaction
        clearPool(pPool);
        txnid++;
        tdbTxnOpen(&txn, txnid, poolMalloc, poolFree, pPool, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED);
        tdbBegin(pEnv, &txn);
H
Hongze Cheng 已提交
172 173 174
      }
    }

H
Hongze Cheng 已提交
175 176 177 178
    // commit the transaction
    tdbCommit(pEnv, &txn);
    tdbTxnClose(&txn);

H
Hongze Cheng 已提交
179
    {  // Query the data
H
Hongze Cheng 已提交
180 181 182
      void *pVal = NULL;
      int   vLen;

H
Hongze Cheng 已提交
183 184 185 186
      for (int i = 1; i <= nData; i++) {
        sprintf(key, "key%d", i);
        sprintf(val, "value%d", i);

H
Hongze Cheng 已提交
187
        ret = tdbTbGet(pDb, key, strlen(key), &pVal, &vLen);
H
Hongze Cheng 已提交
188
        ASSERT(ret == 0);
H
Hongze Cheng 已提交
189 190 191 192 193
        GTEST_ASSERT_EQ(ret, 0);

        GTEST_ASSERT_EQ(vLen, strlen(val));
        GTEST_ASSERT_EQ(memcmp(val, pVal, vLen), 0);
      }
H
Hongze Cheng 已提交
194

H
Hongze Cheng 已提交
195
      tdbFree(pVal);
H
Hongze Cheng 已提交
196
    }
H
Hongze Cheng 已提交
197

H
Hongze Cheng 已提交
198
    {  // Iterate to query the DB data
H
Hongze Cheng 已提交
199
      TBC  *pDBC;
H
Hongze Cheng 已提交
200 201 202 203
      void *pKey = NULL;
      void *pVal = NULL;
      int   vLen, kLen;
      int   count = 0;
H
Hongze Cheng 已提交
204

H
Hongze Cheng 已提交
205
      ret = tdbTbcOpen(pDb, &pDBC, NULL);
H
Hongze Cheng 已提交
206 207
      GTEST_ASSERT_EQ(ret, 0);

H
Hongze Cheng 已提交
208
      tdbTbcMoveToFirst(pDBC);
H
Hongze Cheng 已提交
209

H
Hongze Cheng 已提交
210
      for (;;) {
H
Hongze Cheng 已提交
211
        ret = tdbTbcNext(pDBC, &pKey, &kLen, &pVal, &vLen);
H
Hongze Cheng 已提交
212
        if (ret < 0) break;
H
more  
Hongze Cheng 已提交
213 214 215 216 217

        // std::cout.write((char *)pKey, kLen) /* << " " << kLen */ << " ";
        // std::cout.write((char *)pVal, vLen) /* << " " << vLen */;
        // std::cout << std::endl;

H
Hongze Cheng 已提交
218 219 220 221 222
        count++;
      }

      GTEST_ASSERT_EQ(count, nData);

H
Hongze Cheng 已提交
223
      tdbTbcClose(pDBC);
H
Hongze Cheng 已提交
224

H
Hongze Cheng 已提交
225 226
      tdbFree(pKey);
      tdbFree(pVal);
H
Hongze Cheng 已提交
227
    }
H
Hongze Cheng 已提交
228
  }
H
Hongze Cheng 已提交
229

H
Hongze Cheng 已提交
230
  ret = tdbTbDrop(pDb);
H
Hongze Cheng 已提交
231
  GTEST_ASSERT_EQ(ret, 0);
H
Hongze Cheng 已提交
232

H
Hongze Cheng 已提交
233
  // Close a database
H
Hongze Cheng 已提交
234
  tdbTbClose(pDb);
H
Hongze Cheng 已提交
235

H
Hongze Cheng 已提交
236
  // Close Env
H
Hongze Cheng 已提交
237
  ret = tdbClose(pEnv);
H
Hongze Cheng 已提交
238 239 240
  GTEST_ASSERT_EQ(ret, 0);
}

H
Hongze Cheng 已提交
241
TEST(tdb_test, simple_insert2) {
H
Hongze Cheng 已提交
242
  int           ret;
H
Hongze Cheng 已提交
243 244
  TDB          *pEnv;
  TTB          *pDb;
H
Hongze Cheng 已提交
245 246 247
  tdb_cmpr_fn_t compFunc;
  int           nData = 1000000;
  TXN           txn;
H
Hongze Cheng 已提交
248

H
Hongze Cheng 已提交
249 250
  taosRemoveDir("tdb");

H
Hongze Cheng 已提交
251
  // Open Env
H
Hongze Cheng 已提交
252
  ret = tdbOpen("tdb", 1024, 10, &pEnv);
H
Hongze Cheng 已提交
253 254 255
  GTEST_ASSERT_EQ(ret, 0);

  // Create a database
H
Hongze Cheng 已提交
256
  compFunc = tDefaultKeyCmpr;
H
Hongze Cheng 已提交
257
  ret = tdbTbOpen("db.db", -1, -1, compFunc, pEnv, &pDb);
H
Hongze Cheng 已提交
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
  GTEST_ASSERT_EQ(ret, 0);

  {
    char      key[64];
    char      val[64];
    int64_t   txnid = 0;
    SPoolMem *pPool;

    // open the pool
    pPool = openPool();

    // start a transaction
    txnid++;
    tdbTxnOpen(&txn, txnid, poolMalloc, poolFree, pPool, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED);
    tdbBegin(pEnv, &txn);

    for (int iData = 1; iData <= nData; iData++) {
      sprintf(key, "key%d", iData);
      sprintf(val, "value%d", iData);
H
Hongze Cheng 已提交
277
      ret = tdbTbInsert(pDb, key, strlen(key), val, strlen(val), &txn);
H
Hongze Cheng 已提交
278 279 280 281
      GTEST_ASSERT_EQ(ret, 0);
    }

    {  // Iterate to query the DB data
H
Hongze Cheng 已提交
282
      TBC  *pDBC;
H
Hongze Cheng 已提交
283 284 285 286 287
      void *pKey = NULL;
      void *pVal = NULL;
      int   vLen, kLen;
      int   count = 0;

H
Hongze Cheng 已提交
288
      ret = tdbTbcOpen(pDb, &pDBC, NULL);
H
Hongze Cheng 已提交
289 290
      GTEST_ASSERT_EQ(ret, 0);

H
Hongze Cheng 已提交
291
      tdbTbcMoveToFirst(pDBC);
H
Hongze Cheng 已提交
292

H
Hongze Cheng 已提交
293
      for (;;) {
H
Hongze Cheng 已提交
294
        ret = tdbTbcNext(pDBC, &pKey, &kLen, &pVal, &vLen);
H
Hongze Cheng 已提交
295 296
        if (ret < 0) break;

H
Hongze Cheng 已提交
297 298 299
        // std::cout.write((char *)pKey, kLen) /* << " " << kLen */ << " ";
        // std::cout.write((char *)pVal, vLen) /* << " " << vLen */;
        // std::cout << std::endl;
H
Hongze Cheng 已提交
300 301 302 303 304 305

        count++;
      }

      GTEST_ASSERT_EQ(count, nData);

H
Hongze Cheng 已提交
306
      tdbTbcClose(pDBC);
H
Hongze Cheng 已提交
307

H
Hongze Cheng 已提交
308 309
      tdbFree(pKey);
      tdbFree(pVal);
H
Hongze Cheng 已提交
310 311 312 313 314 315 316
    }
  }

  // commit the transaction
  tdbCommit(pEnv, &txn);
  tdbTxnClose(&txn);

H
Hongze Cheng 已提交
317
  ret = tdbTbDrop(pDb);
H
Hongze Cheng 已提交
318 319 320
  GTEST_ASSERT_EQ(ret, 0);

  // Close a database
H
Hongze Cheng 已提交
321
  tdbTbClose(pDb);
H
Hongze Cheng 已提交
322

H
Hongze Cheng 已提交
323
  // Close Env
H
Hongze Cheng 已提交
324
  ret = tdbClose(pEnv);
H
Hongze Cheng 已提交
325
  GTEST_ASSERT_EQ(ret, 0);
H
Hongze Cheng 已提交
326 327
}

H
Hongze Cheng 已提交
328 329
TEST(tdb_test, simple_delete1) {
  int       ret;
H
Hongze Cheng 已提交
330
  TTB      *pDb;
H
Hongze Cheng 已提交
331 332 333
  char      key[128];
  char      data[128];
  TXN       txn;
H
Hongze Cheng 已提交
334
  TDB      *pEnv;
H
Hongze Cheng 已提交
335 336 337 338
  SPoolMem *pPool;
  void     *pKey = NULL;
  void     *pData = NULL;
  int       nKey;
H
Hongze Cheng 已提交
339
  TBC      *pDbc;
H
Hongze Cheng 已提交
340
  int       nData;
H
Hongze Cheng 已提交
341
  int       nKV = 69;
H
Hongze Cheng 已提交
342 343 344 345 346 347

  taosRemoveDir("tdb");

  pPool = openPool();

  // open env
H
Hongze Cheng 已提交
348
  ret = tdbOpen("tdb", 1024, 256, &pEnv);
H
Hongze Cheng 已提交
349 350 351
  GTEST_ASSERT_EQ(ret, 0);

  // open database
H
Hongze Cheng 已提交
352
  ret = tdbTbOpen("db.db", -1, -1, tKeyCmpr, pEnv, &pDb);
H
Hongze Cheng 已提交
353 354 355 356 357 358 359 360 361
  GTEST_ASSERT_EQ(ret, 0);

  tdbTxnOpen(&txn, 0, poolMalloc, poolFree, pPool, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED);
  tdbBegin(pEnv, &txn);

  // loop to insert batch data
  for (int iData = 0; iData < nKV; iData++) {
    sprintf(key, "key%d", iData);
    sprintf(data, "data%d", iData);
H
Hongze Cheng 已提交
362
    ret = tdbTbInsert(pDb, key, strlen(key), data, strlen(data), &txn);
H
Hongze Cheng 已提交
363 364 365 366 367 368 369 370
    GTEST_ASSERT_EQ(ret, 0);
  }

  // query the data
  for (int iData = 0; iData < nKV; iData++) {
    sprintf(key, "key%d", iData);
    sprintf(data, "data%d", iData);

H
Hongze Cheng 已提交
371
    ret = tdbTbGet(pDb, key, strlen(key), &pData, &nData);
H
Hongze Cheng 已提交
372 373 374 375 376
    GTEST_ASSERT_EQ(ret, 0);
    GTEST_ASSERT_EQ(memcmp(data, pData, nData), 0);
  }

  // loop to delete some data
H
Hongze Cheng 已提交
377
  for (int iData = nKV - 1; iData > 30; iData--) {
H
Hongze Cheng 已提交
378 379
    sprintf(key, "key%d", iData);

H
Hongze Cheng 已提交
380
    ret = tdbTbDelete(pDb, key, strlen(key), &txn);
H
Hongze Cheng 已提交
381 382 383 384
    GTEST_ASSERT_EQ(ret, 0);
  }

  // query the data
H
Hongze Cheng 已提交
385 386 387
  for (int iData = 0; iData < nKV; iData++) {
    sprintf(key, "key%d", iData);

H
Hongze Cheng 已提交
388
    ret = tdbTbGet(pDb, key, strlen(key), &pData, &nData);
H
Hongze Cheng 已提交
389 390 391 392 393 394 395 396
    if (iData <= 30) {
      GTEST_ASSERT_EQ(ret, 0);
    } else {
      GTEST_ASSERT_EQ(ret, -1);
    }
  }

  // loop to iterate the data
H
Hongze Cheng 已提交
397
  tdbTbcOpen(pDb, &pDbc, NULL);
H
Hongze Cheng 已提交
398

H
Hongze Cheng 已提交
399
  ret = tdbTbcMoveToFirst(pDbc);
H
Hongze Cheng 已提交
400 401 402 403 404
  GTEST_ASSERT_EQ(ret, 0);

  pKey = NULL;
  pData = NULL;
  for (;;) {
H
Hongze Cheng 已提交
405
    ret = tdbTbcNext(pDbc, &pKey, &nKey, &pData, &nData);
H
Hongze Cheng 已提交
406 407 408 409 410 411 412
    if (ret < 0) break;

    std::cout.write((char *)pKey, nKey) /* << " " << kLen */ << " ";
    std::cout.write((char *)pData, nData) /* << " " << vLen */;
    std::cout << std::endl;
  }

H
Hongze Cheng 已提交
413
  tdbTbcClose(pDbc);
H
Hongze Cheng 已提交
414 415 416 417 418

  tdbCommit(pEnv, &txn);

  closePool(pPool);

H
Hongze Cheng 已提交
419 420
  tdbTbClose(pDb);
  tdbClose(pEnv);
H
Hongze Cheng 已提交
421 422 423 424
}

TEST(tdb_test, simple_upsert1) {
  int       ret;
H
Hongze Cheng 已提交
425 426
  TDB      *pEnv;
  TTB      *pDb;
H
Hongze Cheng 已提交
427 428 429 430 431 432 433 434 435 436
  int       nData = 100000;
  char      key[64];
  char      data[64];
  void     *pData = NULL;
  SPoolMem *pPool;
  TXN       txn;

  taosRemoveDir("tdb");

  // open env
H
Hongze Cheng 已提交
437
  ret = tdbOpen("tdb", 4096, 64, &pEnv);
H
Hongze Cheng 已提交
438 439 440
  GTEST_ASSERT_EQ(ret, 0);

  // open database
H
Hongze Cheng 已提交
441
  ret = tdbTbOpen("db.db", -1, -1, NULL, pEnv, &pDb);
H
Hongze Cheng 已提交
442 443 444 445 446 447 448 449 450 451
  GTEST_ASSERT_EQ(ret, 0);

  pPool = openPool();
  // insert some data
  tdbTxnOpen(&txn, 0, poolMalloc, poolFree, pPool, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED);
  tdbBegin(pEnv, &txn);

  for (int iData = 0; iData < nData; iData++) {
    sprintf(key, "key%d", iData);
    sprintf(data, "data%d", iData);
H
Hongze Cheng 已提交
452
    ret = tdbTbInsert(pDb, key, strlen(key), data, strlen(data), &txn);
H
Hongze Cheng 已提交
453 454 455 456 457 458 459
    GTEST_ASSERT_EQ(ret, 0);
  }

  // query the data
  for (int iData = 0; iData < nData; iData++) {
    sprintf(key, "key%d", iData);
    sprintf(data, "data%d", iData);
H
Hongze Cheng 已提交
460
    ret = tdbTbGet(pDb, key, strlen(key), &pData, &nData);
H
Hongze Cheng 已提交
461 462 463 464 465 466 467 468
    GTEST_ASSERT_EQ(ret, 0);
    GTEST_ASSERT_EQ(memcmp(pData, data, nData), 0);
  }

  // upsert some data
  for (int iData = 0; iData < nData; iData++) {
    sprintf(key, "key%d", iData);
    sprintf(data, "data%d-u", iData);
H
Hongze Cheng 已提交
469
    ret = tdbTbUpsert(pDb, key, strlen(key), data, strlen(data), &txn);
H
Hongze Cheng 已提交
470 471 472 473 474 475 476 477 478
    GTEST_ASSERT_EQ(ret, 0);
  }

  tdbCommit(pEnv, &txn);

  // query the data
  for (int iData = 0; iData < nData; iData++) {
    sprintf(key, "key%d", iData);
    sprintf(data, "data%d-u", iData);
H
Hongze Cheng 已提交
479
    ret = tdbTbGet(pDb, key, strlen(key), &pData, &nData);
H
Hongze Cheng 已提交
480 481 482 483
    GTEST_ASSERT_EQ(ret, 0);
    GTEST_ASSERT_EQ(memcmp(pData, data, nData), 0);
  }

H
Hongze Cheng 已提交
484 485
  tdbTbClose(pDb);
  tdbClose(pEnv);
H
Hongze Cheng 已提交
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
}

TEST(tdb_test, multi_thread_query) {
  int           ret;
  TDB          *pEnv;
  TTB          *pDb;
  tdb_cmpr_fn_t compFunc;
  int           nData = 20000;
  TXN           txn;

  taosRemoveDir("tdb");

  // Open Env
  ret = tdbOpen("tdb", 512, 1, &pEnv);
  GTEST_ASSERT_EQ(ret, 0);

  // Create a database
  compFunc = tKeyCmpr;
  ret = tdbTbOpen("db.db", -1, -1, compFunc, pEnv, &pDb);
  GTEST_ASSERT_EQ(ret, 0);

  char      key[64];
  char      val[64];
  int64_t   poolLimit = 4096;  // 1M pool limit
  int64_t   txnid = 0;
  SPoolMem *pPool;

  // open the pool
  pPool = openPool();

  // start a transaction
  txnid++;
H
Hongze Cheng 已提交
518 519 520 521 522
  txn.flags = TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED;
  txn.txnId = -1;
  txn.xMalloc = poolMalloc;
  txn.xFree = poolFree;
  txn.xArg = pPool;
H
Hongze Cheng 已提交
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
  // tdbTxnOpen(&txn, txnid, poolMalloc, poolFree, pPool, );
  tdbBegin(pEnv, &txn);

  for (int iData = 1; iData <= nData; iData++) {
    sprintf(key, "key%d", iData);
    sprintf(val, "value%d", iData);
    ret = tdbTbInsert(pDb, key, strlen(key), val, strlen(val), &txn);
    GTEST_ASSERT_EQ(ret, 0);
  }

  auto f = [](TTB *pDb, int nData) {
    TBC  *pDBC;
    void *pKey = NULL;
    void *pVal = NULL;
    int   vLen, kLen;
    int   count = 0;
    int   ret;
    TXN   txn;

    SPoolMem *pPool = openPool();
H
Hongze Cheng 已提交
543 544 545 546 547
    txn.flags = 0;
    txn.txnId = 0;
    txn.xMalloc = poolMalloc;
    txn.xFree = poolFree;
    txn.xArg = pPool;
H
Hongze Cheng 已提交
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599

    ret = tdbTbcOpen(pDb, &pDBC, &txn);
    GTEST_ASSERT_EQ(ret, 0);

    tdbTbcMoveToFirst(pDBC);

    for (;;) {
      ret = tdbTbcNext(pDBC, &pKey, &kLen, &pVal, &vLen);
      if (ret < 0) break;

      // std::cout.write((char *)pKey, kLen) /* << " " << kLen */ << " ";
      // std::cout.write((char *)pVal, vLen) /* << " " << vLen */;
      // std::cout << std::endl;

      count++;
    }

    GTEST_ASSERT_EQ(count, nData);

    tdbTbcClose(pDBC);

    tdbFree(pKey);
    tdbFree(pVal);
  };

  // tdbCommit(pEnv, &txn);

  // multi-thread query
  int                      nThreads = 20;
  std::vector<std::thread> threads;
  for (int i = 0; i < nThreads; i++) {
    if (i == 0) {
      threads.push_back(std::thread(tdbCommit, pEnv, &txn));
    } else {
      threads.push_back(std::thread(f, pDb, nData));
    }
  }

  for (auto &th : threads) {
    th.join();
  }

  // commit the transaction
  tdbCommit(pEnv, &txn);
  tdbTxnClose(&txn);

  // Close a database
  tdbTbClose(pDb);

  // Close Env
  ret = tdbClose(pEnv);
  GTEST_ASSERT_EQ(ret, 0);
H
Hongze Cheng 已提交
600
}