Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  hstest.cpp   Sprache: C

 


// vim:sw=2:ai

#include <signal.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <stdlib.h>
#include <memory>
#include <errno.h>
#include <mysql.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "util.hpp"
#include "auto_ptrcontainer.hpp"
#include "socket.hpp"
#include "thread.hpp"
#include "hstcpcli.hpp"

#if __GNUC__ >= 4
long atomic_exchange_and_add(volatile long *valp, long c)
{
  return __sync_fetch_and_add(valp, c);
}
#else
#include <bits/atomicity.h>
using namespace __gnu_cxx;
long atomic_exchange_and_add(volatile long *valp, long c)
{
  return __exchange_and_add((volatile _Atomic_word *)valp, c);
}
#endif

namespace dena {

struct auto_mysql : private noncopyable {
  auto_mysql() : db(0) {
    reset();
  }
  ~auto_mysql() {
    if (db) {
      mysql_close(db);
    }
  }
  void reset() {
    if (db) {
      mysql_close(db);
    }
    if ((db = mysql_init(0)) == 0) {
      fatal_abort("failed to initialize mysql client");
    }
  }
  operator MYSQL *() const { return db; }
 private:
  MYSQL *db;
};

struct auto_mysql_res : private noncopyable {
  auto_mysql_res(MYSQL *db) {
    res = mysql_store_result(db);
  }
  ~auto_mysql_res() {
    if (res) {
      mysql_free_result(res);
    }
  }
  operator MYSQL_RES *() const { return res; }
 private:
  MYSQL_RES *res;
};

struct auto_mysql_stmt : private noncopyable {
  auto_mysql_stmt(MYSQL *db) {
    stmt = mysql_stmt_init(db);
  }
  ~auto_mysql_stmt() {
    if (stmt) {
      mysql_stmt_close(stmt);
    }
  }
  operator MYSQL_STMT *() const { return stmt; }
 private:
  MYSQL_STMT *stmt;
};

namespace {

double
gettimeofday_double()
{
  struct timeval tv;
  if (gettimeofday(&tv, 0) != 0) {
    fatal_abort("gettimeofday");
  }
  return static_cast<double>(tv.tv_usec) / 1000000 + tv.tv_sec;
}

// unused
void
wait_close(int fd)
{
  char buf[1024];
  while (true) {
    int r = read(fd, buf, sizeof(buf));
    if (r <= 0) {
      break;
    }
  }
}

// unused
void
gentle_close(int fd)
{
  int r = shutdown(fd, SHUT_WR);
  if (r != 0) {
    return;
  }
  wait_close(fd);
}

};

struct hstest_shared {
  config conf;
  socket_args arg;
  int verbose;
  size_t loop;
  size_t pipe;
  char op;
  long num_threads;
  mutable volatile long count;
  mutable volatile long conn_count;
  long wait_conn;
  volatile char *keygen;
  long keygen_size;
  mutable volatile int enable_timing;
  int usleep;
  int dump;
  hstest_shared() : verbose(0), loop(0), pipe(0), op('G'), num_threads(0),
    count(0), conn_count(0), wait_conn(0), keygen(0), keygen_size(0),
    enable_timing(0), usleep(0), dump(0) { }
  void increment_count(unsigned int c = 1) const volatile {
    atomic_exchange_and_add(&count, c);
  }
  void increment_conn(unsigned int c) const volatile {
    atomic_exchange_and_add(&conn_count, c);
    while (wait_conn != 0 && conn_count < wait_conn) {
      sleep(1);
    }
    // fprintf(stderr, "wait_conn=%ld done\n", wait_conn);
  }
};

struct hstest_thread {
  struct arg_type {
    size_t id;
    const hstest_shared& sh;
    bool watch_flag;
    arg_type(size_t i, const hstest_shared& s, bool w)
      : id(i), sh(s), watch_flag(w) { }
  };
  hstest_thread(const arg_type& a) : arg(a), io_success_count(0),
    op_success_count(0), response_min(99999), response_max(0),
    response_sum(0), response_avg(0) { }
  void operator ()();
  void test_1();
  void test_2_3(int test_num);
  void test_4_5(int test_num);
  void test_6(int test_num);
  void test_7(int test_num);
  void test_8(int test_num);
  void test_9(int test_num);
  void test_10(int test_num);
  void test_11(int test_num);
  void test_12(int test_num);
  void test_21(int test_num);
  void test_22(int test_num);
  void test_watch();
  void sleep_if();
  void set_timing(double time_spent);
  arg_type arg;
  auto_file fd;
  size_t io_success_count;
  size_t op_success_count;
  double response_min, response_max, response_sum, response_avg;
};

void
hstest_thread::test_1()
{
  char buf[1024];
  unsigned int seed = arg.id;
  seed ^= arg.sh.conf.get_int("seed_xor", 0);
  std::string err;
  if (socket_connect(fd, arg.sh.arg, err) != 0) {
    fprintf(stderr, "connect: %d %s\n", errno, strerror(errno));
    return;
  }
  const char op = arg.sh.op;
  const int tablesize = arg.sh.conf.get_int("tablesize", 0);
  for (size_t i = 0; i < arg.sh.loop; ++i) {
    for (size_t j = 0; j < arg.sh.pipe; ++j) {
      int k = 0, v = 0, len = 0;
      if (op == 'G') {
 k = rand_r(&seed);
 v = rand_r(&seed); /* unused */
 if (tablesize != 0) {
   k &= tablesize;
 }
 len = snprintf(buf, sizeof(buf), "%c\tk%d\n", op, k);
      } else {
 k = rand_r(&seed);
 v = rand_r(&seed);
 if (tablesize != 0) {
   k &= tablesize;
 }
 len = snprintf(buf, sizeof(buf), "%c\tk%d\tv%d\n", op, k, v);
      }
      const int wlen = write(fd.get(), buf, len);
      if (wlen != len) {
 return;
      }
    }
    size_t read_cnt = 0;
    size_t read_pos = 0;
    while (read_cnt < arg.sh.pipe) {
      const int rlen = read(fd.get(), buf + read_pos, sizeof(buf) - read_pos);
      if (rlen <= 0) {
 return;
      }
      read_pos += rlen;
      while (true) {
 const char *const p = static_cast<const char *>(memchr(buf, '\n',
   read_pos));
 if (p == 0) {
   break;
 }
 ++read_cnt;
 ++io_success_count;
 arg.sh.increment_count();
 if (p != buf && buf[0] == '=') {
   ++op_success_count;
 }
 const size_t rest_size = buf + read_pos - (p + 1);
 if (rest_size != 0) {
   memmove(buf, p + 1, rest_size);
 }
 read_pos = rest_size;
      }
    }
  }
}

void
hstest_thread::test_2_3(int test_num)
{
#if 0
  char buf_k[128], buf_v[128];
  unsigned int seed = arg.id;
  op_base_t op = static_cast<op_base_t>(arg.sh.op);
  micli_ptr hnd;
  if (test_num == 2) {
    hnd = micli_i::create_remote(arg.sh.conf);
  } else if (test_num == 3) {
    // hnd = micli_i::create_inproc(arg.sh.localdb);
  }
  if (hnd.get() == 0) {
    return;
  }
  for (size_t i = 0; i < arg.sh.loop; ++i) {
    for (size_t j = 0; j < arg.sh.pipe; ++j) {
      int k = 0, v = 0, klen = 0, vlen = 0;
      k = rand_r(&seed);
      klen = snprintf(buf_k, sizeof(buf_k), "k%d", k);
      v = rand_r(&seed); /* unused */
      vlen = snprintf(buf_v, sizeof(buf_v), "v%d", v);
      string_ref arr[2];
      arr[0] = string_ref(buf_k, klen);
      arr[1] = string_ref(buf_v, vlen);
      pstrarr_ptr rec(arr, 2);
      if (hnd->execute(op, 0, 0, rec.get_const())) {
 ++io_success_count;
 arg.sh.increment_count();
 const dataset& res = hnd->get_result_ref();
 if (res.size() == 1) {
   ++op_success_count;
 }
      }
    }
  }
#endif
}

void
hstest_thread::test_4_5(int test_num)
{
#if 0
  char buf_k[128], buf_v[8192];
  memset(buf_v, ' ', sizeof(buf_v));
  unsigned int seed = arg.id;
  op_base_t op = static_cast<op_base_t>(arg.sh.op);
  micli_ptr hnd;
  if (test_num == 4) {
    hnd = micli_i::create_remote(arg.sh.conf);
  } else if (test_num == 5) {
    hnd = micli_i::create_inproc(arg.sh.localdb);
  }
  if (hnd.get() == 0) {
    return;
  }
  for (size_t i = 0; i < arg.sh.loop; ++i) {
    for (size_t j = 0; j < arg.sh.pipe; ++j) {
      int k = 0, klen = 0, vlen = 0;
      k = i & 0x0000ffffUL;
      if (k == 0) {
 fprintf(stderr, "k=0\n");
      }
      klen = snprintf(buf_k, sizeof(buf_k), "k%d", k);
      vlen = rand_r(&seed) % 8192;
      string_ref arr[2];
      arr[0] = string_ref(buf_k, klen);
      arr[1] = string_ref(buf_v, vlen);
      pstrarr_ptr rec(arr, 2);
      if (hnd->execute(op, 0, 0, rec.get_const())) {
 ++io_success_count;
 const dataset& res = hnd->get_result_ref();
 if (res.size() == 1) {
   ++op_success_count;
 }
      }
    }
  }
#endif
}

void
hstest_thread::test_6(int test_num)
{
  int count = arg.sh.conf.get_int("count", 1);
  auto_file fds[count];
  for (int i = 0; i < count; ++i) {
    const double t1 = gettimeofday_double();
    std::string err;
    if (socket_connect(fds[i], arg.sh.arg, err) != 0) {
      fprintf(stderr, "id=%zu i=%d err=%s\n", arg.id, i, err.c_str());
    }
    const double t2 = gettimeofday_double();
    if (t2 - t1 > 1) {
      fprintf(stderr, "id=%zu i=%d time %f\n", arg.id, i, t2 - t1);
    }
  }
}

void
hstest_thread::test_7(int num)
{
  /*
    set foo 0 0 10
    0123456789
    STORED
    get foo
    VALUE foo 0 10
    0123456789
    END
    get var
    END
   */

  char buf[1024];
  const int keep_connection = arg.sh.conf.get_int("keep_connection", 1);
  unsigned int seed = arg.id;
  seed ^= arg.sh.conf.get_int("seed_xor", 0);
  const int tablesize = arg.sh.conf.get_int("tablesize", 0);
  const char op = arg.sh.op;
  for (size_t i = 0; i < arg.sh.loop; ++i) {
    const double tm1 = gettimeofday_double();
    std::string err;
    if (fd.get() < 0 && socket_connect(fd, arg.sh.arg, err) != 0) {
      fprintf(stderr, "connect: %d %s\n", errno, strerror(errno));
      return;
    }
    for (size_t j = 0; j < arg.sh.pipe; ++j) {
      int k = 0, v = 0, len = 0;
      if (op == 'G') {
 k = rand_r(&seed);
 v = rand_r(&seed); /* unused */
 if (tablesize != 0) {
   k &= tablesize;
 }
 len = snprintf(buf, sizeof(buf), "get k%d\r\n", k);
      } else {
 k = rand_r(&seed);
 v = rand_r(&seed);
 if (tablesize != 0) {
   k &= tablesize;
 }
 char vbuf[1024];
 int vlen = snprintf(vbuf, sizeof(vbuf),
   "v%d"
   // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
   // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
   // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
   // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
   // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
   , v);
 len = snprintf(buf, sizeof(buf), "set k%d 0 0 %d\r\n%s\r\n",
   k, vlen, vbuf);
      }
      const int wlen = write(fd.get(), buf, len);
      if (wlen != len) {
 return;
      }
    }
    size_t read_cnt = 0;
    size_t read_pos = 0;
    bool read_response_done = false;
    bool expect_value = false;
    while (!read_response_done) {
      const int rlen = read(fd.get(), buf + read_pos, sizeof(buf) - read_pos);
      if (rlen <= 0) {
 return;
      }
      read_pos += rlen;
      while (true) {
 const char *const p = static_cast<const char *>(memchr(buf, '\n',
   read_pos));
 if (p == 0) {
   break;
 }
 ++read_cnt;
 if (expect_value) {
   expect_value = false;
 } else if (p >= buf + 6 && memcmp(buf, "VALUE ", 6) == 0) {
   expect_value = true;
   ++op_success_count;
 } else {
   if (p == buf + 7 && memcmp(buf, "STORED\r", 7) == 0) {
     ++op_success_count;
   }
   read_response_done = true;
 }
 const size_t rest_size = buf + read_pos - (p + 1);
 if (rest_size != 0) {
   memmove(buf, p + 1, rest_size);
 }
 read_pos = rest_size;
      }
      ++io_success_count;
    }
    arg.sh.increment_count();
    if (!keep_connection) {
      fd.close();
    }
    const double tm2 = gettimeofday_double();
    set_timing(tm2 - tm1);
    sleep_if();
  }
}

struct rec {
  std::string key;
  std::string value;
};

void
hstest_thread::test_8(int test_num)
{
#if 0
  char buf_k[128], buf_v[128];
  unsigned int seed = arg.id;
  // op_base_t op = static_cast<op_base_t>(arg.sh.op);
  using namespace boost::multi_index;
  typedef member<rec, std::string, &rec::key> rec_get_key;
  typedef ordered_unique<rec_get_key> oui;
  typedef multi_index_container< rec, indexed_by<oui> > mic;
  #if 0
  typedef std::map<std::string, std::string> m_type;
  m_type m;
  #endif
  mic m;
  for (size_t i = 0; i < arg.sh.loop; ++i) {
    for (size_t j = 0; j < arg.sh.pipe; ++j) {
      int k = 0, v = 0, klen = 0, vlen = 0;
      k = rand_r(&seed);
      klen = snprintf(buf_k, sizeof(buf_k), "k%d", k);
      v = rand_r(&seed); /* unused */
      vlen = snprintf(buf_v, sizeof(buf_v), "v%d", v);
      const std::string ks(buf_k, klen);
      const std::string vs(buf_v, vlen);
      rec r;
      r.key = ks;
      r.value = vs;
      m.insert(r);
      // m.insert(std::make_pair(ks, vs));
      ++io_success_count;
      ++op_success_count;
      arg.sh.increment_count();
    }
  }
#endif
}

struct mysqltest_thread_initobj : private noncopyable {
  mysqltest_thread_initobj() {
    mysql_thread_init();
  }
  ~mysqltest_thread_initobj() {
    mysql_thread_end();
  }
};

void
hstest_thread::test_9(int test_num)
{
  /* create table hstest
   * ( k varchar(255) not null, v varchar(255) not null, primary key(k))
   * engine = innodb; */

  auto_mysql db;
  // mysqltest_thread_initobj initobj;
  std::string err;
  const char op = arg.sh.op;
  const std::string suffix = arg.sh.conf.get_str("value_suffix", "upd");
  unsigned long long err_cnt = 0;
  unsigned long long query_cnt = 0;
  #if 0
  my_bool reconnect = 0;
  if (mysql_options(db, MYSQL_OPT_RECONNECT, &reconnect) != 0) {
    err = "mysql_options() failed";
    ++err_cnt;
    return;
  }
  #endif
  unsigned int seed = time(0) + arg.id + 1;
  seed ^= arg.sh.conf.get_int("seed_xor", 0);
  drand48_data randbuf;
  srand48_r(seed, &randbuf);
  const std::string mysql_host = arg.sh.conf.get_str("host", "localhost");
  const int mysql_port = arg.sh.conf.get_int("mysqlport", 3306);
  const int num = arg.sh.loop;
  const std::string mysql_user = arg.sh.conf.get_str("mysqluser", "root");
  const std::string mysql_passwd = arg.sh.conf.get_str("mysqlpass", "");
  const std::string mysql_dbname = arg.sh.conf.get_str("dbname", "hstest");
  const int keep_connection = arg.sh.conf.get_int("keep_connection", 1);
  const int verbose = arg.sh.conf.get_int("verbose", 1);
  const int tablesize = arg.sh.conf.get_int("tablesize", 10000);
  const int moreflds = arg.sh.conf.get_int("moreflds", 0);
  const std::string moreflds_prefix = arg.sh.conf.get_str(
    "moreflds_prefix", "column0123456789_");
  const int use_handler = arg.sh.conf.get_int("handler", 0);
  const int sched_flag = arg.sh.conf.get_int("sched", 0);
  const int use_in = arg.sh.conf.get_int("in", 0);
  const int ssps = use_in ? 0 : arg.sh.conf.get_int("ssps", 0);
  std::string flds = "v";
  for (int i = 0; i < moreflds; ++i) {
    char buf[1024];
    snprintf(buf, sizeof(buf), ",%s%d", moreflds_prefix.c_str(), i);
    flds += std::string(buf);
  }
  int connected = 0;
  std::unique_ptr<auto_mysql_stmt> stmt;
  string_buffer wbuf;
  for (int i = 0; i < num; ++i) {
    const double tm1 = gettimeofday_double();
    const int flags = 0;
    if (connected == 0) {
      if (!mysql_real_connect(db, mysql_host.c_str(),
 mysql_user.c_str(), mysql_user.empty() ? 0 : mysql_passwd.c_str(),
 mysql_dbname.c_str(), mysql_port, 0, flags)) {
 err = "failed to connect: " + std::string(mysql_error(db));
 if (verbose >= 1) {
   fprintf(stderr, "e=[%s]\n", err.c_str());
 }
 ++err_cnt;
 return;
      }
      arg.sh.increment_conn(1);
    }
    int r = 0;
    if (connected == 0 && use_handler) {
      const char *const q = "handler hstest_table1 open";
      r = mysql_real_query(db, q, strlen(q));
      if (r != 0) {
 err = 1;
      }
    }
    if (connected == 0 && ssps) {
      stmt.reset(new auto_mysql_stmt(db));
      const char *const q = "select v from hstest_table1 where k = ?";
      r = mysql_stmt_prepare(*stmt, q, strlen(q));
      if (r != 0) {
 fprintf(stderr, "ssps err\n");
 ++err_cnt;
 return;
      }
    }
    connected = 1;
    std::string result_str;
    unsigned int err = 0;
    unsigned int num_flds = 0, num_affected_rows = 0;
    int got_data = 0;
    char buf_query[16384];
    int buf_query_len = 0;
    int k = 0, v = 0;
    {
      double kf = 0, vf = 0;
      drand48_r(&randbuf, &kf);
      drand48_r(&randbuf, &vf);
      k = int(kf * tablesize);
      v = int(vf * tablesize);
      #if 0
      k = rand_r(&seed);
      v = rand_r(&seed);
      if (tablesize != 0) {
 k %= tablesize;
      }
      #endif
      if (op == 'G') {
 if (use_handler) {
   buf_query_len = snprintf(buf_query, sizeof(buf_query),
     "handler hstest_table1 read `primary` = ( '%d' )", k);
     // TODO: moreflds
 } else if (ssps) {
     //
 } else if (use_in) {
   wbuf.clear();
   char *p = wbuf.make_space(1024);
   int len = snprintf(p, 1024, "select %s from hstest_table1 where k in ('%d'", flds.c_str(), k);
   wbuf.space_wrote(len);
   for (int j = 1; j < use_in; ++j) {
     /* generate more key */
     drand48_r(&randbuf, &kf);
     k = int(kf * tablesize);
     p = wbuf.make_space(1024);
     int len = snprintf(p, 1024, ", '%d'", k);
     wbuf.space_wrote(len);
   }
   wbuf.append_literal(")");
 } else {
   buf_query_len = snprintf(buf_query, sizeof(buf_query),
     "select %s from hstest_table1 where k = '%d'", flds.c_str(), k);
 }
      } else if (op == 'U') {
 buf_query_len = snprintf(buf_query, sizeof(buf_query),
   "update hstest_table1 set v = '%d_%d%s' where k = '%d'",
     v, k, suffix.c_str(), k);
      } else if (op == 'R') {
 buf_query_len = snprintf(buf_query, sizeof(buf_query),
   "replace into hstest_table1 values ('%d', 'v%d')", k, v);
   // TODO: moreflds
      }
    }
    if (r == 0) {
      if (ssps) {
 MYSQL_BIND bind[1] = { };
 bind[0].buffer_type = MYSQL_TYPE_LONG;
 bind[0].buffer = (char *)&k;
 bind[0].is_null = 0;
 bind[0].length = 0;
 if (mysql_stmt_bind_param(*stmt, bind)) {
   fprintf(stderr, "err: %s\n", mysql_stmt_error(*stmt));
   ++err_cnt;
   return;
 }
 r = mysql_stmt_execute(*stmt);
 // fprintf(stderr, "stmt exec\n");
      } else if (use_in) {
 r = mysql_real_query(db, wbuf.begin(), wbuf.size());
      } else {
 r = mysql_real_query(db, buf_query, buf_query_len);
 // fprintf(stderr, "real query\n");
      }
      ++query_cnt;
    }
    if (r != 0) {
      err = 1;
    } else if (ssps) {
      if (verbose >= 0) {
 char resbuf[1024];
 unsigned long res_len = 0;
 MYSQL_BIND bind[1] = { };
 bind[0].buffer_type = MYSQL_TYPE_STRING;
 bind[0].buffer = resbuf;
 bind[0].buffer_length = sizeof(resbuf);
 bind[0].length = &res_len;
 if (mysql_stmt_bind_result(*stmt, bind)) {
   fprintf(stderr, "err: %s\n", mysql_stmt_error(*stmt));
   ++err_cnt;
   return;
 }
 if (mysql_stmt_fetch(*stmt)) {
   fprintf(stderr, "err: %s\n", mysql_stmt_error(*stmt));
   ++err_cnt;
   return;
 }
 if (!result_str.empty()) {
   result_str += " ";
 }
 result_str += std::string(resbuf, res_len);
 // fprintf(stderr, "SSPS RES: %s\n", result_str.c_str());
 got_data = 1;
      } else {
 got_data = 1;
      }
    } else {
      auto_mysql_res res(db);
      if (res != 0) {
 if (verbose >= 0) {
   num_flds = mysql_num_fields(res);
   MYSQL_ROW row = 0;
   while ((row = mysql_fetch_row(res)) != 0) {
     got_data += 1;
     unsigned long *const lengths = mysql_fetch_lengths(res);
     if (verbose >= 2) {
       for (unsigned int i = 0; i < num_flds; ++i) {
  if (!result_str.empty()) {
    result_str += " ";
  }
  result_str += std::string(row[i], lengths[i]);
       }
     }
   }
 } else {
   MYSQL_ROW row = 0;
   while ((row = mysql_fetch_row(res)) != 0) {
     got_data += 1;
   }
 }
      } else {
 if (mysql_field_count(db) == 0) {
   num_affected_rows = mysql_affected_rows(db);
 } else {
   err = 1;
 }
      }
    }
    if (verbose >= 2 || (verbose >= 1 && err != 0)) {
      if (err) {
 ++err_cnt;
 const char *const errstr = mysql_error(db);
 fprintf(stderr, "e=[%s] a=%u q=[%s]\n", errstr,
   num_affected_rows, buf_query);
      } else {
 fprintf(stderr, "a=%u q=[%s] r=[%s]\n", num_affected_rows, buf_query,
   result_str.c_str());
      }
    }
    if (err == 0) {
      ++io_success_count;
      if (num_affected_rows > 0 || got_data > 0) {
 op_success_count += got_data;
      } else {
 if (verbose >= 1) {
   fprintf(stderr, "k=%d numaff=%u gotdata=%d\n",
     k, num_affected_rows, got_data);
 }
      }
      arg.sh.increment_count();
    }
    if (!keep_connection) {
      if (stmt.get() != 0) {
 stmt.reset();
      }
      db.reset();
      connected = 0;
    }
    const double tm2 = gettimeofday_double();
    set_timing(tm2 - tm1);
    sleep_if();
    if (sched_flag) {
      sched_yield();
    }
  }
  if (verbose >= 1) {
    fprintf(stderr, "thread finished (error_count=%llu)\n", err_cnt);
  }
}

void
hstest_thread::test_10(int test_num)
{
  const int keep_connection = arg.sh.conf.get_int("keep_connection", 1);
  unsigned int seed = time(0) + arg.id + 1;
  seed ^= arg.sh.conf.get_int("seed_xor", 0);
  drand48_data randbuf;
  srand48_r(seed, &randbuf);
  std::string err;
  int keepconn_count = 0;
  const char op = arg.sh.op;
  const int verbose = arg.sh.conf.get_int("verbose", 1);
  const std::string suffix = arg.sh.conf.get_str("value_suffix", "upd");
  const int tablesize = arg.sh.conf.get_int("tablesize", 10000);
  const int firstkey = arg.sh.conf.get_int("firstkey", 0);
  const int sched_flag = arg.sh.conf.get_int("sched", 0);
  const int moreflds = arg.sh.conf.get_int("moreflds", 0);
  const std::string dbname = arg.sh.conf.get_str("dbname", "hstest");
  const std::string table = arg.sh.conf.get_str("table", "hstest_table1");
  const std::string index = arg.sh.conf.get_str("index", "PRIMARY");
  const std::string field = arg.sh.conf.get_str("field", "v");
  const int use_in = arg.sh.conf.get_int("in", 0);
  const std::string moreflds_prefix = arg.sh.conf.get_str(
    "moreflds_prefix", "column0123456789_");
  const int dump = arg.sh.dump;
  const int nodup = arg.sh.conf.get_int("nodup", 0);
  std::string moreflds_str;
  for (int i = 0; i < moreflds; ++i) {
    char sbuf[1024];
    snprintf(sbuf, sizeof(sbuf), ",%s%d", moreflds_prefix.c_str(), i);
    moreflds_str += std::string(sbuf);
  }
  string_buffer wbuf;
  char rbuf[16384];
  for (size_t i = 0; i < arg.sh.loop; ++i) {
    int len = 0, rlen = 0, wlen = 0;
    #if 0
    const double tm1 = gettimeofday_double();
    #endif
    if (fd.get() < 0) {
      if (socket_connect(fd, arg.sh.arg, err) != 0) {
 fprintf(stderr, "connect: %d %s\n", errno, strerror(errno));
 return;
      }
      char *wp = wbuf.make_space(1024);
      len = snprintf(wp, 1024,
 "P\t1\t%s\t%s\tPRIMARY\t%s%s\n", dbname.c_str(), table.c_str(),
   field.c_str(), moreflds_str.c_str());
 /* pst_num, db, table, index, retflds */
      wbuf.space_wrote(len);
      wlen = write(fd.get(), wbuf.begin(), len);
      if (len != wlen) {
 fprintf(stderr, "write: %d %d\n", len, wlen);
 return;
      }
      wbuf.clear();
      rlen = read(fd.get(), rbuf, sizeof(rbuf));
      if (rlen <= 0 || rbuf[rlen - 1] != '\n') {
 fprintf(stderr, "read: rlen=%d errno=%d\n", rlen, errno);
 return;
      }
      if (rbuf[0] != '0') {
 fprintf(stderr, "failed to open table\n");
 return;
      }
      arg.sh.increment_conn(1);
    }
    const double tm1 = gettimeofday_double();
    for (size_t j = 0; j < arg.sh.pipe; ++j) {
      int k = 0, v = 0;
      {
 while (true) {
   double kf = 0, vf = 0;
   drand48_r(&randbuf, &kf);
   drand48_r(&randbuf, &vf);
   k = int(kf * tablesize) + firstkey;
   v = int(vf * tablesize) + firstkey;
   if (k - firstkey < arg.sh.keygen_size) {
     volatile char *const ptr = arg.sh.keygen + (k - firstkey);
     // int oldv = __sync_fetch_and_or(ptr, 1);
     int oldv = *ptr;
     *ptr += 1;
     if (nodup && oldv != 0) {
       if (dump) {
  fprintf(stderr, "retry\n");
       }
       continue;
     }
   } else {
     if (nodup) {
       if (dump) {
  fprintf(stderr, "retry2\n");
       }
       continue;
     }
   }
   size_t len = 0;
   if (op == 'G') {
     if (use_in) {
       char *wp = wbuf.make_space(1024);
       len = snprintf(wp, 1024, "1\t=\t1\t\t%d\t0\t@\t0\t%d\t%d",
  use_in, use_in, k);
       wbuf.space_wrote(len);
       for (int j = 1; j < use_in; ++j) {
  drand48_r(&randbuf, &kf);
  k = int(kf * tablesize) + firstkey;
  char *wp = wbuf.make_space(1024);
  len = snprintf(wp, 1024, "\t%d", k);
  wbuf.space_wrote(len);
       }
       wbuf.append_literal("\n");
     } else {
       char *wp = wbuf.make_space(1024);
       len = snprintf(wp, 1024, "1\t=\t1\t%d\n", k);
       wbuf.space_wrote(len);
     }
   } else if (op == 'U') {
     char *wp = wbuf.make_space(1024);
     len = snprintf(wp, 1024,
       "1\t=\t1\t%d\t1\t0\tU\t%d_%d%s\n", k, v, k, suffix.c_str());
     wbuf.space_wrote(len);
   }
   break;
 }
      }
    }
    wlen = write(fd.get(), wbuf.begin(), wbuf.size());
    if ((size_t) wlen != wbuf.size()) {
      fprintf(stderr, "write: %d %d\n", (int)wbuf.size(), wlen);
      return;
    }
    wbuf.clear();
    size_t read_cnt = 0;
    size_t read_pos = 0;
    while (read_cnt < arg.sh.pipe) {
      rlen = read(fd.get(), rbuf + read_pos, sizeof(rbuf) - read_pos);
      if (rlen <= 0) {
 fprintf(stderr, "read: %d\n", rlen);
 return;
      }
      read_pos += rlen;
      while (true) {
 const char *const nl = static_cast<const char *>(memchr(rbuf, '\n',
   read_pos));
 if (nl == 0) {
   break;
 }
 ++read_cnt;
 ++io_success_count;
 const char *t1 = static_cast<const char *>(memchr(rbuf, '\t',
   nl - rbuf));
 if (t1 == 0) {
   fprintf(stderr, "error \n");
   break;
 }
 ++t1;
 const char *t2 = static_cast<const char *>(memchr(t1, '\t',
   nl - t1));
 if (t2 == 0) {
   if (verbose > 1) {
     fprintf(stderr, "key: notfound \n");
   }
   break;
 }
 ++t2;
 if (t1 == rbuf + 2 && rbuf[0] == '0') {
   if (op == 'G') {
     ++op_success_count;
     arg.sh.increment_count();
   } else if (op == 'U') {
     const char *t3 = t2;
     while (t3 != nl && t3[0] >= 0x10) {
       ++t3;
     }
     if (t3 != t2 + 1 || t2[0] != '1') {
       const std::string mess(t2, t3);
       fprintf(stderr, "mod: %s\n", mess.c_str());
     } else {
       ++op_success_count;
       arg.sh.increment_count();
       if (arg.sh.dump && arg.sh.pipe == 1) {
  fwrite(wbuf.begin(), wbuf.size(), 1, stderr);
       }
     }
   }
 } else {
   const char *t3 = t2;
   while (t3 != nl && t3[0] >= 0x10) {
     ++t3;
   }
   const std::string mess(t2, t3);
   fprintf(stderr, "err: %s\n", mess.c_str());
 }
 const size_t rest_size = rbuf + read_pos - (nl + 1);
 if (rest_size != 0) {
   memmove(rbuf, nl + 1, rest_size);
 }
 read_pos = rest_size;
      }
    }
    if (!keep_connection) {
      fd.reset();
      arg.sh.increment_conn(-1);
    } else if (keep_connection > 1 && ++keepconn_count > keep_connection) {
      keepconn_count = 0;
      fd.reset();
      arg.sh.increment_conn(-1);
    }
    const double tm2 = gettimeofday_double();
    set_timing(tm2 - tm1);
    sleep_if();
    if (sched_flag) {
      sched_yield();
    }
  }
  if (dump) {
    fprintf(stderr, "done\n");
  }
}

void
hstest_thread::sleep_if()
{
  if (arg.sh.usleep) {
    struct timespec ts = {
      arg.sh.usleep / 1000000,
      (arg.sh.usleep % 1000000) * 1000
    };
    nanosleep(&ts, 0);
  }
}

void
hstest_thread::set_timing(double time_spent)
{
  response_min = std::min(response_min, time_spent);
  response_max = std::max(response_max, time_spent);
  response_sum += time_spent;
  if (op_success_count != 0) {
    response_avg = response_sum / op_success_count;
  }
}

void
hstest_thread::test_11(int test_num)
{
  const int keep_connection = arg.sh.conf.get_int("keep_connection", 1);
  const int tablesize = arg.sh.conf.get_int("tablesize", 0);
  unsigned int seed = arg.id;
  seed ^= arg.sh.conf.get_int("seed_xor", 0);
  std::string err;
  hstcpcli_ptr cli;
  for (size_t i = 0; i < arg.sh.loop; ++i) {
    if (cli.get() == 0) {
      cli = hstcpcli_i::create(arg.sh.arg);
      cli->request_buf_open_index(0, "hstest", "hstest_table1", "", "v");
 /* pst_num, db, table, index, retflds */
      if (cli->request_send() != 0) {
 fprintf(stderr, "reuqest_send: %s\n", cli->get_error().c_str());
 return;
      }
      size_t num_flds = 0;
      if (cli->response_recv(num_flds) != 0) {
 fprintf(stderr, "reuqest_recv: %s\n", cli->get_error().c_str());
 return;
      }
      cli->response_buf_remove();
    }
    for (size_t j = 0; j < arg.sh.pipe; ++j) {
      char buf[256];
      int k = 0, v = 0, len = 0;
      {
 k = rand_r(&seed);
 v = rand_r(&seed); /* unused */
 if (tablesize != 0) {
   k &= tablesize;
 }
 len = snprintf(buf, sizeof(buf), "%d", k);
      }
      const string_ref key(buf, len);
      const string_ref op("=", 1);
      cli->request_buf_exec_generic(0, op, &key, 1, 1, 0, string_ref(), 0, 0);
    }
    if (cli->request_send() != 0) {
      fprintf(stderr, "reuqest_send: %s\n", cli->get_error().c_str());
      return;
    }
    size_t read_cnt = 0;
    for (size_t j = 0; j < arg.sh.pipe; ++j) {
      size_t num_flds = 0;
      if (cli->response_recv(num_flds) != 0) {
 fprintf(stderr, "reuqest_recv: %s\n", cli->get_error().c_str());
 return;
      }
      {
 ++read_cnt;
 ++io_success_count;
 arg.sh.increment_count();
 {
   ++op_success_count;
 }
      }
      cli->response_buf_remove();
    }
    if (!keep_connection) {
      cli.reset();
    }
  }
}

void
hstest_thread::test_watch()
{
  const int timelimit = arg.sh.conf.get_int("timelimit", 0);
  const int timelimit_offset = timelimit / 2;
  int loop = 0;
  double t1 = 0, t2 = 0;
  size_t cnt_t1 = 0, cnt_t2 = 0;
  size_t prev_cnt = 0;
  double now_f = 0;
  while (true) {
    sleep(1);
    const size_t cnt = arg.sh.count;
    const size_t df = cnt - prev_cnt;
    prev_cnt = cnt;
    const double now_prev = now_f;
    now_f = gettimeofday_double();
    if (now_prev != 0) {
      const double rps = static_cast<double>(df) / (now_f - now_prev);
      fprintf(stderr, "now: %zu cntdiff: %zu tdiff: %f rps: %f\n",
        static_cast<size_t>(now_f), df, now_f - now_prev, rps);
    }
    if (timelimit != 0) {
      if (arg.sh.wait_conn == 0 || arg.sh.conn_count >= arg.sh.wait_conn) {
 ++loop;
      }
      if (loop == timelimit_offset) {
        t1 = gettimeofday_double();
        cnt_t1 = cnt;
 arg.sh.enable_timing = 1;
 fprintf(stderr, "start timing\n");
      } else if (loop == timelimit_offset + timelimit) {
        t2 = gettimeofday_double();
        cnt_t2 = cnt;
        const size_t cnt_diff = cnt_t2 - cnt_t1;
        const double tdiff = t2 - t1;
        const double qps = cnt_diff / (tdiff != 0 ? tdiff : 1);
        fprintf(stderr, "(%f: %zu, %f: %zu), %10.5f qps\n",
          t1, cnt_t1, t2, cnt_t2, qps);
 size_t keycnt = 0;
 for (int i = 0; i < arg.sh.keygen_size; ++i) {
   if (arg.sh.keygen[i]) {
     ++keycnt;
   }
 }
 fprintf(stderr, "keygen=%zu\n", keycnt);
 break;
      }
    }
  }
#if 0
  int loop = 0;
  double t1 = 0, t2 = 0;
  size_t cnt_t1 = 0, cnt_t2 = 0;
  size_t prev_cnt = 0;
  while (true) {
    sleep(1);
    const size_t cnt = arg.sh.count;
    const size_t df = cnt - prev_cnt;
    prev_cnt = cnt;
    const size_t now = time(0);
    fprintf(stderr, "%zu %zu\n", now, df);
    if (timelimit != 0) {
      ++loop;
      if (loop == timelimit_offset) {
 t1 = gettimeofday_double();
 cnt_t1 = cnt;
      } else if (loop == timelimit_offset + timelimit) {
 t2 = gettimeofday_double();
 cnt_t2 = cnt;
 const size_t cnt_diff = cnt_t2 - cnt_t1;
 const double tdiff = t2 - t1;
 const double qps = cnt_diff / (tdiff != 0 ? tdiff : 1);
 fprintf(stderr, "(%f: %zu, %f: %zu), %10.5f qps\n",
   t1, cnt_t1, t2, cnt_t2, qps);
 size_t keycnt = 0;
 for (int i = 0; i < arg.sh.keygen_size; ++i) {
   if (arg.sh.keygen[i]) {
     ++keycnt;
   }
 }
 fprintf(stderr, "keygen=%zu\n", keycnt);
 _exit(0);
      }
    }
  }
#endif
}

void
hstest_thread::test_12(int test_num)
{
  /* NOTE: num_threads should be 1 */
  /* create table hstest
   * ( k varchar(255) not null, v varchar(255) not null, primary key(k))
   * engine = innodb; */

  mysqltest_thread_initobj initobj;
  auto_mysql db;
  std::string err;
  unsigned long long err_cnt = 0;
  unsigned long long query_cnt = 0;
  #if 0
  my_bool reconnect = 0;
  if (mysql_options(db, MYSQL_OPT_RECONNECT, &reconnect) != 0) {
    err = "mysql_options() failed";
    ++err_cnt;
    return;
  }
  #endif
  const std::string mysql_host = arg.sh.conf.get_str("host", "localhost");
  const int mysql_port = arg.sh.conf.get_int("mysqlport", 3306);
  const unsigned int num = arg.sh.loop;
  const size_t pipe = arg.sh.pipe;
  const std::string mysql_user = arg.sh.conf.get_str("mysqluser", "root");
  const std::string mysql_passwd = arg.sh.conf.get_str("mysqlpass", "");
  const std::string mysql_dbname = arg.sh.conf.get_str("db", "hstest");
  const int keep_connection = arg.sh.conf.get_int("keep_connection", 1);
  const int verbose = arg.sh.conf.get_int("verbose", 1);
  const int use_handler = arg.sh.conf.get_int("handler", 0);
  int connected = 0;
  unsigned int k = 0;
  string_buffer buf;
  for (unsigned int i = 0; i < num; ++i) {
    const int flags = 0;
    if (connected == 0 && !mysql_real_connect(db, mysql_host.c_str(),
      mysql_user.c_str(), mysql_user.empty() ? 0 : mysql_passwd.c_str(),
      mysql_dbname.c_str(), mysql_port, 0, flags)) {
      err = "failed to connect: " + std::string(mysql_error(db));
      if (verbose >= 1) {
 fprintf(stderr, "e=[%s]\n", err.c_str());
      }
      ++err_cnt;
      return;
    }
    int r = 0;
    if (connected == 0 && use_handler) {
      const char *const q = "handler hstest open";
      r = mysql_real_query(db, q, strlen(q));
      if (r != 0) {
 err = 1;
      }
    }
    connected = 1;
    std::string result_str;
    unsigned int err = 0;
    unsigned int num_flds = 0, num_affected_rows = 0;
    int got_data = 0;
    buf.clear();
    buf.append_literal("insert into hstest values ");
    for (size_t j = 0; j < pipe; ++j) {
      const unsigned int v = ~k;
      if (j != 0) {
 buf.append_literal(",");
      }
      char *wp = buf.make_space(64);
      int buf_query_len = snprintf(wp, 64, "('k%u', 'v%u')", k, v);
      buf.space_wrote(buf_query_len);
      ++k;
    }
    if (r == 0) {
      r = mysql_real_query(db, buf.begin(), buf.size());
      ++query_cnt;
    }
    if (r != 0) {
      err = 1;
    } else {
      auto_mysql_res res(db);
      if (res != 0) {
 if (verbose >= 0) {
   num_flds = mysql_num_fields(res);
   MYSQL_ROW row = 0;
   while ((row = mysql_fetch_row(res)) != 0) {
     got_data = 1;
     unsigned long *const lengths = mysql_fetch_lengths(res);
     if (verbose >= 2) {
       for (unsigned int i = 0; i < num_flds; ++i) {
  if (!result_str.empty()) {
    result_str += " ";
  }
  result_str += std::string(row[i], lengths[i]);
       }
     }
   }
 }
      } else {
 if (mysql_field_count(db) == 0) {
   num_affected_rows = mysql_affected_rows(db);
 } else {
   err = 1;
 }
      }
    }
    if (verbose >= 2 || (verbose >= 1 && err != 0)) {
      if (err) {
 ++err_cnt;
 const char *const errstr = mysql_error(db);
 fprintf(stderr, "e=[%s] a=%u q=[%s]\n", errstr,
   num_affected_rows, std::string(buf.begin(), buf.size()).c_str());
      } else {
 fprintf(stderr, "a=%u q=[%s] r=[%s]\n", num_affected_rows,
   std::string(buf.begin(), buf.size()).c_str(),
   result_str.c_str());
      }
    }
    if (err == 0) {
      ++io_success_count;
      if (num_affected_rows > 0 || got_data > 0) {
 ++op_success_count;
      }
      arg.sh.increment_count(pipe);
    }
    if (!keep_connection) {
      db.reset();
      connected = 0;
    }
  }
  if (verbose >= 1) {
    fprintf(stderr, "thread finished (error_count=%llu)\n", err_cnt);
  }
}

void
hstest_thread::test_21(int num)
{
  /* fsync test */
  unsigned int id = arg.id;
  std::string err;
  #if 0
  if (socket_connect(fd, arg.sh.arg, err) != 0) {
    fprintf(stderr, "connect: %d %s\n", errno, strerror(errno));
    return;
  }
  #endif
  auto_file logfd;
  char fname[1024];
  snprintf(fname, sizeof(fname), "synctest_%u", id);
  int open_flags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND;
  logfd.reset(open(fname, open_flags, 0644));
  if (logfd.get() < 0) {
    fprintf(stderr, "open: %s: %d %s\n", fname, errno, strerror(errno));
    return;
  }
  char buf[1024];
  unsigned long long count = 0;
  while (true) {
    snprintf(buf, sizeof(buf), "%u %llu\n", id, count);
    const size_t len = strlen(buf);
    if (write(logfd.get(), buf, len) != (ssize_t)len) {
      fprintf(stderr, "write: %s: %d %s\n", fname, errno, strerror(errno));
      return;
    }
    #if 0
    if (write(fd.get(), buf, len) != (ssize_t)len) {
      fprintf(stderr, "write(sock): %d %s\n", errno, strerror(errno));
      return;
    }
    #endif
    if (fdatasync(logfd.get()) != 0) {
      fprintf(stderr, "fsync: %s: %d %s\n", fname, errno, strerror(errno));
      return;
    }
    ++count;
    ++op_success_count;
    arg.sh.increment_count();
  }
}

void
hstest_thread::test_22(int num)
{
  /* dd if=/dev/zero of=dummy.dat bs=1024M count=100 */
  unsigned int id = arg.id;
  std::string err;
  auto_file filefd;
  char fname[1024];
  snprintf(fname, sizeof(fname), "dummy.dat");
  int open_flags = O_RDONLY | O_DIRECT;
  filefd.reset(open(fname, open_flags, 0644));
  if (filefd.get() < 0) {
    fprintf(stderr, "open: %s: %d %s\n", fname, errno, strerror(errno));
    return;
  }
  char buf_x[4096 * 2];
  char *const buf = (char *)(size_t(buf_x + 4096) / 4096 * 4096);
  unsigned long long count = 0;
  drand48_data randbuf;
  unsigned long long seed = time(0);
  seed *= 10;
  seed += id;
  srand48_r(seed, &randbuf);
  for (unsigned int i = 0; i < arg.sh.loop; ++i) {
    double kf = 0;
    drand48_r(&randbuf, &kf);
    kf *= (209715200 / 1);
    // fprintf(stderr, "v=%f\n", kf);
    off_t v = static_cast<off_t>(kf);
    v %= (209715200 / 1);
    v *= (512 * 1);
    const double tm1 = gettimeofday_double();
    const ssize_t r = pread(filefd.get(), buf, (512 * 1), v);
    const double tm2 = gettimeofday_double();
    if (r < 0) {
      fprintf(stderr, "pread: %s: %d %s\n", fname, errno, strerror(errno));
      return;
    }
    ++count;
    ++op_success_count;
    arg.sh.increment_count();
    set_timing(tm2 - tm1);
  }
}

void
hstest_thread::operator ()()
{
  if (arg.watch_flag) {
    return test_watch();
  }
  int test_num = arg.sh.conf.get_int("test", 1);
  if (test_num == 1) {
    test_1();
  } else if (test_num == 2 || test_num == 3) {
    test_2_3(test_num);
  } else if (test_num == 4 || test_num == 5) {
    test_4_5(test_num);
  } else if (test_num == 6) {
    test_6(test_num);
  } else if (test_num == 7) {
    test_7(test_num);
  } else if (test_num == 8) {
    test_8(test_num);
  } else if (test_num == 9) {
    test_9(test_num);
  } else if (test_num == 10) {
    test_10(test_num);
  } else if (test_num == 11) {
    test_11(test_num);
  } else if (test_num == 12) {
    test_12(test_num);
  } else if (test_num == 21) {
    test_21(test_num);
  } else if (test_num == 22) {
    test_22(test_num);
  }
  const int halt = arg.sh.conf.get_int("halt", 0);
  if (halt) {
    fprintf(stderr, "thread halted\n");
    while (true) {
      sleep(100000);
    }
  }
  fprintf(stderr, "thread finished\n");
}

int
hstest_main(int argc, char **argv)
{
  ignore_sigpipe();
  hstest_shared shared;
  parse_args(argc, argv, shared.conf);
  shared.conf["port"] = shared.conf["hsport"];
  shared.arg.set(shared.conf);
  shared.loop = shared.conf.get_int("num", 1000);
  shared.pipe = shared.conf.get_int("pipe", 1);
  shared.verbose = shared.conf.get_int("verbose", 1);
  const int tablesize = shared.conf.get_int("tablesize", 0);
  std::vector<char> keygen(tablesize);
  shared.keygen = &keygen[0];
  shared.keygen_size = tablesize;
  shared.usleep = shared.conf.get_int("usleep", 0);
  shared.dump = shared.conf.get_int("dump", 0);
  shared.num_threads = shared.conf.get_int("num_threads", 10);
  shared.wait_conn = shared.conf.get_int("wait_conn", 0);
  const std::string op = shared.conf.get_str("op", "G");
  if (op.size() > 0) {
    shared.op = op[0];
  }
  #if 0
  const int localdb_flag = shared.conf.get_int("local", 0);
  if (localdb_flag) {
    shared.localdb = database_i::create(shared.conf);
  }
  #endif
  const int num_thrs = shared.num_threads;
  typedef thread<hstest_thread> thread_type;
  typedef std::unique_ptr<thread_type> thread_ptr;
  typedef auto_ptrcontainer< std::vector<thread_type *> > thrs_type;
  thrs_type thrs;
  for (int i = 0; i < num_thrs; ++i) {
    const hstest_thread::arg_type arg(i, shared, false);
    thread_ptr thr(new thread<hstest_thread>(arg));
    thrs.push_back_ptr(thr);
  }
  for (size_t i = 0; i < thrs.size(); ++i) {
    thrs[i]->start();
  }
  thread_ptr watch_thread;
  const int timelimit = shared.conf.get_int("timelimit", 0);
  {
    const hstest_thread::arg_type arg(0, shared, true);
    watch_thread = thread_ptr(new thread<hstest_thread>(arg));
    watch_thread->start();
  }
  size_t iocnt = 0, opcnt = 0;
  double respmin = 999999, respmax = 0;
  double respsum = 0;
  if (timelimit != 0) {
    watch_thread->join();
  }
  for (size_t i = 0; i < thrs.size(); ++i) {
    if (timelimit == 0) {
      thrs[i]->join();
    }
    iocnt += (*thrs[i])->io_success_count;
    opcnt += (*thrs[i])->op_success_count;
    respmin = std::min(respmin, (*thrs[i])->response_min);
    respmax = std::max(respmax, (*thrs[i])->response_max);
    respsum += (*thrs[i])->response_sum;
  }
  fprintf(stderr, "io_success_count=%zu op_success_count=%zu\n", iocnt, opcnt);
  fprintf(stderr, "respmin=%f respmax=%f respsum=%f respavg=%f\n",
    respmin, respmax, respsum, respsum / opcnt);
  size_t keycnt = 0;
  for (size_t i = 0; i < keygen.size(); ++i) {
    if (keygen[i]) {
      ++keycnt;
    }
  }
  fprintf(stderr, "keycnt=%zu\n", keycnt);
  _exit(0);
  return 0;
}

};

int
main(int argc, char **argv)
{
  return dena::hstest_main(argc, argv);
}


Messung V0.5 in Prozent
C=98 H=89 G=93

¤ Dauer der Verarbeitung: 0.34 Sekunden  (vorverarbeitet am  2026-10-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1126438
#Domains=1867298