summaryrefslogtreecommitdiff
path: root/storage/ndb/src/kernel/vm/al_test/arrayPoolTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/ndb/src/kernel/vm/al_test/arrayPoolTest.cpp')
-rw-r--r--storage/ndb/src/kernel/vm/al_test/arrayPoolTest.cpp298
1 files changed, 298 insertions, 0 deletions
diff --git a/storage/ndb/src/kernel/vm/al_test/arrayPoolTest.cpp b/storage/ndb/src/kernel/vm/al_test/arrayPoolTest.cpp
new file mode 100644
index 00000000000..e80905121e1
--- /dev/null
+++ b/storage/ndb/src/kernel/vm/al_test/arrayPoolTest.cpp
@@ -0,0 +1,298 @@
+/* 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 <ndb_global.h>
+
+#include <ArrayList.hpp>
+#include <NdbOut.hpp>
+#include <NdbTick.h>
+
+struct A_Poolable_Object {
+ Uint32 next;
+ char somedata[12];
+
+ void print (NdbOut & out) {
+ out << "A_Poolable_Object: next = " << next << endl;
+ }
+
+};
+
+
+NdbOut &
+operator<<(NdbOut & o, A_Poolable_Object & a){
+ a.print(o);
+ return o;
+}
+
+typedef Ptr<A_Poolable_Object> A_Poolable_ObjectPtr;
+#if 1
+#define BPool ArrayPool<A_Poolable_Object>
+#else
+#define BPool ArrayPool(A_Poolable_Object, next)
+#endif
+
+class ArrayPoolTest {
+public:
+ static void tryPool1(int poolSize, int iterations){
+ BPool aPool;
+
+ if(!aPool.setSize(poolSize)){
+ ndbout << "Failed to do aPool.setSize(" << poolSize << ")" << endl;
+ return;
+ }
+
+ ndbout << "Seizing/Releaseing " << iterations
+ << " times over pool with " << poolSize << " elements" << endl;
+
+ int * anArray = new int[poolSize];
+ int arrayElements = 0;
+
+ int noOfSeize = 0;
+ int noFailSeize = 0;
+ int noOfRelease = 0;
+
+ for(int i = 0; i<iterations; i++){
+ if(!((arrayElements <= poolSize) &&
+ (aPool.noOfFree() == aPool.noOfFree2()) &&
+ (aPool.noOfFree() == (poolSize - arrayElements)))){
+ ndbout << "Assertion!!"
+ << " iteration=" << i << endl;
+ const int f1 = aPool.noOfFree();
+ const int f2 = aPool.noOfFree2();
+ ndbout << "noOfFree() = " << f1 << endl;
+ ndbout << "noOfFree2() = " << f2 << endl;
+ ndbout << "poolSize = " << poolSize << endl;
+ ndbout << "arrayElemts = " << arrayElements << endl;
+ aPool.print(ndbout);
+ assert(0);
+ }
+
+ const int r = rand() % (10 * poolSize);
+ if(r < (arrayElements - 1)){
+ /**
+ * Release an element
+ */
+ noOfRelease++;
+ aPool.release(anArray[r]);
+ arrayElements--;
+ for(int j = r; j<arrayElements; j++)
+ anArray[j] = anArray[j+1];
+
+ } else {
+ /**
+ * Seize an element
+ */
+ A_Poolable_ObjectPtr p;
+ const int ret = aPool.seize(p);
+ if(ret == RNIL && arrayElements != poolSize){
+ ndbout << "Failed to seize!!"
+ << " iteration=" << i << endl;
+ ndbout << "Have seized " << arrayElements
+ << " out of " << poolSize << endl;
+ ndbout << "Terminating..." << endl;
+ abort();
+ }
+ if(arrayElements >= poolSize && ret != RNIL){
+ ndbout << "Seize did not fail when it should have"
+ << " iteration=" << i << endl;
+ ndbout << "Have seized " << arrayElements
+ << " out of " << poolSize << endl;
+ ndbout << "Terminating..." << endl;
+ abort();
+ }
+ if(ret != RNIL){
+ noOfSeize++;
+ anArray[arrayElements] = ret;
+ arrayElements++;
+ memset(p.p, i, sizeof(p.p->somedata));
+ } else {
+ noFailSeize++;
+ }
+ }
+ }
+ delete []anArray;
+
+ ndbout << "Seized: " << noOfSeize
+ << " Seized with buffer full: " << noFailSeize
+ << " Release: " << noOfRelease << " --- ";
+ ndbout << "(" << noOfSeize << " + " << noFailSeize << " + " << noOfRelease
+ << " = " << (noOfSeize + noFailSeize + noOfRelease) << ")" << endl;
+ }
+
+ static void tryPool2(int size, int iter, int fail){
+ BPool aPool;
+
+ if(!aPool.setSize(size)){
+ ndbout << "Failed to do aPool.setSize(" << size << ")" << endl;
+ return;
+ }
+
+ ndbout << "doing getPtr(i) where i > size(" << size << ") "
+ << fail << " times mixed with " << iter
+ << " ordinary seize/release" << endl;
+
+ int * anArray = new int[size];
+ int arrayElements = 0;
+
+ int noOfSeize = 0;
+ int noFailSeize = 0;
+ int noOfRelease = 0;
+
+ for(int i = 0; i<iter; i++){
+ if(!((arrayElements <= size) &&
+ (aPool.noOfFree() == aPool.noOfFree2()) &&
+ (aPool.noOfFree() == (size - arrayElements)))){
+ ndbout << "Assertion!!"
+ << " iteration=" << i << endl;
+ const int f1 = aPool.noOfFree();
+ const int f2 = aPool.noOfFree2();
+ ndbout << "noOfFree() = " << f1 << endl;
+ ndbout << "noOfFree2() = " << f2 << endl;
+ ndbout << "poolSize = " << size << endl;
+ ndbout << "arrayElemts = " << arrayElements << endl;
+ aPool.print(ndbout);
+ assert(0);
+ }
+ const int r = rand() % (10 * size);
+
+ if((i + 1)%(iter/fail) == 0){
+ aPool.getPtr(size + r);
+ continue;
+ }
+
+ if(r < (arrayElements - 1)){
+ /**
+ * Release an element
+ */
+ noOfRelease++;
+ aPool.release(anArray[r]);
+ arrayElements--;
+ for(int j = r; j<arrayElements; j++)
+ anArray[j] = anArray[j+1];
+
+ } else {
+ /**
+ * Seize an element
+ */
+ A_Poolable_ObjectPtr p;
+ const int ret = aPool.seize(p);
+ if(ret == RNIL && arrayElements != size){
+ ndbout << "Failed to seize!!"
+ << " iteration=" << i << endl;
+ ndbout << "Have seized " << arrayElements
+ << " out of " << size << endl;
+ ndbout << "Terminating..." << endl;
+ abort();
+ }
+ if(arrayElements >= size && ret != RNIL){
+ ndbout << "Seize did not fail when it should have"
+ << " iteration=" << i << endl;
+ ndbout << "Have seized " << arrayElements
+ << " out of " << size << endl;
+ ndbout << "Terminating..." << endl;
+ abort();
+ }
+ if(ret != RNIL){
+ noOfSeize++;
+ anArray[arrayElements] = ret;
+ arrayElements++;
+ memset(p.p, p.i, sizeof(p.p->somedata));
+ } else {
+ noFailSeize++;
+ }
+ }
+ }
+ delete []anArray;
+ }
+
+ static void
+ tryPool3(int size, int fail){
+ ndbout << "Failing " << fail << " times " << endl;
+
+ for(int i = 0; i<fail; i++){
+ BPool aPool;
+ if(!aPool.setSize(size)){
+ ndbout << "Failed to do aPool.setSize(" << size << ")" << endl;
+ return;
+ }
+
+ const int noOfElementsInBufferWhenFail = (i + 1) * (size /(fail + 1));
+
+ int * anArray = new int[size];
+ for(int i = 0; i<size; i++)
+ anArray[i] = i;
+ int arrayElements = 0;
+
+ int noOfSeize = 0;
+ int noFailSeize = 0;
+ int noOfRelease = 0;
+
+ while(true){
+ assert(arrayElements <= size);
+ if(arrayElements == noOfElementsInBufferWhenFail){
+ ndbout << "++ You should get a ErrorReporter::handle... " << endl;
+ aPool.release(anArray[arrayElements]);
+ ndbout << "++ Inbetween these lines" << endl << endl;
+ break;
+ }
+ const int r = rand() % (10 * size);
+ if(r < (arrayElements - 1)){
+ /**
+ * Release an element
+ */
+ noOfRelease++;
+ aPool.release(anArray[r]);
+ arrayElements--;
+ for(int j = r; j<arrayElements; j++)
+ anArray[j] = anArray[j+1];
+
+ } else {
+ /**
+ * Seize an element
+ */
+ A_Poolable_ObjectPtr p;
+ const int ret = aPool.seize(p);
+ if(ret == RNIL && arrayElements != size){
+ ndbout << "Failed to seize!!" << endl;
+ ndbout << "Have seized " << arrayElements
+ << " out of " << size << endl;
+ ndbout << "Terminating..." << endl;
+ abort();
+ }
+ if(arrayElements >= size && ret != RNIL){
+ ndbout << "Seize did not fail when it should have" << endl;
+ ndbout << "Have seized " << arrayElements
+ << " out of " << size << endl;
+ ndbout << "Terminating..." << endl;
+ abort();
+ }
+ if(ret != RNIL){
+ noOfSeize++;
+ anArray[arrayElements] = ret;
+ arrayElements++;
+ } else {
+ noFailSeize++;
+ }
+ }
+ }
+ delete []anArray;
+ }
+
+ }
+};
+