📄 testoibasic.cpp
字号:
if (xbytes[j] != 0) { ok = true; break; } } if (! ok) { miss3++; continue; } // check for duplicate (before normalize) ok = true; for (unsigned j = 0; j < i; j++) { const Chr& chr = m_chr[j]; if (chr.m_size == size && memcmp(chr.m_bytes, bytes, size) == 0) { ok = false; break; } } if (! ok) { miss4++; continue; } i++; } bool disorder = true; unsigned bubbles = 0; while (disorder) { disorder = false; for (unsigned i = 1; i < maxcharcount; i++) { unsigned len = sizeof(m_chr[i].m_xbytes); if (memcmp(m_chr[i-1].m_xbytes, m_chr[i].m_xbytes, len) > 0) { Chr chr = m_chr[i]; m_chr[i] = m_chr[i-1]; m_chr[i-1] = chr; disorder = true; bubbles++; } } } LL3("inited charset " << *this << " miss=" << miss1 << "," << miss2 << "," << miss3 << "," << miss4 << " bubbles=" << bubbles);}Chs::~Chs(){ delete [] m_chr;}static NdbOut&operator<<(NdbOut& out, const Chs& chs){ CHARSET_INFO* cs = chs.m_cs; out << cs->name << "[" << cs->mbminlen << "-" << cs->mbmaxlen << "," << chs.m_xmul << "]"; return out;}static Chs* cslist[maxcsnumber];static voidresetcslist(){ for (unsigned i = 0; i < maxcsnumber; i++) { delete cslist[i]; cslist[i] = 0; }}static Chs*getcs(Par par){ CHARSET_INFO* cs; if (par.m_cs != 0) { cs = par.m_cs; } else { while (1) { unsigned n = urandom(maxcsnumber); cs = get_charset(n, MYF(0)); if (cs != 0) { // prefer complex charsets if (cs->mbmaxlen != 1 || urandom(5) == 0) break; } } } if (cslist[cs->number] == 0) cslist[cs->number] = new Chs(cs); return cslist[cs->number];}// tables and indexes// Col - table columnstruct Col { enum Type { Unsigned = NdbDictionary::Column::Unsigned, Char = NdbDictionary::Column::Char, Varchar = NdbDictionary::Column::Varchar, Longvarchar = NdbDictionary::Column::Longvarchar }; const class Tab& m_tab; unsigned m_num; const char* m_name; bool m_pk; Type m_type; unsigned m_length; unsigned m_bytelength; // multiplied by char width unsigned m_attrsize; // base type size unsigned m_headsize; // length bytes unsigned m_bytesize; // full value size bool m_nullable; const Chs* m_chs; Col(const class Tab& tab, unsigned num, const char* name, bool pk, Type type, unsigned length, bool nullable, const Chs* chs); ~Col(); bool equal(const Col& col2) const; void wellformed(const void* addr) const;};Col::Col(const class Tab& tab, unsigned num, const char* name, bool pk, Type type, unsigned length, bool nullable, const Chs* chs) : m_tab(tab), m_num(num), m_name(strcpy(new char [strlen(name) + 1], name)), m_pk(pk), m_type(type), m_length(length), m_bytelength(length * (chs == 0 ? 1 : chs->m_cs->mbmaxlen)), m_attrsize( type == Unsigned ? sizeof(Uint32) : type == Char ? sizeof(char) : type == Varchar ? sizeof(char) : type == Longvarchar ? sizeof(char) : ~0), m_headsize( type == Unsigned ? 0 : type == Char ? 0 : type == Varchar ? 1 : type == Longvarchar ? 2 : ~0), m_bytesize(m_headsize + m_attrsize * m_bytelength), m_nullable(nullable), m_chs(chs){ // fix long varchar if (type == Varchar && m_bytelength > 255) { m_type = Longvarchar; m_headsize += 1; m_bytesize += 1; }}Col::~Col(){ delete [] m_name;}boolCol::equal(const Col& col2) const{ return m_type == col2.m_type && m_length == col2.m_length && m_chs == col2.m_chs;}voidCol::wellformed(const void* addr) const{ switch (m_type) { case Col::Unsigned: break; case Col::Char: { CHARSET_INFO* cs = m_chs->m_cs; const char* src = (const char*)addr; unsigned len = m_bytelength; int not_used; assert((*cs->cset->well_formed_len)(cs, src, src + len, 0xffff, ¬_used) == len); } break; case Col::Varchar: { CHARSET_INFO* cs = m_chs->m_cs; const unsigned char* src = (const unsigned char*)addr; const char* ssrc = (const char*)src; unsigned len = src[0]; int not_used; assert(len <= m_bytelength); assert((*cs->cset->well_formed_len)(cs, ssrc + 1, ssrc + 1 + len, 0xffff, ¬_used) == len); } break; case Col::Longvarchar: { CHARSET_INFO* cs = m_chs->m_cs; const unsigned char* src = (const unsigned char*)addr; const char* ssrc = (const char*)src; unsigned len = src[0] + (src[1] << 8); int not_used; assert(len <= m_bytelength); assert((*cs->cset->well_formed_len)(cs, ssrc + 2, ssrc + 2 + len, 0xffff, ¬_used) == len); } break; default: assert(false); break; }}static NdbOut&operator<<(NdbOut& out, const Col& col){ out << "col[" << col.m_num << "] " << col.m_name; switch (col.m_type) { case Col::Unsigned: out << " unsigned"; break; case Col::Char: { CHARSET_INFO* cs = col.m_chs->m_cs; out << " char(" << col.m_length << "*" << cs->mbmaxlen << ";" << cs->name << ")"; } break; case Col::Varchar: { CHARSET_INFO* cs = col.m_chs->m_cs; out << " varchar(" << col.m_length << "*" << cs->mbmaxlen << ";" << cs->name << ")"; } break; case Col::Longvarchar: { CHARSET_INFO* cs = col.m_chs->m_cs; out << " longvarchar(" << col.m_length << "*" << cs->mbmaxlen << ";" << cs->name << ")"; } break; default: out << "type" << (int)col.m_type; assert(false); break; } out << (col.m_pk ? " pk" : ""); out << (col.m_nullable ? " nullable" : ""); return out;}// ICol - index columnstruct ICol { const class ITab& m_itab; unsigned m_num; const Col& m_col; ICol(const class ITab& itab, unsigned num, const Col& col); ~ICol();};ICol::ICol(const class ITab& itab, unsigned num, const Col& col) : m_itab(itab), m_num(num), m_col(col){}ICol::~ICol(){}static NdbOut&operator<<(NdbOut& out, const ICol& icol){ out << "icol[" << icol.m_num << "] " << icol.m_col; return out;}// ITab - indexstruct ITab { enum Type { OrderedIndex = NdbDictionary::Index::OrderedIndex, UniqueHashIndex = NdbDictionary::Index::UniqueHashIndex }; const class Tab& m_tab; const char* m_name; Type m_type; unsigned m_icols; const ICol** m_icol; unsigned m_colmask; ITab(const class Tab& tab, const char* name, Type type, unsigned icols); ~ITab(); void icoladd(unsigned k, const ICol* icolptr);};ITab::ITab(const class Tab& tab, const char* name, Type type, unsigned icols) : m_tab(tab), m_name(strcpy(new char [strlen(name) + 1], name)), m_type(type), m_icols(icols), m_icol(new const ICol* [icols + 1]), m_colmask(0){ for (unsigned k = 0; k <= m_icols; k++) m_icol[k] = 0;}ITab::~ITab(){ delete [] m_name; for (unsigned i = 0; i < m_icols; i++) delete m_icol[i]; delete [] m_icol;}voidITab::icoladd(unsigned k, const ICol* icolptr){ assert(k == icolptr->m_num && k < m_icols && m_icol[k] == 0); m_icol[k] = icolptr; m_colmask |= (1 << icolptr->m_col.m_num);}static NdbOut&operator<<(NdbOut& out, const ITab& itab){ out << "itab " << itab.m_name << " icols=" << itab.m_icols; for (unsigned k = 0; k < itab.m_icols; k++) { const ICol& icol = *itab.m_icol[k]; out << endl << icol; } return out;}// Tab - tablestruct Tab { const char* m_name; unsigned m_cols; const Col** m_col; unsigned m_itabs; const ITab** m_itab; // pk must contain an Unsigned column unsigned m_keycol; void coladd(unsigned k, Col* colptr); void itabadd(unsigned j, ITab* itab); Tab(const char* name, unsigned cols, unsigned itabs, unsigned keycol); ~Tab();};Tab::Tab(const char* name, unsigned cols, unsigned itabs, unsigned keycol) : m_name(strcpy(new char [strlen(name) + 1], name)), m_cols(cols), m_col(new const Col* [cols + 1]), m_itabs(itabs), m_itab(new const ITab* [itabs + 1]), m_keycol(keycol){ for (unsigned k = 0; k <= cols; k++) m_col[k] = 0; for (unsigned j = 0; j <= itabs; j++) m_itab[j] = 0;}Tab::~Tab(){ delete [] m_name; for (unsigned i = 0; i < m_cols; i++) delete m_col[i]; delete [] m_col; for (unsigned i = 0; i < m_itabs; i++) delete m_itab[i]; delete [] m_itab;}voidTab::coladd(unsigned k, Col* colptr){ assert(k == colptr->m_num && k < m_cols && m_col[k] == 0); m_col[k] = colptr;}voidTab::itabadd(unsigned j, ITab* itabptr){ assert(j < m_itabs && m_itab[j] == 0); m_itab[j] = itabptr;}static NdbOut&operator<<(NdbOut& out, const Tab& tab){ out << "tab " << tab.m_name << " cols=" << tab.m_cols; for (unsigned k = 0; k < tab.m_cols; k++) { const Col& col = *tab.m_col[k]; out << endl << col; } for (unsigned i = 0; i < tab.m_itabs; i++) { if (tab.m_itab[i] == 0) continue; const ITab& itab = *tab.m_itab[i]; out << endl << itab; } return out;}// make table structsstatic const Tab** tablist = 0;static unsigned tabcount = 0;static voidverifytables(){ for (unsigned j = 0; j < tabcount; j++) { const Tab* t = tablist[j]; if (t == 0) continue; assert(t->m_cols != 0 && t->m_col != 0); for (unsigned k = 0; k < t->m_cols; k++) { const Col* c = t->m_col[k]; assert(c != 0 && c->m_num == k); assert(! (c->m_pk && c->m_nullable)); } assert(t->m_col[t->m_cols] == 0); { assert(t->m_keycol < t->m_cols); const Col* c = t->m_col[t->m_keycol]; assert(c->m_pk && c->m_type == Col::Unsigned); } assert(t->m_itabs != 0 && t->m_itab != 0); for (unsigned i = 0; i < t->m_itabs; i++) { const ITab* x = t->m_itab[i]; if (x == 0) continue; assert(x != 0 && x->m_icols != 0 && x->m_icol != 0); for (unsigned k = 0; k < x->m_icols; k++) { const ICol* c = x->m_icol[k]; assert(c != 0 && c->m_num == k && c->m_col.m_num < t->m_cols); if (x->m_type == ITab::UniqueHashIndex) { assert(! c->m_col.m_nullable); } } } assert(t->m_itab[t->m_itabs] == 0); }}static voidmakebuiltintables(Par par){ LL2("makebuiltintables"); resetcslist(); tabcount = 3; if (tablist == 0) { tablist = new const Tab* [tabcount]; for (unsigned j = 0; j < tabcount; j++) { tablist[j] = 0; } } else { for (unsigned j = 0; j < tabcount; j++) { delete tablist[j]; tablist[j] = 0; } } // ti0 - basic if (usetable(par, 0)) { Tab* t = new Tab("ti0", 5, 7, 0); // name - pk - type - length - nullable - cs t->coladd(0, new Col(*t, 0, "a", 1, Col::Unsigned, 1, 0, 0)); t->coladd(1, new Col(*t, 1, "b", 0, Col::Unsigned, 1, 1, 0)); t->coladd(2, new Col(*t, 2, "c", 0, Col::Unsigned, 1, 0, 0)); t->coladd(3, new Col(*t, 3, "d", 0, Col::Unsigned, 1, 1, 0)); t->coladd(4, new Col(*t, 4, "e", 0, Col::Unsigned, 1, 0, 0)); if (useindex(par, 0)) { // a ITab* x = new ITab(*t, "ti0x0", ITab::OrderedIndex, 1); x->icoladd(0, new ICol(*x, 0, *t->m_col[0])); t->itabadd(0, x); } if (useindex(par, 1)) { // b ITab* x = new ITab(*t, "ti0x1", ITab::OrderedIndex, 1); x->icoladd(0, new ICol(*x, 0, *t->m_col[1])); t->itabadd(1, x); } if (useindex(par, 2)) { // b, c ITab* x = new ITab(*t, "ti0x2", ITab::OrderedIndex, 2); x->icoladd(0, new ICol(*x, 0, *t->m_col[1])); x->icoladd(1, new ICol(*x, 1, *t->m_col[2])); t->itabadd(2, x); } if (useindex(par, 3)) { // b, e, c, d ITab* x = new ITab(*t, "ti0x3", ITab::OrderedIndex, 4); x->icoladd(0, new ICol(*x, 0, *t->m_col[1])); x->icoladd(1, new ICol(*x, 1, *t->m_col[4])); x->icoladd(2, new ICol(*x, 2, *t->m_col[2])); x->icoladd(3, new ICol(*x, 3, *t->m_col[3])); t->itabadd(3, x); } if (useindex(par, 4)) { // a, c ITab* x = new ITab(*t, "ti0z4", ITab::UniqueHashIndex, 2); x->icoladd(0, new ICol(*x, 0, *t->m_col[0])); x->icoladd(1, new ICol(*x, 1, *t->m_col[2])); t->itabadd(4, x); } if (useindex(par, 5)) { // a, e ITab* x = new ITab(*t, "ti0z5", ITab::UniqueHashIndex, 2); x->icoladd(0, new ICol(*x, 0, *t->m_col[0])); x->icoladd(1, new ICol(*x, 1, *t->m_col[4])); t->itabadd(5, x); } tablist[0] = t; } // ti1 - simple char fields if (usetable(par, 1)) { Tab* t = new Tab("ti1", 5, 7, 1); // name - pk - type - length - nullable - cs t->coladd(0, new Col(*t, 0, "a", 0, Col::Unsigned, 1, 0, 0)); t->coladd(1, new Col(*t, 1, "b", 1, Col::Unsigned, 1, 0, 0)); t->coladd(2, new Col(*t, 2, "c", 0, Col::Varchar, 20, 0, getcs(par))); t->coladd(3, new Col(*t, 3, "d", 0, Col::Char, 5, 0, getcs(par))); t->coladd(4, new Col(*t, 4, "e", 0, Col::Longvarchar, 5, 1, getcs(par))); if (useindex(par, 0)) { // b ITab* x = new ITab(*t, "ti1x0", ITab::OrderedIndex, 1); x->icoladd(0, new ICol(*x, 0, *t->m_col[1])); t->itabadd(0, x); } if (useindex(par, 1)) { // c, a ITab* x = new ITab(*t, "ti1x1", ITab::OrderedIndex, 2); x->icoladd(0, new ICol(*x, 0, *t->m_col[2])); x->icoladd(1, new ICol(*x, 1, *t->m_col[0])); t->itabadd(1, x); } if (useindex(par, 2)) { // d ITab* x = new ITab(*t, "ti1x2", ITab::OrderedIndex, 1); x->icoladd(0, new ICol(*x, 0, *t->m_col[3])); t->itabadd(2, x); } if (useindex(par, 3)) { // e, d, c, b ITab* x = new ITab(*t, "ti1x3", ITab::OrderedIndex, 4); x->icoladd(0, new ICol(*x, 0, *t->m_col[4])); x->icoladd(1, new ICol(*x, 1, *t->m_col[3])); x->icoladd(2, new ICol(*x, 2, *t->m_col[2])); x->icoladd(3, new ICol(*x, 3, *t->m_col[1])); t->itabadd(3, x); } if (useindex(par, 4)) { // a, b ITab* x = new ITab(*t, "ti1z4", ITab::UniqueHashIndex, 2); x->icoladd(0, new ICol(*x, 0, *t->m_col[0])); x->icoladd(1, new ICol(*x, 1, *t->m_col[1])); t->itabadd(4, x); } if (useindex(par, 5)) { // b, c, d ITab* x = new ITab(*t, "ti1z5", ITab::UniqueHashIndex, 3); x->icoladd(0, new ICol(*x, 0, *t->m_col[1])); x->icoladd(1, new ICol(*x, 1, *t->m_col[2])); x->icoladd(2, new ICol(*x, 2, *t->m_col[3])); t->itabadd(5, x); } tablist[1] = t; } // ti2 - complex char fields if (usetable(par, 2)) { Tab* t = new Tab("ti2", 5, 7, 2); // name - pk - type - length - nullable - cs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -