Example #1
0
	void brm_dumb_1()
	{
		DBRM brm;
		vector<LBID_t> lbids;
		int allocdSize, err;
		const uint32_t extentSize = brm.getExtentSize();

 		err = brm.createExtent(extentSize, 1, lbids, allocdSize);
		CPPUNIT_ASSERT(err == 0);
 		err = brm.markExtentInvalid(lbids[0]);
		CPPUNIT_ASSERT(err == 0);
		int64_t min;	
		int64_t max;	
		int32_t seq;
 		err = brm.getExtentMaxMin(lbids[0], max, min, seq);
#ifdef SAFE_CP
		CPPUNIT_ASSERT(err == 0);
#else
		CPPUNIT_ASSERT(err == 1);
#endif

 		err = brm.setExtentMaxMin(lbids[0], max, min, seq);
		CPPUNIT_ASSERT(err == 0);

		err = brm.deleteOID(1);
		CPPUNIT_ASSERT(err == 0);
	}	
Example #2
0
void DBRM_resource_graph_1()
{
	DBRM dbrm;
	pthread_t t;
	VER_t txn = 1;
	int err, allocSize;
	LBIDRange range;
	vector<LBID_t> lbids;
	vector<LBIDRange> ranges;
	vector<VBRange> freeList;

	err = dbrm.createExtent(8000, 1, lbids, allocSize);
	CPPUNIT_ASSERT(err == 0);

	range.start = 1000;
	range.size = 1000;
	ranges.push_back(range);
	err = dbrm.beginVBCopy(txn, ranges, freeList);
	CPPUNIT_ASSERT(err == 0);

	pthread_create(&t, NULL, DBRM_dummy_1, NULL);
	sleep(1);
	
	// thread tries to grab 500-1500, blocks
	err = dbrm.endVBCopy(txn, ranges);
	CPPUNIT_ASSERT(err == 0);
	err = dbrm.vbCommit(txn);
	CPPUNIT_ASSERT(err == 0);

	dbrm.deleteOID(1);
	
	//thread finishes
	pthread_join(t, NULL);
}
Example #3
0
	void brm_markExtentsInvalid()
	{
		
		DBRM brm;
		int i, err, allocdSize, iterations = 100;  // (EM_INITIAL_SIZE + 3*EM_INCREMENT)
		vector<LBID_t> lbids;
		int64_t min, max;
		int32_t seqNum;
		const uint32_t extentSize = brm.getExtentSize();
		
		cerr << "brm_markExtentsInvalid" << endl;

		err = brm.createExtent(extentSize * iterations, 1, lbids, allocdSize);
		CPPUNIT_ASSERT(lbids.size() == iterations);
		CPPUNIT_ASSERT(err == 0);

		// mark all extents valid
		for (i = 0; i < iterations; i++) {
			err = brm.setExtentMaxMin(lbids[i], 1, 0, 0);
			CPPUNIT_ASSERT(err == 0);
		}

		err = brm.markExtentsInvalid(lbids);
		CPPUNIT_ASSERT(err == 0);

		// check that they are all invalid/updating/whatever.
		// != CP_VALID is what we're looking for
		for (i = 0; i < iterations; i++) {
			err = brm.getExtentMaxMin(lbids[i], max, min, seqNum);
			CPPUNIT_ASSERT(err == CP_UPDATING);
		}

		// cleanup
		err = brm.deleteOID(1);
	}
Example #4
0
	/* This test verifies that deleteOID returns an error for
	non-existant OIDs (bug #105) */
	void brm_deleteOID()
	{
		DBRM brm;
		int err;
		vector<EMEntry> extents;
		
 		cerr << "brm_deleteOID" << endl;

		err = brm.getExtents(1, extents);
#ifdef BRM_DEBUG
		if (err == 0)
			cerr << "Make sure OID 1 isn't allocated in the extent map" << endl;
#endif
		CPPUNIT_ASSERT(err != 0);
		CPPUNIT_ASSERT(extents.empty());
		err = brm.deleteOID(1);
		CPPUNIT_ASSERT(err != 0);
	}
Example #5
0
	// cut & pasted from brm_good_2(), but with rollback instead of commit.
	void brm_good_3()
	{
		DBRM brm;
		VBBM vbbm;
		VSS vss;
		CopyLocks cl;
		int i, err, size;
		vector<LBID_t> lbids;
		vector<LBID_t>::iterator lbid;
		vector<EMEntry> extents;
		LBIDRange_v ranges;
		LBIDRange_v::iterator lbidRangeIT;
		VBRange_v vbRanges, vbRanges2;
		VBRange_v::iterator vbRangesIT;
		LBIDRange_v tmp;
		EMEntry em;
		OID_t oid;
		uint32_t fbo;
		LBIDRange range;
		VBRange vbRange;
		VER_t verID;
		bool vbFlag;
		bool caughtException;
		
		// Buildbot times out on the getBlocks() call during leakcheck b/c it takes
		// > 5 mins for some reason.  Have to ping it before 300 seconds go by.
		void (*oldsig)(int);
		
 		cerr << "brm_good_3" << endl;

		oldsig = signal(SIGALRM, keepalive);
		alarm(290);
		
 		err = brm.lookup(0, 0, false, oid, fbo);
 		CPPUNIT_ASSERT(err != 0); 
		err = brm.lookup(0, 0, true, oid, fbo);
		CPPUNIT_ASSERT(err != 0);
		
 		err = brm.createExtent(8000, 1, lbids, size);
 		CPPUNIT_ASSERT(err == 0);
 		CPPUNIT_ASSERT(size == brm.getExtentSize());
 		CPPUNIT_ASSERT(lbids.size() == 1);
  		CPPUNIT_ASSERT(*(lbids.begin()) == 0);
		
		err = brm.getExtents(1, extents);
		CPPUNIT_ASSERT(err == 0);
		CPPUNIT_ASSERT(extents.size() == 1);
		
		em = *(extents.begin());
 		CPPUNIT_ASSERT(em.range.start == 0);
		CPPUNIT_ASSERT(em.range.size*1024 == static_cast<uint32_t>(brm.getExtentSize()));
		CPPUNIT_ASSERT(em.HWM == 0);
		CPPUNIT_ASSERT(em.blockOffset == 0);
		
		for (i = 0; i < 5; i++) {
			range.start = i * 100;
			range.size = 100;
			ranges.push_back(range);
		}

		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		err = brm.beginVBCopy(1, ranges, vbRanges);
		CPPUNIT_ASSERT(err == 0);
		
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		cl.lock(CopyLocks::READ);
		for (lbidRangeIT = ranges.begin(); lbidRangeIT != ranges.end(); 
				   lbidRangeIT++)
			CPPUNIT_ASSERT(cl.isLocked(*lbidRangeIT));
		cl.release(CopyLocks::READ);
		
		err = brm.beginVBCopy(1, ranges, vbRanges2);
		CPPUNIT_ASSERT(err != 0);
		
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		cl.lock(CopyLocks::READ);
		for (lbidRangeIT = ranges.begin(); lbidRangeIT != ranges.end(); 
				   lbidRangeIT++)
			CPPUNIT_ASSERT(cl.isLocked(*lbidRangeIT));
		cl.release(CopyLocks::READ);
		
		for (i = 0; i < 500; i++) {
			verID = MAXINT;
			err = brm.vssLookup(i, verID, 1, vbFlag);
			CPPUNIT_ASSERT(err != 0);
		}
		
		vbRange = *(vbRanges.begin());
// 		CPPUNIT_ASSERT(vbRange.vbFBO == 0);
		for (i = 0; i < (int)vbRange.size; i++) {
			err = brm.writeVBEntry(1, i, vbRange.vbOID, vbRange.vbFBO + i);
			CPPUNIT_ASSERT(err == 0);
		}
		
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		for (i = 0; i < (int)vbRange.size; i++) { 
			verID = MAXINT;
			err = brm.vssLookup(i, verID, 1, vbFlag);
			CPPUNIT_ASSERT(err == 0);
			CPPUNIT_ASSERT(verID == 1);
			CPPUNIT_ASSERT(vbFlag == false);
			verID = MAXINT;
			err = brm.vssLookup(i, verID, 0, vbFlag);
			CPPUNIT_ASSERT(err == 0);
			CPPUNIT_ASSERT(verID == 0);
			CPPUNIT_ASSERT(vbFlag == true);
		}
		
		for (; i < 500; i++) {
			verID = MAXINT;
			err = brm.vssLookup(i, verID, 1, vbFlag);
			CPPUNIT_ASSERT(err != 0);
		}
					
		err = brm.endVBCopy(0, ranges);
			
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		cl.lock(CopyLocks::READ);
		for (lbidRangeIT = ranges.begin(); lbidRangeIT != ranges.end(); 
				   lbidRangeIT++)
			CPPUNIT_ASSERT(!cl.isLocked(*lbidRangeIT));
		cl.release(CopyLocks::READ);
		
		err = brm.getUncommittedLBIDs(1, lbids);
		CPPUNIT_ASSERT(err == 0);
		CPPUNIT_ASSERT(lbids.size() == vbRange.size);
		sort<vector<LBID_t>::iterator>(lbids.begin(), lbids.end());
		lbid = lbids.begin();
		for (i = 0; i < static_cast<int>(lbids.size()); i++, lbid++)
			CPPUNIT_ASSERT((*lbid) == static_cast<LBID_t>(i));
		
		range.start = 0;
		range.size = i;
		tmp.push_back(range);
		err = brm.vbRollback(1, tmp);
		CPPUNIT_ASSERT(err == 0);
		
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		for (i = 0; i < (int)vbRange.size; i++) { 
			verID = MAXINT;
			
			err = brm.vssLookup(i, verID, 0, vbFlag);
			CPPUNIT_ASSERT(err == 0);
			CPPUNIT_ASSERT(verID == 0);
			CPPUNIT_ASSERT(vbFlag == false);
			
			err = brm.lookup(i, verID, vbFlag, oid, fbo);
			CPPUNIT_ASSERT(err == 0);
 			CPPUNIT_ASSERT(oid == 1);
			CPPUNIT_ASSERT(fbo == static_cast<uint32_t>(i));
			
			vbbm.lock(VBBM::WRITE);
			vss.lock(VSS::WRITE);

#ifdef BRM_DEBUG
 			caughtException = false;
			try {
				vbbm.removeEntry(i, verID);
				vbbm.confirmChanges();
			}
			catch (logic_error &e) {
				vbbm.undoChanges();
				caughtException = true;
			}
			CPPUNIT_ASSERT(caughtException);
			caughtException = false;
			try {
				vss.removeEntry(i, 1);
				vss.confirmChanges();
			}
			catch (logic_error &e) {
				vss.undoChanges();
				caughtException = true;
			}
			CPPUNIT_ASSERT(caughtException);
#endif

			vss.removeEntry(i, verID);
			vss.confirmChanges();
			vss.release(VSS::WRITE);
			vbbm.release(VBBM::WRITE);
		}
		
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		brm.deleteOID(1);
		
		vbbm.lock(VBBM::READ);
		vss.lock(VSS::READ);
		CPPUNIT_ASSERT(vbbm.size() == 0);
		CPPUNIT_ASSERT(vbbm.hashEmpty());
		CPPUNIT_ASSERT(vss.size() == 0);
		CPPUNIT_ASSERT(vss.hashEmpty());
		vss.release(VSS::READ);
		vbbm.release(VBBM::READ);
		
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);

		err = brm.saveState();
		CPPUNIT_ASSERT(err==0);
	}
Example #6
0
	void brm_extentmap_good_1()
	{
		
		DBRM brm;
		int i, err, oid, allocdSize, 
			iterations = 100;  // (EM_INITIAL_SIZE + 3*EM_INCREMENT)
		uint32_t fbo, hwm;
		vector<LBID_t> lbids;
		HWM_t hwm2;
		VER_t txnID;
		const uint32_t extentSize = brm.getExtentSize();
		
 		cerr << "brm_extentmap_good_1" << endl;

		for (i = 1; i < iterations; i++) {
			err = brm.createExtent(extentSize, i, lbids, allocdSize);
			CPPUNIT_ASSERT(err == 0);
			CPPUNIT_ASSERT(lbids.back() == static_cast<LBID_t>((i-1)*extentSize));

			err=brm.markExtentInvalid(lbids[0]);
			CPPUNIT_ASSERT(err==0);

			int64_t min;	
			int64_t max;	
			int32_t seq;
 			err = brm.getExtentMaxMin(lbids[0], max, min, seq);
#ifdef SAFE_CP
			CPPUNIT_ASSERT(err == 0);
#else
			CPPUNIT_ASSERT(err == 1);
#endif

 			err = brm.setExtentMaxMin(lbids[0], max, min, seq);
			CPPUNIT_ASSERT(err == 0);

		}

		CPPUNIT_ASSERT(err==0);

		for (i = 1; i < iterations; i++) {
			err = brm.lookup(static_cast<LBID_t>((i-1)*extentSize), 0, false, oid, fbo);
			CPPUNIT_ASSERT(err == 0);
			CPPUNIT_ASSERT(oid == i);
			CPPUNIT_ASSERT(fbo == 0);
			if (i != 1) {
				err = brm.lookup(static_cast<LBID_t>((i-1)*extentSize - 1), 0, false, oid, fbo);
				CPPUNIT_ASSERT(err == 0);
				CPPUNIT_ASSERT(oid == i-1);
				CPPUNIT_ASSERT(fbo == extentSize - 1);
			}
			if (i != iterations) {
				err = brm.lookup(static_cast<LBID_t>((i-1)*extentSize + 1), 0, false, oid, fbo);
				CPPUNIT_ASSERT(err == 0);
				CPPUNIT_ASSERT(oid == i);
				CPPUNIT_ASSERT(fbo == 1);
			}
			err = brm.markExtentInvalid(oid);
			CPPUNIT_ASSERT(err==0);
			err = brm.markExtentInvalid(lbids[0]);
			CPPUNIT_ASSERT(err==0);
			int64_t min;	
			int64_t max;	
			int32_t seq;
 			err = brm.getExtentMaxMin(lbids[0], max, min, seq);
#ifdef SAFE_CP
			CPPUNIT_ASSERT(err == 0);
#else
			CPPUNIT_ASSERT(err == 1);
#endif

 			err = brm.setExtentMaxMin(lbids[0], max, min, seq);
			CPPUNIT_ASSERT(err == 0);
		}
		
 		CPPUNIT_ASSERT(brm.checkConsistency() == 0);

		err = brm.lookup(static_cast<LBID_t>((i-1)*extentSize), 0, false, oid, fbo);
		CPPUNIT_ASSERT(err == -1);
		
		for (i = 1; i < iterations; i++) {
			err = brm.getBulkInsertVars(static_cast<LBID_t>((i-1)*extentSize),
									   hwm2, txnID);
			CPPUNIT_ASSERT(err == 0);
			CPPUNIT_ASSERT(hwm2 == 0);
			CPPUNIT_ASSERT(txnID == 0);
			err = brm.setBulkInsertVars(static_cast<LBID_t>((i-1)*extentSize),
									   i, i + 1);
			CPPUNIT_ASSERT(err == 0);
			err = brm.getBulkInsertVars(static_cast<LBID_t>((i-1)*extentSize),
									   hwm2, txnID);
			CPPUNIT_ASSERT(err == 0);
			CPPUNIT_ASSERT(hwm2 == static_cast<BRM::LBID_t>(i));
			CPPUNIT_ASSERT(txnID == static_cast<BRM::VER_t>(i+1));
			
			err = brm.getHWM(i, hwm);
			CPPUNIT_ASSERT(err == 0);
			CPPUNIT_ASSERT(hwm == 0);
			err = brm.setHWM(i, ((uint32_t)i > extentSize - 1 ? extentSize - 1 : i));
			CPPUNIT_ASSERT(err == 0);
			err = brm.getHWM(i, hwm);
			CPPUNIT_ASSERT(err == 0);
			CPPUNIT_ASSERT(hwm == static_cast<uint32_t>((uint32_t)i > extentSize - 1 ? extentSize - 1 : i));
		}
		
 		CPPUNIT_ASSERT(brm.checkConsistency() == 0);

#ifdef BRM_DEBUG
		err = brm.setHWM(i, hwm);
		CPPUNIT_ASSERT(err != 0);
#endif

		for (i = 1; i < iterations; i++) {
			err = brm.deleteOID(i);
			CPPUNIT_ASSERT(err == 0);
		}
 
		err = brm.deleteOID(i);
		CPPUNIT_ASSERT(err != 0);
		
 		CPPUNIT_ASSERT(brm.checkConsistency() == 0);

		err = brm.saveState();
		CPPUNIT_ASSERT(err==0);

	}
Example #7
0
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.
	
	struct EMEntries {
		u_int64_t LBIDstart;
		u_int32_t size;
		int OID;
		u_int32_t FBO;
		u_int32_t HWM;
		u_int32_t secondHWM;
		u_int32_t txnID;
		struct EMEntries *next;
		EMEntries() { next = NULL; HWM = 0; secondHWM = 0; txnID = 0; }
	};
	
#ifdef BRM_VERBOSE
	int threadNum = reinterpret_cast<int>(arg);
#endif
	int op, listSize = 0, i;
	uint 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<uint>(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(&mutex);
		OID = oid++;
		opCount++;
		pthread_mutex_unlock(&mutex);
				
		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((uint)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(&mutex);
		opCount++;
		pthread_mutex_unlock(&mutex);
		CPPUNIT_ASSERT(err == 0);		
		
		entries = size/brm_si.getExtentSize();
		if ((size % brm_si.getExtentSize()) != 0)
			entries++;
				
		CPPUNIT_ASSERT((uint)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(&mutex);
		opCount++;
		pthread_mutex_unlock(&mutex);
		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;
		u_int32_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(&mutex);
		opCount++;
		pthread_mutex_unlock(&mutex);
#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(&mutex);
		opCount++;
		pthread_mutex_unlock(&mutex);
#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;
		u_int32_t hwm;
				
		for (i = 0, tmp = head; i < entryRand; i++)
			tmp = tmp->next;
				
		err = brm_si.getHWM(tmp->OID, hwm);
		pthread_mutex_lock(&mutex);
		opCount++;
		pthread_mutex_unlock(&mutex);
		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(&mutex);
		opCount++;
		pthread_mutex_unlock(&mutex);
		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(&mutex);
		opCount++;
		pthread_mutex_unlock(&mutex);
		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(&mutex);
		opCount++;
		pthread_mutex_unlock(&mutex);
		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;
}