You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-10-30 07:25:34 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			1914 lines
		
	
	
		
			57 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1914 lines
		
	
	
		
			57 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* Copyright (C) 2014 InfiniDB, Inc.
 | |
|    Copyright (C) 2016-2021 MariaDB Corporation
 | |
| 
 | |
|    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 Street, Fifth Floor, Boston,
 | |
|    MA 02110-1301, USA. */
 | |
| 
 | |
| /*****************************************************************************
 | |
|  * $Id: tdriver-dbrm2.cpp 1823 2013-01-21 14:13:09Z rdempsey $
 | |
|  *
 | |
|  ****************************************************************************/
 | |
| 
 | |
| #include <iostream>
 | |
| #include <vector>
 | |
| #include <pthread.h>
 | |
| #include <errno.h>
 | |
| #include <sys/types.h>
 | |
| #include <sys/ipc.h>
 | |
| #include <sys/sem.h>
 | |
| #include <sys/shm.h>
 | |
| #include <stdexcept>
 | |
| #include <pthread.h>
 | |
| #include <sys/time.h>
 | |
| #include <values.h>
 | |
| 
 | |
| #include <cppunit/extensions/HelperMacros.h>
 | |
| 
 | |
| #include "brm.h"
 | |
| #include "extentmap.h"
 | |
| #include "IDBPolicy.h"
 | |
| 
 | |
| // #define BRM_VERBOSE 1
 | |
| 
 | |
| using namespace BRM;
 | |
| using namespace std;
 | |
| 
 | |
| int threadStop;
 | |
| int oid = 1;
 | |
| uint64_t opCount = 0;
 | |
| LBID_t lbidCounter = 0;
 | |
| VER_t nextTxnID = 1;
 | |
| u_int64_t vbOffset = 0;
 | |
| pthread_mutex_t pthreadMutex;
 | |
| const std::vector<uint32_t> colWidthsAvailable = {1, 2, 4, 8, 16};
 | |
| const DBRootT dbroot = 1;
 | |
| 
 | |
| struct Range
 | |
| {
 | |
|   LBID_t start, end, nextBlock;
 | |
|   VER_t txnID;
 | |
|   Range()
 | |
|   {
 | |
|     start = end = nextBlock = 0;
 | |
|     txnID = 0;
 | |
|   }
 | |
| };
 | |
| 
 | |
| struct EMEntries
 | |
| {
 | |
|   LBID_t LBIDstart;
 | |
|   uint32_t size;
 | |
|   OID_t OID;
 | |
|   uint32_t FBO;
 | |
|   uint32_t HWM;
 | |
|   uint32_t secondHWM;
 | |
|   int32_t txnID;
 | |
|   DBRootT dbroot;
 | |
|   PartitionNumberT partNum;
 | |
|   SegmentT segNum;
 | |
|   struct EMEntries* next;
 | |
|   EMEntries() : HWM(0), secondHWM(0), txnID(0), next(nullptr)
 | |
|   {
 | |
|   }
 | |
|   EMEntries(const uint32_t aSize, const OID_t aOid, const uint32_t aFbo, const LBID_t aLBIDStart,
 | |
|             EMEntries* aNext)
 | |
|    : LBIDstart(aLBIDStart), size(aSize), OID(aOid), FBO(aFbo), HWM(0), secondHWM(0), txnID(0), next(aNext)
 | |
|   {
 | |
|   }
 | |
|   EMEntries(const uint32_t aSize, const OID_t aOid, const uint32_t aFbo, const LBID_t aLBIDStart,
 | |
|             EMEntries* aNext, const DBRootT aDbroot, const PartitionNumberT aPartNum, const SegmentT aSegNum)
 | |
|    : LBIDstart(aLBIDStart)
 | |
|    , size(aSize)
 | |
|    , OID(aOid)
 | |
|    , FBO(aFbo)
 | |
|    , HWM(0)
 | |
|    , secondHWM(0)
 | |
|    , txnID(0)
 | |
|    , dbroot(aDbroot)
 | |
|    , partNum(aPartNum)
 | |
|    , segNum(aSegNum)
 | |
|    , next(aNext)
 | |
|   {
 | |
|   }
 | |
| };
 | |
| /*
 | |
| static void* BRMRunner_2(void* arg)
 | |
| {
 | |
| 
 | |
|     vector<Range> copyList, copiedList, committedList;
 | |
|     vector<Range>::iterator rit;
 | |
|     vector<LBID_t> writtenList;
 | |
|     vector<LBID_t>::iterator lit;
 | |
| 
 | |
|     pthread_mutex_t listMutex;
 | |
|     int op;
 | |
|     uint32_t randstate;
 | |
|     DBRM* brm;
 | |
|     struct timeval tv;
 | |
|     VER_t txnID;
 | |
| 
 | |
|     pthread_mutex_init(&listMutex, NULL);
 | |
|     gettimeofday(&tv, NULL);
 | |
|     randstate = static_cast<uint32_t>(tv.tv_usec);
 | |
|     brm = new DBRM();
 | |
| 
 | |
|     while (!threadStop)
 | |
|     {
 | |
|         op = rand_r(&randstate) % 9;
 | |
| 
 | |
|         switch (op)
 | |
|         {
 | |
|             case 0:   // beginVBCopy
 | |
|             {
 | |
|                 int blockCount, size, err;
 | |
|                 Range newEntry;
 | |
|                 VBRange_v vbRanges;
 | |
|                 VBRange_v::iterator vit;
 | |
|                 LBIDRange_v ranges;
 | |
|                 LBIDRange range;
 | |
| 
 | |
|                 size = rand_r(&randstate) % 10000;
 | |
| 
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 newEntry.start = lbidCounter;
 | |
|                 lbidCounter += size;
 | |
|                 txnID = nextTxnID++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
| 
 | |
|                 newEntry.nextBlock = newEntry.start;
 | |
|                 newEntry.end = newEntry.start + size;
 | |
|                 range.start = newEntry.start;
 | |
|                 range.size = size;
 | |
| 
 | |
|                 err = brm->beginVBCopy(txnID, dbroot, ranges, vbRanges);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
| 
 | |
|                 for (blockCount = 0, vit = vbRanges.begin(); vit != vbRanges.end(); vit++)
 | |
|                     blockCount += (*vit).size;
 | |
| 
 | |
|                 CPPUNIT_ASSERT(blockCount == size);
 | |
| 
 | |
|                 pthread_mutex_lock(&listMutex);
 | |
|                 copyList.push_back(newEntry);
 | |
|                 pthread_mutex_unlock(&listMutex);
 | |
| 
 | |
|                 err = brm->beginVBCopy(txnID, dbroot, ranges, vbRanges);
 | |
|                 CPPUNIT_ASSERT(err == -1);
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 1:		// writeVBEntry
 | |
|             {
 | |
|                 int randIndex;
 | |
|                 Range* entry;
 | |
| 
 | |
|                 pthread_mutex_lock(&listMutex);
 | |
| 
 | |
|                 if (copyList.size() == 0)
 | |
|                     break;
 | |
| 
 | |
|                 randIndex = rand_r(&randstate) % copyList.size();
 | |
|                 entry = &(copyList[randIndex]);
 | |
|                 entry->nextBlock++;
 | |
|                 txnID = entry->txnID;
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             default:
 | |
|                 cerr << "not finished yet" << endl;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return NULL;
 | |
| }
 | |
| */
 | |
| 
 | |
| /*
 | |
| static void* BRMRunner_1(void* arg)
 | |
| {
 | |
| 
 | |
|     // keep track of LBID ranges allocated here and
 | |
|     // randomly allocate, lookup, delete, get/set HWM, and
 | |
|     // destroy the EM object.
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|     int threadNum = reinterpret_cast<int>(arg);
 | |
| #endif
 | |
|     int op, listSize = 0, i;
 | |
|     uint32_t randstate;
 | |
|     struct EMEntries* head = NULL, *tmp;
 | |
|     struct timeval tv;
 | |
|     DBRM* brm;
 | |
|     ExtentMap em;
 | |
|     vector<LBID_t> lbids;
 | |
|     LBID_t lbid;
 | |
|     uint32_t colWidth;
 | |
|     PartitionNumberT partNum;
 | |
|     SegmentT segmentNum;
 | |
|     execplan::CalpontSystemCatalog::ColDataType colDataType;
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|     cerr << "thread number " << threadNum << " started." << endl;
 | |
| #endif
 | |
| 
 | |
|     gettimeofday(&tv, NULL);
 | |
|     randstate = static_cast<uint32_t>(tv.tv_usec);
 | |
|     brm = new DBRM();
 | |
| 
 | |
| 
 | |
|     while (!threadStop)
 | |
|     {
 | |
|         auto randNumber = rand_r(&randstate);
 | |
|         op = randNumber % 10;
 | |
|         colWidth = colWidthsAvailable[randNumber % colWidthsAvailable.size()];
 | |
|         partNum = randNumber % std::numeric_limits<PartitionNumberT>::max();
 | |
|         segmentNum = randNumber % std::numeric_limits<SegmentT>::max();
 | |
|         colDataType = (execplan::CalpontSystemCatalog::ColDataType) (randNumber %
 | |
| (int)execplan::CalpontSystemCatalog::ColDataType::TIMESTAMP); #ifdef BRM_VERBOSE cerr << "next op is " << op
 | |
| << endl; #endif
 | |
| 
 | |
|         switch (op)
 | |
|         {
 | |
|             case 0:   //allocate space for a new file
 | |
|             {
 | |
|                 struct EMEntries* newEm;
 | |
|                 size_t size = rand_r(&randstate) % 102399 + 1;
 | |
|                 int entries, OID, allocdSize, err;
 | |
|                 uint32_t startBlockOffset;
 | |
| 
 | |
| 
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 OID = oid++;
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 lbids.clear();
 | |
|                 for (size_t i = 0; i < size; ++i)
 | |
|                 {
 | |
|                     err = brm->createColumnExtent_DBroot(OID, colWidth, dbroot,
 | |
|                         partNum, segmentNum, colDataType, lbid, allocdSize, startBlockOffset);
 | |
|                     CPPUNIT_ASSERT(err == 0);
 | |
|                     lbids.push_back(lbid);
 | |
|                 }
 | |
| 
 | |
|                 entries = size / brm->getExtentSize();
 | |
| 
 | |
|                 if ((size % brm->getExtentSize()) != 0)
 | |
|                     entries++;
 | |
| 
 | |
|                 if ((uint32_t)entries != lbids.size())
 | |
|                     cerr << "entries = " << entries << " lbids.size = " << lbids.size() << endl;
 | |
| 
 | |
|                 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
 | |
| 
 | |
|                 for (i = 0 ; i < entries; i++)
 | |
|                 {
 | |
| 
 | |
|                     newEm = new EMEntries(brm->getExtentSize(), OID, brm->getExtentSize(), lbids[i],
 | |
|                         head, dbroot, partNum, segmentNum);
 | |
|                     head = newEm;
 | |
|                     listSize++;
 | |
|                 }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "created new space for OID " << newEm->OID << endl;
 | |
| #endif
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 1:		//allocate space for an existing file
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 struct EMEntries* newEm, *tmp;
 | |
|                 int size = rand_r(&randstate) % 102399 + 1;
 | |
|                 int fileRand = rand_r(&randstate) % listSize;
 | |
|                 int i, lastExtent, blockEnd, oid;
 | |
|                 int tmpHWM, entries, allocdSize, err;
 | |
|                 uint32_t startBlockOffset;
 | |
|                 vector<LBID_t> lbids;
 | |
|                 LBID_t lbid;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < fileRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 oid = tmp->OID;
 | |
| 
 | |
|                 for (lastExtent = 0, tmp = head; tmp != NULL; tmp = tmp->next)
 | |
|                 {
 | |
|                     if (tmp->OID != oid)
 | |
|                         continue;
 | |
| 
 | |
|                     tmpHWM = tmp->HWM;
 | |
|                     blockEnd = tmp->FBO + tmp->size;
 | |
| 
 | |
|                     if (lastExtent < blockEnd)
 | |
|                         lastExtent = blockEnd;
 | |
|                 }
 | |
| 
 | |
|                 err = brm->createColumnExtentExactFile(oid, colWidth, dbroot,
 | |
|                     partNum, segmentNum, colDataType, lbid, allocdSize, startBlockOffset);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
| 
 | |
|                 entries = size / brm->getExtentSize();
 | |
| 
 | |
|                 if ((size % brm->getExtentSize()) != 0)
 | |
|                     entries++;
 | |
| 
 | |
|                 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
 | |
| 
 | |
|                 for (i = 0; i < entries; i++)
 | |
|                 {
 | |
| 
 | |
|                     newEm = new EMEntries((i != entries) ? brm->getExtentSize() : size % brm->getExtentSize(),
 | |
|                        oid, lastExtent + (i * brm->getExtentSize()),
 | |
|                        lbids[i], head, dbroot, partNum, segmentNum);
 | |
|                     newEm->HWM = tmpHWM;
 | |
|                     head = newEm;
 | |
|                     listSize++;
 | |
|                 }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "created another extent for OID " << newEm->OID << endl;
 | |
| #endif
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 2:  			//delete an OID
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 struct EMEntries* tmp, *prev;
 | |
|                 int fileRand = rand_r(&randstate) % listSize;
 | |
|                 int i, oid, err;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < fileRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 oid = tmp->OID;
 | |
| 
 | |
|                 err = brm->deleteOID(oid);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
| 
 | |
|                 for (tmp = head; tmp != NULL;)
 | |
|                 {
 | |
|                     if (tmp->OID == oid)
 | |
|                     {
 | |
|                         if (tmp == head)
 | |
|                         {
 | |
|                             head = head->next;
 | |
|                             delete tmp;
 | |
|                             tmp = head;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             prev->next = tmp->next;
 | |
|                             delete tmp;
 | |
|                             tmp = prev->next;
 | |
|                         }
 | |
| 
 | |
|                         listSize--;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         prev = tmp;
 | |
|                         tmp = tmp->next;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "deleted OID " << oid << endl;
 | |
| #endif
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 3:   //lookup by LBID
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, err, offset, oid;
 | |
|                 struct EMEntries* tmp;
 | |
|                 LBID_t target;
 | |
|                 uint32_t fbo;
 | |
|                 DBRootT localDbroot;
 | |
|                 PartitionNumberT localPartNum;
 | |
|                 SegmentT localSegmentNum;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 offset = rand_r(&randstate) % tmp->size;
 | |
| 
 | |
|                 target = tmp->LBIDstart + offset;
 | |
|                 err = brm->lookupLocal(target, 0, false, oid, localDbroot, localPartNum,
 | |
|                     localSegmentNum, fbo);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "looked up LBID " << target << " got oid " << oid << " fbo " << fbo << endl;
 | |
|                 cerr << "   oid should be " << tmp->OID << " fbo should be " << offset + tmp->FBO << endl;
 | |
| #endif
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
|                 CPPUNIT_ASSERT(oid == tmp->OID);
 | |
|                 CPPUNIT_ASSERT(fbo == offset + tmp->FBO);
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 4:   //lookup by OID, FBO
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, oid, err, offset;
 | |
|                 struct EMEntries* tmp;
 | |
|                 LBID_t lbid;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 offset = rand_r(&randstate) % tmp->size;
 | |
|                 oid = tmp->OID;
 | |
| 
 | |
|                 err = brm->lookupLocal(oid, partNum, segmentNum, offset + tmp->FBO, lbid);
 | |
| 
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "looked up OID " << oid << " fbo " << offset + tmp->FBO <<
 | |
|                      " got lbid " << lbid << endl;
 | |
|                 cerr << "  lbid should be " << tmp->LBIDstart + offset << endl;
 | |
| #endif
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
|                 CPPUNIT_ASSERT(lbid == static_cast<LBID_t>(tmp->LBIDstart + offset));
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 5:		//getHWM
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, err, status;
 | |
|                 struct EMEntries* tmp;
 | |
|                 uint32_t hwm;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
|                 err = brm->getLocalHWM(tmp->OID, partNum, segmentNum, hwm, status);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "stored HWM for OID " << tmp->OID << " is " << tmp->HWM
 | |
|                      << " BRM says it's " << hwm << endl;
 | |
| #endif
 | |
|                 CPPUNIT_ASSERT(hwm == tmp->HWM);
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 6: 		//setHWM
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, hwm, oid, err;
 | |
|                 struct EMEntries* tmp;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 oid = tmp->OID;
 | |
|                 hwm = rand_r(&randstate) % (tmp->FBO + brm->getExtentSize());
 | |
|                 err = brm->setLocalHWM(oid, tmp->partNum, tmp->segNum, hwm);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
| 
 | |
|                 for (tmp = head; tmp != NULL; tmp = tmp->next)
 | |
|                     if (tmp->OID == oid)
 | |
|                         tmp->HWM = hwm;
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "setHWM of OID " << oid << " to " << hwm << endl;
 | |
| #endif
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 7:			// renew this EM object
 | |
|             {
 | |
|                 delete brm;
 | |
|                 brm = new DBRM();
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "got a new BRM instance" << endl;
 | |
| #endif
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| #if 0
 | |
|             case 8:			//getBulkInsertVars
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 HWM_t hwm;
 | |
|                 VER_t txnID;
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, err, offset;
 | |
|                 EMEntries* tmp;
 | |
|                 LBID_t lbid;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 offset = rand_r(&randstate) % tmp->size;
 | |
|                 lbid = tmp->LBIDstart + offset;
 | |
|                 err = brm->getBulkInsertVars(lbid, hwm, txnID);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
|                 CPPUNIT_ASSERT(hwm == tmp->secondHWM);
 | |
|                 CPPUNIT_ASSERT(txnID == tmp->txnID);
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 9:			//setBulkInsertVars
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, err, offset;
 | |
|                 EMEntries* tmp;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 offset = rand_r(&randstate) % tmp->size;
 | |
|                 tmp->secondHWM = rand_r(&randstate) % MAXINT;
 | |
|                 tmp->txnID = rand_r(&randstate) % MAXINT;
 | |
|                 err = brm->setBulkInsertVars(tmp->LBIDstart + offset,
 | |
|                                              tmp->secondHWM, tmp->txnID);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
|                 break;
 | |
|             }
 | |
| #endif
 | |
|             default:
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     delete brm;
 | |
| 
 | |
|     while (head != NULL)
 | |
|     {
 | |
|         tmp = head->next;
 | |
|         delete head;
 | |
|         head = tmp;
 | |
|     }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|     cerr << "thread " << threadNum << " exiting" << endl;
 | |
| #endif
 | |
|     return NULL;
 | |
| }
 | |
| */
 | |
