📄 testblobs.cpp
字号:
/* 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 *//* * testBlobs */#include <ndb_global.h>#include <NdbMain.h>#include <NdbOut.hpp>#include <NdbTest.hpp>#include <NdbTick.h>struct Bcol { bool m_nullable; unsigned m_inline; unsigned m_partsize; unsigned m_stripe; char m_btname[200]; Bcol(bool a, unsigned b, unsigned c, unsigned d) : m_nullable(a), m_inline(b), m_partsize(c), m_stripe(d) {}};struct Opt { unsigned m_batch; bool m_core; bool m_dbg; bool m_dbgall; const char* m_dbug; bool m_full; unsigned m_loop; unsigned m_parts; unsigned m_rows; unsigned m_seed; const char* m_skip; const char* m_test; // metadata const char* m_tname; const char* m_x1name; // hash index const char* m_x2name; // ordered index unsigned m_pk1off; unsigned m_pk2len; bool m_oneblob; Bcol m_blob1; Bcol m_blob2; // perf const char* m_tnameperf; unsigned m_rowsperf; // bugs int m_bug; int (*m_bugtest)(); Opt() : m_batch(7), m_core(false), m_dbg(false), m_dbgall(false), m_dbug(0), m_full(false), m_loop(1), m_parts(10), m_rows(100), m_seed(0), m_skip(0), m_test(0), // metadata m_tname("TBLOB1"), m_x1name("TBLOB1X1"), m_x2name("TBLOB1X2"), m_pk1off(0x12340000), m_pk2len(55), m_oneblob(false), m_blob1(false, 7, 1137, 10), m_blob2(true, 99, 55, 1), // perf m_tnameperf("TBLOB2"), m_rowsperf(10000), // bugs m_bug(0), m_bugtest(0) { }};static const unsigned g_max_pk2len = 256;static voidprintusage(){ Opt d; ndbout << "usage: testBlobs options [default/max]" << endl << " -batch N number of pk ops in batch [" << d.m_batch << "]" << endl << " -core dump core on error" << endl << " -dbg print debug" << endl << " -dbgall print also NDB API debug (if compiled in)" << endl << " -dbug opt dbug options" << endl << " -full read/write only full blob values" << endl << " -loop N loop N times 0=forever [" << d.m_loop << "]" << endl << " -parts N max parts in blob value [" << d.m_parts << "]" << endl << " -rows N number of rows [" << d.m_rows << "]" << endl << " -rowsperf N rows for performace test [" << d.m_rowsperf << "]" << endl << " -seed N random seed 0=loop number [" << d.m_seed << "]" << endl << " -skip xxx skip given tests (see list) [no tests]" << endl << " -test xxx only given tests (see list) [all tests]" << endl << "metadata" << endl << " -pk2len N length of PK2 [" << d.m_pk2len << "/" << g_max_pk2len <<"]" << endl << " -oneblob only 1 blob attribute [default 2]" << endl << "testcases for test/skip" << endl << " k primary key ops" << endl << " i hash index ops" << endl << " s table scans" << endl << " r ordered index scans" << endl << " p performance test" << endl << "additional flags for test/skip" << endl << " u update existing blob value" << endl << " n normal insert and update" << endl << " w insert and update using writeTuple" << endl << " 0 getValue / setValue" << endl << " 1 setActiveHook" << endl << " 2 readData / writeData" << endl << "bug tests (no blob test)" << endl << " -bug 4088 ndb api hang with mixed ops on index table" << endl << " -bug nnnn delete + write gives 626" << endl << " -bug nnnn acc crash on delete and long key" << endl ;}static Opt g_opt;static booltestcase(char x){ if (x < 10) x += '0'; return (g_opt.m_test == 0 || strchr(g_opt.m_test, x) != 0) && (g_opt.m_skip == 0 || strchr(g_opt.m_skip, x) == 0);}static Ndb_cluster_connection* g_ncc = 0;static Ndb* g_ndb = 0;static NdbDictionary::Dictionary* g_dic = 0;static NdbConnection* g_con = 0;static NdbOperation* g_opr = 0;static NdbIndexOperation* g_opx = 0;static NdbScanOperation* g_ops = 0;static NdbBlob* g_bh1 = 0;static NdbBlob* g_bh2 = 0;static bool g_printerror = true;static unsigned g_loop = 0;static voidprinterror(int line, const char* msg){ ndbout << "line " << line << " FAIL " << msg << endl; if (! g_printerror) { return; } if (g_ndb != 0 && g_ndb->getNdbError().code != 0) { ndbout << "ndb: " << g_ndb->getNdbError() << endl; } if (g_dic != 0 && g_dic->getNdbError().code != 0) { ndbout << "dic: " << g_dic->getNdbError() << endl; } if (g_con != 0 && g_con->getNdbError().code != 0) { ndbout << "con: " << g_con->getNdbError() << endl; if (g_opr != 0 && g_opr->getNdbError().code != 0) { ndbout << "opr: table=" << g_opr->getTableName() << " " << g_opr->getNdbError() << endl; } if (g_opx != 0 && g_opx->getNdbError().code != 0) { ndbout << "opx: table=" << g_opx->getTableName() << " " << g_opx->getNdbError() << endl; } if (g_ops != 0 && g_ops->getNdbError().code != 0) { ndbout << "ops: table=" << g_ops->getTableName() << " " << g_ops->getNdbError() << endl; } NdbOperation* ope = g_con->getNdbErrorOperation(); if (ope != 0 && ope->getNdbError().code != 0) { if (ope != g_opr && ope != g_opx && ope != g_ops) ndbout << "ope: table=" << ope->getTableName() << " " << ope->getNdbError() << endl; } } if (g_bh1 != 0 && g_bh1->getNdbError().code != 0) { ndbout << "bh1: " << g_bh1->getNdbError() << endl; } if (g_bh2 != 0 && g_bh2->getNdbError().code != 0) { ndbout << "bh2: " << g_bh2->getNdbError() << endl; } if (g_opt.m_core) { abort(); } g_printerror = false;}#define CHK(x) \ do { \ if (x) break; \ printerror(__LINE__, #x); return -1; \ } while (0)#define DBG(x) \ do { \ if (! g_opt.m_dbg) break; \ ndbout << "line " << __LINE__ << " " << x << endl; \ } while (0)static intdropTable(){ NdbDictionary::Table tab(g_opt.m_tname); if (g_dic->getTable(g_opt.m_tname) != 0) CHK(g_dic->dropTable(tab) == 0); return 0;}static intcreateTable(){ NdbDictionary::Table tab(g_opt.m_tname); tab.setLogging(false); // col PK1 - Uint32 { NdbDictionary::Column col("PK1"); col.setType(NdbDictionary::Column::Unsigned); col.setPrimaryKey(true); tab.addColumn(col); } // col BL1 - Blob not-nullable { NdbDictionary::Column col("BL1"); const Bcol& b = g_opt.m_blob1; col.setType(NdbDictionary::Column::Blob); col.setInlineSize(b.m_inline); col.setPartSize(b.m_partsize); col.setStripeSize(b.m_stripe); tab.addColumn(col); } // col PK2 - Char[55] if (g_opt.m_pk2len != 0) { NdbDictionary::Column col("PK2"); col.setType(NdbDictionary::Column::Char); col.setLength(g_opt.m_pk2len); col.setPrimaryKey(true); tab.addColumn(col); } // col BL2 - Text nullable if (! g_opt.m_oneblob) { NdbDictionary::Column col("BL2"); const Bcol& b = g_opt.m_blob2; col.setType(NdbDictionary::Column::Text); col.setNullable(true); col.setInlineSize(b.m_inline); col.setPartSize(b.m_partsize); col.setStripeSize(b.m_stripe); tab.addColumn(col); } // create table CHK(g_dic->createTable(tab) == 0); // unique hash index on PK2 if (g_opt.m_pk2len != 0) { NdbDictionary::Index idx(g_opt.m_x1name); idx.setType(NdbDictionary::Index::UniqueHashIndex); idx.setLogging(false); idx.setTable(g_opt.m_tname); idx.addColumnName("PK2"); CHK(g_dic->createIndex(idx) == 0); } // ordered index on PK2 if (g_opt.m_pk2len != 0) { NdbDictionary::Index idx(g_opt.m_x2name); idx.setType(NdbDictionary::Index::OrderedIndex); idx.setLogging(false); idx.setTable(g_opt.m_tname); idx.addColumnName("PK2"); CHK(g_dic->createIndex(idx) == 0); } return 0;}// tuplesstruct Bval { char* m_val; unsigned m_len; char* m_buf; unsigned m_buflen; Bval() : m_val(0), m_len(0), m_buf(0), // read/write buffer m_buflen(0) {} ~Bval() { delete [] m_val; delete [] m_buf; } void alloc(unsigned buflen) { m_buflen = buflen; delete [] m_buf; m_buf = new char [m_buflen]; trash(); } void copyfrom(const Bval& v) { m_len = v.m_len; delete [] m_val; if (v.m_val == 0) m_val = 0; else m_val = (char*)memcpy(new char [m_len], v.m_val, m_len); } void trash() const { assert(m_buf != 0); memset(m_buf, 'x', m_buflen); }private: Bval(const Bval&); Bval& operator=(const Bval&);};struct Tup { bool m_exists; // exists in table Uint32 m_pk1; // primary keys concatenated like keyinfo char m_pk2[g_max_pk2len + 1]; Bval m_blob1; Bval m_blob2; Tup() : m_exists(false) {} ~Tup() { } // alloc buffers of max size void alloc() { m_blob1.alloc(g_opt.m_blob1.m_inline + g_opt.m_blob1.m_partsize * g_opt.m_parts); m_blob2.alloc(g_opt.m_blob2.m_inline + g_opt.m_blob2.m_partsize * g_opt.m_parts); } void copyfrom(const Tup& tup) { assert(m_pk1 == tup.m_pk1); m_blob1.copyfrom(tup.m_blob1); m_blob2.copyfrom(tup.m_blob2); }private: Tup(const Tup&); Tup& operator=(const Tup&);};static Tup* g_tups;static unsignedurandom(unsigned n){ return n == 0 ? 0 : random() % n;}static voidcalcBval(const Bcol& b, Bval& v, bool keepsize){ if (b.m_nullable && urandom(10) == 0) { v.m_len = 0; delete [] v.m_val; v.m_val = 0; v.m_buf = new char [1]; } else { if (keepsize && v.m_val != 0) ; else if (urandom(10) == 0) v.m_len = urandom(b.m_inline); else v.m_len = urandom(b.m_inline + g_opt.m_parts * b.m_partsize + 1); delete [] v.m_val; v.m_val = new char [v.m_len + 1]; for (unsigned i = 0; i < v.m_len; i++) v.m_val[i] = 'a' + urandom(25); v.m_val[v.m_len] = 0; v.m_buf = new char [v.m_len]; } v.m_buflen = v.m_len; v.trash();}static voidcalcBval(Tup& tup, bool keepsize){ calcBval(g_opt.m_blob1, tup.m_blob1, keepsize); if (! g_opt.m_oneblob) calcBval(g_opt.m_blob2, tup.m_blob2, keepsize);}static voidcalcTups(bool keepsize){ for (unsigned k = 0; k < g_opt.m_rows; k++) { Tup& tup = g_tups[k]; tup.m_pk1 = g_opt.m_pk1off + k; for (unsigned i = 0, n = k; i < g_opt.m_pk2len; i++) { if (n != 0) { tup.m_pk2[i] = '0' + n % 10; n = n / 10; } else { tup.m_pk2[i] = 'a' + i % 26; } } calcBval(tup, keepsize); }}// blob handle opsstatic intgetBlobHandles(NdbOperation* opr){ CHK((g_bh1 = opr->getBlobHandle("BL1")) != 0); if (! g_opt.m_oneblob) CHK((g_bh2 = opr->getBlobHandle("BL2")) != 0); return 0;}static intgetBlobHandles(NdbIndexOperation* opx){ CHK((g_bh1 = opx->getBlobHandle("BL1")) != 0); if (! g_opt.m_oneblob) CHK((g_bh2 = opx->getBlobHandle("BL2")) != 0); return 0;}static intgetBlobHandles(NdbScanOperation* ops){ CHK((g_bh1 = ops->getBlobHandle("BL1")) != 0); if (! g_opt.m_oneblob) CHK((g_bh2 = ops->getBlobHandle("BL2")) != 0); return 0;}static intgetBlobLength(NdbBlob* h, unsigned& len){ Uint64 len2 = (unsigned)-1; CHK(h->getLength(len2) == 0); len = (unsigned)len2; assert(len == len2); bool isNull; CHK(h->getNull(isNull) == 0); DBG("getBlobLength " << h->getColumn()->getName() << " len=" << len << " null=" << isNull); return 0;}// setValue / getValuestatic intsetBlobValue(NdbBlob* h, const Bval& v){ bool null = (v.m_val == 0); bool isNull; unsigned len; DBG("setValue " << h->getColumn()->getName() << " len=" << v.m_len << " null=" << null); if (null) { CHK(h->setNull() == 0); isNull = false; CHK(h->getNull(isNull) == 0 && isNull == true); CHK(getBlobLength(h, len) == 0 && len == 0); } else { CHK(h->setValue(v.m_val, v.m_len) == 0); CHK(h->getNull(isNull) == 0 && isNull == false); CHK(getBlobLength(h, len) == 0 && len == v.m_len); } return 0;}static intsetBlobValue(const Tup& tup){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -