Blame kcstashtest.cc

Packit Service ac2942
/*************************************************************************************************
Packit Service ac2942
 * The test cases of the stash database
Packit Service ac2942
 *                                                               Copyright (C) 2009-2012 FAL Labs
Packit Service ac2942
 * This file is part of Kyoto Cabinet.
Packit Service ac2942
 * This program is free software: you can redistribute it and/or modify it under the terms of
Packit Service ac2942
 * the GNU General Public License as published by the Free Software Foundation, either version
Packit Service ac2942
 * 3 of the License, or any later version.
Packit Service ac2942
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
Packit Service ac2942
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Packit Service ac2942
 * See the GNU General Public License for more details.
Packit Service ac2942
 * You should have received a copy of the GNU General Public License along with this program.
Packit Service ac2942
 * If not, see <http://www.gnu.org/licenses/>.
Packit Service ac2942
 *************************************************************************************************/
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
#include <kcstashdb.h>
Packit Service ac2942
#include "cmdcommon.h"
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// global variables
Packit Service ac2942
const char* g_progname;                  // program name
Packit Service ac2942
uint32_t g_randseed;                     // random seed
Packit Service ac2942
int64_t g_memusage;                      // memory usage
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// function prototypes
Packit Service ac2942
int main(int argc, char** argv);
Packit Service ac2942
static void usage();
Packit Service ac2942
static void dberrprint(kc::BasicDB* db, int32_t line, const char* func);
Packit Service ac2942
static void dbmetaprint(kc::BasicDB* db, bool verbose);
Packit Service ac2942
static int32_t runorder(int argc, char** argv);
Packit Service ac2942
static int32_t runqueue(int argc, char** argv);
Packit Service ac2942
static int32_t runwicked(int argc, char** argv);
Packit Service ac2942
static int32_t runtran(int argc, char** argv);
Packit Service ac2942
static int32_t procorder(int64_t rnum, int32_t thnum, bool rnd, bool etc, bool tran,
Packit Service ac2942
                         int64_t bnum, bool lv);
Packit Service ac2942
static int32_t procqueue(int64_t rnum, int32_t thnum, int32_t itnum, bool rnd,
Packit Service ac2942
                         int64_t bnum, bool lv);
Packit Service ac2942
static int32_t procwicked(int64_t rnum, int32_t thnum, int32_t itnum, int64_t bnum, bool lv);
Packit Service ac2942
static int32_t proctran(int64_t rnum, int32_t thnum, int32_t itnum, int64_t bnum, bool lv);
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// main routine
Packit Service ac2942
int main(int argc, char** argv) {
Packit Service ac2942
  g_progname = argv[0];
Packit Service ac2942
  const char* ebuf = kc::getenv("KCRNDSEED");
Packit Service ac2942
  g_randseed = ebuf ? (uint32_t)kc::atoi(ebuf) : (uint32_t)(kc::time() * 1000);
Packit Service ac2942
  mysrand(g_randseed);
Packit Service ac2942
  g_memusage = memusage();
Packit Service ac2942
  kc::setstdiobin();
Packit Service ac2942
  if (argc < 2) usage();
Packit Service ac2942
  int32_t rv = 0;
Packit Service ac2942
  if (!std::strcmp(argv[1], "order")) {
Packit Service ac2942
    rv = runorder(argc, argv);
Packit Service ac2942
  } else if (!std::strcmp(argv[1], "queue")) {
Packit Service ac2942
    rv = runqueue(argc, argv);
Packit Service ac2942
  } else if (!std::strcmp(argv[1], "wicked")) {
Packit Service ac2942
    rv = runwicked(argc, argv);
Packit Service ac2942
  } else if (!std::strcmp(argv[1], "tran")) {
Packit Service ac2942
    rv = runtran(argc, argv);
Packit Service ac2942
  } else {
Packit Service ac2942
    usage();
Packit Service ac2942
  }
Packit Service ac2942
  if (rv != 0) {
Packit Service ac2942
    oprintf("FAILED: KCRNDSEED=%u PID=%ld", g_randseed, (long)kc::getpid());
Packit Service ac2942
    for (int32_t i = 0; i < argc; i++) {
Packit Service ac2942
      oprintf(" %s", argv[i]);
Packit Service ac2942
    }
Packit Service ac2942
    oprintf("\n\n");
Packit Service ac2942
  }
Packit Service ac2942
  return rv;
Packit Service ac2942
}
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// print the usage and exit
Packit Service ac2942
static void usage() {
Packit Service ac2942
  eprintf("%s: test cases of the stash database of Kyoto Cabinet\n", g_progname);
Packit Service ac2942
  eprintf("\n");
Packit Service ac2942
  eprintf("usage:\n");
Packit Service ac2942
  eprintf("  %s order [-th num] [-rnd] [-etc] [-tran] [-bnum num] [-lv] rnum\n",
Packit Service ac2942
          g_progname);
Packit Service ac2942
  eprintf("  %s queue [-th num] [-it num] [-rnd] [-bnum num] [-lv] rnum\n", g_progname);
Packit Service ac2942
  eprintf("  %s wicked [-th num] [-it num] [-bnum num] [-lv] rnum\n", g_progname);
Packit Service ac2942
  eprintf("  %s tran [-th num] [-it num] [-bnum num] [-lv] rnum\n", g_progname);
Packit Service ac2942
  eprintf("\n");
Packit Service ac2942
  std::exit(1);
Packit Service ac2942
}
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// print the error message of a database
Packit Service ac2942
static void dberrprint(kc::BasicDB* db, int32_t line, const char* func) {
Packit Service ac2942
  const kc::BasicDB::Error& err = db->error();
Packit Service ac2942
  oprintf("%s: %d: %s: %s: %d: %s: %s\n",
Packit Service ac2942
          g_progname, line, func, db->path().c_str(), err.code(), err.name(), err.message());
Packit Service ac2942
}
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// print members of a database
Packit Service ac2942
static void dbmetaprint(kc::BasicDB* db, bool verbose) {
Packit Service ac2942
  if (verbose) {
Packit Service ac2942
    std::map<std::string, std::string> status;
Packit Service ac2942
    status["opaque"] = "";
Packit Service ac2942
    status["bnum_used"] = "";
Packit Service ac2942
    if (db->status(&status)) {
Packit Service ac2942
      uint32_t type = kc::atoi(status["type"].c_str());
Packit Service ac2942
      oprintf("type: %s (%s) (type=0x%02X)\n",
Packit Service ac2942
              kc::BasicDB::typecname(type), kc::BasicDB::typestring(type), type);
Packit Service ac2942
      uint32_t rtype = kc::atoi(status["realtype"].c_str());
Packit Service ac2942
      if (rtype > 0 && rtype != type)
Packit Service ac2942
        oprintf("real type: %s (%s) (realtype=0x%02X)\n",
Packit Service ac2942
                kc::BasicDB::typecname(rtype), kc::BasicDB::typestring(rtype), rtype);
Packit Service ac2942
      if (status["opaque"].size() >= 16) {
Packit Service ac2942
        const char* opaque = status["opaque"].c_str();
Packit Service ac2942
        oprintf("opaque:");
Packit Service ac2942
        if (std::count(opaque, opaque + 16, 0) != 16) {
Packit Service ac2942
          for (int32_t i = 0; i < 16; i++) {
Packit Service ac2942
            oprintf(" %02X", ((unsigned char*)opaque)[i]);
Packit Service ac2942
          }
Packit Service ac2942
        } else {
Packit Service ac2942
          oprintf(" 0");
Packit Service ac2942
        }
Packit Service ac2942
        oprintf("\n");
Packit Service ac2942
      }
Packit Service ac2942
      int64_t bnum = kc::atoi(status["bnum"].c_str());
Packit Service ac2942
      int64_t bnumused = kc::atoi(status["bnum_used"].c_str());
Packit Service ac2942
      int64_t count = kc::atoi(status["count"].c_str());
Packit Service ac2942
      double load = 0;
Packit Service ac2942
      if (count > 0 && bnumused > 0) load = (double)count / bnumused;
Packit Service ac2942
      oprintf("buckets: %lld (used=%lld) (load=%.2f)\n",
Packit Service ac2942
              (long long)bnum, (long long)bnumused, load);
Packit Service ac2942
      std::string cntstr = unitnumstr(count);
Packit Service ac2942
      oprintf("count: %lld (%s)\n", count, cntstr.c_str());
Packit Service ac2942
      int64_t size = kc::atoi(status["size"].c_str());
Packit Service ac2942
      std::string sizestr = unitnumstrbyte(size);
Packit Service ac2942
      oprintf("size: %lld (%s)\n", size, sizestr.c_str());
Packit Service ac2942
    }
Packit Service ac2942
  } else {
Packit Service ac2942
    oprintf("count: %lld\n", (long long)db->count());
Packit Service ac2942
    oprintf("size: %lld\n", (long long)db->size());
Packit Service ac2942
  }
Packit Service ac2942
  int64_t musage = memusage();
Packit Service ac2942
  if (musage > 0) oprintf("memory: %lld\n", (long long)(musage - g_memusage));
Packit Service ac2942
}
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// parse arguments of order command
Packit Service ac2942
static int32_t runorder(int argc, char** argv) {
Packit Service ac2942
  bool argbrk = false;
Packit Service ac2942
  const char* rstr = NULL;
Packit Service ac2942
  int32_t thnum = 1;
Packit Service ac2942
  bool rnd = false;
Packit Service ac2942
  bool etc = false;
Packit Service ac2942
  bool tran = false;
Packit Service ac2942
  int64_t bnum = -1;
Packit Service ac2942
  bool lv = false;
Packit Service ac2942
  for (int32_t i = 2; i < argc; i++) {
Packit Service ac2942
    if (!argbrk && argv[i][0] == '-') {
Packit Service ac2942
      if (!std::strcmp(argv[i], "--")) {
Packit Service ac2942
        argbrk = true;
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-th")) {
Packit Service ac2942
        if (++i >= argc) usage();
Packit Service ac2942
        thnum = kc::atoix(argv[i]);
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-rnd")) {
Packit Service ac2942
        rnd = true;
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-etc")) {
Packit Service ac2942
        etc = true;
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-tran")) {
Packit Service ac2942
        tran = true;
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-bnum")) {
Packit Service ac2942
        if (++i >= argc) usage();
Packit Service ac2942
        bnum = kc::atoix(argv[i]);
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-lv")) {
Packit Service ac2942
        lv = true;
Packit Service ac2942
      } else {
Packit Service ac2942
        usage();
Packit Service ac2942
      }
Packit Service ac2942
    } else if (!rstr) {
Packit Service ac2942
      argbrk = true;
Packit Service ac2942
      rstr = argv[i];
Packit Service ac2942
    } else {
Packit Service ac2942
      usage();
Packit Service ac2942
    }
Packit Service ac2942
  }
Packit Service ac2942
  if (!rstr) usage();
Packit Service ac2942
  int64_t rnum = kc::atoix(rstr);
Packit Service ac2942
  if (rnum < 1 || thnum < 1) usage();
Packit Service ac2942
  if (thnum > THREADMAX) thnum = THREADMAX;
Packit Service ac2942
  int32_t rv = procorder(rnum, thnum, rnd, etc, tran, bnum, lv);
Packit Service ac2942
  return rv;
Packit Service ac2942
}
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// parse arguments of queue command
Packit Service ac2942
static int32_t runqueue(int argc, char** argv) {
Packit Service ac2942
  bool argbrk = false;
Packit Service ac2942
  const char* rstr = NULL;
Packit Service ac2942
  int32_t thnum = 1;
Packit Service ac2942
  int32_t itnum = 1;
Packit Service ac2942
  bool rnd = false;
Packit Service ac2942
  int64_t bnum = -1;
Packit Service ac2942
  bool lv = false;
Packit Service ac2942
  for (int32_t i = 2; i < argc; i++) {
Packit Service ac2942
    if (!argbrk && argv[i][0] == '-') {
Packit Service ac2942
      if (!std::strcmp(argv[i], "--")) {
Packit Service ac2942
        argbrk = true;
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-th")) {
Packit Service ac2942
        if (++i >= argc) usage();
Packit Service ac2942
        thnum = kc::atoix(argv[i]);
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-it")) {
Packit Service ac2942
        if (++i >= argc) usage();
Packit Service ac2942
        itnum = kc::atoix(argv[i]);
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-rnd")) {
Packit Service ac2942
        rnd = true;
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-bnum")) {
Packit Service ac2942
        if (++i >= argc) usage();
Packit Service ac2942
        bnum = kc::atoix(argv[i]);
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-lv")) {
Packit Service ac2942
        lv = true;
Packit Service ac2942
      } else {
Packit Service ac2942
        usage();
Packit Service ac2942
      }
Packit Service ac2942
    } else if (!rstr) {
Packit Service ac2942
      argbrk = true;
Packit Service ac2942
      rstr = argv[i];
Packit Service ac2942
    } else {
Packit Service ac2942
      usage();
Packit Service ac2942
    }
Packit Service ac2942
  }
Packit Service ac2942
  if (!rstr) usage();
Packit Service ac2942
  int64_t rnum = kc::atoix(rstr);
Packit Service ac2942
  if (rnum < 1 || thnum < 1 || itnum < 1) usage();
Packit Service ac2942
  if (thnum > THREADMAX) thnum = THREADMAX;
Packit Service ac2942
  int32_t rv = procqueue(rnum, thnum, itnum, rnd, bnum, lv);
Packit Service ac2942
  return rv;
Packit Service ac2942
}
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// parse arguments of wicked command
Packit Service ac2942
static int32_t runwicked(int argc, char** argv) {
Packit Service ac2942
  bool argbrk = false;
Packit Service ac2942
  const char* rstr = NULL;
Packit Service ac2942
  int32_t thnum = 1;
Packit Service ac2942
  int32_t itnum = 1;
Packit Service ac2942
  int64_t bnum = -1;
Packit Service ac2942
  bool lv = false;
Packit Service ac2942
  for (int32_t i = 2; i < argc; i++) {
Packit Service ac2942
    if (!argbrk && argv[i][0] == '-') {
Packit Service ac2942
      if (!std::strcmp(argv[i], "--")) {
Packit Service ac2942
        argbrk = true;
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-th")) {
Packit Service ac2942
        if (++i >= argc) usage();
Packit Service ac2942
        thnum = kc::atoix(argv[i]);
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-it")) {
Packit Service ac2942
        if (++i >= argc) usage();
Packit Service ac2942
        itnum = kc::atoix(argv[i]);
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-bnum")) {
Packit Service ac2942
        if (++i >= argc) usage();
Packit Service ac2942
        bnum = kc::atoix(argv[i]);
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-lv")) {
Packit Service ac2942
        lv = true;
Packit Service ac2942
      } else {
Packit Service ac2942
        usage();
Packit Service ac2942
      }
Packit Service ac2942
    } else if (!rstr) {
Packit Service ac2942
      argbrk = true;
Packit Service ac2942
      rstr = argv[i];
Packit Service ac2942
    } else {
Packit Service ac2942
      usage();
Packit Service ac2942
    }
Packit Service ac2942
  }
Packit Service ac2942
  if (!rstr) usage();
Packit Service ac2942
  int64_t rnum = kc::atoix(rstr);
Packit Service ac2942
  if (rnum < 1 || thnum < 1 || itnum < 1) usage();
Packit Service ac2942
  if (thnum > THREADMAX) thnum = THREADMAX;
Packit Service ac2942
  int32_t rv = procwicked(rnum, thnum, itnum, bnum, lv);
Packit Service ac2942
  return rv;
Packit Service ac2942
}
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// parse arguments of tran command
Packit Service ac2942
static int32_t runtran(int argc, char** argv) {
Packit Service ac2942
  bool argbrk = false;
Packit Service ac2942
  const char* rstr = NULL;
Packit Service ac2942
  int32_t thnum = 1;
Packit Service ac2942
  int32_t itnum = 1;
Packit Service ac2942
  int64_t bnum = -1;
Packit Service ac2942
  bool lv = false;
Packit Service ac2942
  for (int32_t i = 2; i < argc; i++) {
Packit Service ac2942
    if (!argbrk && argv[i][0] == '-') {
Packit Service ac2942
      if (!std::strcmp(argv[i], "--")) {
Packit Service ac2942
        argbrk = true;
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-th")) {
Packit Service ac2942
        if (++i >= argc) usage();
Packit Service ac2942
        thnum = kc::atoix(argv[i]);
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-it")) {
Packit Service ac2942
        if (++i >= argc) usage();
Packit Service ac2942
        itnum = kc::atoix(argv[i]);
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-bnum")) {
Packit Service ac2942
        if (++i >= argc) usage();
Packit Service ac2942
        bnum = kc::atoix(argv[i]);
Packit Service ac2942
      } else if (!std::strcmp(argv[i], "-lv")) {
Packit Service ac2942
        lv = true;
Packit Service ac2942
      } else {
Packit Service ac2942
        usage();
Packit Service ac2942
      }
Packit Service ac2942
    } else if (!rstr) {
Packit Service ac2942
      argbrk = true;
Packit Service ac2942
      rstr = argv[i];
Packit Service ac2942
    } else {
Packit Service ac2942
      usage();
Packit Service ac2942
    }
Packit Service ac2942
  }
Packit Service ac2942
  if (!rstr) usage();
Packit Service ac2942
  int64_t rnum = kc::atoix(rstr);
Packit Service ac2942
  if (rnum < 1 || thnum < 1 || itnum < 1) usage();
Packit Service ac2942
  if (thnum > THREADMAX) thnum = THREADMAX;
Packit Service ac2942
  int32_t rv = proctran(rnum, thnum, itnum, bnum, lv);
Packit Service ac2942
  return rv;
Packit Service ac2942
}
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// perform order command
Packit Service ac2942
static int32_t procorder(int64_t rnum, int32_t thnum, bool rnd, bool etc, bool tran,
Packit Service ac2942
                         int64_t bnum, bool lv) {
Packit Service ac2942
  oprintf("<In-order Test>\n  seed=%u  rnum=%lld  thnum=%d  rnd=%d  etc=%d  tran=%d"
Packit Service ac2942
          "  bnum=%lld  lv=%d\n\n",
Packit Service ac2942
          g_randseed, (long long)rnum, thnum, rnd, etc, tran, (long long)bnum, lv);
Packit Service ac2942
  bool err = false;
Packit Service ac2942
  kc::StashDB db;
Packit Service ac2942
  oprintf("opening the database:\n");
Packit Service ac2942
  double stime = kc::time();
Packit Service ac2942
  db.tune_logger(stdlogger(g_progname, &std::cout),
Packit Service ac2942
                 lv ? kc::UINT32MAX : kc::BasicDB::Logger::WARN | kc::BasicDB::Logger::ERROR);
Packit Service ac2942
  if (bnum > 0) db.tune_buckets(bnum);
Packit Service ac2942
  if (!db.open(":", kc::StashDB::OWRITER | kc::StashDB::OCREATE | kc::StashDB::OTRUNCATE)) {
Packit Service ac2942
    dberrprint(&db, __LINE__, "DB::open");
Packit Service ac2942
    err = true;
Packit Service ac2942
  }
Packit Service ac2942
  double etime = kc::time();
Packit Service ac2942
  dbmetaprint(&db, false);
Packit Service ac2942
  oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
  oprintf("setting records:\n");
Packit Service ac2942
  stime = kc::time();
Packit Service ac2942
  class ThreadSet : public kc::Thread {
Packit Service ac2942
   public:
Packit Service ac2942
    void setparams(int32_t id, kc::BasicDB* db, int64_t rnum, int32_t thnum,
Packit Service ac2942
                   bool rnd, bool tran) {
Packit Service ac2942
      id_ = id;
Packit Service ac2942
      db_ = db;
Packit Service ac2942
      rnum_ = rnum;
Packit Service ac2942
      thnum_ = thnum;
Packit Service ac2942
      err_ = false;
Packit Service ac2942
      rnd_ = rnd;
Packit Service ac2942
      tran_ = tran;
Packit Service ac2942
    }
Packit Service ac2942
    bool error() {
Packit Service ac2942
      return err_;
Packit Service ac2942
    }
Packit Service ac2942
    void run() {
Packit Service ac2942
      int64_t base = id_ * rnum_;
Packit Service ac2942
      int64_t range = rnum_ * thnum_;
Packit Service ac2942
      for (int64_t i = 1; !err_ && i <= rnum_; i++) {
Packit Service ac2942
        if (tran_ && !db_->begin_transaction(false)) {
Packit Service ac2942
          dberrprint(db_, __LINE__, "DB::begin_transaction");
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        char kbuf[RECBUFSIZ];
Packit Service ac2942
        size_t ksiz = std::sprintf(kbuf, "%08lld",
Packit Service ac2942
                                   (long long)(rnd_ ? myrand(range) + 1 : base + i));
Packit Service ac2942
        if (!db_->set(kbuf, ksiz, kbuf, ksiz)) {
Packit Service ac2942
          dberrprint(db_, __LINE__, "DB::set");
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        if (rnd_ && i % 8 == 0) {
Packit Service ac2942
          switch (myrand(8)) {
Packit Service ac2942
            case 0: {
Packit Service ac2942
              if (!db_->set(kbuf, ksiz, kbuf, ksiz)) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::set");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
            case 1: {
Packit Service ac2942
              if (!db_->append(kbuf, ksiz, kbuf, ksiz)) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::append");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
            case 2: {
Packit Service ac2942
              if (!db_->remove(kbuf, ksiz) && db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::remove");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
            case 3: {
Packit Service ac2942
              kc::DB::Cursor* cur = db_->cursor();
Packit Service ac2942
              if (cur->jump(kbuf, ksiz)) {
Packit Service ac2942
                switch (myrand(8)) {
Packit Service ac2942
                  default: {
Packit Service ac2942
                    size_t rsiz;
Packit Service ac2942
                    char* rbuf = cur->get_key(&rsiz, myrand(10) == 0);
Packit Service ac2942
                    if (rbuf) {
Packit Service ac2942
                      delete[] rbuf;
Packit Service ac2942
                    } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::get_key");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                  case 1: {
Packit Service ac2942
                    size_t rsiz;
Packit Service ac2942
                    char* rbuf = cur->get_value(&rsiz, myrand(10) == 0);
Packit Service ac2942
                    if (rbuf) {
Packit Service ac2942
                      delete[] rbuf;
Packit Service ac2942
                    } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::get_value");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                  case 2: {
Packit Service ac2942
                    size_t rksiz;
Packit Service ac2942
                    const char* rvbuf;
Packit Service ac2942
                    size_t rvsiz;
Packit Service ac2942
                    char* rkbuf = cur->get(&rksiz, &rvbuf, &rvsiz, myrand(10) == 0);
Packit Service ac2942
                    if (rkbuf) {
Packit Service ac2942
                      delete[] rkbuf;
Packit Service ac2942
                    } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::get");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                  case 3: {
Packit Service ac2942
                    std::string key, value;
Packit Service ac2942
                    if (!cur->get(&key, &value, myrand(10) == 0) &&
Packit Service ac2942
                        db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::get");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                  case 4: {
Packit Service ac2942
                    if (myrand(8) == 0 && !cur->remove() &&
Packit Service ac2942
                        db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::remove");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                }
Packit Service ac2942
              } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "Cursor::jump");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              delete cur;
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
            default: {
Packit Service ac2942
              size_t vsiz;
Packit Service ac2942
              char* vbuf = db_->get(kbuf, ksiz, &vsiz);
Packit Service ac2942
              if (vbuf) {
Packit Service ac2942
                delete[] vbuf;
Packit Service ac2942
              } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::get");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
          }
Packit Service ac2942
        }
Packit Service ac2942
        if (tran_ && !db_->end_transaction(true)) {
Packit Service ac2942
          dberrprint(db_, __LINE__, "DB::end_transaction");
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
Packit Service ac2942
          oputchar('.');
Packit Service ac2942
          if (i == rnum_ || i % (rnum_ / 10) == 0) oprintf(" (%08lld)\n", (long long)i);
Packit Service ac2942
        }
Packit Service ac2942
      }
Packit Service ac2942
    }
Packit Service ac2942
   private:
Packit Service ac2942
    int32_t id_;
Packit Service ac2942
    kc::BasicDB* db_;
Packit Service ac2942
    int64_t rnum_;
Packit Service ac2942
    int32_t thnum_;
Packit Service ac2942
    bool err_;
Packit Service ac2942
    bool rnd_;
Packit Service ac2942
    bool tran_;
Packit Service ac2942
  };
Packit Service ac2942
  ThreadSet threadsets[THREADMAX];
Packit Service ac2942
  if (thnum < 2) {
Packit Service ac2942
    threadsets[0].setparams(0, &db, rnum, thnum, rnd, tran);
Packit Service ac2942
    threadsets[0].run();
Packit Service ac2942
    if (threadsets[0].error()) err = true;
Packit Service ac2942
  } else {
Packit Service ac2942
    for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
      threadsets[i].setparams(i, &db, rnum, thnum, rnd, tran);
Packit Service ac2942
      threadsets[i].start();
Packit Service ac2942
    }
Packit Service ac2942
    for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
      threadsets[i].join();
Packit Service ac2942
      if (threadsets[i].error()) err = true;
Packit Service ac2942
    }
Packit Service ac2942
  }
Packit Service ac2942
  etime = kc::time();
Packit Service ac2942
  dbmetaprint(&db, false);
Packit Service ac2942
  oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
  if (etc) {
Packit Service ac2942
    oprintf("adding records:\n");
Packit Service ac2942
    stime = kc::time();
Packit Service ac2942
    class ThreadAdd : public kc::Thread {
Packit Service ac2942
     public:
Packit Service ac2942
      void setparams(int32_t id, kc::BasicDB* db, int64_t rnum, int32_t thnum,
Packit Service ac2942
                     bool rnd, bool tran) {
Packit Service ac2942
        id_ = id;
Packit Service ac2942
        db_ = db;
Packit Service ac2942
        rnum_ = rnum;
Packit Service ac2942
        thnum_ = thnum;
Packit Service ac2942
        err_ = false;
Packit Service ac2942
        rnd_ = rnd;
Packit Service ac2942
        tran_ = tran;
Packit Service ac2942
      }
Packit Service ac2942
      bool error() {
Packit Service ac2942
        return err_;
Packit Service ac2942
      }
Packit Service ac2942
      void run() {
Packit Service ac2942
        int64_t base = id_ * rnum_;
Packit Service ac2942
        int64_t range = rnum_ * thnum_;
Packit Service ac2942
        for (int64_t i = 1; !err_ && i <= rnum_; i++) {
Packit Service ac2942
          if (tran_ && !db_->begin_transaction(false)) {
Packit Service ac2942
            dberrprint(db_, __LINE__, "DB::begin_transaction");
Packit Service ac2942
            err_ = true;
Packit Service ac2942
          }
Packit Service ac2942
          char kbuf[RECBUFSIZ];
Packit Service ac2942
          size_t ksiz = std::sprintf(kbuf, "%08lld",
Packit Service ac2942
                                     (long long)(rnd_ ? myrand(range) + 1 : base + i));
Packit Service ac2942
          if (!db_->add(kbuf, ksiz, kbuf, ksiz) &&
Packit Service ac2942
              db_->error() != kc::BasicDB::Error::DUPREC) {
Packit Service ac2942
            dberrprint(db_, __LINE__, "DB::add");
Packit Service ac2942
            err_ = true;
Packit Service ac2942
          }
Packit Service ac2942
          if (tran_ && !db_->end_transaction(true)) {
Packit Service ac2942
            dberrprint(db_, __LINE__, "DB::end_transaction");
Packit Service ac2942
            err_ = true;
Packit Service ac2942
          }
Packit Service ac2942
          if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
Packit Service ac2942
            oputchar('.');
Packit Service ac2942
            if (i == rnum_ || i % (rnum_ / 10) == 0) oprintf(" (%08lld)\n", (long long)i);
Packit Service ac2942
          }
Packit Service ac2942
        }
Packit Service ac2942
      }
Packit Service ac2942
     private:
Packit Service ac2942
      int32_t id_;
Packit Service ac2942
      kc::BasicDB* db_;
Packit Service ac2942
      int64_t rnum_;
Packit Service ac2942
      int32_t thnum_;
Packit Service ac2942
      bool err_;
Packit Service ac2942
      bool rnd_;
Packit Service ac2942
      bool tran_;
Packit Service ac2942
    };
Packit Service ac2942
    ThreadAdd threadadds[THREADMAX];
Packit Service ac2942
    if (thnum < 2) {
Packit Service ac2942
      threadadds[0].setparams(0, &db, rnum, thnum, rnd, tran);
Packit Service ac2942
      threadadds[0].run();
Packit Service ac2942
      if (threadadds[0].error()) err = true;
Packit Service ac2942
    } else {
Packit Service ac2942
      for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
        threadadds[i].setparams(i, &db, rnum, thnum, rnd, tran);
Packit Service ac2942
        threadadds[i].start();
Packit Service ac2942
      }
Packit Service ac2942
      for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
        threadadds[i].join();
Packit Service ac2942
        if (threadadds[i].error()) err = true;
Packit Service ac2942
      }
Packit Service ac2942
    }
Packit Service ac2942
    etime = kc::time();
Packit Service ac2942
    dbmetaprint(&db, false);
Packit Service ac2942
    oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
  }
Packit Service ac2942
  if (etc) {
Packit Service ac2942
    oprintf("appending records:\n");
Packit Service ac2942
    stime = kc::time();
Packit Service ac2942
    class ThreadAppend : public kc::Thread {
Packit Service ac2942
     public:
Packit Service ac2942
      void setparams(int32_t id, kc::BasicDB* db, int64_t rnum, int32_t thnum,
Packit Service ac2942
                     bool rnd, bool tran) {
Packit Service ac2942
        id_ = id;
Packit Service ac2942
        db_ = db;
Packit Service ac2942
        rnum_ = rnum;
Packit Service ac2942
        thnum_ = thnum;
Packit Service ac2942
        err_ = false;
Packit Service ac2942
        rnd_ = rnd;
Packit Service ac2942
        tran_ = tran;
Packit Service ac2942
      }
Packit Service ac2942
      bool error() {
Packit Service ac2942
        return err_;
Packit Service ac2942
      }
Packit Service ac2942
      void run() {
Packit Service ac2942
        int64_t base = id_ * rnum_;
Packit Service ac2942
        int64_t range = rnum_ * thnum_;
Packit Service ac2942
        for (int64_t i = 1; !err_ && i <= rnum_; i++) {
Packit Service ac2942
          if (tran_ && !db_->begin_transaction(false)) {
Packit Service ac2942
            dberrprint(db_, __LINE__, "DB::begin_transaction");
Packit Service ac2942
            err_ = true;
Packit Service ac2942
          }
Packit Service ac2942
          char kbuf[RECBUFSIZ];
Packit Service ac2942
          size_t ksiz = std::sprintf(kbuf, "%08lld",
Packit Service ac2942
                                     (long long)(rnd_ ? myrand(range) + 1 : base + i));
Packit Service ac2942
          if (!db_->append(kbuf, ksiz, kbuf, ksiz)) {
Packit Service ac2942
            dberrprint(db_, __LINE__, "DB::append");
Packit Service ac2942
            err_ = true;
Packit Service ac2942
          }
Packit Service ac2942
          if (tran_ && !db_->end_transaction(true)) {
Packit Service ac2942
            dberrprint(db_, __LINE__, "DB::end_transaction");
Packit Service ac2942
            err_ = true;
Packit Service ac2942
          }
Packit Service ac2942
          if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
Packit Service ac2942
            oputchar('.');
Packit Service ac2942
            if (i == rnum_ || i % (rnum_ / 10) == 0) oprintf(" (%08lld)\n", (long long)i);
Packit Service ac2942
          }
Packit Service ac2942
        }
Packit Service ac2942
      }
Packit Service ac2942
     private:
Packit Service ac2942
      int32_t id_;
Packit Service ac2942
      kc::BasicDB* db_;
Packit Service ac2942
      int64_t rnum_;
Packit Service ac2942
      int32_t thnum_;
Packit Service ac2942
      bool err_;
Packit Service ac2942
      bool rnd_;
Packit Service ac2942
      bool tran_;
Packit Service ac2942
    };
Packit Service ac2942
    ThreadAppend threadappends[THREADMAX];
Packit Service ac2942
    if (thnum < 2) {
Packit Service ac2942
      threadappends[0].setparams(0, &db, rnum, thnum, rnd, tran);
Packit Service ac2942
      threadappends[0].run();
Packit Service ac2942
      if (threadappends[0].error()) err = true;
Packit Service ac2942
    } else {
Packit Service ac2942
      for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
        threadappends[i].setparams(i, &db, rnum, thnum, rnd, tran);
Packit Service ac2942
        threadappends[i].start();
Packit Service ac2942
      }
Packit Service ac2942
      for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
        threadappends[i].join();
Packit Service ac2942
        if (threadappends[i].error()) err = true;
Packit Service ac2942
      }
Packit Service ac2942
    }
Packit Service ac2942
    etime = kc::time();
Packit Service ac2942
    dbmetaprint(&db, false);
Packit Service ac2942
    oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
    char* opaque = db.opaque();
Packit Service ac2942
    if (opaque) {
Packit Service ac2942
      std::memcpy(opaque, "1234567890123456", 16);
Packit Service ac2942
      if (!db.synchronize_opaque()) {
Packit Service ac2942
        dberrprint(&db, __LINE__, "DB::synchronize_opaque");
Packit Service ac2942
        err = true;
Packit Service ac2942
      }
Packit Service ac2942
    } else {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::opaque");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
  }
Packit Service ac2942
  oprintf("getting records:\n");
Packit Service ac2942
  stime = kc::time();
Packit Service ac2942
  class ThreadGet : public kc::Thread {
Packit Service ac2942
   public:
Packit Service ac2942
    void setparams(int32_t id, kc::BasicDB* db, int64_t rnum, int32_t thnum,
Packit Service ac2942
                   bool rnd, bool tran) {
Packit Service ac2942
      id_ = id;
Packit Service ac2942
      db_ = db;
Packit Service ac2942
      rnum_ = rnum;
Packit Service ac2942
      thnum_ = thnum;
Packit Service ac2942
      err_ = false;
Packit Service ac2942
      rnd_ = rnd;
Packit Service ac2942
      tran_ = tran;
Packit Service ac2942
    }
Packit Service ac2942
    bool error() {
Packit Service ac2942
      return err_;
Packit Service ac2942
    }
Packit Service ac2942
    void run() {
Packit Service ac2942
      int64_t base = id_ * rnum_;
Packit Service ac2942
      int64_t range = rnum_ * thnum_;
Packit Service ac2942
      for (int64_t i = 1; !err_ && i <= rnum_; i++) {
Packit Service ac2942
        if (tran_ && !db_->begin_transaction(false)) {
Packit Service ac2942
          dberrprint(db_, __LINE__, "DB::begin_transaction");
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        char kbuf[RECBUFSIZ];
Packit Service ac2942
        size_t ksiz = std::sprintf(kbuf, "%08lld",
Packit Service ac2942
                                   (long long)(rnd_ ? myrand(range) + 1 : base + i));
Packit Service ac2942
        size_t vsiz;
Packit Service ac2942
        char* vbuf = db_->get(kbuf, ksiz, &vsiz);
Packit Service ac2942
        if (vbuf) {
Packit Service ac2942
          if (vsiz < ksiz || std::memcmp(vbuf, kbuf, ksiz)) {
Packit Service ac2942
            dberrprint(db_, __LINE__, "DB::get");
Packit Service ac2942
            err_ = true;
Packit Service ac2942
          }
Packit Service ac2942
          delete[] vbuf;
Packit Service ac2942
        } else if (!rnd_ || db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
          dberrprint(db_, __LINE__, "DB::get");
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        if (rnd_ && i % 8 == 0) {
Packit Service ac2942
          switch (myrand(8)) {
Packit Service ac2942
            case 0: {
Packit Service ac2942
              if (!db_->set(kbuf, ksiz, kbuf, ksiz)) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::set");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
            case 1: {
Packit Service ac2942
              if (!db_->append(kbuf, ksiz, kbuf, ksiz)) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::append");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
            case 2: {
Packit Service ac2942
              if (!db_->remove(kbuf, ksiz) &&
Packit Service ac2942
                  db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::remove");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
            case 3: {
Packit Service ac2942
              kc::DB::Cursor* cur = db_->cursor();
Packit Service ac2942
              if (cur->jump(kbuf, ksiz)) {
Packit Service ac2942
                switch (myrand(8)) {
Packit Service ac2942
                  default: {
Packit Service ac2942
                    size_t rsiz;
Packit Service ac2942
                    char* rbuf = cur->get_key(&rsiz, myrand(10) == 0);
Packit Service ac2942
                    if (rbuf) {
Packit Service ac2942
                      delete[] rbuf;
Packit Service ac2942
                    } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::get_key");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                  case 1: {
Packit Service ac2942
                    size_t rsiz;
Packit Service ac2942
                    char* rbuf = cur->get_value(&rsiz, myrand(10) == 0);
Packit Service ac2942
                    if (rbuf) {
Packit Service ac2942
                      delete[] rbuf;
Packit Service ac2942
                    } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::get_value");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                  case 2: {
Packit Service ac2942
                    size_t rksiz;
Packit Service ac2942
                    const char* rvbuf;
Packit Service ac2942
                    size_t rvsiz;
Packit Service ac2942
                    char* rkbuf = cur->get(&rksiz, &rvbuf, &rvsiz, myrand(10) == 0);
Packit Service ac2942
                    if (rkbuf) {
Packit Service ac2942
                      delete[] rkbuf;
Packit Service ac2942
                    } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::get");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                  case 3: {
Packit Service ac2942
                    std::string key, value;
Packit Service ac2942
                    if (!cur->get(&key, &value, myrand(10) == 0) &&
Packit Service ac2942
                        db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::get");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                  case 4: {
Packit Service ac2942
                    if (myrand(8) == 0 && !cur->remove() &&
Packit Service ac2942
                        db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::remove");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                }
Packit Service ac2942
              } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "Cursor::jump");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              delete cur;
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
            default: {
Packit Service ac2942
              size_t vsiz;
Packit Service ac2942
              char* vbuf = db_->get(kbuf, ksiz, &vsiz);
Packit Service ac2942
              if (vbuf) {
Packit Service ac2942
                delete[] vbuf;
Packit Service ac2942
              } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::get");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
          }
Packit Service ac2942
        }
Packit Service ac2942
        if (tran_ && !db_->end_transaction(true)) {
Packit Service ac2942
          dberrprint(db_, __LINE__, "DB::end_transaction");
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
Packit Service ac2942
          oputchar('.');
Packit Service ac2942
          if (i == rnum_ || i % (rnum_ / 10) == 0) oprintf(" (%08lld)\n", (long long)i);
Packit Service ac2942
        }
Packit Service ac2942
      }
Packit Service ac2942
    }
Packit Service ac2942
   private:
Packit Service ac2942
    int32_t id_;
Packit Service ac2942
    kc::BasicDB* db_;
Packit Service ac2942
    int64_t rnum_;
Packit Service ac2942
    int32_t thnum_;
Packit Service ac2942
    bool err_;
Packit Service ac2942
    bool rnd_;
Packit Service ac2942
    bool tran_;
Packit Service ac2942
  };
Packit Service ac2942
  ThreadGet threadgets[THREADMAX];
Packit Service ac2942
  if (thnum < 2) {
Packit Service ac2942
    threadgets[0].setparams(0, &db, rnum, thnum, rnd, tran);
Packit Service ac2942
    threadgets[0].run();
Packit Service ac2942
    if (threadgets[0].error()) err = true;
Packit Service ac2942
  } else {
Packit Service ac2942
    for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
      threadgets[i].setparams(i, &db, rnum, thnum, rnd, tran);
Packit Service ac2942
      threadgets[i].start();
Packit Service ac2942
    }
Packit Service ac2942
    for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
      threadgets[i].join();
Packit Service ac2942
      if (threadgets[i].error()) err = true;
Packit Service ac2942
    }
Packit Service ac2942
  }
Packit Service ac2942
  etime = kc::time();
Packit Service ac2942
  dbmetaprint(&db, false);
Packit Service ac2942
  oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
  if (etc) {
Packit Service ac2942
    oprintf("getting records with a buffer:\n");
Packit Service ac2942
    stime = kc::time();
Packit Service ac2942
    class ThreadGetBuffer : public kc::Thread {
Packit Service ac2942
     public:
Packit Service ac2942
      void setparams(int32_t id, kc::BasicDB* db, int64_t rnum, int32_t thnum,
Packit Service ac2942
                     bool rnd, bool tran) {
Packit Service ac2942
        id_ = id;
Packit Service ac2942
        db_ = db;
Packit Service ac2942
        rnum_ = rnum;
Packit Service ac2942
        thnum_ = thnum;
Packit Service ac2942
        err_ = false;
Packit Service ac2942
        rnd_ = rnd;
Packit Service ac2942
        tran_ = tran;
Packit Service ac2942
      }
Packit Service ac2942
      bool error() {
Packit Service ac2942
        return err_;
Packit Service ac2942
      }
Packit Service ac2942
      void run() {
Packit Service ac2942
        int64_t base = id_ * rnum_;
Packit Service ac2942
        int64_t range = rnum_ * thnum_;
Packit Service ac2942
        for (int64_t i = 1; !err_ && i <= rnum_; i++) {
Packit Service ac2942
          if (tran_ && !db_->begin_transaction(false)) {
Packit Service ac2942
            dberrprint(db_, __LINE__, "DB::begin_transaction");
Packit Service ac2942
            err_ = true;
Packit Service ac2942
          }
Packit Service ac2942
          char kbuf[RECBUFSIZ];
Packit Service ac2942
          size_t ksiz = std::sprintf(kbuf, "%08lld",
Packit Service ac2942
                                     (long long)(rnd_ ? myrand(range) + 1 : base + i));
Packit Service ac2942
          char vbuf[RECBUFSIZ];
Packit Service ac2942
          int32_t vsiz = db_->get(kbuf, ksiz, vbuf, sizeof(vbuf));
Packit Service ac2942
          if (vsiz >= 0) {
Packit Service ac2942
            if (vsiz < (int32_t)ksiz || std::memcmp(vbuf, kbuf, ksiz)) {
Packit Service ac2942
              dberrprint(db_, __LINE__, "DB::get");
Packit Service ac2942
              err_ = true;
Packit Service ac2942
            }
Packit Service ac2942
          } else if (!rnd_ || db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
            dberrprint(db_, __LINE__, "DB::get");
Packit Service ac2942
            err_ = true;
Packit Service ac2942
          }
Packit Service ac2942
          if (tran_ && !db_->end_transaction(true)) {
Packit Service ac2942
            dberrprint(db_, __LINE__, "DB::end_transaction");
Packit Service ac2942
            err_ = true;
Packit Service ac2942
          }
Packit Service ac2942
          if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
Packit Service ac2942
            oputchar('.');
Packit Service ac2942
            if (i == rnum_ || i % (rnum_ / 10) == 0) oprintf(" (%08lld)\n", (long long)i);
Packit Service ac2942
          }
Packit Service ac2942
        }
Packit Service ac2942
      }
Packit Service ac2942
     private:
Packit Service ac2942
      int32_t id_;
Packit Service ac2942
      kc::BasicDB* db_;
Packit Service ac2942
      int64_t rnum_;
Packit Service ac2942
      int32_t thnum_;
Packit Service ac2942
      bool err_;
Packit Service ac2942
      bool rnd_;
Packit Service ac2942
      bool tran_;
Packit Service ac2942
    };
Packit Service ac2942
    ThreadGetBuffer threadgetbuffers[THREADMAX];
Packit Service ac2942
    if (thnum < 2) {
Packit Service ac2942
      threadgetbuffers[0].setparams(0, &db, rnum, thnum, rnd, tran);
Packit Service ac2942
      threadgetbuffers[0].run();
Packit Service ac2942
      if (threadgetbuffers[0].error()) err = true;
Packit Service ac2942
    } else {
Packit Service ac2942
      for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
        threadgetbuffers[i].setparams(i, &db, rnum, thnum, rnd, tran);
Packit Service ac2942
        threadgetbuffers[i].start();
Packit Service ac2942
      }
Packit Service ac2942
      for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
        threadgetbuffers[i].join();
Packit Service ac2942
        if (threadgetbuffers[i].error()) err = true;
Packit Service ac2942
      }
Packit Service ac2942
    }
Packit Service ac2942
    etime = kc::time();
Packit Service ac2942
    dbmetaprint(&db, false);
Packit Service ac2942
    oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
  }
Packit Service ac2942
  if (etc) {
Packit Service ac2942
    oprintf("traversing the database by the inner iterator:\n");
Packit Service ac2942
    stime = kc::time();
Packit Service ac2942
    int64_t cnt = db.count();
Packit Service ac2942
    class VisitorIterator : public kc::DB::Visitor {
Packit Service ac2942
     public:
Packit Service ac2942
      explicit VisitorIterator(int64_t rnum, bool rnd) :
Packit Service ac2942
          rnum_(rnum), rnd_(rnd), cnt_(0), rbuf_() {
Packit Service ac2942
        std::memset(rbuf_, '+', sizeof(rbuf_));
Packit Service ac2942
      }
Packit Service ac2942
      int64_t cnt() {
Packit Service ac2942
        return cnt_;
Packit Service ac2942
      }
Packit Service ac2942
     private:
Packit Service ac2942
      const char* visit_full(const char* kbuf, size_t ksiz,
Packit Service ac2942
                             const char* vbuf, size_t vsiz, size_t* sp) {
Packit Service ac2942
        cnt_++;
Packit Service ac2942
        const char* rv = NOP;
Packit Service ac2942
        switch (rnd_ ? myrand(7) : cnt_ % 7) {
Packit Service ac2942
          case 0: {
Packit Service ac2942
            rv = rbuf_;
Packit Service ac2942
            *sp = rnd_ ? myrand(sizeof(rbuf_)) : sizeof(rbuf_) / (cnt_ % 5 + 1);
Packit Service ac2942
            break;
Packit Service ac2942
          }
Packit Service ac2942
          case 1: {
Packit Service ac2942
            rv = REMOVE;
Packit Service ac2942
            break;
Packit Service ac2942
          }
Packit Service ac2942
        }
Packit Service ac2942
        if (rnum_ > 250 && cnt_ % (rnum_ / 250) == 0) {
Packit Service ac2942
          oputchar('.');
Packit Service ac2942
          if (cnt_ == rnum_ || cnt_ % (rnum_ / 10) == 0) oprintf(" (%08lld)\n", (long long)cnt_);
Packit Service ac2942
        }
Packit Service ac2942
        return rv;
Packit Service ac2942
      }
Packit Service ac2942
      int64_t rnum_;
Packit Service ac2942
      bool rnd_;
Packit Service ac2942
      int64_t cnt_;
Packit Service ac2942
      char rbuf_[RECBUFSIZ];
Packit Service ac2942
    } visitoriterator(rnum, rnd);
Packit Service ac2942
    if (tran && !db.begin_transaction(false)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::begin_transaction");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    if (!db.iterate(&visitoriterator, true)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::iterate");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    if (rnd) oprintf(" (end)\n");
Packit Service ac2942
    if (tran && !db.end_transaction(true)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::end_transaction");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    if (visitoriterator.cnt() != cnt) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::iterate");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    etime = kc::time();
Packit Service ac2942
    dbmetaprint(&db, false);
Packit Service ac2942
    oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
  }
Packit Service ac2942
  if (etc) {
Packit Service ac2942
    oprintf("traversing the database by the outer cursor:\n");
Packit Service ac2942
    stime = kc::time();
Packit Service ac2942
    int64_t cnt = db.count();
Packit Service ac2942
    class VisitorCursor : public kc::DB::Visitor {
Packit Service ac2942
     public:
Packit Service ac2942
      explicit VisitorCursor(int64_t rnum, bool rnd) :
Packit Service ac2942
          rnum_(rnum), rnd_(rnd), cnt_(0), rbuf_() {
Packit Service ac2942
        std::memset(rbuf_, '-', sizeof(rbuf_));
Packit Service ac2942
      }
Packit Service ac2942
      int64_t cnt() {
Packit Service ac2942
        return cnt_;
Packit Service ac2942
      }
Packit Service ac2942
     private:
Packit Service ac2942
      const char* visit_full(const char* kbuf, size_t ksiz,
Packit Service ac2942
                             const char* vbuf, size_t vsiz, size_t* sp) {
Packit Service ac2942
        cnt_++;
Packit Service ac2942
        const char* rv = NOP;
Packit Service ac2942
        switch (rnd_ ? myrand(7) : cnt_ % 7) {
Packit Service ac2942
          case 0: {
Packit Service ac2942
            rv = rbuf_;
Packit Service ac2942
            *sp = rnd_ ? myrand(sizeof(rbuf_)) : sizeof(rbuf_) / (cnt_ % 5 + 1);
Packit Service ac2942
            break;
Packit Service ac2942
          }
Packit Service ac2942
          case 1: {
Packit Service ac2942
            rv = REMOVE;
Packit Service ac2942
            break;
Packit Service ac2942
          }
Packit Service ac2942
        }
Packit Service ac2942
        if (rnum_ > 250 && cnt_ % (rnum_ / 250) == 0) {
Packit Service ac2942
          oputchar('.');
Packit Service ac2942
          if (cnt_ == rnum_ || cnt_ % (rnum_ / 10) == 0) oprintf(" (%08lld)\n", (long long)cnt_);
Packit Service ac2942
        }
Packit Service ac2942
        return rv;
Packit Service ac2942
      }
Packit Service ac2942
      int64_t rnum_;
Packit Service ac2942
      bool rnd_;
Packit Service ac2942
      int64_t cnt_;
Packit Service ac2942
      char rbuf_[RECBUFSIZ];
Packit Service ac2942
    } visitorcursor(rnum, rnd);
Packit Service ac2942
    if (tran && !db.begin_transaction(false)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::begin_transaction");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    kc::StashDB::Cursor cur(&db);
Packit Service ac2942
    if (!cur.jump() && db.error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "Cursor::jump");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    kc::DB::Cursor* paracur = db.cursor();
Packit Service ac2942
    int64_t range = rnum * thnum;
Packit Service ac2942
    while (!err && cur.accept(&visitorcursor, true, !rnd)) {
Packit Service ac2942
      if (rnd) {
Packit Service ac2942
        char kbuf[RECBUFSIZ];
Packit Service ac2942
        size_t ksiz = std::sprintf(kbuf, "%08lld", (long long)myrand(range));
Packit Service ac2942
        switch (myrand(3)) {
Packit Service ac2942
          case 0: {
Packit Service ac2942
            if (!db.remove(kbuf, ksiz) && db.error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
              dberrprint(&db, __LINE__, "DB::remove");
Packit Service ac2942
              err = true;
Packit Service ac2942
            }
Packit Service ac2942
            break;
Packit Service ac2942
          }
Packit Service ac2942
          case 1: {
Packit Service ac2942
            if (!paracur->jump(kbuf, ksiz) && db.error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
              dberrprint(&db, __LINE__, "Cursor::jump");
Packit Service ac2942
              err = true;
Packit Service ac2942
            }
Packit Service ac2942
            break;
Packit Service ac2942
          }
Packit Service ac2942
          default: {
Packit Service ac2942
            if (!cur.step() && db.error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
              dberrprint(&db, __LINE__, "Cursor::step");
Packit Service ac2942
              err = true;
Packit Service ac2942
            }
Packit Service ac2942
            break;
Packit Service ac2942
          }
Packit Service ac2942
        }
Packit Service ac2942
      }
Packit Service ac2942
    }
Packit Service ac2942
    if (db.error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "Cursor::accept");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    oprintf(" (end)\n");
Packit Service ac2942
    delete paracur;
Packit Service ac2942
    if (tran && !db.end_transaction(true)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::end_transaction");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    if (!rnd && visitorcursor.cnt() != cnt) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "Cursor::accept");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    etime = kc::time();
Packit Service ac2942
    dbmetaprint(&db, false);
Packit Service ac2942
    oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
  }
Packit Service ac2942
  if (etc) {
Packit Service ac2942
    oprintf("synchronizing the database:\n");
Packit Service ac2942
    stime = kc::time();
Packit Service ac2942
    if (!db.synchronize(false, NULL)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::synchronize");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    class SyncProcessor : public kc::BasicDB::FileProcessor {
Packit Service ac2942
     public:
Packit Service ac2942
      explicit SyncProcessor(int64_t rnum, bool rnd, int64_t size) :
Packit Service ac2942
          rnum_(rnum), rnd_(rnd), size_(size) {}
Packit Service ac2942
     private:
Packit Service ac2942
      bool process(const std::string& path, int64_t count, int64_t size) {
Packit Service ac2942
        if (size != size_) return false;
Packit Service ac2942
        return true;
Packit Service ac2942
      }
Packit Service ac2942
      int64_t rnum_;
Packit Service ac2942
      bool rnd_;
Packit Service ac2942
      int64_t size_;
Packit Service ac2942
    } syncprocessor(rnum, rnd, db.size());
Packit Service ac2942
    if (!db.synchronize(false, &syncprocessor)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::synchronize");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    if (!db.occupy(rnd ? myrand(2) == 0 : true, &syncprocessor)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::occupy");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    etime = kc::time();
Packit Service ac2942
    dbmetaprint(&db, false);
Packit Service ac2942
    oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
  }
Packit Service ac2942
  if (etc && db.size() < (256LL << 20)) {
Packit Service ac2942
    oprintf("dumping records into snapshot:\n");
Packit Service ac2942
    stime = kc::time();
Packit Service ac2942
    std::ostringstream ostrm;
Packit Service ac2942
    if (!db.dump_snapshot(&ostrm)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::dump_snapshot");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    etime = kc::time();
Packit Service ac2942
    dbmetaprint(&db, false);
Packit Service ac2942
    oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
    oprintf("loading records from snapshot:\n");
Packit Service ac2942
    stime = kc::time();
Packit Service ac2942
    int64_t cnt = db.count();
Packit Service ac2942
    if (rnd && myrand(2) == 0 && !db.clear()) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::clear");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    const std::string& str = ostrm.str();
Packit Service ac2942
    std::istringstream istrm(str);
Packit Service ac2942
    if (!db.load_snapshot(&istrm) || db.count() != cnt) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::load_snapshot");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    etime = kc::time();
Packit Service ac2942
    dbmetaprint(&db, false);
Packit Service ac2942
    oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
  }
Packit Service ac2942
  oprintf("removing records:\n");
Packit Service ac2942
  stime = kc::time();
Packit Service ac2942
  class ThreadRemove : public kc::Thread {
Packit Service ac2942
   public:
Packit Service ac2942
    void setparams(int32_t id, kc::BasicDB* db, int64_t rnum, int32_t thnum,
Packit Service ac2942
                   bool rnd, bool etc, bool tran) {
Packit Service ac2942
      id_ = id;
Packit Service ac2942
      db_ = db;
Packit Service ac2942
      rnum_ = rnum;
Packit Service ac2942
      thnum_ = thnum;
Packit Service ac2942
      err_ = false;
Packit Service ac2942
      rnd_ = rnd;
Packit Service ac2942
      etc_ = etc;
Packit Service ac2942
      tran_ = tran;
Packit Service ac2942
    }
Packit Service ac2942
    bool error() {
Packit Service ac2942
      return err_;
Packit Service ac2942
    }
Packit Service ac2942
    void run() {
Packit Service ac2942
      int64_t base = id_ * rnum_;
Packit Service ac2942
      int64_t range = rnum_ * thnum_;
Packit Service ac2942
      for (int64_t i = 1; !err_ && i <= rnum_; i++) {
Packit Service ac2942
        if (tran_ && !db_->begin_transaction(false)) {
Packit Service ac2942
          dberrprint(db_, __LINE__, "DB::begin_transaction");
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        char kbuf[RECBUFSIZ];
Packit Service ac2942
        size_t ksiz = std::sprintf(kbuf, "%08lld",
Packit Service ac2942
                                   (long long)(rnd_ ? myrand(range) + 1 : base + i));
Packit Service ac2942
        if (!db_->remove(kbuf, ksiz) &&
Packit Service ac2942
            ((!rnd_ && !etc_) || db_->error() != kc::BasicDB::Error::NOREC)) {
Packit Service ac2942
          dberrprint(db_, __LINE__, "DB::remove");
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        if (rnd_ && i % 8 == 0) {
Packit Service ac2942
          switch (myrand(8)) {
Packit Service ac2942
            case 0: {
Packit Service ac2942
              if (!db_->set(kbuf, ksiz, kbuf, ksiz)) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::set");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
            case 1: {
Packit Service ac2942
              if (!db_->append(kbuf, ksiz, kbuf, ksiz)) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::append");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
            case 2: {
Packit Service ac2942
              if (!db_->remove(kbuf, ksiz) &&
Packit Service ac2942
                  db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::remove");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
            case 3: {
Packit Service ac2942
              kc::DB::Cursor* cur = db_->cursor();
Packit Service ac2942
              if (cur->jump(kbuf, ksiz)) {
Packit Service ac2942
                switch (myrand(8)) {
Packit Service ac2942
                  default: {
Packit Service ac2942
                    size_t rsiz;
Packit Service ac2942
                    char* rbuf = cur->get_key(&rsiz, myrand(10) == 0);
Packit Service ac2942
                    if (rbuf) {
Packit Service ac2942
                      delete[] rbuf;
Packit Service ac2942
                    } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::get_key");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                  case 1: {
Packit Service ac2942
                    size_t rsiz;
Packit Service ac2942
                    char* rbuf = cur->get_value(&rsiz, myrand(10) == 0);
Packit Service ac2942
                    if (rbuf) {
Packit Service ac2942
                      delete[] rbuf;
Packit Service ac2942
                    } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::get_value");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                  case 2: {
Packit Service ac2942
                    size_t rksiz;
Packit Service ac2942
                    const char* rvbuf;
Packit Service ac2942
                    size_t rvsiz;
Packit Service ac2942
                    char* rkbuf = cur->get(&rksiz, &rvbuf, &rvsiz, myrand(10) == 0);
Packit Service ac2942
                    if (rkbuf) {
Packit Service ac2942
                      delete[] rkbuf;
Packit Service ac2942
                    } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::get");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                  case 3: {
Packit Service ac2942
                    std::string key, value;
Packit Service ac2942
                    if (!cur->get(&key, &value, myrand(10) == 0) &&
Packit Service ac2942
                        db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::get");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                  case 4: {
Packit Service ac2942
                    if (myrand(8) == 0 && !cur->remove() &&
Packit Service ac2942
                        db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::remove");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    break;
Packit Service ac2942
                  }
Packit Service ac2942
                }
Packit Service ac2942
              } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "Cursor::jump");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              delete cur;
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
            default: {
Packit Service ac2942
              size_t vsiz;
Packit Service ac2942
              char* vbuf = db_->get(kbuf, ksiz, &vsiz);
Packit Service ac2942
              if (vbuf) {
Packit Service ac2942
                delete[] vbuf;
Packit Service ac2942
              } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::get");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              break;
Packit Service ac2942
            }
Packit Service ac2942
          }
Packit Service ac2942
        }
Packit Service ac2942
        if (tran_ && !db_->end_transaction(true)) {
Packit Service ac2942
          dberrprint(db_, __LINE__, "DB::end_transaction");
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
Packit Service ac2942
          oputchar('.');
Packit Service ac2942
          if (i == rnum_ || i % (rnum_ / 10) == 0) oprintf(" (%08lld)\n", (long long)i);
Packit Service ac2942
        }
Packit Service ac2942
      }
Packit Service ac2942
    }
Packit Service ac2942
   private:
Packit Service ac2942
    int32_t id_;
Packit Service ac2942
    kc::BasicDB* db_;
Packit Service ac2942
    int64_t rnum_;
Packit Service ac2942
    int32_t thnum_;
Packit Service ac2942
    bool err_;
Packit Service ac2942
    bool rnd_;
Packit Service ac2942
    bool etc_;
Packit Service ac2942
    bool tran_;
Packit Service ac2942
  };
Packit Service ac2942
  ThreadRemove threadremoves[THREADMAX];
Packit Service ac2942
  if (thnum < 2) {
Packit Service ac2942
    threadremoves[0].setparams(0, &db, rnum, thnum, rnd, etc, tran);
Packit Service ac2942
    threadremoves[0].run();
Packit Service ac2942
    if (threadremoves[0].error()) err = true;
Packit Service ac2942
  } else {
Packit Service ac2942
    for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
      threadremoves[i].setparams(i, &db, rnum, thnum, rnd, etc, tran);
Packit Service ac2942
      threadremoves[i].start();
Packit Service ac2942
    }
Packit Service ac2942
    for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
      threadremoves[i].join();
Packit Service ac2942
      if (threadremoves[i].error()) err = true;
Packit Service ac2942
    }
Packit Service ac2942
  }
Packit Service ac2942
  etime = kc::time();
Packit Service ac2942
  dbmetaprint(&db, true);
Packit Service ac2942
  oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
  oprintf("closing the database:\n");
Packit Service ac2942
  stime = kc::time();
Packit Service ac2942
  if (!db.close()) {
Packit Service ac2942
    dberrprint(&db, __LINE__, "DB::close");
Packit Service ac2942
    err = true;
Packit Service ac2942
  }
Packit Service ac2942
  etime = kc::time();
Packit Service ac2942
  oprintf("time: %.3f\n", etime - stime);
Packit Service ac2942
  oprintf("%s\n\n", err ? "error" : "ok");
Packit Service ac2942
  return err ? 1 : 0;
Packit Service ac2942
}
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// perform queue command
Packit Service ac2942
static int32_t procqueue(int64_t rnum, int32_t thnum, int32_t itnum, bool rnd,
Packit Service ac2942
                         int64_t bnum, bool lv) {
Packit Service ac2942
  oprintf("<Queue Test>\n  seed=%u  rnum=%lld  thnum=%d  itnum=%d  rnd=%d"
Packit Service ac2942
          "  bnum=%lld  lv=%d\n\n",
Packit Service ac2942
          g_randseed, (long long)rnum, thnum, itnum, rnd, (long long)bnum, lv);
Packit Service ac2942
  bool err = false;
Packit Service ac2942
  kc::StashDB db;
Packit Service ac2942
  db.tune_logger(stdlogger(g_progname, &std::cout),
Packit Service ac2942
                 lv ? kc::UINT32MAX : kc::BasicDB::Logger::WARN | kc::BasicDB::Logger::ERROR);
Packit Service ac2942
  if (bnum > 0) db.tune_buckets(bnum);
Packit Service ac2942
  for (int32_t itcnt = 1; itcnt <= itnum; itcnt++) {
Packit Service ac2942
    if (itnum > 1) oprintf("iteration %d:\n", itcnt);
Packit Service ac2942
    double stime = kc::time();
Packit Service ac2942
    uint32_t omode = kc::StashDB::OWRITER | kc::StashDB::OCREATE;
Packit Service ac2942
    if (itcnt == 1) omode |= kc::StashDB::OTRUNCATE;
Packit Service ac2942
    if (!db.open(":", omode)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::open");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    class ThreadQueue : public kc::Thread {
Packit Service ac2942
     public:
Packit Service ac2942
      void setparams(int32_t id, kc::StashDB* db, int64_t rnum, int32_t thnum, bool rnd,
Packit Service ac2942
                     int64_t width) {
Packit Service ac2942
        id_ = id;
Packit Service ac2942
        db_ = db;
Packit Service ac2942
        rnum_ = rnum;
Packit Service ac2942
        thnum_ = thnum;
Packit Service ac2942
        rnd_ = rnd;
Packit Service ac2942
        width_ = width;
Packit Service ac2942
        err_ = false;
Packit Service ac2942
      }
Packit Service ac2942
      bool error() {
Packit Service ac2942
        return err_;
Packit Service ac2942
      }
Packit Service ac2942
      void run() {
Packit Service ac2942
        kc::DB::Cursor* cur = db_->cursor();
Packit Service ac2942
        int64_t base = id_ * rnum_;
Packit Service ac2942
        int64_t range = rnum_ * thnum_;
Packit Service ac2942
        for (int64_t i = 1; !err_ && i <= rnum_; i++) {
Packit Service ac2942
          char kbuf[RECBUFSIZ];
Packit Service ac2942
          size_t ksiz = std::sprintf(kbuf, "%010lld", (long long)(base + i));
Packit Service ac2942
          if (!db_->set(kbuf, ksiz, kbuf, ksiz)) {
Packit Service ac2942
            dberrprint(db_, __LINE__, "DB::set");
Packit Service ac2942
            err_ = true;
Packit Service ac2942
          }
Packit Service ac2942
          if (rnd_) {
Packit Service ac2942
            if (myrand(width_ / 2) == 0) {
Packit Service ac2942
              if (!cur->jump() && db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "Cursor::jump");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              ksiz = std::sprintf(kbuf, "%010lld", (long long)myrand(range) + 1);
Packit Service ac2942
              switch (myrand(10)) {
Packit Service ac2942
                case 0: {
Packit Service ac2942
                  if (!db_->set(kbuf, ksiz, kbuf, ksiz)) {
Packit Service ac2942
                    dberrprint(db_, __LINE__, "DB::set");
Packit Service ac2942
                    err_ = true;
Packit Service ac2942
                  }
Packit Service ac2942
                  break;
Packit Service ac2942
                }
Packit Service ac2942
                case 1: {
Packit Service ac2942
                  if (!db_->append(kbuf, ksiz, kbuf, ksiz)) {
Packit Service ac2942
                    dberrprint(db_, __LINE__, "DB::append");
Packit Service ac2942
                    err_ = true;
Packit Service ac2942
                  }
Packit Service ac2942
                  break;
Packit Service ac2942
                }
Packit Service ac2942
                case 2: {
Packit Service ac2942
                  if (!db_->remove(kbuf, ksiz) &&
Packit Service ac2942
                      db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                    dberrprint(db_, __LINE__, "DB::remove");
Packit Service ac2942
                    err_ = true;
Packit Service ac2942
                  }
Packit Service ac2942
                  break;
Packit Service ac2942
                }
Packit Service ac2942
              }
Packit Service ac2942
              int64_t dnum = myrand(width_) + 2;
Packit Service ac2942
              for (int64_t j = 0; j < dnum; j++) {
Packit Service ac2942
                if (myrand(2) == 0) {
Packit Service ac2942
                  size_t rsiz;
Packit Service ac2942
                  char* rbuf = cur->get_key(&rsiz);
Packit Service ac2942
                  if (rbuf) {
Packit Service ac2942
                    if (myrand(10) == 0 && !db_->remove(rbuf, rsiz) &&
Packit Service ac2942
                        db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "DB::remove");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    if (myrand(2) == 0 && !cur->jump(rbuf, rsiz) &&
Packit Service ac2942
                        db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "Cursor::jump");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    if (myrand(10) == 0 && !db_->remove(rbuf, rsiz) &&
Packit Service ac2942
                        db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                      dberrprint(db_, __LINE__, "DB::remove");
Packit Service ac2942
                      err_ = true;
Packit Service ac2942
                    }
Packit Service ac2942
                    delete[] rbuf;
Packit Service ac2942
                  } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                    dberrprint(db_, __LINE__, "Cursor::get_key");
Packit Service ac2942
                    err_ = true;
Packit Service ac2942
                  }
Packit Service ac2942
                }
Packit Service ac2942
                if (!cur->remove() && db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "Cursor::remove");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
              }
Packit Service ac2942
            }
Packit Service ac2942
          } else {
Packit Service ac2942
            if (i > width_) {
Packit Service ac2942
              if (!cur->jump() && db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "Cursor::jump");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
              if (!cur->remove() && db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "Cursor::remove");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
            }
Packit Service ac2942
          }
Packit Service ac2942
          if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
Packit Service ac2942
            oputchar('.');
Packit Service ac2942
            if (i == rnum_ || i % (rnum_ / 10) == 0) oprintf(" (%08lld)\n", (long long)i);
Packit Service ac2942
          }
Packit Service ac2942
        }
Packit Service ac2942
        delete cur;
Packit Service ac2942
      }
Packit Service ac2942
     private:
Packit Service ac2942
      int32_t id_;
Packit Service ac2942
      kc::StashDB* db_;
Packit Service ac2942
      int64_t rnum_;
Packit Service ac2942
      int32_t thnum_;
Packit Service ac2942
      bool rnd_;
Packit Service ac2942
      int64_t width_;
Packit Service ac2942
      bool err_;
Packit Service ac2942
    };
Packit Service ac2942
    int64_t width = rnum / 10;
Packit Service ac2942
    ThreadQueue threads[THREADMAX];
Packit Service ac2942
    if (thnum < 2) {
Packit Service ac2942
      threads[0].setparams(0, &db, rnum, thnum, rnd, width);
Packit Service ac2942
      threads[0].run();
Packit Service ac2942
      if (threads[0].error()) err = true;
Packit Service ac2942
    } else {
Packit Service ac2942
      for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
        threads[i].setparams(i, &db, rnum, thnum, rnd, width);
Packit Service ac2942
        threads[i].start();
Packit Service ac2942
      }
Packit Service ac2942
      for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
        threads[i].join();
Packit Service ac2942
        if (threads[i].error()) err = true;
Packit Service ac2942
      }
Packit Service ac2942
    }
Packit Service ac2942
    int64_t count = db.count();
Packit Service ac2942
    if (!rnd && itcnt == 1 && count != width * thnum) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::count");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    if ((rnd ? (myrand(2) == 0) : itcnt == itnum) && count > 0) {
Packit Service ac2942
      kc::DB::Cursor* cur = db.cursor();
Packit Service ac2942
      if (!cur->jump()) {
Packit Service ac2942
        dberrprint(&db, __LINE__, "Cursor::jump");
Packit Service ac2942
        err = true;
Packit Service ac2942
      }
Packit Service ac2942
      for (int64_t i = 1; i <= count; i++) {
Packit Service ac2942
        if (!cur->remove()) {
Packit Service ac2942
          dberrprint(&db, __LINE__, "Cursor::remove");
Packit Service ac2942
          err = true;
Packit Service ac2942
        }
Packit Service ac2942
        if (rnum > 250 && i % (rnum / 250) == 0) {
Packit Service ac2942
          oputchar('.');
Packit Service ac2942
          if (i == rnum || i % (rnum / 10) == 0) oprintf(" (%08lld)\n", (long long)i);
Packit Service ac2942
        }
Packit Service ac2942
      }
Packit Service ac2942
      if (rnd) oprintf(" (end)\n");
Packit Service ac2942
      delete cur;
Packit Service ac2942
      if (db.count() != 0) {
Packit Service ac2942
        dberrprint(&db, __LINE__, "DB::count");
Packit Service ac2942
        err = true;
Packit Service ac2942
      }
Packit Service ac2942
    }
Packit Service ac2942
    dbmetaprint(&db, itcnt == itnum);
Packit Service ac2942
    if (!db.close()) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::close");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    oprintf("time: %.3f\n", kc::time() - stime);
Packit Service ac2942
  }
Packit Service ac2942
  oprintf("%s\n\n", err ? "error" : "ok");
Packit Service ac2942
  return err ? 1 : 0;
Packit Service ac2942
}
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// perform wicked command
Packit Service ac2942
static int32_t procwicked(int64_t rnum, int32_t thnum, int32_t itnum, int64_t bnum, bool lv) {
Packit Service ac2942
  oprintf("<Wicked Test>\n  seed=%u  rnum=%lld  thnum=%d  itnum=%d"
Packit Service ac2942
          "  bnum=%lld  lv=%d\n\n",
Packit Service ac2942
          g_randseed, (long long)rnum, thnum, itnum, (long long)bnum, lv);
Packit Service ac2942
  bool err = false;
Packit Service ac2942
  kc::StashDB db;
Packit Service ac2942
  db.tune_logger(stdlogger(g_progname, &std::cout),
Packit Service ac2942
                 lv ? kc::UINT32MAX : kc::BasicDB::Logger::WARN | kc::BasicDB::Logger::ERROR);
Packit Service ac2942
  if (bnum > 0) db.tune_buckets(bnum);
Packit Service ac2942
  for (int32_t itcnt = 1; itcnt <= itnum; itcnt++) {
Packit Service ac2942
    if (itnum > 1) oprintf("iteration %d:\n", itcnt);
Packit Service ac2942
    double stime = kc::time();
Packit Service ac2942
    uint32_t omode = kc::StashDB::OWRITER | kc::StashDB::OCREATE;
Packit Service ac2942
    if (itcnt == 1) omode |= kc::StashDB::OTRUNCATE;
Packit Service ac2942
    if (!db.open(":", omode)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::open");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    class ThreadWicked : public kc::Thread {
Packit Service ac2942
     public:
Packit Service ac2942
      void setparams(int32_t id, kc::StashDB* db, int64_t rnum, int32_t thnum,
Packit Service ac2942
                     const char* lbuf) {
Packit Service ac2942
        id_ = id;
Packit Service ac2942
        db_ = db;
Packit Service ac2942
        rnum_ = rnum;
Packit Service ac2942
        thnum_ = thnum;
Packit Service ac2942
        lbuf_ = lbuf;
Packit Service ac2942
        err_ = false;
Packit Service ac2942
      }
Packit Service ac2942
      bool error() {
Packit Service ac2942
        return err_;
Packit Service ac2942
      }
Packit Service ac2942
      void run() {
Packit Service ac2942
        kc::DB::Cursor* cur = db_->cursor();
Packit Service ac2942
        int64_t range = rnum_ * thnum_ / 2;
Packit Service ac2942
        for (int64_t i = 1; !err_ && i <= rnum_; i++) {
Packit Service ac2942
          bool tran = myrand(100) == 0;
Packit Service ac2942
          if (tran) {
Packit Service ac2942
            if (myrand(2) == 0) {
Packit Service ac2942
              if (!db_->begin_transaction(myrand(rnum_) == 0)) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::begin_transaction");
Packit Service ac2942
                tran = false;
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
            } else {
Packit Service ac2942
              if (!db_->begin_transaction_try(myrand(rnum_) == 0)) {
Packit Service ac2942
                if (db_->error() != kc::BasicDB::Error::LOGIC) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "DB::begin_transaction_try");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                tran = false;
Packit Service ac2942
              }
Packit Service ac2942
            }
Packit Service ac2942
          }
Packit Service ac2942
          char kbuf[RECBUFSIZ];
Packit Service ac2942
          size_t ksiz = std::sprintf(kbuf, "%lld", (long long)(myrand(range) + 1));
Packit Service ac2942
          if (myrand(1000) == 0) {
Packit Service ac2942
            ksiz = myrand(RECBUFSIZ) + 1;
Packit Service ac2942
            if (myrand(2) == 0) {
Packit Service ac2942
              for (size_t j = 0; j < ksiz; j++) {
Packit Service ac2942
                kbuf[j] = j;
Packit Service ac2942
              }
Packit Service ac2942
            } else {
Packit Service ac2942
              for (size_t j = 0; j < ksiz; j++) {
Packit Service ac2942
                kbuf[j] = myrand(256);
Packit Service ac2942
              }
Packit Service ac2942
            }
Packit Service ac2942
          }
Packit Service ac2942
          const char* vbuf = kbuf;
Packit Service ac2942
          size_t vsiz = ksiz;
Packit Service ac2942
          if (myrand(10) == 0) {
Packit Service ac2942
            vbuf = lbuf_;
Packit Service ac2942
            vsiz = myrand(RECBUFSIZL) / (myrand(5) + 1);
Packit Service ac2942
          }
Packit Service ac2942
          do {
Packit Service ac2942
            switch (myrand(9)) {
Packit Service ac2942
              case 0: {
Packit Service ac2942
                if (!db_->set(kbuf, ksiz, vbuf, vsiz)) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "DB::set");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
              case 1: {
Packit Service ac2942
                if (!db_->add(kbuf, ksiz, vbuf, vsiz) &&
Packit Service ac2942
                    db_->error() != kc::BasicDB::Error::DUPREC) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "DB::add");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
              case 2: {
Packit Service ac2942
                if (!db_->replace(kbuf, ksiz, vbuf, vsiz) &&
Packit Service ac2942
                    db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "DB::replace");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
              case 3: {
Packit Service ac2942
                if (!db_->append(kbuf, ksiz, vbuf, vsiz)) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "DB::append");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
              case 4: {
Packit Service ac2942
                if (myrand(2) == 0) {
Packit Service ac2942
                  int64_t num = myrand(rnum_);
Packit Service ac2942
                  int64_t orig = myrand(10) == 0 ? kc::INT64MIN : myrand(rnum_);
Packit Service ac2942
                  if (myrand(10) == 0) orig = orig == kc::INT64MIN ? kc::INT64MAX : -orig;
Packit Service ac2942
                  if (db_->increment(kbuf, ksiz, num, orig) == kc::INT64MIN &&
Packit Service ac2942
                      db_->error() != kc::BasicDB::Error::LOGIC) {
Packit Service ac2942
                    dberrprint(db_, __LINE__, "DB::increment");
Packit Service ac2942
                    err_ = true;
Packit Service ac2942
                  }
Packit Service ac2942
                } else {
Packit Service ac2942
                  double num = myrand(rnum_ * 10) / (myrand(rnum_) + 1.0);
Packit Service ac2942
                  double orig = myrand(10) == 0 ? -kc::inf() : myrand(rnum_);
Packit Service ac2942
                  if (myrand(10) == 0) orig = -orig;
Packit Service ac2942
                  if (kc::chknan(db_->increment_double(kbuf, ksiz, num, orig)) &&
Packit Service ac2942
                      db_->error() != kc::BasicDB::Error::LOGIC) {
Packit Service ac2942
                    dberrprint(db_, __LINE__, "DB::increment_double");
Packit Service ac2942
                    err_ = true;
Packit Service ac2942
                  }
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
              case 5: {
Packit Service ac2942
                if (!db_->cas(kbuf, ksiz, kbuf, ksiz, vbuf, vsiz) &&
Packit Service ac2942
                    db_->error() != kc::BasicDB::Error::LOGIC) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "DB::cas");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
              case 6: {
Packit Service ac2942
                if (!db_->remove(kbuf, ksiz) &&
Packit Service ac2942
                    db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "DB::remove");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
              case 7: {
Packit Service ac2942
                if (myrand(2) == 0) {
Packit Service ac2942
                  if (db_->check(kbuf, ksiz) < 0 && db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                    dberrprint(db_, __LINE__, "DB::check");
Packit Service ac2942
                    err_ = true;
Packit Service ac2942
                  }
Packit Service ac2942
                } else {
Packit Service ac2942
                  size_t rsiz;
Packit Service ac2942
                  char* rbuf = db_->seize(kbuf, ksiz, &rsiz);
Packit Service ac2942
                  if (rbuf) {
Packit Service ac2942
                    delete[] rbuf;
Packit Service ac2942
                  } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                    dberrprint(db_, __LINE__, "DB::seize");
Packit Service ac2942
                    err_ = true;
Packit Service ac2942
                  }
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
              case 8: {
Packit Service ac2942
                if (myrand(10) == 0) {
Packit Service ac2942
                  if (!cur->jump(kbuf, ksiz) &&
Packit Service ac2942
                      db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                    dberrprint(db_, __LINE__, "Cursor::jump");
Packit Service ac2942
                    err_ = true;
Packit Service ac2942
                  }
Packit Service ac2942
                } else {
Packit Service ac2942
                  class VisitorImpl : public kc::DB::Visitor {
Packit Service ac2942
                   public:
Packit Service ac2942
                    explicit VisitorImpl(const char* lbuf) : lbuf_(lbuf) {}
Packit Service ac2942
                   private:
Packit Service ac2942
                    const char* visit_full(const char* kbuf, size_t ksiz,
Packit Service ac2942
                                           const char* vbuf, size_t vsiz, size_t* sp) {
Packit Service ac2942
                      const char* rv = NOP;
Packit Service ac2942
                      switch (myrand(3)) {
Packit Service ac2942
                        case 0: {
Packit Service ac2942
                          rv = lbuf_;
Packit Service ac2942
                          *sp = myrand(RECBUFSIZL) / (myrand(5) + 1);
Packit Service ac2942
                          break;
Packit Service ac2942
                        }
Packit Service ac2942
                        case 1: {
Packit Service ac2942
                          rv = REMOVE;
Packit Service ac2942
                          break;
Packit Service ac2942
                        }
Packit Service ac2942
                      }
Packit Service ac2942
                      return rv;
Packit Service ac2942
                    }
Packit Service ac2942
                    const char* lbuf_;
Packit Service ac2942
                  } visitor(lbuf_);
Packit Service ac2942
                  if (!cur->accept(&visitor, true, myrand(2) == 0) &&
Packit Service ac2942
                      db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                    dberrprint(db_, __LINE__, "Cursor::accept");
Packit Service ac2942
                    err_ = true;
Packit Service ac2942
                  }
Packit Service ac2942
                  if (myrand(5) > 0 && !cur->step() &&
Packit Service ac2942
                      db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                    dberrprint(db_, __LINE__, "Cursor::step");
Packit Service ac2942
                    err_ = true;
Packit Service ac2942
                  }
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
              default: {
Packit Service ac2942
                size_t rsiz;
Packit Service ac2942
                char* rbuf = db_->get(kbuf, ksiz, &rsiz);
Packit Service ac2942
                if (rbuf) {
Packit Service ac2942
                  delete[] rbuf;
Packit Service ac2942
                } else if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "DB::get");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
            }
Packit Service ac2942
          } while (myrand(100) == 0);
Packit Service ac2942
          if (myrand(100) == 0) {
Packit Service ac2942
            int32_t jnum = myrand(10);
Packit Service ac2942
            switch (myrand(4)) {
Packit Service ac2942
              case 0: {
Packit Service ac2942
                std::map<std::string, std::string> recs;
Packit Service ac2942
                for (int32_t j = 0; j < jnum; j++) {
Packit Service ac2942
                  char jbuf[RECBUFSIZ];
Packit Service ac2942
                  size_t jsiz = std::sprintf(jbuf, "%lld", (long long)(myrand(range) + 1));
Packit Service ac2942
                  recs[std::string(jbuf, jsiz)] = std::string(kbuf, ksiz);
Packit Service ac2942
                }
Packit Service ac2942
                if (db_->set_bulk(recs, myrand(4)) != (int64_t)recs.size()) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "DB::set_bulk");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
              case 1: {
Packit Service ac2942
                std::vector<std::string> keys;
Packit Service ac2942
                for (int32_t j = 0; j < jnum; j++) {
Packit Service ac2942
                  char jbuf[RECBUFSIZ];
Packit Service ac2942
                  size_t jsiz = std::sprintf(jbuf, "%lld", (long long)(myrand(range) + 1));
Packit Service ac2942
                  keys.push_back(std::string(jbuf, jsiz));
Packit Service ac2942
                }
Packit Service ac2942
                if (db_->remove_bulk(keys, myrand(4)) < 0) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "DB::remove_bulk");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
              default: {
Packit Service ac2942
                std::vector<std::string> keys;
Packit Service ac2942
                for (int32_t j = 0; j < jnum; j++) {
Packit Service ac2942
                  char jbuf[RECBUFSIZ];
Packit Service ac2942
                  size_t jsiz = std::sprintf(jbuf, "%lld", (long long)(myrand(range) + 1));
Packit Service ac2942
                  keys.push_back(std::string(jbuf, jsiz));
Packit Service ac2942
                }
Packit Service ac2942
                std::map<std::string, std::string> recs;
Packit Service ac2942
                if (db_->get_bulk(keys, &recs, myrand(4)) < 0) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "DB::get_bulk");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
            }
Packit Service ac2942
          }
Packit Service ac2942
          if (i == rnum_ / 2) {
Packit Service ac2942
            if (myrand(thnum_ * 4) == 0) {
Packit Service ac2942
              if (!db_->clear()) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::clear");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
            } else {
Packit Service ac2942
              class SyncProcessor : public kc::BasicDB::FileProcessor {
Packit Service ac2942
               private:
Packit Service ac2942
                bool process(const std::string& path, int64_t count, int64_t size) {
Packit Service ac2942
                  yield();
Packit Service ac2942
                  return true;
Packit Service ac2942
                }
Packit Service ac2942
              } syncprocessor;
Packit Service ac2942
              if (!db_->synchronize(false, &syncprocessor)) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::synchronize");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
            }
Packit Service ac2942
          }
Packit Service ac2942
          if (tran) {
Packit Service ac2942
            yield();
Packit Service ac2942
            if (!db_->end_transaction(myrand(10) > 0)) {
Packit Service ac2942
              dberrprint(db_, __LINE__, "DB::end_transactin");
Packit Service ac2942
              err_ = true;
Packit Service ac2942
            }
Packit Service ac2942
          }
Packit Service ac2942
          if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
Packit Service ac2942
            oputchar('.');
Packit Service ac2942
            if (i == rnum_ || i % (rnum_ / 10) == 0) oprintf(" (%08lld)\n", (long long)i);
Packit Service ac2942
          }
Packit Service ac2942
        }
Packit Service ac2942
        delete cur;
Packit Service ac2942
      }
Packit Service ac2942
     private:
Packit Service ac2942
      int32_t id_;
Packit Service ac2942
      kc::StashDB* db_;
Packit Service ac2942
      int64_t rnum_;
Packit Service ac2942
      int32_t thnum_;
Packit Service ac2942
      const char* lbuf_;
Packit Service ac2942
      bool err_;
Packit Service ac2942
    };
Packit Service ac2942
    char lbuf[RECBUFSIZL];
Packit Service ac2942
    std::memset(lbuf, '*', sizeof(lbuf));
Packit Service ac2942
    ThreadWicked threads[THREADMAX];
Packit Service ac2942
    if (thnum < 2) {
Packit Service ac2942
      threads[0].setparams(0, &db, rnum, thnum, lbuf);
Packit Service ac2942
      threads[0].run();
Packit Service ac2942
      if (threads[0].error()) err = true;
Packit Service ac2942
    } else {
Packit Service ac2942
      for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
        threads[i].setparams(i, &db, rnum, thnum, lbuf);
Packit Service ac2942
        threads[i].start();
Packit Service ac2942
      }
Packit Service ac2942
      for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
        threads[i].join();
Packit Service ac2942
        if (threads[i].error()) err = true;
Packit Service ac2942
      }
Packit Service ac2942
    }
Packit Service ac2942
    dbmetaprint(&db, itcnt == itnum);
Packit Service ac2942
    if (!db.close()) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::close");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    oprintf("time: %.3f\n", kc::time() - stime);
Packit Service ac2942
  }
Packit Service ac2942
  oprintf("%s\n\n", err ? "error" : "ok");
Packit Service ac2942
  return err ? 1 : 0;
Packit Service ac2942
}
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// perform tran command
Packit Service ac2942
static int32_t proctran(int64_t rnum, int32_t thnum, int32_t itnum, int64_t bnum, bool lv) {
Packit Service ac2942
  oprintf("<Transaction Test>\n  seed=%u  rnum=%lld  thnum=%d  itnum=%d"
Packit Service ac2942
          "  bnum=%lld  lv=%d\n\n",
Packit Service ac2942
          g_randseed, (long long)rnum, thnum, itnum, (long long)bnum, lv);
Packit Service ac2942
  bool err = false;
Packit Service ac2942
  kc::StashDB db;
Packit Service ac2942
  kc::StashDB paradb;
Packit Service ac2942
  db.tune_logger(stdlogger(g_progname, &std::cout),
Packit Service ac2942
                 lv ? kc::UINT32MAX : kc::BasicDB::Logger::WARN | kc::BasicDB::Logger::ERROR);
Packit Service ac2942
  paradb.tune_logger(stdlogger(g_progname, &std::cout), lv ? kc::UINT32MAX :
Packit Service ac2942
                     kc::BasicDB::Logger::WARN | kc::BasicDB::Logger::ERROR);
Packit Service ac2942
  if (bnum > 0) db.tune_buckets(bnum);
Packit Service ac2942
  for (int32_t itcnt = 1; itcnt <= itnum; itcnt++) {
Packit Service ac2942
    oprintf("iteration %d updating:\n", itcnt);
Packit Service ac2942
    double stime = kc::time();
Packit Service ac2942
    uint32_t omode = kc::StashDB::OWRITER | kc::StashDB::OCREATE;
Packit Service ac2942
    if (itcnt == 1) omode |= kc::StashDB::OTRUNCATE;
Packit Service ac2942
    if (!db.open(":", omode)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::open");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    if (!paradb.open("para", omode)) {
Packit Service ac2942
      dberrprint(&paradb, __LINE__, "DB::open");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    class ThreadTran : public kc::Thread {
Packit Service ac2942
     public:
Packit Service ac2942
      void setparams(int32_t id, kc::StashDB* db, kc::StashDB* paradb, int64_t rnum,
Packit Service ac2942
                     int32_t thnum, const char* lbuf) {
Packit Service ac2942
        id_ = id;
Packit Service ac2942
        db_ = db;
Packit Service ac2942
        paradb_ = paradb;
Packit Service ac2942
        rnum_ = rnum;
Packit Service ac2942
        thnum_ = thnum;
Packit Service ac2942
        lbuf_ = lbuf;
Packit Service ac2942
        err_ = false;
Packit Service ac2942
      }
Packit Service ac2942
      bool error() {
Packit Service ac2942
        return err_;
Packit Service ac2942
      }
Packit Service ac2942
      void run() {
Packit Service ac2942
        kc::DB::Cursor* cur = db_->cursor();
Packit Service ac2942
        int64_t range = rnum_ * thnum_;
Packit Service ac2942
        char kbuf[RECBUFSIZ];
Packit Service ac2942
        size_t ksiz = std::sprintf(kbuf, "%lld", (long long)(myrand(range) + 1));
Packit Service ac2942
        if (!cur->jump(kbuf, ksiz) && db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
          dberrprint(db_, __LINE__, "Cursor::jump");
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        bool tran = true;
Packit Service ac2942
        if (!db_->begin_transaction(false)) {
Packit Service ac2942
          dberrprint(db_, __LINE__, "DB::begin_transaction");
Packit Service ac2942
          tran = false;
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        bool commit = myrand(10) > 0;
Packit Service ac2942
        for (int64_t i = 1; !err_ && i <= rnum_; i++) {
Packit Service ac2942
          ksiz = std::sprintf(kbuf, "%lld", (long long)(myrand(range) + 1));
Packit Service ac2942
          const char* vbuf = kbuf;
Packit Service ac2942
          size_t vsiz = ksiz;
Packit Service ac2942
          if (myrand(10) == 0) {
Packit Service ac2942
            vbuf = lbuf_;
Packit Service ac2942
            vsiz = myrand(RECBUFSIZL) / (myrand(5) + 1);
Packit Service ac2942
          }
Packit Service ac2942
          class VisitorImpl : public kc::DB::Visitor {
Packit Service ac2942
           public:
Packit Service ac2942
            explicit VisitorImpl(const char* vbuf, size_t vsiz, kc::BasicDB* paradb) :
Packit Service ac2942
                vbuf_(vbuf), vsiz_(vsiz), paradb_(paradb) {}
Packit Service ac2942
           private:
Packit Service ac2942
            const char* visit_full(const char* kbuf, size_t ksiz,
Packit Service ac2942
                                   const char* vbuf, size_t vsiz, size_t* sp) {
Packit Service ac2942
              return visit_empty(kbuf, ksiz, sp);
Packit Service ac2942
            }
Packit Service ac2942
            const char* visit_empty(const char* kbuf, size_t ksiz, size_t* sp) {
Packit Service ac2942
              const char* rv = NOP;
Packit Service ac2942
              switch (myrand(3)) {
Packit Service ac2942
                case 0: {
Packit Service ac2942
                  rv = vbuf_;
Packit Service ac2942
                  *sp = vsiz_;
Packit Service ac2942
                  if (paradb_) paradb_->set(kbuf, ksiz, vbuf_, vsiz_);
Packit Service ac2942
                  break;
Packit Service ac2942
                }
Packit Service ac2942
                case 1: {
Packit Service ac2942
                  rv = REMOVE;
Packit Service ac2942
                  if (paradb_) paradb_->remove(kbuf, ksiz);
Packit Service ac2942
                  break;
Packit Service ac2942
                }
Packit Service ac2942
              }
Packit Service ac2942
              return rv;
Packit Service ac2942
            }
Packit Service ac2942
            const char* vbuf_;
Packit Service ac2942
            size_t vsiz_;
Packit Service ac2942
            kc::BasicDB* paradb_;
Packit Service ac2942
          } visitor(vbuf, vsiz, !tran || commit ? paradb_ : NULL);
Packit Service ac2942
          if (myrand(4) == 0) {
Packit Service ac2942
            if (!cur->accept(&visitor, true, myrand(2) == 0) &&
Packit Service ac2942
                db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
              dberrprint(db_, __LINE__, "Cursor::accept");
Packit Service ac2942
              err_ = true;
Packit Service ac2942
            }
Packit Service ac2942
          } else {
Packit Service ac2942
            if (!db_->accept(kbuf, ksiz, &visitor, true)) {
Packit Service ac2942
              dberrprint(db_, __LINE__, "DB::accept");
Packit Service ac2942
              err_ = true;
Packit Service ac2942
            }
Packit Service ac2942
          }
Packit Service ac2942
          if (myrand(1000) == 0) {
Packit Service ac2942
            ksiz = std::sprintf(kbuf, "%lld", (long long)(myrand(range) + 1));
Packit Service ac2942
            if (!cur->jump(kbuf, ksiz)) {
Packit Service ac2942
              if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "Cursor::jump");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              } else if (!cur->jump() && db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "Cursor::jump");
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
            }
Packit Service ac2942
            std::vector<std::string> keys;
Packit Service ac2942
            keys.reserve(100);
Packit Service ac2942
            while (myrand(50) != 0) {
Packit Service ac2942
              std::string key;
Packit Service ac2942
              if (cur->get_key(&key)) {
Packit Service ac2942
                keys.push_back(key);
Packit Service ac2942
                if (!cur->get_value(&key) && kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "Cursor::get_value");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
              } else {
Packit Service ac2942
                if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "Cursor::get_key");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
              if (!cur->step()) {
Packit Service ac2942
                if (db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "Cursor::jump");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
                break;
Packit Service ac2942
              }
Packit Service ac2942
            }
Packit Service ac2942
            class Remover : public kc::DB::Visitor {
Packit Service ac2942
             public:
Packit Service ac2942
              explicit Remover(kc::BasicDB* paradb) : paradb_(paradb) {}
Packit Service ac2942
             private:
Packit Service ac2942
              const char* visit_full(const char* kbuf, size_t ksiz,
Packit Service ac2942
                                     const char* vbuf, size_t vsiz, size_t* sp) {
Packit Service ac2942
                if (myrand(200) == 0) return NOP;
Packit Service ac2942
                if (paradb_) paradb_->remove(kbuf, ksiz);
Packit Service ac2942
                return REMOVE;
Packit Service ac2942
              }
Packit Service ac2942
              kc::BasicDB* paradb_;
Packit Service ac2942
            } remover(!tran || commit ? paradb_ : NULL);
Packit Service ac2942
            std::vector<std::string>::iterator it = keys.begin();
Packit Service ac2942
            std::vector<std::string>::iterator end = keys.end();
Packit Service ac2942
            while (it != end) {
Packit Service ac2942
              if (myrand(50) == 0) {
Packit Service ac2942
                if (!cur->accept(&remover, true, false) &&
Packit Service ac2942
                    db_->error() != kc::BasicDB::Error::NOREC) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "Cursor::accept");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
              } else {
Packit Service ac2942
                if (!db_->accept(it->c_str(), it->size(), &remover, true)) {
Packit Service ac2942
                  dberrprint(db_, __LINE__, "DB::accept");
Packit Service ac2942
                  err_ = true;
Packit Service ac2942
                }
Packit Service ac2942
              }
Packit Service ac2942
              ++it;
Packit Service ac2942
            }
Packit Service ac2942
          }
Packit Service ac2942
          if (tran && myrand(100) == 0) {
Packit Service ac2942
            if (db_->end_transaction(commit)) {
Packit Service ac2942
              yield();
Packit Service ac2942
              if (!db_->begin_transaction(false)) {
Packit Service ac2942
                dberrprint(db_, __LINE__, "DB::begin_transaction");
Packit Service ac2942
                tran = false;
Packit Service ac2942
                err_ = true;
Packit Service ac2942
              }
Packit Service ac2942
            } else {
Packit Service ac2942
              dberrprint(db_, __LINE__, "DB::end_transaction");
Packit Service ac2942
              err_ = true;
Packit Service ac2942
            }
Packit Service ac2942
          }
Packit Service ac2942
          if (id_ < 1 && rnum_ > 250 && i % (rnum_ / 250) == 0) {
Packit Service ac2942
            oputchar('.');
Packit Service ac2942
            if (i == rnum_ || i % (rnum_ / 10) == 0) oprintf(" (%08lld)\n", (long long)i);
Packit Service ac2942
          }
Packit Service ac2942
        }
Packit Service ac2942
        if (tran && !db_->end_transaction(commit)) {
Packit Service ac2942
          dberrprint(db_, __LINE__, "DB::end_transaction");
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        delete cur;
Packit Service ac2942
      }
Packit Service ac2942
     private:
Packit Service ac2942
      int32_t id_;
Packit Service ac2942
      kc::StashDB* db_;
Packit Service ac2942
      kc::StashDB* paradb_;
Packit Service ac2942
      int64_t rnum_;
Packit Service ac2942
      int32_t thnum_;
Packit Service ac2942
      const char* lbuf_;
Packit Service ac2942
      bool err_;
Packit Service ac2942
    };
Packit Service ac2942
    char lbuf[RECBUFSIZL];
Packit Service ac2942
    std::memset(lbuf, '*', sizeof(lbuf));
Packit Service ac2942
    ThreadTran threads[THREADMAX];
Packit Service ac2942
    if (thnum < 2) {
Packit Service ac2942
      threads[0].setparams(0, &db, &paradb, rnum, thnum, lbuf);
Packit Service ac2942
      threads[0].run();
Packit Service ac2942
      if (threads[0].error()) err = true;
Packit Service ac2942
    } else {
Packit Service ac2942
      for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
        threads[i].setparams(i, &db, &paradb, rnum, thnum, lbuf);
Packit Service ac2942
        threads[i].start();
Packit Service ac2942
      }
Packit Service ac2942
      for (int32_t i = 0; i < thnum; i++) {
Packit Service ac2942
        threads[i].join();
Packit Service ac2942
        if (threads[i].error()) err = true;
Packit Service ac2942
      }
Packit Service ac2942
    }
Packit Service ac2942
    oprintf("iteration %d checking:\n", itcnt);
Packit Service ac2942
    if (db.count() != paradb.count()) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::count");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    class VisitorImpl : public kc::DB::Visitor {
Packit Service ac2942
     public:
Packit Service ac2942
      explicit VisitorImpl(int64_t rnum, kc::BasicDB* paradb) :
Packit Service ac2942
          rnum_(rnum), paradb_(paradb), err_(false), cnt_(0) {}
Packit Service ac2942
      bool error() {
Packit Service ac2942
        return err_;
Packit Service ac2942
      }
Packit Service ac2942
     private:
Packit Service ac2942
      const char* visit_full(const char* kbuf, size_t ksiz,
Packit Service ac2942
                             const char* vbuf, size_t vsiz, size_t* sp) {
Packit Service ac2942
        cnt_++;
Packit Service ac2942
        size_t rsiz;
Packit Service ac2942
        char* rbuf = paradb_->get(kbuf, ksiz, &rsiz);
Packit Service ac2942
        if (rbuf) {
Packit Service ac2942
          delete[] rbuf;
Packit Service ac2942
        } else {
Packit Service ac2942
          dberrprint(paradb_, __LINE__, "DB::get");
Packit Service ac2942
          err_ = true;
Packit Service ac2942
        }
Packit Service ac2942
        if (rnum_ > 250 && cnt_ % (rnum_ / 250) == 0) {
Packit Service ac2942
          oputchar('.');
Packit Service ac2942
          if (cnt_ == rnum_ || cnt_ % (rnum_ / 10) == 0) oprintf(" (%08lld)\n", (long long)cnt_);
Packit Service ac2942
        }
Packit Service ac2942
        return NOP;
Packit Service ac2942
      }
Packit Service ac2942
      int64_t rnum_;
Packit Service ac2942
      kc::BasicDB* paradb_;
Packit Service ac2942
      bool err_;
Packit Service ac2942
      int64_t cnt_;
Packit Service ac2942
    } visitor(rnum, &paradb), paravisitor(rnum, &db);
Packit Service ac2942
    if (!db.iterate(&visitor, false)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::iterate");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    oprintf(" (end)\n");
Packit Service ac2942
    if (visitor.error()) err = true;
Packit Service ac2942
    if (!paradb.iterate(&paravisitor, false)) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::iterate");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    oprintf(" (end)\n");
Packit Service ac2942
    if (paravisitor.error()) err = true;
Packit Service ac2942
    if (!paradb.close()) {
Packit Service ac2942
      dberrprint(&paradb, __LINE__, "DB::close");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    dbmetaprint(&db, itcnt == itnum);
Packit Service ac2942
    if (!db.close()) {
Packit Service ac2942
      dberrprint(&db, __LINE__, "DB::close");
Packit Service ac2942
      err = true;
Packit Service ac2942
    }
Packit Service ac2942
    oprintf("time: %.3f\n", kc::time() - stime);
Packit Service ac2942
  }
Packit Service ac2942
  oprintf("%s\n\n", err ? "error" : "ok");
Packit Service ac2942
  return err ? 1 : 0;
Packit Service ac2942
}
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
Packit Service ac2942
// END OF FILE