diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index 0595c018b2e..6d488107b27 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -8533,11 +8533,20 @@ void Dbdih::openingTableErrorLab(Signal* signal, FileRecordPtr filePtr) /* WE FAILED IN OPENING A FILE. IF THE FIRST FILE THEN TRY WITH THE */ /* DUPLICATE FILE, OTHERWISE WE REPORT AN ERROR IN THE SYSTEM RESTART. */ /* ---------------------------------------------------------------------- */ - ndbrequire(filePtr.i == tabPtr.p->tabFile[0]); - filePtr.i = tabPtr.p->tabFile[1]; - ptrCheckGuard(filePtr, cfileFileSize, fileRecord); - openFileRw(signal, filePtr); - filePtr.p->reqStatus = FileRecord::OPENING_TABLE; + if (filePtr.i == tabPtr.p->tabFile[0]) + { + filePtr.i = tabPtr.p->tabFile[1]; + ptrCheckGuard(filePtr, cfileFileSize, fileRecord); + openFileRw(signal, filePtr); + filePtr.p->reqStatus = FileRecord::OPENING_TABLE; + } + else + { + char buf[256]; + BaseString::snprintf(buf, "Error opening DIH schema files for table: %d", + tabPtr.i); + progError(__LINE__, NDBD_EXIT_AFS_NO_SUCH_FILE, buf); + } }//Dbdih::openingTableErrorLab() void Dbdih::readingTableLab(Signal* signal, FileRecordPtr filePtr) diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 695580d556c..8e6333e4615 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -12796,19 +12796,17 @@ void Dblqh::lastWriteInFileLab(Signal* signal) void Dblqh::writePageZeroLab(Signal* signal) { - if (false && logPartPtr.p->logPartState == LogPartRecord::FILE_CHANGE_PROBLEM) + if (logPartPtr.p->logPartState == LogPartRecord::FILE_CHANGE_PROBLEM) { if (logPartPtr.p->firstLogQueue == RNIL) { jam(); logPartPtr.p->logPartState = LogPartRecord::IDLE; - ndbout_c("resetting logPartState to IDLE"); } else { jam(); logPartPtr.p->logPartState = LogPartRecord::ACTIVE; - ndbout_c("resetting logPartState to ACTIVE"); } } diff --git a/storage/ndb/src/kernel/vm/DynArr256.cpp b/storage/ndb/src/kernel/vm/DynArr256.cpp new file mode 100644 index 00000000000..12e1b9ec40a --- /dev/null +++ b/storage/ndb/src/kernel/vm/DynArr256.cpp @@ -0,0 +1,1015 @@ +/* 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 */ + +#include "DynArr256.hpp" +#include +#include +#include + +#define DA256_BITS 5 +#define DA256_MASK 31 + +struct DA256CL +{ + Uint32 m_magic; + Uint32 m_data[15]; +}; + +struct DA256Free +{ + Uint32 m_magic; + Uint32 m_next_free; +}; + +struct DA256Node +{ + struct DA256CL m_lines[17]; +}; + +struct DA256Page +{ + struct DA256CL m_header[2]; + struct DA256Node m_nodes[30]; +}; + +#define require(x) require_impl(x, __LINE__) +//#define DA256_USE_PX +//#define DA256_USE_PREFETCH +#define DA256_EXTRA_SAFE + + +#ifdef UNIT_TEST +#ifdef USE_CALLGRIND +#include +#else +#define CALLGRIND_TOGGLE_COLLECT() +#endif +Uint32 allocatedpages = 0; +Uint32 allocatednodes = 0; +Uint32 releasednodes = 0; +#endif + +inline +void +require_impl(bool x, int line) +{ + if (!x) + { + ndbout_c("LINE: %d", line); + abort(); + } +} + +DynArr256Pool::DynArr256Pool() +{ + m_type_id = RNIL; + m_first_free = RNIL; + m_memroot = 0; +} + +void +DynArr256Pool::init(Uint32 type_id, const Pool_context & pc) +{ + m_ctx = pc; + m_type_id = type_id; + m_memroot = (DA256Page*)m_ctx.get_memroot(); +} + +static const Uint32 g_max_sizes[5] = { 0, 256, 65536, 16777216, ~0 }; + +/** + * sz = 0 = 1 - 0 level + * sz = 1 = 256^1 - 1 level + * sz = 2 = 256^2 - 2 level + * sz = 3 = 256^3 - 3 level + * sz = 4 = 256^4 - 4 level + */ +Uint32 * +DynArr256::get(Uint32 pos) const +{ + Uint32 sz = m_head.m_sz; + Uint32 ptrI = m_head.m_ptr_i; + DA256Page * memroot = m_pool.m_memroot; + Uint32 type_id = (~m_pool.m_type_id) & 0xFFFF; + + if (unlikely(pos >= g_max_sizes[sz])) + { + return 0; + } + +#ifdef DA256_USE_PX + Uint32 px[4] = { (pos >> 24) & 255, + (pos >> 16) & 255, + (pos >> 8) & 255, + (pos >> 0) & 255 }; +#endif + + Uint32* retVal = &m_head.m_ptr_i; + for(; sz --;) + { + if (unlikely(ptrI == RNIL)) + { + return 0; + } +#ifdef DA256_USE_PX + Uint32 p0 = px[sz]; +#else + Uint32 shr = sz << 3; + Uint32 p0 = (pos >> shr) & 255; +#endif + Uint32 page_no = ptrI >> DA256_BITS; + Uint32 page_idx = ptrI & DA256_MASK; + DA256Page * page = memroot + page_no; + + Uint32 *magic_ptr, p; + if (p0 != 255) + { + Uint32 line = ((p0 << 8) + (p0 << 4) + p0 + 255) >> 12; + Uint32 * ptr = (Uint32*)(page->m_nodes + page_idx); + + p = 0; + retVal = (ptr + 1 + p0 + line); + magic_ptr =(ptr + (p0 & ~15)); + } + else + { + Uint32 b = (page_idx + 1) >> 4; + Uint32 * ptr = (Uint32*)(page->m_header+b); + + p = page_idx - (b << 4) + b; + retVal = (ptr + 1 + p); + magic_ptr = ptr; + } + + ptrI = *retVal; + Uint32 magic = *magic_ptr; + + if (unlikely(! ((magic & (1 << p)) && (magic >> 16) == type_id))) + goto err; + } + + return retVal; +err: + require(false); + return 0; +} + +Uint32 * +DynArr256::set(Uint32 pos) +{ + Uint32 sz = m_head.m_sz; + Uint32 type_id = (~m_pool.m_type_id) & 0xFFFF; + DA256Page * memroot = m_pool.m_memroot; + + if (unlikely(pos >= g_max_sizes[sz])) + { + if (unlikely(!expand(pos))) + { + return 0; + } + sz = m_head.m_sz; + } + +#ifdef DA256_USE_PX + Uint32 px[4] = { (pos >> 24) & 255, + (pos >> 16) & 255, + (pos >> 8) & 255, + (pos >> 0) & 255 }; +#endif + + Uint32 ptrI = m_head.m_ptr_i; + Uint32 *retVal = &m_head.m_ptr_i; + for(; sz --;) + { +#ifdef DA256_USE_PX + Uint32 p0 = px[sz]; +#else + Uint32 shr = sz << 3; + Uint32 p0 = (pos >> shr) & 255; +#endif + if (ptrI == RNIL) + { + if (unlikely((ptrI = m_pool.seize()) == RNIL)) + { + return 0; + } + * retVal = ptrI; + } + + Uint32 page_no = ptrI >> DA256_BITS; + Uint32 page_idx = ptrI & DA256_MASK; + DA256Page * page = memroot + page_no; + + Uint32 *magic_ptr, p; + if (p0 != 255) + { + Uint32 line = ((p0 << 8) + (p0 << 4) + p0 + 255) >> 12; + Uint32 * ptr = (Uint32*)(page->m_nodes + page_idx); + + p = 0; + magic_ptr = (ptr + (p0 & ~15)); + retVal = (ptr + 1 + p0 + line); + } + else + { + Uint32 b = (page_idx + 1) >> 4; + Uint32 * ptr = (Uint32*)(page->m_header+b); + + p = page_idx - (b << 4) + b; + magic_ptr = ptr; + retVal = (ptr + 1 + p); + } + + ptrI = * retVal; + Uint32 magic = *magic_ptr; + + if (unlikely(! ((magic & (1 << p)) && (magic >> 16) == type_id))) + goto err; + } + + return retVal; + +err: + require(false); + return 0; +} + +static +inline +void +initpage(DA256Page* p, Uint32 page_no, Uint32 type_id) +{ + Uint32 i, j; +#ifdef DA256_USE_PREFETCH +#if defined(__GNUC__) && !(__GNUC__ == 2 && __GNUC_MINOR__ < 96) +#ifdef DA256_EXTRA_SAFE + for (i = 0; i<(30 * 17 + 2); i++) + { + __builtin_prefetch (p->m_header + i, 1); + } +#else + { + __builtin_prefetch (p->m_header + 0, 1); + __builtin_prefetch (p->m_header + 1, 1); + for (i = 0; i<30; i++) + { + __builtin_prefetch (p->m_nodes + i, 1); + } + } +#endif +#endif +#endif + DA256CL* cl; + for (i = 0; i<2; i++) + { + cl = p->m_header + i; + cl->m_magic = (~type_id << 16); + } + + DA256Free* free; + + for (i = 0; i<30; i++) + { + free = (DA256Free*)(p->m_nodes+i); + free->m_magic = type_id; + free->m_next_free = (page_no << DA256_BITS) + (i + 1); +#ifdef DA256_EXTRA_SAFE + DA256Node* node = p->m_nodes+i; + for (j = 0; j<17; j++) + node->m_lines[j].m_magic = type_id; +#endif + } + + free = (DA256Free*)(p->m_nodes+29); + free->m_next_free = RNIL; +} + +bool +DynArr256::expand(Uint32 pos) +{ + Uint32 i; + Uint32 idx = 0; + Uint32 alloc[5]; + Uint32 sz = m_head.m_sz; + Uint32 shl = 0; + + for (; pos >= g_max_sizes[sz]; sz++); + + if (m_head.m_sz == 0) + { + m_head.m_sz = sz; + return true; + } + + sz = m_head.m_sz; + for (; pos >= g_max_sizes[sz]; sz++) + { + Uint32 ptrI = m_pool.seize(); + if (unlikely(ptrI == RNIL)) + goto err; + alloc[idx++] = ptrI; + } + + alloc[idx] = m_head.m_ptr_i; + m_head.m_sz = 1; + for (Uint32 i = 0; i> DA256_BITS; + Uint32 page_idx = ptrI & DA256_MASK; + Uint32 type_id = (~m_pool.m_type_id) & 0xFFFF; + DA256Page * memroot = m_pool.m_memroot; + DA256Page * page = memroot + page_no; + + if (ptrI != RNIL) + { + Uint32 tmp = iter.m_pos & 255; + Uint32 p0 = tmp; + for (; p0<256 && p0 < tmp + 16; p0++) + { + Uint32 *retVal, *magic_ptr, p; + if (p0 != 255) + { + Uint32 line = ((p0 << 8) + (p0 << 4) + p0 + 255) >> 12; + Uint32 * ptr = (Uint32*)(page->m_nodes + page_idx); + + p = 0; + retVal = (ptr + 1 + p0 + line); + magic_ptr =(ptr + (p0 & ~15)); + } + else + { + Uint32 b = (page_idx + 1) >> 4; + Uint32 * ptr = (Uint32*)(page->m_header+b); + + p = page_idx - (b << 4) + b; + retVal = (ptr + 1 + p); + magic_ptr = ptr; + } + + Uint32 magic = *magic_ptr; + if (unlikely(! ((magic & (1 << p)) && (magic >> 16) == type_id))) + goto err; + + Uint32 val = * retVal; + if (val != RNIL) + { + if (iter.m_sz + 2 == m_head.m_sz) + { + * retVal = RNIL; + m_pool.release(val); + iter.m_pos = (iter.m_pos & ~255) + p0; + return false; + } + else + { + * retVal = RNIL; + iter.m_sz++; + iter.m_ptr_i[iter.m_sz] = val; + iter.m_pos = (p0 << 8); + return false; + } + } + } + + if (p0 == 256) + { + if (iter.m_sz == 0) + goto done; + iter.m_sz--; + iter.m_pos >>= 8; + + m_pool.release(ptrI); + return false; + } + else + { + iter.m_pos = (iter.m_pos & ~255) + p0; + return false; + } + } + +done: + if (m_head.m_ptr_i != RNIL) + { + m_pool.release(m_head.m_ptr_i); + } + + new (&m_head) Head(); + return true; + +err: + require(false); + return false; +} + +static +inline +bool +seizenode(DA256Page* page, Uint32 idx, Uint32 type_id) +{ + Uint32 i; + Uint32 b = (idx + 1) >> 4; + Uint32 p = idx - (b << 4) + b; + + DA256Node * ptr = (DA256Node*)(page->m_nodes + idx); + +#ifdef DA256_USE_PREFETCH +#if defined(__GNUC__) && !(__GNUC__ == 2 && __GNUC_MINOR__ < 96) + __builtin_prefetch (page->m_header + b, 1); + for (i = 0; i<17; i++) + { + __builtin_prefetch (ptr->m_lines+i, 1); + } +#endif +#endif + +#ifdef DA256_EXTRA_SAFE + Uint32 check = type_id; +#endif + type_id = ((~type_id) << 16) | 0xFFFF; + +#ifdef DA256_EXTRA_SAFE + if (unlikely(((page->m_header + b)->m_magic & (1 << p)) != 0)) + { + return false; + } +#endif + + (page->m_header + b)->m_magic |= (1 << p); + (page->m_header + b)->m_data[p] = RNIL; + for (i = 0; i<17; i++) + { + DA256CL * line = ptr->m_lines + i; +#ifdef DA256_EXTRA_SAFE + if (unlikely(line->m_magic != check)) + { + return false; + } +#endif + line->m_magic = type_id; + for (Uint32 j = 0; j<15; j++) + line->m_data[j] = RNIL; + } + +#ifdef UNIT_TEST + allocatednodes++; +#endif + return true; +} + +static +bool +releasenode(DA256Page* page, Uint32 idx, Uint32 type_id) +{ + Uint32 i; + Uint32 b = (idx + 1) >> 4; + Uint32 p = idx - (b << 4) + b; + + DA256Node * ptr = (DA256Node*)(page->m_nodes + idx); + +#ifdef DA256_USE_PREFETCH +#if defined(__GNUC__) && !(__GNUC__ == 2 && __GNUC_MINOR__ < 96) + __builtin_prefetch (page->m_header + b, 1); + for (i = 0; i<17; i++) + { + __builtin_prefetch (ptr->m_lines+i, 1); + } +#endif +#endif + +#ifdef DA256_EXTRA_SAFE + Uint32 check = ((~type_id) << 16) | 0xFFFF; +#endif + +#ifdef DA256_EXTRA_SAFE + if (unlikely((((page->m_header + b)->m_magic & (1 << p)) == 0))) + { + return false; + } +#endif + + (page->m_header + b)->m_magic ^= (1 << p); + for (i = 0; i<17; i++) + { + DA256CL * line = ptr->m_lines + i; +#ifdef DA256_EXTRA_SAFE + if (unlikely(line->m_magic != check)) + { + return false; + } +#endif + line->m_magic = type_id; + } + +#ifdef UNIT_TEST + releasednodes++; +#endif + + return true; +} + +Uint32 +DynArr256Pool::seize() +{ + Uint32 ff = m_first_free; + Uint32 type_id = m_type_id; + + DA256Page* page; + DA256Page * memroot = m_memroot; + if (ff == RNIL) + { + Uint32 page_no; + if (likely((page = (DA256Page*)m_ctx.alloc_page(type_id, &page_no)) != 0)) + { + initpage(page, page_no, type_id); +#ifdef UNIT_TEST + allocatedpages++; +#endif + } + else + { + return RNIL; + } + ff = (page_no << DA256_BITS); + } + else + { + page = memroot + (ff >> DA256_BITS); + } + + Uint32 idx = ff & DA256_MASK; + DA256Free * ptr = (DA256Free*)(page->m_nodes + idx); + if (likely(ptr->m_magic == type_id)) + { + Uint32 next = ptr->m_next_free; + if (likely(seizenode(page, idx, type_id))) + { + m_first_free = next; + return ff; + } + } + +//error: + require(false); + return 0; +} + +void +DynArr256Pool::release(Uint32 ptrI) +{ + Uint32 ff = m_first_free; + Uint32 type_id = m_type_id; + + Uint32 page_no = ptrI >> DA256_BITS; + Uint32 page_idx = ptrI & DA256_MASK; + DA256Page * memroot = m_memroot; + DA256Page * page = memroot + page_no; + + DA256Free * ptr = (DA256Free*)(page->m_nodes + page_idx); + if (likely(releasenode(page, page_idx, type_id))) + { + ptr->m_next_free = ff; + ptr->m_magic = type_id; + m_first_free = ptrI; + return; + } + require(false); +} + +#ifdef UNIT_TEST + +#include +#include "ndbd_malloc_impl.hpp" +#include "SimulatedBlock.hpp" + +Ndbd_mem_manager mm; +Configuration cfg; +Block_context ctx(cfg, mm); +struct BB : public SimulatedBlock +{ + BB(int no, Block_context& ctx) : SimulatedBlock(no, ctx) {} +}; + +BB block(DBACC, ctx); + +static +void +simple(DynArr256 & arr, int argc, char* argv[]) +{ + for (Uint32 i = 1; i<(Uint32)argc; i++) + { + Uint32 * s = arr.set(atoi(argv[i])); + { + bool found = false; + for (Uint32 j = 1; j 50; + if (len == 0) + op = 1; + if (len == MAXLEN) + op = 0; + switch(op){ + case 0:{ // get + Uint32 item = (rand() % len) << 1; + Uint32 idx = save[item]; + Uint32 val = save[item+1]; + //ndbout_c("get(%d)", idx); + Uint32 *p = arr.get(idx); + assert(p); + assert(* p == val); + break; + } + case 1:{ // set + Uint32 item = len << 1; + Uint32 idx = i; //rand() & 0xFFFFF; // & 0xFFFFF; //rand(); //(65536*i) / 10000; + Uint32 val = rand(); +#if 0 + for(Uint32 j = 0; j < item; j += 2) + { + if (save[j] == idx) + { + item = j; + break; + } + } +#endif + //ndbout_c("set(%d, %x)", idx, val); + Uint32 *p = arr.set(idx); + assert(* p); + if (item == (len << 1)) + { + *p = val; + len++; + } + else + { + assert(* p == save[item+1]); + * p = val; + } + save[item] = idx; + save[item+1] = val; + } + } + } +} + +unsigned long long +micro() +{ + struct timeval tv; + gettimeofday(&tv, 0); + unsigned long long ret = tv.tv_sec; + ret *= 1000000; + ret += tv.tv_usec; + return ret; +} + +static +void +read(DynArr256& arr, int argc, char ** argv) +{ + Uint32 cnt = 100000; + Uint64 mbytes = 16*1024; + Uint32 seed = time(0); + Uint32 seq = 0, seqmask = 0; + + for (Uint32 i = 2; i %d entries (%dkb)", + mbytes, maxidx, 32*pages); + + for (Uint32 i = 0; i %f us/get", start, sum0 - sum1, uspg); + } +} + +static +void +write(DynArr256& arr, int argc, char ** argv) +{ + Uint32 seq = 0, seqmask = 0; + Uint32 cnt = 100000; + Uint64 mbytes = 16*1024; + Uint32 seed = time(0); + + for (Uint32 i = 2; i %d entries (%dkb)", + mbytes, maxidx, 32*pages); + + srand(seed); + + if (seq) + { + seq = rand(); + seqmask = ~(Uint32)0; + } + + ndbout_c("Timing %d %s writes (seed: %u)", cnt, + seq ? "sequential" : "random", seed); + for (Uint32 i = 0; i<10; i++) + { + Uint64 start = micro(); + for (Uint32 i = 0; i %f us/set", start, uspg); + DynArr256::ReleaseIterator iter; + arr.init(iter); + while(!arr.release(iter)); + } +} + +int +main(int argc, char** argv) +{ + if (0) + { + for (Uint32 i = 0; i<30; i++) + { + Uint32 b = (i + 1) >> 4; + Uint32 p = i - (b << 4) + b; + printf("[ %d %d %d ]\n", i, b, p); + } + return 0; + } + + Pool_context pc; + pc.m_block = █ + + Resource_limit rl; + rl.m_min = 0; + rl.m_max = 10000; + rl.m_resource_id = 0; + mm.set_resource_limit(rl); + if(!mm.init()) + { + abort(); + } + + DynArr256Pool pool; + pool.init(0x2001, pc); + + DynArr256::Head head; + DynArr256 arr(pool, head); + + if (strcmp(argv[1], "--args") == 0) + simple(arr, argc, argv); + else if (strcmp(argv[1], "--basic") == 0) + basic(arr, argc, argv); + else if (strcmp(argv[1], "--read") == 0) + read(arr, argc, argv); + else if (strcmp(argv[1], "--write") == 0) + write(arr, argc, argv); + + DynArr256::ReleaseIterator iter; + arr.init(iter); + Uint32 cnt = 0; + while (!arr.release(iter)) cnt++; + + ndbout_c("allocatedpages: %d allocatednodes: %d releasednodes: %d" + " releasecnt: %d", + allocatedpages, + allocatednodes, + releasednodes, + cnt); + + return 0; +#if 0 + printf("sizeof(DA256Page): %d\n", sizeof(DA256Page)); + + DA256Page page; + + for (Uint32 i = 0; i<10000; i++) + { + Uint32 arg = rand() & 255; + Uint32 base = 0; + Uint32 idx = arg & 256; + printf("%d\n", arg); + + assert(base <= 30); + + if (idx == 255) + { + Uint32 b = (base + 1) >> 4; + Uint32 p = base - (b << 4) + b; + Uint32 magic = page.m_header[b].m_magic; + Uint32 retVal = page.m_header[b].m_data[p]; + + require(magic & (1 << p)); + return retVal; + } + else + { + // 4 bit extra offset per idx + Uint32 line = idx / 15; + Uint32 off = idx % 15; + + { + Uint32 pos = 1 + idx + line; + Uint32 magic = pos & ~15; + + Uint32 * ptr = (Uint32*)&page.m_nodes[base]; + assert((ptr + pos) == &page.m_nodes[base].m_lines[line].m_data[off]); + assert((ptr + magic) == &page.m_nodes[base].m_lines[line].m_magic); + } + } + } +#endif +} + +Uint32 g_currentStartPhase; +Uint32 g_start_type; +NdbNodeBitmask g_nowait_nodes; + +void childExit(int code, Uint32 currentStartPhase) +{ + abort(); +} + +void childAbort(int code, Uint32 currentStartPhase) +{ + abort(); +} + +void childReportError(int error) +{ + abort(); +} + +void +UpgradeStartup::sendCmAppChg(Ndbcntr& cntr, Signal* signal, Uint32 startLevel){ +} + +void +UpgradeStartup::execCM_APPCHG(SimulatedBlock & block, Signal* signal){ +} + +void +UpgradeStartup::sendCntrMasterReq(Ndbcntr& cntr, Signal* signal, Uint32 n){ +} + +void +UpgradeStartup::execCNTR_MASTER_REPLY(SimulatedBlock & block, Signal* signal){ +} + +#include + +void +SimBlockList::unload() +{ + +} + +#endif diff --git a/storage/ndb/src/kernel/vm/DynArr256.hpp b/storage/ndb/src/kernel/vm/DynArr256.hpp new file mode 100644 index 00000000000..d70b126e8c2 --- /dev/null +++ b/storage/ndb/src/kernel/vm/DynArr256.hpp @@ -0,0 +1,79 @@ +/* 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 */ + +#ifndef DYNARR256_HPP +#define DYNARR256_HPP + +#include "Pool.hpp" + +class DynArr256; +struct DA256Page; + +class DynArr256Pool +{ + friend class DynArr256; +public: + DynArr256Pool(); + + void init(Uint32 type_id, const Pool_context& pc); + +protected: + Uint32 m_type_id; + Uint32 m_first_free; + Pool_context m_ctx; + struct DA256Page* m_memroot; + +private: + Uint32 seize(); + void release(Uint32); +}; + +class DynArr256 +{ +public: + struct Head + { + Head() { m_ptr_i = RNIL; m_sz = 0;} + + Uint32 m_ptr_i; + Uint32 m_sz; + }; + + DynArr256(DynArr256Pool & pool, Head& head) : + m_head(head), m_pool(pool){} + + Uint32* set(Uint32 pos); + Uint32* get(Uint32 pos) const ; + + struct ReleaseIterator + { + Uint32 m_sz; + Uint32 m_pos; + Uint32 m_ptr_i[4]; + }; + + void init(ReleaseIterator&); + bool release(ReleaseIterator&); + +protected: + Head & m_head; + DynArr256Pool & m_pool; + + bool expand(Uint32 pos); + void handle_invalid_ptr(Uint32 pos, Uint32 ptrI, Uint32 p0); +}; + +#endif diff --git a/storage/ndb/src/kernel/vm/Makefile.am b/storage/ndb/src/kernel/vm/Makefile.am index 71fede97da3..5182e42e561 100644 --- a/storage/ndb/src/kernel/vm/Makefile.am +++ b/storage/ndb/src/kernel/vm/Makefile.am @@ -20,7 +20,8 @@ libkernel_a_SOURCES = \ Mutex.cpp SafeCounter.cpp \ Rope.cpp \ ndbd_malloc.cpp ndbd_malloc_impl.cpp \ - Pool.cpp WOPool.cpp RWPool.cpp + Pool.cpp WOPool.cpp RWPool.cpp \ + DynArr256.cpp INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/mgmapi @@ -44,7 +45,7 @@ libkernel.dsp: Makefile \ @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libkernel_a_SOURCES) @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD) -EXTRA_PROGRAMS = ndbd_malloc_impl_test bench_pool +EXTRA_PROGRAMS = ndbd_malloc_impl_test bench_pool testDynArr256 ndbd_malloc_impl_test_CXXFLAGS = -DUNIT_TEST ndbd_malloc_impl_test_SOURCES = ndbd_malloc_impl.cpp ndbd_malloc_impl_test_LDFLAGS = @ndb_bin_am_ldflags@ \ @@ -54,9 +55,19 @@ ndbd_malloc_impl_test_LDFLAGS = @ndb_bin_am_ldflags@ \ $(top_builddir)/strings/libmystrings.a bench_pool_SOURCES = bench_pool.cpp -bench_pool_LDFLAGS = @ndb_bin_am_ldflags@ ../SimBlockList.o \ +bench_pool_LDFLAGS = @ndb_bin_am_ldflags@\ libkernel.a ../error/liberror.a \ $(top_builddir)/storage/ndb/src/libndbclient.la \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a + +testDynArr256_CXXFLAGS = -DUNIT_TEST +testDynArr256_SOURCES = DynArr256.cpp +testDynArr256_LDFLAGS = @ndb_bin_am_ldflags@ \ + libkernel.a ../error/liberror.a \ + $(top_builddir)/storage/ndb/src/libndbclient.la \ + $(top_builddir)/mysys/libmysys.a \ + $(top_builddir)/dbug/libdbug.a \ + $(top_builddir)/strings/libmystrings.a + diff --git a/storage/ndb/src/kernel/vm/bench_pool.cpp b/storage/ndb/src/kernel/vm/bench_pool.cpp index d728710da61..31f8ea78e99 100644 --- a/storage/ndb/src/kernel/vm/bench_pool.cpp +++ b/storage/ndb/src/kernel/vm/bench_pool.cpp @@ -60,7 +60,7 @@ Uint32 sizes = 7; unsigned int seed; Ndbd_mem_manager mm; Configuration cfg; -Block_context ctx = { cfg, mm }; +Block_context ctx(cfg, mm); struct BB : public SimulatedBlock { BB(int no, Block_context& ctx) : SimulatedBlock(no, ctx) {} @@ -548,6 +548,8 @@ main(int argc, char **argv) } Uint32 g_currentStartPhase; +Uint32 g_start_type; +NdbNodeBitmask g_nowait_nodes; void childExit(int code, Uint32 currentStartPhase) { diff --git a/storage/ndb/test/include/HugoTransactions.hpp b/storage/ndb/test/include/HugoTransactions.hpp index 5c987a576bc..f9acaf322f7 100644 --- a/storage/ndb/test/include/HugoTransactions.hpp +++ b/storage/ndb/test/include/HugoTransactions.hpp @@ -34,7 +34,8 @@ public: bool allowConstraintViolation = true, int doSleep = 0, bool oneTrans = false, - int updateValue = 0); + int updateValue = 0, + bool abort = false); int scanReadRecords(Ndb*, int records, diff --git a/storage/ndb/test/src/HugoTransactions.cpp b/storage/ndb/test/src/HugoTransactions.cpp index 74aab2aa55a..525f50f5231 100644 --- a/storage/ndb/test/src/HugoTransactions.cpp +++ b/storage/ndb/test/src/HugoTransactions.cpp @@ -519,7 +519,8 @@ HugoTransactions::loadTable(Ndb* pNdb, bool allowConstraintViolation, int doSleep, bool oneTrans, - int value){ + int value, + bool abort){ int check, a; int retryAttempt = 0; int retryMax = 5; @@ -585,10 +586,22 @@ HugoTransactions::loadTable(Ndb* pNdb, if (!oneTrans || (c + batch) >= records) { // closeTrans = true; closeTrans = false; - check = pTrans->execute( Commit ); - if(check != -1) - m_latest_gci = pTrans->getGCI(); - pTrans->restart(); + if (!abort) + { + check = pTrans->execute( Commit ); + if(check != -1) + m_latest_gci = pTrans->getGCI(); + pTrans->restart(); + } + else + { + check = pTrans->execute( NoCommit ); + if (check != -1) + { + check = pTrans->execute( Rollback ); + closeTransaction(pNdb); + } + } } else { closeTrans = false; check = pTrans->execute( NoCommit ); diff --git a/storage/ndb/test/tools/hugoLoad.cpp b/storage/ndb/test/tools/hugoLoad.cpp index 49c489e5db5..870ce8b0289 100644 --- a/storage/ndb/test/tools/hugoLoad.cpp +++ b/storage/ndb/test/tools/hugoLoad.cpp @@ -31,6 +31,8 @@ int main(int argc, const char** argv){ int _batch = 512; int _loops = -1; int _rand = 0; + int _onetrans = 0; + int _abort = 0; const char* db = 0; struct getargs args[] = { @@ -39,7 +41,9 @@ int main(int argc, const char** argv){ { "loops", 'l', arg_integer, &_loops, "Number of loops", "" }, { "database", 'd', arg_string, &db, "Database", "" }, { "usage", '?', arg_flag, &_help, "Print help", "" }, - { "rnd-rows", 0, arg_flag, &_rand, "Rand number of records", "recs" } + { "rnd-rows", 0, arg_flag, &_rand, "Rand number of records", "recs" }, + { "one-trans", 0, arg_flag, &_onetrans, "Insert as 1 trans", "" }, + { "abort", 0, arg_integer, &_abort, "Abort probability", "" } }; int num_args = sizeof(args) / sizeof(args[0]); int optind = 0; @@ -92,10 +96,13 @@ int main(int argc, const char** argv){ HugoTransactions hugoTrans(*pTab); loop: int rows = (_rand ? rand() % _records : _records); + int abort = (rand() % 100) < _abort ? 1 : 0; + if (abort) + ndbout << "load+abort" << endl; if (hugoTrans.loadTable(&MyNdb, rows, _batch, - true, 0, false, _loops) != 0){ + true, 0, _onetrans, _loops, abort) != 0){ return NDBT_ProgramExit(NDBT_FAILED); }