⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testoibasic.cpp

📁 mysql-5.0.22.tar.gz源码包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* Copyright (C) 2003 MySQL AB   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* * testOIBasic - ordered index test */#include <ndb_global.h>#include <NdbMain.h>#include <NdbOut.hpp>#include <NdbApi.hpp>#include <NdbTest.hpp>#include <NdbMutex.h>#include <NdbCondition.h>#include <NdbThread.h>#include <NdbTick.h>#include <NdbSleep.h>#include <my_sys.h>#include <NdbSqlUtil.hpp>#include <ndb_version.h>// optionsstruct Opt {  // common options  unsigned m_batch;  const char* m_bound;  const char* m_case;  bool m_collsp;  bool m_core;  const char* m_csname;  CHARSET_INFO* m_cs;  int m_die;  bool m_dups;  NdbDictionary::Object::FragmentType m_fragtype;  unsigned m_subsubloop;  const char* m_index;  unsigned m_loop;  bool m_msglock;  bool m_nologging;  bool m_noverify;  unsigned m_pctnull;  unsigned m_rows;  unsigned m_samples;  unsigned m_scanpar;  unsigned m_scanstop;  int m_seed;  unsigned m_subloop;  const char* m_table;  unsigned m_threads;  int m_v;      // int for lint  Opt() :    m_batch(32),    m_bound("01234"),    m_case(0),    m_collsp(false),    m_core(false),    m_csname("random"),    m_cs(0),    m_die(0),    m_dups(false),    m_fragtype(NdbDictionary::Object::FragUndefined),    m_subsubloop(4),    m_index(0),    m_loop(1),    m_msglock(true),    m_nologging(false),    m_noverify(false),    m_pctnull(10),    m_rows(1000),    m_samples(0),    m_scanpar(0),    m_scanstop(0),    m_seed(-1),    m_subloop(4),    m_table(0),    m_threads(4),    m_v(1) {  }};static Opt g_opt;static void printcases();static void printtables();static voidprinthelp(){  Opt d;  ndbout    << "usage: testOIbasic [options]" << endl    << "  -batch N      pk operations in batch [" << d.m_batch << "]" << endl    << "  -bound xyz    use only these bound types 0-4 [" << d.m_bound << "]" << endl    << "  -case abc     only given test cases (letters a-z)" << endl    << "  -collsp       use strnncollsp instead of strnxfrm" << endl    << "  -core         core dump on error [" << d.m_core << "]" << endl    << "  -csname S     charset or collation [" << d.m_csname << "]" << endl    << "  -die nnn      exit immediately on NDB error code nnn" << endl    << "  -dups         allow duplicate tuples from index scan [" << d.m_dups << "]" << endl    << "  -fragtype T   fragment type single/small/medium/large" << endl    << "  -index xyz    only given index numbers (digits 0-9)" << endl    << "  -loop N       loop count full suite 0=forever [" << d.m_loop << "]" << endl    << "  -nologging    create tables in no-logging mode" << endl    << "  -noverify     skip index verifications" << endl    << "  -pctnull N    pct NULL values in nullable column [" << d.m_pctnull << "]" << endl    << "  -rows N       rows per thread [" << d.m_rows << "]" << endl    << "  -samples N    samples for some timings (0=all) [" << d.m_samples << "]" << endl    << "  -scanpar N    scan parallelism [" << d.m_scanpar << "]" << endl    << "  -seed N       srandom seed 0=loop number -1=random [" << d.m_seed << "]" << endl    << "  -subloop N    subtest loop count [" << d.m_subloop << "]" << endl    << "  -table xyz    only given table numbers (digits 0-9)" << endl    << "  -threads N    number of threads [" << d.m_threads << "]" << endl    << "  -vN           verbosity [" << d.m_v << "]" << endl    << "  -h or -help   print this help text" << endl    ;  printcases();  printtables();}// not yet configurablestatic const bool g_store_null_key = true;// compare NULL like normal value (NULL < not NULL, NULL == NULL)static const bool g_compare_null = true;static const char* hexstr = "0123456789abcdef";// random intsstatic unsignedurandom(unsigned n){  if (n == 0)    return 0;  unsigned i = random() % n;  return i;}static intirandom(unsigned n){  if (n == 0)    return 0;  int i = random() % n;  if (random() & 0x1)    i = -i;  return i;}static boolrandompct(unsigned pct){  if (pct == 0)    return false;  if (pct >= 100)    return true;  return urandom(100) < pct;}static unsignedrandom_coprime(unsigned n){    unsigned prime[] = { 101, 211, 307, 401, 503, 601, 701, 809, 907 };    unsigned count = sizeof(prime) / sizeof(prime[0]);    if (n == 0)      return 0;    while (1) {      unsigned i = urandom(count);      if (n % prime[i] != 0)        return prime[i];    }}// random re-sequence of 0...(n-1)struct Rsq {  Rsq(unsigned n);  unsigned next();private:  unsigned m_n;  unsigned m_i;  unsigned m_start;  unsigned m_prime;};Rsq::Rsq(unsigned n){  m_n = n;  m_i = 0;  m_start = urandom(n);  m_prime = random_coprime(n);}unsignedRsq::next(){  assert(m_n != 0);  return (m_start + m_i++ * m_prime) % m_n;}// log and error macrosstatic NdbMutex *ndbout_mutex = NULL;static unsigned getthrno();static const char*getthrstr(){  static char buf[20];  unsigned n = getthrno();  if (n == (unsigned)-1)    strcpy(buf, "");  else {    unsigned m =      g_opt.m_threads < 10 ? 1 :      g_opt.m_threads < 100 ? 2 : 3;    sprintf(buf, "[%0*u] ", m, n);  }  return buf;}#define LLN(n, s) \  do { \    if ((n) > g_opt.m_v) break; \    if (g_opt.m_msglock) NdbMutex_Lock(ndbout_mutex); \    ndbout << getthrstr() << s << endl; \    if (g_opt.m_msglock) NdbMutex_Unlock(ndbout_mutex); \  } while(0)#define LL0(s) LLN(0, s)#define LL1(s) LLN(1, s)#define LL2(s) LLN(2, s)#define LL3(s) LLN(3, s)#define LL4(s) LLN(4, s)#define LL5(s) LLN(5, s)// following check a condition and return -1 on failure#undef CHK      // simple check#undef CHKTRY   // check with action on fail#undef CHKCON   // print NDB API errors on failure#define CHK(x)  CHKTRY(x, ;)#define CHKTRY(x, act) \  do { \    if (x) break; \    LL0("line " << __LINE__ << ": " << #x << " failed"); \    if (g_opt.m_core) abort(); \    act; \    return -1; \  } while (0)#define CHKCON(x, con) \  do { \    if (x) break; \    LL0("line " << __LINE__ << ": " << #x << " failed"); \    (con).printerror(ndbout); \    if (g_opt.m_core) abort(); \    return -1; \  } while (0)// method parametersclass Thr;class Con;class Tab;class Set;class Tmr;struct Par : public Opt {  unsigned m_no;  Con* m_con;  Con& con() const { assert(m_con != 0); return *m_con; }  const Tab* m_tab;  const Tab& tab() const { assert(m_tab != 0); return *m_tab; }  Set* m_set;  Set& set() const { assert(m_set != 0); return *m_set; }  Tmr* m_tmr;  Tmr& tmr() const { assert(m_tmr != 0); return *m_tmr; }  unsigned m_lno;  unsigned m_slno;  unsigned m_totrows;  // value calculation  unsigned m_range;  unsigned m_pctrange;  unsigned m_pctbrange;  int m_bdir;  // choice of key  bool m_randomkey;  // do verify after read  bool m_verify;  // deadlock possible  bool m_deadlock;  // abort percentabge  unsigned m_abortpct;  NdbOperation::LockMode m_lockmode;  // scan options  bool m_tupscan;  bool m_ordered;  bool m_descending;  // timer location  Par(const Opt& opt) :    Opt(opt),    m_no(0),    m_con(0),    m_tab(0),    m_set(0),    m_tmr(0),    m_lno(0),    m_slno(0),    m_totrows(m_threads * m_rows),    m_range(m_rows),    m_pctrange(40),    m_pctbrange(80),    m_bdir(0),    m_randomkey(false),    m_verify(false),    m_deadlock(false),    m_abortpct(0),    m_lockmode(NdbOperation::LM_Read),    m_tupscan(false),    m_ordered(false),    m_descending(false) {  }};static boolusetable(Par par, unsigned i){  return par.m_table == 0 || strchr(par.m_table, '0' + i) != 0;}static booluseindex(Par par, unsigned i){  return par.m_index == 0 || strchr(par.m_index, '0' + i) != 0;}static unsignedthrrow(Par par, unsigned j){  return par.m_threads * j + par.m_no;}static boolisthrrow(Par par, unsigned i){  return i % par.m_threads == par.m_no;}// timerstruct Tmr {  void clr();  void on();  void off(unsigned cnt = 0);  const char* time();  const char* pct(const Tmr& t1);  const char* over(const Tmr& t1);  NDB_TICKS m_on;  unsigned m_ms;  unsigned m_cnt;  char m_time[100];  char m_text[100];  Tmr() { clr(); }};voidTmr::clr(){  m_on = m_ms = m_cnt = m_time[0] = m_text[0] = 0;}voidTmr::on(){  assert(m_on == 0);  m_on = NdbTick_CurrentMillisecond();}voidTmr::off(unsigned cnt){  NDB_TICKS off = NdbTick_CurrentMillisecond();  assert(m_on != 0 && off >= m_on);  m_ms += off - m_on;  m_cnt += cnt;  m_on = 0;}const char*Tmr::time(){  if (m_cnt == 0) {    sprintf(m_time, "%u ms", m_ms);  } else {    sprintf(m_time, "%u ms per %u ( %u ms per 1000 )", m_ms, m_cnt, (1000 * m_ms) / m_cnt);  }  return m_time;}const char*Tmr::pct(const Tmr& t1){  if (0 < t1.m_ms) {    sprintf(m_text, "%u pct", (100 * m_ms) / t1.m_ms);  } else {    sprintf(m_text, "[cannot measure]");  }  return m_text;}const char*Tmr::over(const Tmr& t1){  if (0 < t1.m_ms) {    if (t1.m_ms <= m_ms)      sprintf(m_text, "%u pct", (100 * (m_ms - t1.m_ms)) / t1.m_ms);    else      sprintf(m_text, "-%u pct", (100 * (t1.m_ms - m_ms)) / t1.m_ms);  } else {    sprintf(m_text, "[cannot measure]");  }  return m_text;}// list of intsstruct Lst {  Lst();  unsigned m_arr[1000];  unsigned m_cnt;  void push(unsigned i);  unsigned cnt() const;  void reset();};Lst::Lst() :  m_cnt(0){}voidLst::push(unsigned i){  assert(m_cnt < sizeof(m_arr)/sizeof(m_arr[0]));  m_arr[m_cnt++] = i;}unsignedLst::cnt() const{  return m_cnt;}voidLst::reset(){  m_cnt = 0;}// character setsstatic const unsigned maxcsnumber = 512;static const unsigned maxcharcount = 32;static const unsigned maxcharsize = 4;static const unsigned maxxmulsize = 8;// single mb charstruct Chr {  unsigned char m_bytes[maxcharsize];  unsigned char m_xbytes[maxxmulsize * maxcharsize];  unsigned m_size;  Chr();};Chr::Chr(){  memset(m_bytes, 0, sizeof(m_bytes));  memset(m_xbytes, 0, sizeof(m_xbytes));  m_size = 0;}// charset and random valid chars to usestruct Chs {  CHARSET_INFO* m_cs;  unsigned m_xmul;  Chr* m_chr;  Chs(CHARSET_INFO* cs);  ~Chs();};static NdbOut&operator<<(NdbOut& out, const Chs& chs);Chs::Chs(CHARSET_INFO* cs) :  m_cs(cs){  m_xmul = m_cs->strxfrm_multiply;  if (m_xmul == 0)    m_xmul = 1;  assert(m_xmul <= maxxmulsize);  m_chr = new Chr [maxcharcount];  unsigned i = 0;  unsigned miss1 = 0;  unsigned miss2 = 0;  unsigned miss3 = 0;  unsigned miss4 = 0;  while (i < maxcharcount) {    unsigned char* bytes = m_chr[i].m_bytes;    unsigned char* xbytes = m_chr[i].m_xbytes;    unsigned& size = m_chr[i].m_size;    bool ok;    size = m_cs->mbminlen + urandom(m_cs->mbmaxlen - m_cs->mbminlen + 1);    assert(m_cs->mbminlen <= size && size <= m_cs->mbmaxlen);    // prefer longer chars    if (size == m_cs->mbminlen && m_cs->mbminlen < m_cs->mbmaxlen && urandom(5) != 0)      continue;    for (unsigned j = 0; j < size; j++) {      bytes[j] = urandom(256);    }    int not_used;    // check wellformed    const char* sbytes = (const char*)bytes;    if ((*cs->cset->well_formed_len)(cs, sbytes, sbytes + size, 1, &not_used) != size) {      miss1++;      continue;    }    // check no proper prefix wellformed    ok = true;    for (unsigned j = 1; j < size; j++) {      if ((*cs->cset->well_formed_len)(cs, sbytes, sbytes + j, 1, &not_used) == j) {        ok = false;        break;      }    }    if (! ok) {      miss2++;      continue;    }    // normalize    memset(xbytes, 0, sizeof(xbytes));    // currently returns buffer size always    int xlen = (*cs->coll->strnxfrm)(cs, xbytes, m_xmul * size, bytes, size);    // check we got something    ok = false;    for (unsigned j = 0; j < xlen; j++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -