3743 jonas oreland 2011-12-23 [merge]
ndb - merge 72-tip
modified:
mysql-test/suite/ndb_rpl/t/ndb_rpl_ddl_open_trans.test
mysql-test/suite/ndb_team/t/ndb_autodiscover3.test
mysql-test/suite/sys_vars/t/disabled.def
sql/ha_ndbcluster.cc
sql/ndb_local_schema.cc
sql/ndb_local_schema.h
sql/ndb_thd_ndb.h
=== added file 'mysql-test/suite/ndb_rpl/r/ndb_rpl_bug_13440282.result'
--- a/mysql-test/suite/ndb_rpl/r/ndb_rpl_bug_13440282.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb_rpl/r/ndb_rpl_bug_13440282.result 2011-12-23 14:34:57 +0000
@@ -0,0 +1,118 @@
+include/master-slave.inc
+[connection master]
+CREATE TABLE `loadreptable` (
+`nid` int(11) NOT NULL,
+`nom` char(255) DEFAULT NULL,
+`prenom` char(255) DEFAULT NULL,
+`abc` char(255) DEFAULT NULL,
+`wkz` char(255) DEFAULT NULL,
+`xyz` char(255) DEFAULT NULL,
+PRIMARY KEY (`nid`) USING HASH
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
+CREATE PROCEDURE MAJ ()
+BEGIN
+DECLARE fini INT default 0;
+WHILE fini < 20 DO
+DELETE FROM loadreptable WHERE nid > 2;
+UPDATE loadreptable SET nid=nid+1 ORDER BY nid DESC;
+UPDATE loadreptable SET
+nom="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxx";
+INSERT INTO loadreptable VALUES(1,"w","t","y","k","b");
+SET fini=fini+1;
+END WHILE;
+END ;
+//
+call MAJ();
+"master"
+select count(*) from loadreptable;
+count(*)
+3
+"slave"
+select count(*) from loadreptable;
+count(*)
+3
+call MAJ();
+"master"
+select count(*) from loadreptable;
+count(*)
+3
+"slave"
+select count(*) from loadreptable;
+count(*)
+3
+call MAJ();
+"master"
+select count(*) from loadreptable;
+count(*)
+3
+"slave"
+select count(*) from loadreptable;
+count(*)
+3
+call MAJ();
+"master"
+select count(*) from loadreptable;
+count(*)
+3
+"slave"
+select count(*) from loadreptable;
+count(*)
+3
+call MAJ();
+"master"
+select count(*) from loadreptable;
+count(*)
+3
+"slave"
+select count(*) from loadreptable;
+count(*)
+3
+call MAJ();
+"master"
+select count(*) from loadreptable;
+count(*)
+3
+"slave"
+select count(*) from loadreptable;
+count(*)
+3
+call MAJ();
+"master"
+select count(*) from loadreptable;
+count(*)
+3
+"slave"
+select count(*) from loadreptable;
+count(*)
+3
+call MAJ();
+"master"
+select count(*) from loadreptable;
+count(*)
+3
+"slave"
+select count(*) from loadreptable;
+count(*)
+3
+call MAJ();
+"master"
+select count(*) from loadreptable;
+count(*)
+3
+"slave"
+select count(*) from loadreptable;
+count(*)
+3
+call MAJ();
+"master"
+select count(*) from loadreptable;
+count(*)
+3
+"slave"
+select count(*) from loadreptable;
+count(*)
+3
+drop table loadreptable;
+drop procedure MAJ;
+include/rpl_end.inc
=== added file 'mysql-test/suite/ndb_rpl/t/ndb_rpl_bug_13440282.test'
--- a/mysql-test/suite/ndb_rpl/t/ndb_rpl_bug_13440282.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb_rpl/t/ndb_rpl_bug_13440282.test 2011-12-23 14:34:57 +0000
@@ -0,0 +1,53 @@
+--source include/have_ndb.inc
+--source include/have_binlog_format_mixed_or_row.inc
+--source suite/ndb_rpl/ndb_master-slave.inc
+
+CREATE TABLE `loadreptable` (
+ `nid` int(11) NOT NULL,
+ `nom` char(255) DEFAULT NULL,
+ `prenom` char(255) DEFAULT NULL,
+ `abc` char(255) DEFAULT NULL,
+ `wkz` char(255) DEFAULT NULL,
+ `xyz` char(255) DEFAULT NULL,
+ PRIMARY KEY (`nid`) USING HASH
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
+
+delimiter //;
+CREATE PROCEDURE MAJ ()
+BEGIN
+DECLARE fini INT default 0;
+WHILE fini < 20 DO
+DELETE FROM loadreptable WHERE nid > 2;
+UPDATE loadreptable SET nid=nid+1 ORDER BY nid DESC;
+UPDATE loadreptable SET
+nom="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxx";
+INSERT INTO loadreptable VALUES(1,"w","t","y","k","b");
+SET fini=fini+1;
+END WHILE;
+END ;
+//
+delimiter ;//
+
+--sync_slave_with_master
+
+let $i=10;
+while ($i)
+{
+ --connection master
+ call MAJ();
+ --echo "master"
+ select count(*) from loadreptable;
+ --sync_slave_with_master
+ --connection slave
+ --echo "slave"
+ select count(*) from loadreptable;
+ dec $i;
+}
+
+--connection master
+drop table loadreptable;
+drop procedure MAJ;
+
+--sync_slave_with_master
+--source include/rpl_end.inc
=== modified file 'storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp 2011-12-01 13:47:41 +0000
+++ b/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp 2011-12-23 17:07:44 +0000
@@ -2345,6 +2345,17 @@ Dbacc::removerow(Uint32 opPtrI, const Lo
/* Mark element disappeared */
opbits |= Operationrec::OP_ELEMENT_DISAPPEARED;
opbits &= ~Uint32(Operationrec::OP_COMMIT_DELETE_CHECK);
+
+ /**
+ * This function is (currently?) only used when refreshTuple()
+ * inserts a record...and later wants to remove it
+ *
+ * Since this should not affect row-count...we change the optype to UPDATE
+ * execACC_COMMITREQ will be called in same timeslice as this change...
+ */
+ opbits &= ~Uint32(Operationrec::OP_MASK);
+ opbits |= ZUPDATE;
+
operationRecPtr.p->m_op_bits = opbits;
#ifdef VM_TRACE
@@ -2383,6 +2394,11 @@ void Dbacc::execACC_COMMITREQ(Signal* si
return;
} else {
jam();
+#ifdef ERROR_INSERT
+ ndbrequire(fragrecptr.p->noOfElements > 0);
+#else
+ ndbassert(fragrecptr.p->noOfElements > 0);
+#endif
fragrecptr.p->noOfElements--;
fragrecptr.p->slack += fragrecptr.p->elementLength;
if (fragrecptr.p->slack > fragrecptr.p->slackCheck) {
@@ -2402,16 +2418,6 @@ void Dbacc::execACC_COMMITREQ(Signal* si
}//if
} else {
jam(); /* EXPAND PROCESS HANDLING */
- if (unlikely(opbits & Operationrec::OP_ELEMENT_DISAPPEARED))
- {
- jam();
- /* Commit of refresh of non existing tuple.
- * ZREFRESH->ZWRITE->ZINSERT
- * Do not affect element count
- */
- ndbrequire((opbits & Operationrec::OP_MASK) == ZINSERT);
- return;
- }
fragrecptr.p->noOfElements++;
fragrecptr.p->slack -= fragrecptr.p->elementLength;
if (fragrecptr.p->slack >= (1u << 31)) {
=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2011-11-28 08:27:10 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2011-12-23 17:07:44 +0000
@@ -4617,11 +4617,11 @@ void Dblqh::execLQHKEYREQ(Signal* signal
nextPos += 2;
}
+ regTcPtr->m_fire_trig_pass = 0;
Uint32 Tdeferred = LqhKeyReq::getDeferredConstraints(Treqinfo);
if (isLongReq && Tdeferred)
{
regTcPtr->m_flags |= TcConnectionrec::OP_DEFERRED_CONSTRAINTS;
- regTcPtr->m_fire_trig_pass = 0;
}
UintR TitcKeyLen = 0;
@@ -11910,6 +11910,12 @@ Uint32 Dblqh::sendKeyinfo20(Signal* sign
#endif
const bool longable = true; // TODO is_api && !old_dest;
+ if (isNdbMtLqh())
+ {
+ jam();
+ nodeId = 0; // prevent execute direct
+ }
+
Uint32 * dst = keyInfo->keyData;
dst += nodeId == getOwnNodeId() ? 0 : KeyInfo20::DataLength;
@@ -11943,11 +11949,6 @@ Uint32 Dblqh::sendKeyinfo20(Signal* sign
{
jam();
- if (isNdbMtLqh() && instance() != refToInstance(ref))
- {
- jam();
- nodeId = 0; // prevent execute direct
- }
if (nodeId == getOwnNodeId())
{
EXECUTE_DIRECT(refToBlock(ref), GSN_KEYINFO20, signal,
=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp 2011-07-05 12:46:07 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp 2011-12-23 17:07:44 +0000
@@ -741,6 +741,7 @@ Dbtup::checkDeferredTriggersDuringPrepar
NoOfFiredTriggers::setDeferredBit(req_struct->no_fired_triggers);
return;
}
+ triggerList.next(trigPtr);
}
}
=== modified file 'storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp 2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp 2011-12-23 08:29:16 +0000
@@ -259,6 +259,11 @@ struct Tup_varsize_page
{
return ((get_index_word(page_idx) & FREE) != 0) ? true : false;
}
+
+ bool is_empty() const
+ {
+ return high_index == 1;
+ }
};
NdbOut& operator<< (NdbOut& out, const Tup_varsize_page& page);
=== modified file 'storage/ndb/src/kernel/vm/CMakeLists.txt'
--- a/storage/ndb/src/kernel/vm/CMakeLists.txt 2011-09-16 13:53:33 +0000
+++ b/storage/ndb/src/kernel/vm/CMakeLists.txt 2011-12-23 17:22:50 +0000
@@ -67,3 +67,13 @@ SET_TARGET_PROPERTIES(mt_thr_config-t
PROPERTIES COMPILE_FLAGS "-DTEST_MT_THR_CONFIG")
TARGET_LINK_LIBRARIES(mt_thr_config-t ndbgeneral)
+ADD_EXECUTABLE(DynArr256-t DynArr256.cpp test_context.cpp)
+SET_TARGET_PROPERTIES(DynArr256-t
+ PROPERTIES COMPILE_FLAGS "-DTAP_TEST")
+TARGET_LINK_LIBRARIES(DynArr256-t ndbkernel ndbsched ndberror
+ ndbtransport
+ ndbmgmcommon
+ ndbmgmapi
+ ndbportlib
+ ndbgeneral)
+
=== modified file 'storage/ndb/src/kernel/vm/DLList.hpp'
--- a/storage/ndb/src/kernel/vm/DLList.hpp 2011-02-01 21:05:11 +0000
+++ b/storage/ndb/src/kernel/vm/DLList.hpp 2011-12-23 08:27:36 +0000
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2003, 2010, 2011 Oracle and/or its affiliates. All rights reserved.
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
@@ -21,13 +21,32 @@
#include "ArrayPool.hpp"
/**
- * Template class used for implementing an
- * list of object retreived from a pool
+ * DLMList implements a intrusive list using chaining
+ * (with a double links)
+ *
+ * The entries in the (uninstansiated) meta class passed to the
+ * list must have the following methods:
+ *
+ * -# nextList(U&) returning a reference to the next link
+ * -# prevList(U&) returning a reference to the prev link
*/
-template <typename P, typename T, typename U = T>
-class DLListImpl
+
+template <typename T, typename U = T> struct DLListDefaultMethods {
+static inline Uint32& nextList(U& t) { return t.nextList; }
+static inline Uint32& prevList(U& t) { return t.prevList; }
+};
+
+template <typename P, typename T, typename M = DLListDefaultMethods<T> >
+class DLMList
{
public:
+ explicit DLMList(P& thePool);
+ ~DLMList() { }
+private:
+ DLMList(const DLMList&);
+ DLMList& operator=(const DLMList&);
+
+public:
/**
* List head
*/
@@ -55,8 +74,6 @@ public:
}
};
- DLListImpl(P& thePool);
-
/**
* Allocate an object from pool - update Ptr
*
@@ -169,12 +186,12 @@ protected:
P & thePool;
};
-template <typename P, typename T, typename U = T>
-class LocalDLListImpl : public DLListImpl<P,T,U>
+template <typename P, typename T, typename M = DLListDefaultMethods<T> >
+class LocalDLMList : public DLMList<P, T, M>
{
public:
- LocalDLListImpl(P & thePool, typename DLListImpl<P,T,U>::HeadPOD & _src)
- : DLListImpl<P,T,U>(thePool), src(_src)
+ LocalDLMList(P& thePool, typename DLMList<P, T, M>::HeadPOD& _src)
+ : DLMList<P, T, M>(thePool), src(_src)
{
this->head = src;
#ifdef VM_TRACE
@@ -183,19 +200,20 @@ public:
#endif
}
- ~LocalDLListImpl(){
+ ~LocalDLMList()
+ {
#ifdef VM_TRACE
assert(src.in_use == true);
#endif
src = this->head;
}
private:
- typename DLListImpl<P,T,U>::HeadPOD & src;
+ typename DLMList<P, T, M>::HeadPOD& src;
};
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
-DLListImpl<P,T,U>::DLListImpl(P & _pool)
+DLMList<P, T, M>::DLMList(P& _pool)
: thePool(_pool)
{
// Require user defined constructor on T since we fiddle
@@ -203,9 +221,9 @@ DLListImpl<P,T,U>::DLListImpl(P & _pool)
ASSERT_TYPE_HAS_CONSTRUCTOR(T);
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
-DLListImpl<P,T,U>::Head::Head()
+DLMList<P, T, M>::Head::Head()
{
this->init();
}
@@ -215,10 +233,10 @@ DLListImpl<P,T,U>::Head::Head()
*
* Return i
*/
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-DLListImpl<P,T,U>::seize(Ptr<T> & p)
+DLMList<P, T, M>::seize(Ptr<T>& p)
{
if (likely(thePool.seize(p)))
{
@@ -233,10 +251,10 @@ DLListImpl<P,T,U>::seize(Ptr<T> & p)
*
* Return i
*/
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-DLListImpl<P,T,U>::seizeId(Ptr<T> & p, Uint32 ir)
+DLMList<P, T, M>::seizeId(Ptr<T>& p, Uint32 ir)
{
if (likely(thePool.seizeId(p, ir)))
{
@@ -246,75 +264,75 @@ DLListImpl<P,T,U>::seizeId(Ptr<T> & p, U
return false;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-DLListImpl<P,T,U>::findId(Uint32 i) const
+DLMList<P, T, M>::findId(Uint32 i) const
{
return thePool.findId(i);
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-DLListImpl<P,T,U>::add(Ptr<T> & p)
+DLMList<P, T, M>::add(Ptr<T>& p)
{
T * t = p.p;
Uint32 ff = head.firstItem;
- t->U::nextList = ff;
- t->U::prevList = RNIL;
+ M::nextList(*t) = ff;
+ M::prevList(*t) = RNIL;
head.firstItem = p.i;
if(ff != RNIL)
{
T * t2 = thePool.getPtr(ff);
- t2->U::prevList = p.i;
+ M::prevList(*t2) = p.i;
}
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-DLListImpl<P,T,U>::add(Uint32 first, Ptr<T> & lastPtr)
+DLMList<P, T, M>::add(Uint32 first, Ptr<T>& lastPtr)
{
Uint32 ff = head.firstItem;
head.firstItem = first;
- lastPtr.p->U::nextList = ff;
+ M::nextList(*lastPtr.p) = ff;
if(ff != RNIL)
{
T * t2 = thePool.getPtr(ff);
- t2->U::prevList = lastPtr.i;
+ M::prevList(*t2) = lastPtr.i;
}
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-DLListImpl<P,T,U>::remove(Ptr<T> & p)
+DLMList<P, T, M>::remove(Ptr<T>& p)
{
remove(p.p);
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-DLListImpl<P,T,U>::remove(T * p)
+DLMList<P, T, M>::remove(T * p)
{
T * t = p;
- Uint32 ni = t->U::nextList;
- Uint32 pi = t->U::prevList;
+ Uint32 ni = M::nextList(*t);
+ Uint32 pi = M::prevList(*t);
if(ni != RNIL){
T * tn = thePool.getPtr(ni);
- tn->U::prevList = pi;
+ M::prevList(*tn) = pi;
}
if(pi != RNIL){
T * tp = thePool.getPtr(pi);
- tp->U::nextList = ni;
+ M::nextList(*tp) = ni;
} else {
head.firstItem = ni;
}
@@ -323,10 +341,10 @@ DLListImpl<P,T,U>::remove(T * p)
/**
* Return an object to pool
*/
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-DLListImpl<P,T,U>::release(Uint32 i)
+DLMList<P, T, M>::release(Uint32 i)
{
Ptr<T> p;
p.i = i;
@@ -337,60 +355,60 @@ DLListImpl<P,T,U>::release(Uint32 i)
/**
* Return an object to pool
*/
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-DLListImpl<P,T,U>::release(Ptr<T> & p)
+DLMList<P, T, M>::release(Ptr<T>& p)
{
remove(p);
thePool.release(p);
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-DLListImpl<P,T,U>::release()
+DLMList<P, T, M>::release()
{
Ptr<T> ptr;
Uint32 curr = head.firstItem;
while(curr != RNIL)
{
thePool.getPtr(ptr, curr);
- curr = ptr.p->U::nextList;
+ curr = M::nextList(*ptr.p);
thePool.release(ptr);
}
head.firstItem = RNIL;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-DLListImpl<P,T,U>::remove()
+DLMList<P, T, M>::remove()
{
head.firstItem = RNIL;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-DLListImpl<P,T,U>::getPtr(Ptr<T> & p, Uint32 i) const
+DLMList<P, T, M>::getPtr(Ptr<T>& p, Uint32 i) const
{
p.i = i;
p.p = thePool.getPtr(i);
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-DLListImpl<P,T,U>::getPtr(Ptr<T> & p) const
+DLMList<P, T, M>::getPtr(Ptr<T>& p) const
{
thePool.getPtr(p);
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
T *
-DLListImpl<P,T,U>::getPtr(Uint32 i) const
+DLMList<P, T, M>::getPtr(Uint32 i) const
{
return thePool.getPtr(i);
}
@@ -400,10 +418,10 @@ DLListImpl<P,T,U>::getPtr(Uint32 i) cons
*
* Return i
*/
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-DLListImpl<P,T,U>::first(Ptr<T> & p) const
+DLMList<P, T, M>::first(Ptr<T>& p) const
{
Uint32 i = head.firstItem;
p.i = i;
@@ -416,12 +434,12 @@ DLListImpl<P,T,U>::first(Ptr<T> & p) con
return false;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-DLListImpl<P,T,U>::next(Ptr<T> & p) const
+DLMList<P, T, M>::next(Ptr<T>& p) const
{
- Uint32 i = p.p->U::nextList;
+ Uint32 i = M::nextList(*p.p);
p.i = i;
if(i != RNIL){
p.p = thePool.getPtr(i);
@@ -431,28 +449,42 @@ DLListImpl<P,T,U>::next(Ptr<T> & p) cons
return false;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-DLListImpl<P,T,U>::hasNext(const Ptr<T> & p) const
+DLMList<P, T, M>::hasNext(const Ptr<T>& p) const
{
- return p.p->U::nextList != RNIL;
+ return M::nextList(*p.p) != RNIL;
}
// Specializations
-template <typename T, typename U = T>
-class DLList : public DLListImpl<ArrayPool<T>, T, U>
+template <typename P, typename T, typename U = T, typename M = DLListDefaultMethods<T, U> >
+class DLListImpl : public DLMList<P, T, M >
+{
+public:
+ DLListImpl(P& p) : DLMList<P, T, M >(p) {}
+};
+
+template <typename P, typename T, typename U = T, typename M = DLListDefaultMethods<T, U> >
+class LocalDLListImpl : public LocalDLMList<P, T, M > {
+public:
+ LocalDLListImpl(P& p, typename DLMList<P, T, M>::HeadPOD& _src)
+ : LocalDLMList<P, T, M>(p, _src) {}
+};
+
+template <typename T, typename U = T, typename M = DLListDefaultMethods<T, U> >
+class DLList : public DLMList<ArrayPool<T>, T, M >
{
public:
- DLList(ArrayPool<T> & p) : DLListImpl<ArrayPool<T>, T, U>(p) {}
+ DLList(ArrayPool<T>& p) : DLMList<ArrayPool<T>, T, M >(p) {}
};
-template <typename T, typename U = T>
-class LocalDLList : public LocalDLListImpl<ArrayPool<T>, T, U> {
+template <typename T, typename U = T, typename M = DLListDefaultMethods<T, U> >
+class LocalDLList : public LocalDLMList<ArrayPool<T>, T, M > {
public:
- LocalDLList(ArrayPool<T> & p, typename DLList<T,U>::HeadPOD & _src)
- : LocalDLListImpl<ArrayPool<T>, T, U>(p, _src) {}
+ LocalDLList(ArrayPool<T>& p, typename DLList<T, U, M>::HeadPOD& _src)
+ : LocalDLMList<ArrayPool<T>, T, M>(p, _src) {}
};
#endif
=== modified file 'storage/ndb/src/kernel/vm/DynArr256.cpp'
--- a/storage/ndb/src/kernel/vm/DynArr256.cpp 2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/kernel/vm/DynArr256.cpp 2011-12-23 17:22:50 +0000
@@ -637,20 +637,6 @@ DynArr256Pool::release(Uint32 ptrI)
#ifdef UNIT_TEST
-#include <NdbTick.h>
-#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[])
@@ -759,7 +745,7 @@ read(DynArr256& arr, int argc, char ** a
Uint32 seed = time(0);
Uint32 seq = 0, seqmask = 0;
- for (Uint32 i = 2; i<argc; i++)
+ for (Uint32 i = 1; i<argc; i++)
{
if (strncmp(argv[i], "--mbytes=", sizeof("--mbytes=")-1) == 0)
{
@@ -831,7 +817,7 @@ write(DynArr256& arr, int argc, char **
Uint64 mbytes = 16*1024;
Uint32 seed = time(0);
- for (Uint32 i = 2; i<argc; i++)
+ for (Uint32 i = 1; i<argc; i++)
{
if (strncmp(argv[i], "--mbytes=", sizeof("--mbytes=")-1) == 0)
{
@@ -888,32 +874,30 @@ write(DynArr256& arr, int argc, char **
}
}
+static
+void
+usage(FILE *f, int argc, char **argv)
+{
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, "\t%s --simple <index1> <index2> ... <indexN>\n", argv[0]);
+ fprintf(stderr, "\t%s --basic\n", argv[0]);
+ fprintf(stderr, "\t%s { --read | --write } [ --mbytes=<megabytes> | --mbytes=<gigabytes>[gG] ] [ --cnt=<count> ] [ --seq ]\n", argv[0]);
+ fprintf(stderr, "defaults:\n");
+ fprintf(stderr, "\t--mbytes=16g\n");
+ fprintf(stderr, "\t--cnt=100000\n");
+}
+
+# include "test_context.hpp"
+
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;
+ if (argc == 1) {
+ usage(stderr, argc, argv);
+ exit(2);
}
- 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();
- }
+ Pool_context pc = test_context(10000 /* pages */);
DynArr256Pool pool;
pool.init(0x2001, pc);
@@ -922,13 +906,18 @@ main(int argc, char** argv)
DynArr256 arr(pool, head);
if (strcmp(argv[1], "--simple") == 0)
- simple(arr, argc, argv);
+ simple(arr, argc - 1, argv + 1);
else if (strcmp(argv[1], "--basic") == 0)
- basic(arr, argc, argv);
+ basic(arr, argc - 1, argv + 1);
else if (strcmp(argv[1], "--read") == 0)
- read(arr, argc, argv);
+ read(arr, argc - 1, argv + 1);
else if (strcmp(argv[1], "--write") == 0)
- write(arr, argc, argv);
+ write(arr, argc - 1, argv + 1);
+ else
+ {
+ usage(stderr, argc, argv);
+ exit(2);
+ }
DynArr256::ReleaseIterator iter;
arr.init(iter);
@@ -943,75 +932,20 @@ main(int argc, char** argv)
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
-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){
-}
+#endif
-#include <SimBlockList.hpp>
+#ifdef TAP_TEST
+#include <NdbTap.hpp>
+#include "test_context.hpp"
-void
-SimBlockList::unload()
+TAPTEST(DynArr256)
{
+ Pool_context pc = test_context(100);
-}
+ OK(true);
+ return 1;
+}
#endif
=== modified file 'storage/ndb/src/kernel/vm/SLList.hpp'
--- a/storage/ndb/src/kernel/vm/SLList.hpp 2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/kernel/vm/SLList.hpp 2011-12-23 08:27:36 +0000
@@ -1,6 +1,5 @@
/*
- Copyright (C) 2003-2006 MySQL AB
- All rights reserved. Use is subject to license terms.
+ Copyright (C) 2003-2006, 2011 Oracle and/or its affiliates. All rights reserved.
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
@@ -23,13 +22,30 @@
#include <NdbOut.hpp>
/**
- * Template class used for implementing an
- * list of object retreived from a pool
+ * SLMList implements a intrusive list using chaining
+ * (with a single link)
+ *
+ * The entries in the (uninstansiated) meta class passed to the
+ * list must have the following methods:
+ *
+ * -# nextList(U&) returning a reference to the next link
*/
-template <typename P, typename T, typename U = T>
-class SLListImpl
+
+template <typename T, typename U = T> struct SLListDefaultMethods {
+static inline Uint32& nextList(U& t) { return t.nextList; }
+};
+
+template <typename P, typename T, typename M = SLListDefaultMethods<T> >
+class SLMList
{
public:
+ explicit SLMList(P& thePool);
+ ~SLMList() { }
+private:
+ SLMList(const SLMList&);
+ SLMList& operator=(const SLMList&);
+
+public:
/**
* List head
*/
@@ -46,8 +62,6 @@ public:
}
};
- SLListImpl(P & thePool);
-
/**
* Allocate an object from pool - update Ptr
*
@@ -119,7 +133,7 @@ public:
* Add
*/
void add(Ptr<T> & p){
- p.p->U::nextList = head.firstItem;
+ M::nextList(*p.p) = head.firstItem;
head.firstItem = p.i;
}
@@ -142,7 +156,7 @@ public:
while(i != RNIL){
c++;
const T * t = thePool.getPtr(i);
- i = t->U::nextList;
+ i = M::nextList(*t);
}
return c;
}
@@ -168,75 +182,75 @@ protected:
P & thePool;
};
-template <typename P, typename T, typename U = T>
-class LocalSLListImpl : public SLListImpl<P, T, U>
+template <typename P, typename T, typename M = SLListDefaultMethods<T> >
+class LocalSLMList : public SLMList<P, T, M>
{
public:
- LocalSLListImpl(P & thePool, typename SLListImpl<P, T, U>::HeadPOD & _src)
- : SLListImpl<P, T, U>(thePool), src(_src)
+ LocalSLMList(P& thePool, typename SLMList<P, T, M>::HeadPOD& _src)
+ : SLMList<P, T, M>(thePool), src(_src)
{
this->head = src;
}
- ~LocalSLListImpl(){
+ ~LocalSLMList(){
src = this->head;
}
private:
- typename SLListImpl<P, T, U>::HeadPOD & src;
+ typename SLMList<P, T, M>::HeadPOD& src;
};
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
-SLListImpl<P, T, U>::SLListImpl(P & _pool):
+SLMList<P, T, M>::SLMList(P& _pool):
thePool(_pool)
{
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
-SLListImpl<P, T, U>::Head::Head()
+SLMList<P, T, M>::Head::Head()
{
this->init();
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-SLListImpl<P, T, U>::seize(Ptr<T> & p)
+SLMList<P, T, M>::seize(Ptr<T>& p)
{
thePool.seize(p);
T * t = p.p;
Uint32 ff = head.firstItem;
if(p.i != RNIL)
{
- t->U::nextList = ff;
+ M::nextList(*t) = ff;
head.firstItem = p.i;
return true;
}
return false;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-SLListImpl<P, T, U>::seizeId(Ptr<T> & p, Uint32 ir)
+SLMList<P, T, M>::seizeId(Ptr<T>& p, Uint32 ir)
{
thePool.seizeId(p, ir);
T * t = p.p;
Uint32 ff = head.firstItem;
if(p.i != RNIL)
{
- t->U::nextList = ff;
+ M::nextList(*t) = ff;
head.firstItem = p.i;
return true;
}
return false;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-SLListImpl<P, T, U>::seizeN(Ptr<T> & p, Uint32 n)
+SLMList<P, T, M>::seizeN(Ptr<T>& p, Uint32 n)
{
for(Uint32 i = 0; i < n; i++)
{
@@ -249,7 +263,7 @@ SLListImpl<P, T, U>::seizeN(Ptr<T> & p,
{
p.i = head.firstItem;
thePool.getPtr(p);
- head.firstItem = p.p->U::nextList;
+ head.firstItem = M::nextList(*p.p);
thePool.release(p);
}
return false;
@@ -266,75 +280,75 @@ SLListImpl<P, T, U>::seizeN(Ptr<T> & p,
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-SLListImpl<P, T, U>::remove()
+SLMList<P, T, M>::remove()
{
head.firstItem = RNIL;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-SLListImpl<P, T, U>::remove_front(Ptr<T> & p)
+SLMList<P, T, M>::remove_front(Ptr<T>& p)
{
p.i = head.firstItem;
if (p.i != RNIL)
{
p.p = thePool.getPtr(p.i);
- head.firstItem = p.p->U::nextList;
+ head.firstItem = M::nextList(*p.p);
return true;
}
return false;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-SLListImpl<P, T, U>::add(Uint32 first, Ptr<T> & last)
+SLMList<P, T, M>::add(Uint32 first, Ptr<T>& last)
{
- last.p->U::nextList = head.firstItem;
+ M::nextList(*last.p) = head.firstItem;
head.firstItem = first;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-SLListImpl<P, T, U>::release()
+SLMList<P, T, M>::release()
{
Ptr<T> ptr;
Uint32 curr = head.firstItem;
while(curr != RNIL)
{
thePool.getPtr(ptr, curr);
- curr = ptr.p->U::nextList;
+ curr = M::nextList(*ptr.p);
thePool.release(ptr);
}
head.firstItem = RNIL;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-SLListImpl<P, T, U>::getPtr(Ptr<T> & p, Uint32 i) const
+SLMList<P, T, M>::getPtr(Ptr<T>& p, Uint32 i) const
{
p.i = i;
p.p = thePool.getPtr(i);
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
void
-SLListImpl<P, T, U>::getPtr(Ptr<T> & p) const
+SLMList<P, T, M>::getPtr(Ptr<T>& p) const
{
thePool.getPtr(p);
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
T *
-SLListImpl<P, T, U>::getPtr(Uint32 i) const
+SLMList<P, T, M>::getPtr(Uint32 i) const
{
return thePool.getPtr(i);
}
@@ -344,10 +358,10 @@ SLListImpl<P, T, U>::getPtr(Uint32 i) co
*
* Return i
*/
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-SLListImpl<P, T, U>::first(Ptr<T> & p) const
+SLMList<P, T, M>::first(Ptr<T>& p) const
{
Uint32 i = head.firstItem;
p.i = i;
@@ -360,12 +374,12 @@ SLListImpl<P, T, U>::first(Ptr<T> & p) c
return false;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-SLListImpl<P, T, U>::next(Ptr<T> & p) const
+SLMList<P, T, M>::next(Ptr<T>& p) const
{
- Uint32 i = p.p->U::nextList;
+ Uint32 i = M::nextList(*p.p);
p.i = i;
if(i != RNIL)
{
@@ -376,28 +390,44 @@ SLListImpl<P, T, U>::next(Ptr<T> & p) co
return false;
}
-template <typename P, typename T, typename U>
+template <typename P, typename T, typename M>
inline
bool
-SLListImpl<P, T, U>::hasNext(const Ptr<T> & p) const
+SLMList<P, T, M>::hasNext(const Ptr<T>& p) const
{
- return p.p->U::nextList != RNIL;
+ return M::nextList(*p.p) != RNIL;
}
// Specializations
-template <typename T, typename U = T>
-class SLList : public SLListImpl<ArrayPool<T>, T, U>
+template <typename P, typename T, typename U = T, typename M = SLListDefaultMethods<T, U> >
+class SLListImpl : public SLMList<P, T, M>
+{
+public:
+ SLListImpl(P& p) : SLMList<P, T, M>(p) {}
+};
+
+template <typename P, typename T, typename U = T, typename M = SLListDefaultMethods<T, U> >
+class LocalSLListImpl : public LocalSLMList<P, T, M> {
+public:
+ LocalSLListImpl(P& p, typename SLMList<P, T, M>::Head& _src)
+ : LocalSLMList<P, T, M>(p, _src) {}
+};
+
+//
+
+template <typename T, typename U = T, typename M = SLListDefaultMethods<T, U> >
+class SLList : public SLMList<ArrayPool<T>, T, M>
{
public:
- SLList(ArrayPool<T> & p) : SLListImpl<ArrayPool<T>, T, U>(p) {}
+ SLList(ArrayPool<T>& p) : SLMList<ArrayPool<T>, T, M>(p) {}
};
-template <typename T, typename U = T>
-class LocalSLList : public LocalSLListImpl<ArrayPool<T>,T,U> {
+template <typename T, typename U = T, typename M = SLListDefaultMethods<T, U> >
+class LocalSLList : public LocalSLMList<ArrayPool<T>, T, M> {
public:
- LocalSLList(ArrayPool<T> & p, typename SLList<T,U>::Head & _src)
- : LocalSLListImpl<ArrayPool<T>,T,U>(p, _src) {}
+ LocalSLList(ArrayPool<T>& p, typename SLMList<ArrayPool<T>, T, M>::Head& _src)
+ : LocalSLMList<ArrayPool<T>, T, M>(p, _src) {}
};
=== added file 'storage/ndb/src/kernel/vm/test_context.cpp'
--- a/storage/ndb/src/kernel/vm/test_context.cpp 1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/kernel/vm/test_context.cpp 2011-12-23 08:47:48 +0000
@@ -0,0 +1,104 @@
+/*
+ Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+ 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; version 2 of the License.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "blocks/dbdih/Dbdih.hpp"
+#include "GlobalData.hpp"
+#include "ndbapi/NdbApi.hpp"
+#include "ndbd_malloc_impl.hpp"
+#include "NdbTick.h"
+#include "SimBlockList.hpp"
+#include "SimulatedBlock.hpp"
+#include "test_context.hpp"
+
+struct DummyBlock : public SimulatedBlock
+{
+ DummyBlock(int no, Block_context& ctx) : SimulatedBlock(no, ctx) {}
+ ~DummyBlock() { }
+};
+
+static Ndbd_mem_manager mm;
+static Configuration cfg;
+static Block_context ctx(cfg, mm);
+static DummyBlock block(DBACC, ctx);
+
+// Force enough modules from libkernel that libsched need
+static SimulatedBlock::MutexManager mxm(block);
+static SafeCounterManager scm(block);
+
+Pool_context
+test_context(Uint32 pages)
+{
+ ndb_init();
+
+ Pool_context pc;
+ pc.m_block = █
+
+ Resource_limit rl;
+ for (Uint32 resid = 1; resid < RG_COUNT; resid++)
+ {
+ rl.m_min = 0;
+ rl.m_max = 0;
+ rl.m_resource_id = resid;
+ mm.set_resource_limit(rl);
+ }
+ rl.m_min = 0;
+ rl.m_max = pages;
+ rl.m_resource_id = 0;
+ mm.set_resource_limit(rl);
+
+ if (!mm.init(NULL /* watchCounter */))
+ {
+ abort();
+ }
+
+ mm.map(NULL /* watchCounter */, 0 /* memlock */); // Map all
+
+ return pc;
+}
+
+void dummy_calls_to_force_some_modules_from_libkernel_needed_by_libsched()
+{
+ globalData.getBlock(0,0);
+ Ndbinfo::getNumTables();
+}
+
+// Some undefined globals needed
+
+Uint32 g_currentStartPhase;
+Uint32 g_start_type;
+NdbNodeBitmask g_nowait_nodes;
+
+void
+SimBlockList::unload()
+{
+
+}
+
+void
+NdbShutdown(int error_code,
+ NdbShutdownType type,
+ NdbRestartType restartType)
+{
+ abort();
+}
+
+Uint32
+Dbdih::dihGetInstanceKey(Uint32 tabId, Uint32 fragId)
+{
+ abort();
+ return 0;
+}
=== added file 'storage/ndb/src/kernel/vm/test_context.hpp'
--- a/storage/ndb/src/kernel/vm/test_context.hpp 1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/kernel/vm/test_context.hpp 2011-12-23 08:47:48 +0000
@@ -0,0 +1,25 @@
+# ifndef TESTBLOCK_HPP
+# define TESTBLOCK_HPP
+
+/*
+ Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+ 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; version 2 of the License.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "Pool.hpp"
+
+Pool_context test_context(Uint32 pages);
+
+# endif
=== modified file 'storage/ndb/test/ndbapi/testNodeRestart.cpp'
--- a/storage/ndb/test/ndbapi/testNodeRestart.cpp 2011-12-16 14:54:50 +0000
+++ b/storage/ndb/test/ndbapi/testNodeRestart.cpp 2011-12-23 17:07:44 +0000
@@ -2594,6 +2594,9 @@ runBug34216(NDBT_Context* ctx, NDBT_Step
while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped())
{
+ if (i > 0 && ctx->closeToTimeout(100 / loops))
+ break;
+
int id = lastId % restarter.getNumDbNodes();
int nodeId = restarter.getDbNodeId(id);
int err = 5048 + ((i+offset) % 2);
=== modified file 'storage/ndb/test/ndbapi/testSystemRestart.cpp'
--- a/storage/ndb/test/ndbapi/testSystemRestart.cpp 2011-12-20 08:49:07 +0000
+++ b/storage/ndb/test/ndbapi/testSystemRestart.cpp 2011-12-23 17:07:44 +0000
@@ -1405,7 +1405,7 @@ int runSR_DD_1(NDBT_Context* ctx, NDBT_S
HugoTransactions hugoTrans(*ctx->getTab());
while(i<=loops && result != NDBT_FAILED)
{
- if (i > 0 && ctx->closeToTimeout(15))
+ if (i > 0 && ctx->closeToTimeout(30))
break;
if (lcploop)
@@ -1510,7 +1510,7 @@ int runSR_DD_2(NDBT_Context* ctx, NDBT_S
HugoTransactions hugoTrans(*ctx->getTab());
while(i<=loops && result != NDBT_FAILED)
{
- if (i > 0 && ctx->closeToTimeout(15))
+ if (i > 0 && ctx->closeToTimeout(30))
break;
if (lcploop)
@@ -1616,7 +1616,7 @@ int runSR_DD_3(NDBT_Context* ctx, NDBT_S
HugoTransactions hugoTrans(*ctx->getTab());
while(i<=loops && result != NDBT_FAILED)
{
- if (i > 0 && ctx->closeToTimeout(15))
+ if (i > 0 && ctx->closeToTimeout(30))
break;
if (lcploop)
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-5.5-cluster-7.2 branch (jonas.oreland:3743) | jonas oreland | 25 Dec |