| DBRM brm_si;
 | |
| /*
 | |
| static void* BRMRunner_si(void* arg)
 | |
| {
 | |
| 
 | |
|     // keep track of LBID ranges allocated here and
 | |
|     // randomly allocate, lookup, delete, get/set HWM, and
 | |
|     // destroy the EM object.
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|     int threadNum = reinterpret_cast<int>(arg);
 | |
| #endif
 | |
|     int op, listSize = 0, i;
 | |
|     uint32_t randstate;
 | |
|     struct EMEntries* head = NULL, *tmp;
 | |
|     struct timeval tv;
 | |
|     ExtentMap em;
 | |
|     vector<LBID_t> lbids;
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|     cerr << "thread number " << threadNum << " started." << endl;
 | |
| #endif
 | |
| 
 | |
|     gettimeofday(&tv, NULL);
 | |
|     randstate = static_cast<uint32_t>(tv.tv_usec);
 | |
| 
 | |
|     while (!threadStop)
 | |
|     {
 | |
|         op = rand_r(&randstate) % 10;
 | |
| #ifdef BRM_VERBOSE
 | |
|         cerr << "next op is " << op << endl;
 | |
| #endif
 | |
| 
 | |
|         switch (op)
 | |
|         {
 | |
|             case 0:   //allocate space for a new file
 | |
|             {
 | |
|                 struct EMEntries* newEm;
 | |
|                 int size = rand_r(&randstate) % 102399 + 1;
 | |
|                 int entries, OID, allocdSize, err;
 | |
| 
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 OID = oid++;
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
| 
 | |
|                 err = brm_si.createExtent(size, OID, lbids, allocdSize);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
| 
 | |
|                 entries = size / brm_si.getExtentSize();
 | |
| 
 | |
|                 if ((size % brm_si.getExtentSize()) != 0)
 | |
|                     entries++;
 | |
| 
 | |
|                 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
 | |
| 
 | |
|                 for (i = 0 ; i < entries; i++)
 | |
|                 {
 | |
| 
 | |
|                     newEm = new EMEntries();
 | |
|                     newEm->size = brm_si.getExtentSize();
 | |
|                     newEm->OID = OID;
 | |
|                     newEm->FBO = i * brm_si.getExtentSize();
 | |
|                     newEm->LBIDstart = lbids[i];
 | |
| 
 | |
|                     newEm->next = head;
 | |
|                     head = newEm;
 | |
|                     listSize++;
 | |
|                 }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "created new space for OID " << newEm->OID << endl;
 | |
| #endif
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 1:		//allocate space for an existing file
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 struct EMEntries* newEm, *tmp;
 | |
|                 int size = rand_r(&randstate) % 102399 + 1;
 | |
|                 int fileRand = rand_r(&randstate) % listSize;
 | |
|                 int i, lastExtent, blockEnd, oid;
 | |
|                 int tmpHWM, entries, allocdSize, err;
 | |
|                 vector<LBID_t> lbids;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < fileRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 oid = tmp->OID;
 | |
| 
 | |
|                 for (lastExtent = 0, tmp = head; tmp != NULL; tmp = tmp->next)
 | |
|                 {
 | |
|                     if (tmp->OID != oid)
 | |
|                         continue;
 | |
| 
 | |
|                     tmpHWM = tmp->HWM;
 | |
|                     blockEnd = tmp->FBO + tmp->size;
 | |
| 
 | |
|                     if (lastExtent < blockEnd)
 | |
|                         lastExtent = blockEnd;
 | |
|                 }
 | |
| 
 | |
|                 err = brm_si.createExtent(size, oid, lbids, allocdSize);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
| 
 | |
|                 entries = size / brm_si.getExtentSize();
 | |
| 
 | |
|                 if ((size % brm_si.getExtentSize()) != 0)
 | |
|                     entries++;
 | |
| 
 | |
|                 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
 | |
| 
 | |
|                 for (i = 0; i < entries; i++)
 | |
|                 {
 | |
| 
 | |
|                     newEm = new EMEntries();
 | |
| 
 | |
|                     if (i != entries)
 | |
|                         newEm->size = brm_si.getExtentSize();
 | |
|                     else
 | |
|                         newEm->size = size % brm_si.getExtentSize();
 | |
| 
 | |
|                     newEm->OID = oid;
 | |
|                     newEm->FBO = lastExtent + (i * brm_si.getExtentSize());
 | |
|                     newEm->LBIDstart = lbids[i];
 | |
|                     newEm->HWM = tmpHWM;
 | |
| 
 | |
|                     newEm->next = head;
 | |
|                     head = newEm;
 | |
|                     listSize++;
 | |
|                 }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "created another extent for OID " << newEm->OID << endl;
 | |
| #endif
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 2:  			//delete an OID
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 struct EMEntries* tmp, *prev;
 | |
|                 int fileRand = rand_r(&randstate) % listSize;
 | |
|                 int i, oid, err;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < fileRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 oid = tmp->OID;
 | |
| 
 | |
|                 err = brm_si.deleteOID(oid);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
| 
 | |
|                 for (tmp = head; tmp != NULL;)
 | |
|                 {
 | |
|                     if (tmp->OID == oid)
 | |
|                     {
 | |
|                         if (tmp == head)
 | |
|                         {
 | |
|                             head = head->next;
 | |
|                             delete tmp;
 | |
|                             tmp = head;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             prev->next = tmp->next;
 | |
|                             delete tmp;
 | |
|                             tmp = prev->next;
 | |
|                         }
 | |
| 
 | |
|                         listSize--;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         prev = tmp;
 | |
|                         tmp = tmp->next;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "deleted OID " << oid << endl;
 | |
| #endif
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 3:   //lookup by LBID
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, err, offset, oid;
 | |
|                 struct EMEntries* tmp;
 | |
|                 LBID_t target;
 | |
|                 uint32_t fbo;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 offset = rand_r(&randstate) % tmp->size;
 | |
| 
 | |
|                 target = tmp->LBIDstart + offset;
 | |
|                 err = brm_si.lookup(target, 0, false, oid, fbo);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "looked up LBID " << target << " got oid " << oid << " fbo " << fbo << endl;
 | |
|                 cerr << "   oid should be " << tmp->OID << " fbo should be " << offset + tmp->FBO << endl;
 | |
| #endif
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
|                 CPPUNIT_ASSERT(oid == tmp->OID);
 | |
|                 CPPUNIT_ASSERT(fbo == offset + tmp->FBO);
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 4:   //lookup by OID, FBO
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, oid, err, offset;
 | |
|                 struct EMEntries* tmp;
 | |
|                 LBID_t lbid;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 offset = rand_r(&randstate) % tmp->size;
 | |
|                 oid = tmp->OID;
 | |
| 
 | |
|                 err = brm_si.lookup(oid, offset + tmp->FBO, lbid);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "looked up OID " << oid << " fbo " << offset + tmp->FBO <<
 | |
|                      " got lbid " << lbid << endl;
 | |
|                 cerr << "  lbid should be " << tmp->LBIDstart + offset << endl;
 | |
| #endif
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
|                 CPPUNIT_ASSERT(lbid == static_cast<LBID_t>(tmp->LBIDstart + offset));
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 5:		//getHWM
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, err;
 | |
|                 struct EMEntries* tmp;
 | |
|                 uint32_t hwm;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 err = brm_si.getHWM(tmp->OID, hwm);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "stored HWM for OID " << tmp->OID << " is " << tmp->HWM
 | |
|                      << " BRM says it's " << hwm << endl;
 | |
| #endif
 | |
|                 CPPUNIT_ASSERT(hwm == tmp->HWM);
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 6: 		//setHWM
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, hwm, oid, err;
 | |
|                 struct EMEntries* tmp;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 oid = tmp->OID;
 | |
|                 hwm = rand_r(&randstate) % (tmp->FBO + brm_si.getExtentSize());
 | |
|                 err = brm_si.setHWM(oid, hwm);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
| 
 | |
|                 for (tmp = head; tmp != NULL; tmp = tmp->next)
 | |
|                     if (tmp->OID == oid)
 | |
|                         tmp->HWM = hwm;
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "setHWM of OID " << oid << " to " << hwm << endl;
 | |
| #endif
 | |
|                 em.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 7:			//getBulkInsertVars
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 HWM_t hwm;
 | |
|                 VER_t txnID;
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, err, offset;
 | |
|                 EMEntries* tmp;
 | |
|                 LBID_t lbid;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 offset = rand_r(&randstate) % tmp->size;
 | |
|                 lbid = tmp->LBIDstart + offset;
 | |
|                 err = brm_si.getBulkInsertVars(lbid, hwm, txnID);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
|                 CPPUNIT_ASSERT(hwm == tmp->secondHWM);
 | |
|                 CPPUNIT_ASSERT(txnID == tmp->txnID);
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 8:			//setBulkInsertVars
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, err, offset;
 | |
|                 EMEntries* tmp;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 offset = rand_r(&randstate) % tmp->size;
 | |
|                 tmp->secondHWM = rand_r(&randstate) % MAXINT;
 | |
|                 tmp->txnID = rand_r(&randstate) % MAXINT;
 | |
|                 err = brm_si.setBulkInsertVars(tmp->LBIDstart + offset,
 | |
|                                                tmp->secondHWM, tmp->txnID);
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 opCount++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             default:
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     while (head != NULL)
 | |
|     {
 | |
|         tmp = head->next;
 | |
|         delete head;
 | |
|         head = tmp;
 | |
|     }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|     cerr << "thread " << threadNum << " exiting" << endl;
 | |
| #endif
 | |
|     return NULL;
 | |
| }
 | |
| */
 | |
| 
 | |
| static void* EMRunner([[maybe_unused]] void* arg)
 | |
| {
 | |
|   // keep track of LBID ranges allocated here and
 | |
|   // randomly allocate, lookup, delete, get/set HWM, and
 | |
|   // destroy the EM object.
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|   uint64_t threadNum = (uint64_t)arg;
 | |
| #endif
 | |
|   int op, listSize = 0;
 | |
|   uint32_t randstate;
 | |
|   struct EMEntries *head = NULL, *tmp;
 | |
|   struct timeval tv;
 | |
|   ExtentMap* em;
 | |
|   LBID_t lbid;
 | |
|   uint32_t colWidth;
 | |
|   PartitionNumberT partNum;
 | |
|   SegmentT segmentNum;
 | |
|   execplan::CalpontSystemCatalog::ColDataType colDataType;
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|   cerr << "thread number " << threadNum << " started." << endl;
 | |
| #endif
 | |
| 
 | |
|   gettimeofday(&tv, NULL);
 | |
|   randstate = static_cast<uint32_t>(tv.tv_usec);
 | |
|   // pthread_mutex_lock(&pthreadMutex);
 | |
|   em = new ExtentMap();
 | |
|   // pthread_mutex_unlock(&pthreadMutex);
 | |
| 
 | |
|   while (!threadStop)
 | |
|   {
 | |
|     auto randNumber = rand_r(&randstate);
 | |
|     op = randNumber % 10;
 | |
| 
 | |
|     colWidth = colWidthsAvailable[randNumber % colWidthsAvailable.size()];
 | |
|     partNum = randNumber % std::numeric_limits<PartitionNumberT>::max();
 | |
|     segmentNum = randNumber % std::numeric_limits<SegmentT>::max();
 | |
|     colDataType = (execplan::CalpontSystemCatalog::ColDataType)(
 | |
|         randNumber % (int)execplan::CalpontSystemCatalog::ColDataType::TIMESTAMP);
 | |
| #ifdef BRM_VERBOSE
 | |
|     cerr << "next op is " << op << endl;
 | |
| #endif
 | |
| 
 | |
|     switch (op)
 | |
|     {
 | |
|       case 0:  // allocate space for a new file
 | |
|       {
 | |
|         vector<struct EMEntry> emEntriesVec;
 | |
|         struct EMEntries* newEm;
 | |
|         size_t numberOfExtents = randNumber % 4 + 1;
 | |
|         int OID;
 | |
|         uint32_t startBlockOffset;
 | |
| 
 | |
|         pthread_mutex_lock(&pthreadMutex);
 | |
|         OID = oid++;
 | |
|         pthread_mutex_unlock(&pthreadMutex);
 | |
| 
 | |
|         em->getExtents(OID, emEntriesVec, false, false, true);
 | |
|         size_t extentsNumberBefore = emEntriesVec.size();
 | |
|         int allocdsize;
 | |
|         for (size_t i = 0; i < numberOfExtents; ++i)
 | |
|         {
 | |
|           em->createColumnExtent_DBroot(OID, colWidth, dbroot, colDataType, partNum, segmentNum, lbid,
 | |
|                                         allocdsize, startBlockOffset);
 | |
|           em->confirmChanges();
 | |
| 
 | |
|           newEm = new EMEntries(allocdsize, OID, startBlockOffset, lbid, head, dbroot, partNum, segmentNum);
 | |
|           head = newEm;
 | |
|           listSize++;
 | |
|         }
 | |
| 
 | |
|         emEntriesVec.clear();
 | |
|         em->getExtents(OID, emEntriesVec, false, false, true);
 | |
|         size_t extentsNumberAfter = emEntriesVec.size();
 | |
| 
 | |
|         CPPUNIT_ASSERT(extentsNumberBefore + numberOfExtents == extentsNumberAfter);
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|         cerr << "created new space for OID " << newEm->OID << endl;
 | |
| #endif
 | |
|         // em->checkConsistency();
 | |
|         break;
 | |
|       }
 | |
|         /*
 | |
|                     case 1:		//allocate space for an existing file
 | |
|                     {
 | |
|                         if (listSize == 0)
 | |
|                             break;
 | |
| 
 | |
|                         struct EMEntries* newEm, *tmp;
 | |
|                         size_t size = rand_r(&randstate) % 10;
 | |
|                         int fileRand = rand_r(&randstate) % listSize;
 | |
|                         int i, lastExtent, blockEnd, oid;
 | |
|                         int tmpHWM, entries, allocdSize;
 | |
|                         uint32_t startBlockOffset;
 | |
|                         lbids.clear();
 | |
| 
 | |
|                         for (i = 0, tmp = head; i < fileRand; i++)
 | |
|                             tmp = tmp->next;
 | |
| 
 | |
|                         oid = tmp->OID;
 | |
| 
 | |
|                         for (lastExtent = 0, tmp = head; tmp != NULL; tmp = tmp->next)
 | |
|                         {
 | |
|                             if (tmp->OID != oid)
 | |
|                                 continue;
 | |
| 
 | |
|                             tmpHWM = tmp->HWM;
 | |
|                             blockEnd = tmp->FBO + tmp->size;
 | |
| 
 | |
|                             if (lastExtent < blockEnd)
 | |
|                                 lastExtent = blockEnd;
 | |
|                         }
 | |
| 
 | |
|                         for (size_t i = 0; i < size; ++i)
 | |
|                         {
 | |
|                             em->createColumnExtent_DBroot(oid, colWidth, dbroot, colDataType,
 | |
|                                 partNum, segmentNum, lbid, allocdSize, startBlockOffset);
 | |
|                             em->confirmChanges();
 | |
|                             lbids.push_back(lbid);
 | |
|                         }
 | |
| 
 | |
|                         //em->createExtent(size, oid, lbids, allocdSize);
 | |
|                         //em->confirmChanges();
 | |
| 
 | |
|                         entries = size / em->getExtentSize();
 | |
| 
 | |
|                         if ((size % em->getExtentSize()) != 0)
 | |
|                             entries++;
 | |
| 
 | |
|                         CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
 | |
| 
 | |
|                         for (i = 0; i < entries; i++)
 | |
|                         {
 | |
|                             newEm = new EMEntries((i != entries) ? em->getExtentSize() : size %
 | |
|         em->getExtentSize(), oid, lastExtent + (i * em->getExtentSize()), lbids[i], head, dbroot, partNum,
 | |
|         segmentNum); newEm->HWM = tmpHWM; head = newEm; listSize++;
 | |
|                         }
 | |
| 
 | |
|         #ifdef BRM_VERBOSE
 | |
|                         cerr << "created another extent for OID " << newEm->OID << endl;
 | |
|         #endif
 | |
|                         em->checkConsistency();
 | |
|                         break;
 | |
|                     }
 | |
|         */
 | |
| 
 | |
|       case 2:  // delete an OID
 | |
|       {
 | |
|         if (listSize == 0)
 | |
|           break;
 | |
| 
 | |
|         struct EMEntries *tmp = nullptr, *prev = nullptr;
 | |
|         int fileRand = rand_r(&randstate) % listSize;
 | |
|         int i, oid;
 | |
| 
 | |
|         for (i = 0, tmp = head; i < fileRand; i++)
 | |
|           tmp = tmp->next;
 | |
| 
 | |
|         oid = tmp->OID;
 | |
| 
 | |
|         em->deleteOID(oid);
 | |
|         em->confirmChanges();
 | |
| 
 | |
|         vector<struct EMEntry> emEntriesVec;
 | |
|         em->getExtents(oid, emEntriesVec, false, false, true);
 | |
|         CPPUNIT_ASSERT(emEntriesVec.empty());
 | |
| 
 | |
|         for (tmp = head; tmp != NULL;)
 | |
|         {
 | |
|           if (tmp->OID == oid)
 | |
|           {
 | |
|             if (tmp == head)
 | |
|             {
 | |
|               head = head->next;
 | |
|               delete tmp;
 | |
|               tmp = head;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               prev->next = tmp->next;
 | |
|               delete tmp;
 | |
|               tmp = prev->next;
 | |
|             }
 | |
| 
 | |
|             listSize--;
 | |
|           }
 | |
|           else
 | |
|           {
 | |
|             prev = tmp;
 | |
|             tmp = tmp->next;
 | |
|           }
 | |
|         }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|         cerr << "deleted OID " << oid << endl;
 | |
| #endif
 | |
|         // em->checkConsistency();
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case 3:  // lookup by LBID
 | |
|       {
 | |
|         if (listSize == 0)
 | |
|           break;
 | |
| 
 | |
|         int entryRand = rand_r(&randstate) % listSize;
 | |
|         int i, err, offset, oid;
 | |
|         struct EMEntries* tmp;
 | |
|         LBID_t target;
 | |
|         uint32_t fbo;
 | |
|         DBRootT localDbroot;
 | |
|         PartitionNumberT localPartNum;
 | |
|         SegmentT localSegmentNum;
 | |
| 
 | |
|         for (i = 0, tmp = head; i < entryRand; i++)
 | |
|           tmp = tmp->next;
 | |
| 
 | |
|         offset = rand_r(&randstate) % (tmp->size - 1);
 | |
| 
 | |
|         target = tmp->LBIDstart + offset;
 | |
|         err = em->lookupLocal(target, oid, localDbroot, localPartNum, localSegmentNum, fbo);
 | |
| #ifdef BRM_VERBOSE
 | |
|         cerr << "looked up LBID " << target << " got oid " << oid << " fbo " << fbo << endl;
 | |
|         cerr << "   oid should be " << tmp->OID << " fbo should be " << offset + tmp->FBO << endl;
 | |
|         cerr << "op 3 fbo " << fbo << " offset + tmp->FBO " << offset + tmp->FBO << endl;
 | |
| #endif
 | |
|         CPPUNIT_ASSERT(err == 0);
 | |
|         CPPUNIT_ASSERT(oid == tmp->OID);
 | |
|         CPPUNIT_ASSERT(fbo == offset + tmp->FBO);
 | |
|         // em->checkConsistency();
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case 4:  // lookup by OID, FBO
 | |
|       {
 | |
|         if (listSize == 0)
 | |
|           break;
 | |
| 
 | |
|         int entryRand = rand_r(&randstate) % listSize;
 | |
|         int i, oid, err, offset;
 | |
|         struct EMEntries* tmp;
 | |
|         LBID_t lbid;
 | |
| 
 | |
|         for (i = 0, tmp = head; i < entryRand; i++)
 | |
|           tmp = tmp->next;
 | |
| 
 | |
|         offset = rand_r(&randstate) % (tmp->size - 1);
 | |
|         oid = tmp->OID;
 | |
| 
 | |
|         err = em->lookupLocal(oid, tmp->partNum, tmp->segNum, offset + tmp->FBO, lbid);
 | |
| #ifdef BRM_VERBOSE
 | |
|         cerr << "looked up OID " << oid << " fbo " << offset + tmp->FBO << " got lbid " << lbid << endl;
 | |
|         cerr << "  lbid should be " << tmp->LBIDstart + offset << endl;
 | |
| #endif
 | |
|         CPPUNIT_ASSERT(err == 0);
 | |
|         CPPUNIT_ASSERT(lbid == tmp->LBIDstart + offset);
 | |
|         // em->checkConsistency();
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case 5:  // getHWM
 | |
|       {
 | |
|         if (listSize == 0)
 | |
|           break;
 | |
| 
 | |
|         int entryRand = rand_r(&randstate) % listSize;
 | |
|         int i, status;
 | |
|         struct EMEntries* tmp;
 | |
|         uint32_t hwm;
 | |
| 
 | |
|         for (i = 0, tmp = head; i < entryRand; i++)
 | |
|           tmp = tmp->next;
 | |
| 
 | |
|         hwm = em->getLocalHWM(tmp->OID, tmp->partNum, tmp->segNum, status);
 | |
| #ifdef BRM_VERBOSE_I
 | |
|         cerr << "stored HWM for OID " << tmp->OID << " is " << tmp->HWM << " BRM says it's " << hwm << endl;
 | |
| #endif
 | |
|         CPPUNIT_ASSERT(hwm == tmp->HWM);
 | |
|         // em->checkConsistency();
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case 6:  // setHWM
 | |
|       {
 | |
|         if (listSize == 0)
 | |
|           break;
 | |
| 
 | |
|         int entryRand = rand_r(&randstate) % listSize;
 | |
|         int i, hwm, oid;
 | |
|         struct EMEntries* tmp;
 | |
| 
 | |
|         for (i = 0, tmp = head; i < entryRand; i++)
 | |
|           tmp = tmp->next;
 | |
| 
 | |
|         oid = tmp->OID;
 | |
|         hwm = rand_r(&randstate) % (tmp->size - 1);
 | |
|         bool firstNode = true;
 | |
|         em->setLocalHWM(oid, tmp->partNum, tmp->segNum, hwm, firstNode);
 | |
| 
 | |
|         em->confirmChanges();
 | |
| 
 | |
|         tmp->HWM = hwm;
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|         cerr << "setHWM of OID " << oid << " to " << hwm << endl;
 | |
| #endif
 | |
|         // em->checkConsistency();
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|         /*
 | |
|                     case 7:			// renew this EM object
 | |
|                     {
 | |
|                         delete em;
 | |
|                         em = new ExtentMap();
 | |
|         #ifdef BRM_VERBOSE
 | |
|                         cerr << "got a new EM instance" << endl;
 | |
|         #endif
 | |
|                         em->checkConsistency();
 | |
|                         break;
 | |
|                     }
 | |
|                     case 8:			//getBulkInsertVars
 | |
|                     {
 | |
|                         if (listSize == 0)
 | |
|                             break;
 | |
| 
 | |
|                         HWM_t hwm;
 | |
|                         VER_t txnID;
 | |
|                         int entryRand = rand_r(&randstate) % listSize;
 | |
|                         int i, err, offset;
 | |
|                         EMEntries* tmp;
 | |
|                         LBID_t lbid;
 | |
| 
 | |
|                         for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                             tmp = tmp->next;
 | |
| 
 | |
|                         offset = rand_r(&randstate) % tmp->size;
 | |
|                         lbid = tmp->LBIDstart + offset;
 | |
|                         err = em->getBulkInsertVars(lbid, hwm, txnID);
 | |
|                         CPPUNIT_ASSERT(err == 0);
 | |
|                         CPPUNIT_ASSERT(hwm == tmp->secondHWM);
 | |
|                         CPPUNIT_ASSERT(txnID == tmp->txnID);
 | |
|                         break;
 | |
|                     }
 | |
| 
 | |
|                     case 9:			//setBulkInsertVars
 | |
|                     {
 | |
|                         if (listSize == 0)
 | |
|                             break;
 | |
| 
 | |
|                         int entryRand = rand_r(&randstate) % listSize;
 | |
|                         int i, err, offset;
 | |
|                         EMEntries* tmp;
 | |
| 
 | |
|                         for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                             tmp = tmp->next;
 | |
| 
 | |
|                         offset = rand_r(&randstate) % tmp->size;
 | |
|                         tmp->secondHWM = rand_r(&randstate) % MAXINT;
 | |
|                         tmp->txnID = rand_r(&randstate) % MAXINT;
 | |
|                         err = em->setBulkInsertVars(tmp->LBIDstart + offset,
 | |
|                                                     tmp->secondHWM, tmp->txnID);
 | |
|                         em->confirmChanges();
 | |
|                         CPPUNIT_ASSERT(err == 0);
 | |
|                         break;
 | |
|                     }
 | |
|         */
 | |
|       default: break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   delete em;
 | |
| 
 | |
|   while (head != NULL)
 | |
|   {
 | |
|     tmp = head->next;
 | |
|     delete head;
 | |
|     head = tmp;
 | |
|   }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|   cerr << "thread " << threadNum << " exiting" << endl;
 | |
| #endif
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| /*
 | |
| ExtentMap em_si;
 | |
| static void* EMRunner_si(void* arg)
 | |
| {
 | |
| 
 | |
|     // keep track of LBID ranges allocated here and
 | |
|     // randomly allocate, lookup, delete, get/set HWM, and
 | |
|     // destroy the EM object.
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|     int threadNum = reinterpret_cast<int>(arg);
 | |
| #endif
 | |
|     int op, listSize = 0, i;
 | |
|     uint32_t randstate;
 | |
|     struct EMEntries* head = NULL, *tmp;
 | |
|     struct timeval tv;
 | |
|     vector<LBID_t> lbids;
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|     cerr << "thread number " << threadNum << " started." << endl;
 | |
| #endif
 | |
| 
 | |
|     gettimeofday(&tv, NULL);
 | |
|     randstate = static_cast<uint32_t>(tv.tv_usec);
 | |
| 
 | |
|     while (!threadStop)
 | |
|     {
 | |
|         op = rand_r(&randstate) % 9;
 | |
| #ifdef BRM_VERBOSE
 | |
|         cerr << "next op is " << op << endl;
 | |
| #endif
 | |
| 
 | |
|         switch (op)
 | |
|         {
 | |
|             case 0:   //allocate space for a new file
 | |
|             {
 | |
|                 struct EMEntries* newEm;
 | |
|                 int size = rand_r(&randstate) % 102399 + 1;
 | |
|                 int entries, OID, allocdSize;
 | |
| 
 | |
|                 pthread_mutex_lock(&pthreadMutex);
 | |
|                 OID = oid++;
 | |
|                 pthread_mutex_unlock(&pthreadMutex);
 | |
| 
 | |
|                 em_si.createExtent(size, OID, lbids, allocdSize);
 | |
|                 em_si.confirmChanges();
 | |
| 
 | |
|                 entries = size / em_si.getExtentSize();
 | |
| 
 | |
|                 if ((size % em_si.getExtentSize()) != 0)
 | |
|                     entries++;
 | |
| 
 | |
|                 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
 | |
| 
 | |
|                 for (i = 0 ; i < entries; i++)
 | |
|                 {
 | |
| 
 | |
|                     newEm = new EMEntries();
 | |
|                     newEm->size = em_si.getExtentSize();
 | |
|                     newEm->OID = OID;
 | |
|                     newEm->FBO = i * em_si.getExtentSize();
 | |
|                     newEm->LBIDstart = lbids[i];
 | |
| 
 | |
|                     newEm->next = head;
 | |
|                     head = newEm;
 | |
|                     listSize++;
 | |
|                 }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "created new space for OID " << newEm->OID << endl;
 | |
| #endif
 | |
|                 em_si.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 1:		//allocate space for an existing file
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 struct EMEntries* newEm, *tmp;
 | |
|                 int size = rand_r(&randstate) % 102399 + 1;
 | |
|                 int fileRand = rand_r(&randstate) % listSize;
 | |
|                 int i, lastExtent, blockEnd, oid;
 | |
|                 int tmpHWM, entries, allocdSize;
 | |
|                 vector<LBID_t> lbids;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < fileRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 oid = tmp->OID;
 | |
| 
 | |
|                 for (lastExtent = 0, tmp = head; tmp != NULL; tmp = tmp->next)
 | |
|                 {
 | |
|                     if (tmp->OID != oid)
 | |
|                         continue;
 | |
| 
 | |
|                     tmpHWM = tmp->HWM;
 | |
|                     blockEnd = tmp->FBO + tmp->size;
 | |
| 
 | |
|                     if (lastExtent < blockEnd)
 | |
|                         lastExtent = blockEnd;
 | |
|                 }
 | |
| 
 | |
|                 em_si.createExtent(size, oid, lbids, allocdSize);
 | |
|                 em_si.confirmChanges();
 | |
| 
 | |
|                 entries = size / em_si.getExtentSize();
 | |
| 
 | |
|                 if ((size % em_si.getExtentSize()) != 0)
 | |
|                     entries++;
 | |
| 
 | |
|                 CPPUNIT_ASSERT((uint32_t)entries == lbids.size());
 | |
| 
 | |
|                 for (i = 0; i < entries; i++)
 | |
|                 {
 | |
| 
 | |
|                     newEm = new EMEntries();
 | |
| 
 | |
|                     if (i != entries)
 | |
|                         newEm->size = em_si.getExtentSize();
 | |
|                     else
 | |
|                         newEm->size = size % em_si.getExtentSize();
 | |
| 
 | |
|                     newEm->OID = oid;
 | |
|                     newEm->FBO = lastExtent + (i * em_si.getExtentSize());
 | |
|                     newEm->LBIDstart = lbids[i];
 | |
|                     newEm->HWM = tmpHWM;
 | |
| 
 | |
|                     newEm->next = head;
 | |
|                     head = newEm;
 | |
|                     listSize++;
 | |
|                 }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "created another extent for OID " << newEm->OID << endl;
 | |
| #endif
 | |
|                 em_si.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 2:  			//delete an OID
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 struct EMEntries* tmp, *prev;
 | |
|                 int fileRand = rand_r(&randstate) % listSize;
 | |
|                 int i, oid;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < fileRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 oid = tmp->OID;
 | |
| 
 | |
|                 em_si.deleteOID(oid);
 | |
|                 em_si.confirmChanges();
 | |
| 
 | |
|                 for (tmp = head; tmp != NULL;)
 | |
|                 {
 | |
|                     if (tmp->OID == oid)
 | |
|                     {
 | |
|                         if (tmp == head)
 | |
|                         {
 | |
|                             head = head->next;
 | |
|                             delete tmp;
 | |
|                             tmp = head;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             prev->next = tmp->next;
 | |
|                             delete tmp;
 | |
|                             tmp = prev->next;
 | |
|                         }
 | |
| 
 | |
|                         listSize--;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         prev = tmp;
 | |
|                         tmp = tmp->next;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "deleted OID " << oid << endl;
 | |
| #endif
 | |
|                 em_si.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 3:   //lookup by LBID
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, err, offset, oid;
 | |
|                 struct EMEntries* tmp;
 | |
|                 LBID_t target;
 | |
|                 uint32_t fbo;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 offset = rand_r(&randstate) % tmp->size;
 | |
| 
 | |
|                 target = tmp->LBIDstart + offset;
 | |
|                 err = em_si.lookup(target, oid, fbo);
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "looked up LBID " << target << " got oid " << oid << " fbo " << fbo << endl;
 | |
|                 cerr << "   oid should be " << tmp->OID << " fbo should be " << offset + tmp->FBO << endl;
 | |
| #endif
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
|                 CPPUNIT_ASSERT(oid == tmp->OID);
 | |
|                 CPPUNIT_ASSERT(fbo == offset + tmp->FBO);
 | |
|                 em_si.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 4:   //lookup by OID, FBO
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, oid, err, offset;
 | |
|                 struct EMEntries* tmp;
 | |
|                 LBID_t lbid;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 offset = rand_r(&randstate) % tmp->size;
 | |
|                 oid = tmp->OID;
 | |
| 
 | |
|                 err = em_si.lookup(oid, offset + tmp->FBO, lbid);
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "looked up OID " << oid << " fbo " << offset + tmp->FBO <<
 | |
|                      " got lbid " << lbid << endl;
 | |
|                 cerr << "  lbid should be " << tmp->LBIDstart + offset << endl;
 | |
| #endif
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
|                 CPPUNIT_ASSERT(lbid == tmp->LBIDstart + offset);
 | |
|                 em_si.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 5:		//getHWM
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i;
 | |
|                 struct EMEntries* tmp;
 | |
|                 uint32_t hwm;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 hwm = em_si.getHWM(tmp->OID);
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "stored HWM for OID " << tmp->OID << " is " << tmp->HWM
 | |
|                      << " BRM says it's " << hwm << endl;
 | |
| #endif
 | |
|                 CPPUNIT_ASSERT(hwm == tmp->HWM);
 | |
|                 em_si.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 6: 		//setHWM
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, hwm, oid;
 | |
|                 struct EMEntries* tmp;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 oid = tmp->OID;
 | |
|                 hwm = rand_r(&randstate) % (tmp->FBO + em_si.getExtentSize());
 | |
|                 em_si.setHWM(oid, hwm);
 | |
|                 em_si.confirmChanges();
 | |
| 
 | |
|                 for (tmp = head; tmp != NULL; tmp = tmp->next)
 | |
|                     if (tmp->OID == oid)
 | |
|                         tmp->HWM = hwm;
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|                 cerr << "setHWM of OID " << oid << " to " << hwm << endl;
 | |
| #endif
 | |
|                 em_si.checkConsistency();
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 7:			//getBulkInsertVars
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 HWM_t hwm;
 | |
|                 VER_t txnID;
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, err, offset;
 | |
|                 EMEntries* tmp;
 | |
|                 LBID_t lbid;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 offset = rand_r(&randstate) % tmp->size;
 | |
|                 lbid = tmp->LBIDstart + offset;
 | |
|                 err = em_si.getBulkInsertVars(lbid, hwm, txnID);
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
|                 CPPUNIT_ASSERT(hwm == tmp->secondHWM);
 | |
|                 CPPUNIT_ASSERT(txnID == tmp->txnID);
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             case 8:			//setBulkInsertVars
 | |
|             {
 | |
|                 if (listSize == 0)
 | |
|                     break;
 | |
| 
 | |
|                 int entryRand = rand_r(&randstate) % listSize;
 | |
|                 int i, err, offset;
 | |
|                 EMEntries* tmp;
 | |
| 
 | |
|                 for (i = 0, tmp = head; i < entryRand; i++)
 | |
|                     tmp = tmp->next;
 | |
| 
 | |
|                 offset = rand_r(&randstate) % tmp->size;
 | |
|                 tmp->secondHWM = rand_r(&randstate) % MAXINT;
 | |
|                 tmp->txnID = rand_r(&randstate) % MAXINT;
 | |
|                 err = em_si.setBulkInsertVars(tmp->LBIDstart + offset,
 | |
|                                               tmp->secondHWM, tmp->txnID);
 | |
|                 em_si.confirmChanges();
 | |
|                 CPPUNIT_ASSERT(err == 0);
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             default:
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     while (head != NULL)
 | |
|     {
 | |
|         tmp = head->next;
 | |
|         delete head;
 | |
|         head = tmp;
 | |
|     }
 | |
| 
 | |
| #ifdef BRM_VERBOSE
 | |
|     cerr << "thread " << threadNum << " exiting" << endl;
 | |
| #endif
 | |
|     return NULL;
 | |
| }
 | |
| */
 | |
| 
 | |
| class LongBRMTests : public CppUnit::TestFixture
 | |
| {
 | |
|   CPPUNIT_TEST_SUITE(LongBRMTests);
 | |
| 
 | |
|   CPPUNIT_TEST(longEMTest_1);
 | |
|   // 	CPPUNIT_TEST(longEMTest_2);
 | |
|   //    CPPUNIT_TEST(longBRMTest_1);
 | |
|   //    CPPUNIT_TEST(longBRMTest_2);
 | |
| 
 | |
|   CPPUNIT_TEST_SUITE_END();
 | |
| 
 | |
|  private:
 | |
|  public:
 | |
|   void longEMTest_1()
 | |
|   {
 | |
|     const int threadCount = 10;
 | |
|     int i;
 | |
|     pthread_t threads[threadCount];
 | |
| 
 | |
|     cerr << endl
 | |
|          << "Multithreaded, multiple instance ExtentMap test.  "
 | |
|             "This runs for 5 minutes."
 | |
|          << endl;
 | |
| 
 | |
|     threadStop = 0;
 | |
|     pthread_mutex_init(&pthreadMutex, nullptr);
 | |
| 
 | |
|     for (i = 0; i < threadCount; i++)
 | |
|     {
 | |
|       if (pthread_create(&threads[i], NULL, EMRunner, reinterpret_cast<void*>(i + 1)) < 0)
 | |
|         throw logic_error("Error creating threads for the ExtentMap test");
 | |
| 
 | |
|       usleep(1000);
 | |
|     }
 | |
| 
 | |
|     sleep(300);
 | |
|     threadStop = 1;
 | |
| 
 | |
|     for (i = 0; i < threadCount; i++)
 | |
|     {
 | |
|       cerr << "Waiting for thread #" << i << endl;
 | |
|       pthread_join(threads[i], nullptr);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /*
 | |
|       void longEMTest_2()
 | |
|       {
 | |
|           const int threadCount = 10;
 | |
|           int i;
 | |
|           pthread_t threads[threadCount];
 | |
| 
 | |
|           cerr << endl << "Multithreaded, single instance ExtentMap test.  "
 | |
|                "This runs for 5 minutes." << endl;
 | |
| 
 | |
|           threadStop = 0;
 | |
|           pthread_mutex_init(&pthreadMutex, NULL);
 | |
| 
 | |
|           for (i = 0; i < threadCount; i++)
 | |
|           {
 | |
|               if (pthread_create(&threads[i], NULL, EMRunner_si,
 | |
|                                  reinterpret_cast<void*>(i + 1)) < 0)
 | |
|                   throw logic_error("Error creating threads for the ExtentMap test");
 | |
| 
 | |
|               usleep(1000);
 | |
|           }
 | |
| 
 | |
|           sleep(60);
 | |
|           threadStop = 1;
 | |
| 
 | |
|           for (i = 0; i < threadCount; i++)
 | |
|           {
 | |
|               cerr << "Waiting for thread #" << i << endl;
 | |
|               pthread_join(threads[i], NULL);
 | |
|           }
 | |
|       }
 | |
|       void longBRMTest_1()
 | |
|       {
 | |
|           const int threadCount = 10;
 | |
|           int i;
 | |
|           pthread_t threads[threadCount];
 | |
| 
 | |
|           cerr << endl << "Multithreaded, multiple instance DBRM test.  "
 | |
|                "This runs for 5 minutes." << endl;
 | |
| 
 | |
|           threadStop = 0;
 | |
|           pthread_mutex_init(&pthreadMutex, NULL);
 | |
|           opCount = 0;
 | |
| 
 | |
|           for (i = 0; i < threadCount; i++)
 | |
|           {
 | |
|               if (pthread_create(&threads[i], NULL, BRMRunner_1,
 | |
|                                  reinterpret_cast<void*>(i + 1)) < 0)
 | |
|                   throw logic_error("Error creating threads for the DBRM test");
 | |
| 
 | |
|               usleep(1000);
 | |
|           }
 | |
| 
 | |
|           sleep(300);
 | |
|           threadStop = 1;
 | |
| 
 | |
|           for (i = 0; i < threadCount; i++)
 | |
|           {
 | |
|               cerr << "Waiting for thread #" << i << endl;
 | |
|               pthread_join(threads[i], NULL);
 | |
|           }
 | |
| 
 | |
|           cerr << "opCount = " << opCount << endl;
 | |
|       }
 | |
|       void longBRMTest_2()
 | |
|       {
 | |
|           const int threadCount = 10;
 | |
|           int i;
 | |
|           pthread_t threads[threadCount];
 | |
| 
 | |
|           cerr << endl << "Multithreaded, single instance DBRM test.  "
 | |
|                "This runs for 5 minutes." << endl;
 | |
| 
 | |
|           threadStop = 0;
 | |
|           pthread_mutex_init(&pthreadMutex, NULL);
 | |
|           opCount = 0;
 | |
| 
 | |
|           for (i = 0; i < threadCount; i++)
 | |
|           {
 | |
|               if (pthread_create(&threads[i], NULL, BRMRunner_si,
 | |
|                                  reinterpret_cast<void*>(i + 1)) < 0)
 | |
|                   throw logic_error("Error creating threads for the DBRM test");
 | |
| 
 | |
|               usleep(1000);
 | |
|           }
 | |
| 
 | |
|           sleep(300);
 | |
|           threadStop = 1;
 | |
| 
 | |
|           for (i = 0; i < threadCount; i++)
 | |
|           {
 | |
|               cerr << "Waiting for thread #" << i << endl;
 | |
|               pthread_join(threads[i], NULL);
 | |
|           }
 | |
| 
 | |
|           cerr << "opCount = " << opCount << endl;
 | |
|       }
 | |
|   */
 | |
| };
 | |
| CPPUNIT_TEST_SUITE_REGISTRATION(LongBRMTests);
 | |
| 
 | |
| #include <cppunit/extensions/TestFactoryRegistry.h>
 | |
| #include <cppunit/ui/text/TestRunner.h>
 | |
| 
 | |
| int main(int /*argc*/, char** /*argv*/)
 | |
| {
 | |
|   CppUnit::TextUi::TestRunner runner;
 | |
|   CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry();
 | |
|   runner.addTest(registry.makeTest());
 | |
|   idbdatafile::IDBPolicy::configIDBPolicy();
 | |
|   bool wasSuccessful = runner.run("", false);
 | |
|   return (wasSuccessful ? 0 : 1);
 | |
| }
 |