void BCTest::setUp() { LBIDRange_v r; HWM_t hwm; OID_t oid=1000; extentSize = dbrm.getExtentSize(); maxBlocksAvailable=0; int i=0; fExtentSize=dbrm.getExtentSize(); while ( oid < 5000 ) { int ret=0; ret = dbrm.lookup(oid, r); if (ret==0 && r.size()>0) { dbrm.getHWM(oid, hwm); maxBlocksAvailable+=(r.size()*extentSize); OidRanges_t oid_range(oid, hwm, r); OidRangesList.push_back(oid_range); //cout << "Setup i: " << i++ << " o: " << oid // << " r: " << ret << " s: " << r.size() // << " m: " << maxBlocksAvailable // << endl; hwm=0; r.clear(); } oid++; } //cout << "\t" << OidRangesList.size() << " oid ranges loaded " << endl << endl; i=0; } // setUp()
/*********************************************************** * DESCRIPTION: * Write a number of blocks to the file at specified location * PARAMETERS: * pFile - file handle * writeBuf - write buffer * fbo - file block offset * numOfBlock - total number of file block offset * RETURN: * NO_ERROR if success * other number if something wrong ***********************************************************/ int DbFileOp::writeDBFile( CommBlock& cb, const unsigned char* writeBuf, const uint64_t lbid, const int numOfBlock ) { CacheKey key; int ret; if( Cache::getUseCache() ) { if( Cache::cacheKeyExist( cb.file.oid, lbid ) ) { key = Cache::getCacheKey( cb.file.oid, lbid ); RETURN_ON_ERROR( Cache::modifyCacheBlock( key, writeBuf ) ); return NO_ERROR; } } if (BRMWrapper::getUseVb()) { RETURN_ON_ERROR( writeVB( cb.file.pFile, cb.file.oid, lbid ) ); } ret = writeDBFile( cb.file.pFile, writeBuf, lbid, numOfBlock ); if (BRMWrapper::getUseVb()) { LBIDRange_v ranges; LBIDRange range; range.start = lbid; range.size = 1; ranges.push_back(range); BRMWrapper::getInstance()->writeVBEnd(getTransId(), ranges); } return ret; }
void ReadRange(const LBIDRange_v& v) { blockCacheClient bc(BRP); int found=0; int notfound=0; int ret=0; for(uint32_t i=0; i<v.size(); i++) { const InlineLBIDRange r= {v[i].start, v[i].size}; FileBuffer fb(-1, -1); for(int j=r.start; j<r.start+r.size; j++) { if (r.size > 1024) continue; ret=bc.read(j, ver, fb); if (ret) found++; else notfound++; ret=0; } totBlocks+=found; totBlocks+=notfound; found=0; notfound=0; } }
void LoadRange(const LBIDRange_v& v, uint32_t& loadCount) { blockCacheClient bc(BRP); uint32_t rCount=0; for (uint32_t i =0; i<v.size() ; i++) { const InlineLBIDRange r= {v[i].start, v[i].size}; if (r.size<=1024) { bc.check(r, ver, rCount ); loadCount+=rCount; } rCount=0; } }
void dbrm_clear() { DBRM dbrm; VSS vss; VBBM vbbm; int err, vssShmid, vbbmShmid, txnID = 1, i; struct shmid_ds vssShminfo[3], vbbmShminfo[3]; LBIDRange_v ranges; LBIDRange range; VBRange_v freelist; err = dbrm.clear(); CPPUNIT_ASSERT(err == ERR_OK); // grab the size of vss and vbbm shmsegs somehow vss.lock(VSS::READ); vbbm.lock(VBBM::READ); vssShmid = vss.getShmid(); vbbmShmid = vbbm.getShmid(); err = shmctl(vssShmid, IPC_STAT, &vssShminfo[0]); CPPUNIT_ASSERT(err == 0); err = shmctl(vbbmShmid, IPC_STAT, &vbbmShminfo[0]); CPPUNIT_ASSERT(err == 0); vss.release(VSS::READ); vbbm.release(VBBM::READ); // do begin, write, end vbcopy for 150k blocks cerr << endl << "Adding 150k block entries. "; range.start = 1; range.size = 150000; ranges.push_back(range); err = dbrm.beginVBCopy(txnID, ranges, freelist); CPPUNIT_ASSERT(err == 0); for (i = range.start; (uint32_t) i < range.size; i++) { if (i % 50000 == 0) cerr << " ... " << i; err = dbrm.writeVBEntry(txnID, i, 1, i); CPPUNIT_ASSERT(err == 0); } err = dbrm.endVBCopy(txnID, ranges); CPPUNIT_ASSERT(err == 0); cerr << " done." << endl; // grab the sizes again vss.lock(VSS::READ); vbbm.lock(VBBM::READ); vssShmid = vss.getShmid(); vbbmShmid = vbbm.getShmid(); err = shmctl(vssShmid, IPC_STAT, &vssShminfo[1]); CPPUNIT_ASSERT(err == 0); err = shmctl(vbbmShmid, IPC_STAT, &vbbmShminfo[1]); CPPUNIT_ASSERT(err == 0); vss.release(VSS::READ); vbbm.release(VBBM::READ); // make sure they grew CPPUNIT_ASSERT(vssShminfo[0].shm_segsz < vssShminfo[1].shm_segsz); CPPUNIT_ASSERT(vbbmShminfo[0].shm_segsz < vbbmShminfo[1].shm_segsz); dbrm.clear(); // check that the new size is the same as the original vss.lock(VSS::READ); vbbm.lock(VBBM::READ); vssShmid = vss.getShmid(); vbbmShmid = vbbm.getShmid(); err = shmctl(vssShmid, IPC_STAT, &vssShminfo[2]); CPPUNIT_ASSERT(err == 0); err = shmctl(vbbmShmid, IPC_STAT, &vbbmShminfo[2]); CPPUNIT_ASSERT(err == 0); vss.release(VSS::READ); vbbm.release(VBBM::READ); CPPUNIT_ASSERT(vssShminfo[0].shm_segsz == vssShminfo[2].shm_segsz); CPPUNIT_ASSERT(vbbmShminfo[0].shm_segsz == vbbmShminfo[2].shm_segsz); }
// 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); }
int main(int argc, char *argv[]) { if (argc>=2) thr_cnt=atoi(argv[1]); if (argc>=3) fLoops=atoi(argv[2]); if (thr_cnt<=0) thr_cnt=1; if (thr_cnt>1024) thr_cnt=1024; if (fLoops<=0) fLoops=1; LBIDRange_v r; vector<LBIDRange_v> ranges; DBRM dbrm; uint32_t hwm, lowfbo, highfbo, fbo, extentSize, lowlbid; struct timeval tv, tv2; cout << "Starting " << endl; extentSize = dbrm.getExtentSize(); BRM::OID_t oid=3000; uint32_t totalExt=0; do { int ret = dbrm.lookup(oid, r); if (ret==0 && r.size() > 0) { lowlbid = (r[0].start/extentSize) * extentSize; dbrm.lookup(r[0].start, ver, false, oid, fbo); // need the oid dbrm.getHWM(oid, hwm); lowfbo = fbo - (r[0].start - lowlbid); highfbo = lowfbo + extentSize; r[0].start=lowlbid; if (hwm < highfbo) r[0].size = hwm - lowfbo + 1; else r[0].size = extentSize; for (uint32_t idx=0; idx<r.size(); idx++) totalExt+=r[idx].size; ranges.push_back(r); } oid++; } while ( (r.size() > 0 || oid < 900000) ); cout << ranges.size() << " ranges found" << endl; gettimeofday(&tv, NULL); uint32_t blksLoaded=0; int rangesLoaded=0; for (uint32_t i =0; i<ranges.size() && blksLoaded < cacheSize; i++) { LoadRange(ranges[i], blksLoaded); rangesLoaded++; } cout << endl; gettimeofday(&tv2, NULL); cout << "Loaded: " << blksLoaded << " blks " << rangesLoaded << " ranges sec: " << tv2.tv_sec - tv.tv_sec <<endl; while (ranges.size() > rangesLoaded) ranges.pop_back(); #ifdef BLAH for (uint32_t i =0; i<ranges; i++) ReadRange(ranges[i]); for (uint32_t i =0; i<ranges.size(); i++) { LBIDRange_v rv=ranges[i]; for(uint32_t j=0; j < rv.size(); j++) { const InlineLBIDRange l = {rv[j].start, rv[j].size}; for(uint32_t k=l.start; k<l.start+l.size; k++) { LoadLbid(k, ver); ReadLbid(k, ver); } } } #endif pthread_t thr_id[thr_cnt]; thr_wait_t thr_wait= {0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, ranges}; //start threads running cout << "Starting driver threads" << endl; gettimeofday(&tv, NULL); memset(thr_id, 0, thr_cnt*(sizeof(pthread_t))); for(int i=0; i<thr_cnt; i++) { pthread_create(&thr_id[i], NULL, thr_client, &thr_wait); } // waiting until all threads have indicated completion pthread_mutex_lock(&thr_wait.fMutex); while (thr_wait.predicate>0) { pthread_cond_wait(&thr_wait.fCond, &thr_wait.fMutex); } pthread_mutex_unlock(&thr_wait.fMutex); // join threads back to main for(int i=0; i<thr_cnt; i++) { pthread_join(thr_id[i], NULL); } gettimeofday(&tv2, NULL); time_t tm=time(0); char t[50]; ctime_r(&tm, t); t[strlen(t)-1]=0; uint32_t elTime=tv2.tv_sec-tv.tv_sec; uint64_t total = bfoundTot + rfoundTot; uint64_t avgTot=0; uint64_t rangeAvg=0; uint64_t blkAvg=0; if (elTime>0) { avgTot=(bfoundTot+rfoundTot)/elTime; rangeAvg=(rfoundTot)/elTime; blkAvg=(bfoundTot)/elTime; } else { avgTot=bfoundTot+rfoundTot; rangeAvg=rfoundTot; blkAvg=bfoundTot; } cout << "Summary tm " << t << " " << (tv2.tv_sec-tv.tv_sec) << endl << "\tBlk: c " << blockOpCountTot << " pass " << bfoundTot << " fail " << bnfoundTot << //"\tRng: c "<< rangeOpCountTot << " pass " << rfoundTot << " fail " << rnfoundTot << endl << //"\tNoOp: c " << noOpCountTot << " Total " << total << endl << //"\tblks/sec Blk " << blkAvg << " Rng " << rangeAvg << " Tot " << avgTot << " Thr " << avgTot/thr_cnt << endl << endl; " Blks/Sec Blk " << blkAvg << " Thr " << avgTot/thr_cnt << endl << endl; return 0; } // end main
void brm_good_2() { BlockResolutionManager brm; VBBM vbbm; VSS vss; CopyLocks cl; int i, err, size; vector<LBID_t> lbids; vector<EMEntry> extents; LBIDRange_v ranges; LBIDRange_v::iterator lbidRangeIT; VBRange_v vbRanges, vbRanges2; VBRange_v::iterator vbRangesIT; EMEntry em; OID_t oid; uint32_t fbo; LBIDRange range; VBRange vbRange; VER_t verID; bool vbFlag; // 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); CPPUNIT_ASSERT(brm.checkConsistency() == 0); oldsig = signal(SIGALRM, keepalive); alarm(290); err = brm.lookup(0, 0, false, oid, fbo); CPPUNIT_ASSERT(err == -1); err = brm.lookup(0, 0, true, oid, fbo); CPPUNIT_ASSERT(err == -1); err = brm.createExtent(10000, 0, lbids, size); CPPUNIT_ASSERT(err == 0); CPPUNIT_ASSERT(size == brm.getExtentSize()); CPPUNIT_ASSERT(lbids.size() == 1); // CPPUNIT_ASSERT(*(lbids.begin()) == 0); err = brm.getExtents(0, 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 < 50; 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 == -1); 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 < 5000; i++) { verID = MAXINT; err = brm.vssLookup(i, verID, 1, vbFlag); CPPUNIT_ASSERT(err == -1); } 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 < 5000; i++) { verID = MAXINT; err = brm.vssLookup(i, verID, 1, vbFlag); CPPUNIT_ASSERT(err == -1); } 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); brm.vbCommit(1); 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 == 1); CPPUNIT_ASSERT(vbFlag == false); verID = 0; err = brm.vssLookup(i, verID, 0, vbFlag); CPPUNIT_ASSERT(err == 0); CPPUNIT_ASSERT(verID == 0); CPPUNIT_ASSERT(vbFlag == true); err = brm.lookup(i, verID, vbFlag, oid, fbo); CPPUNIT_ASSERT(err == 0); CPPUNIT_ASSERT(oid == vbRange.vbOID); CPPUNIT_ASSERT(fbo == static_cast<uint32_t>(i + vbRange.vbFBO)); vbbm.lock(VBBM::WRITE); vss.lock(VSS::WRITE); vbbm.removeEntry(i, verID); // vss.removeEntry(i, 1); vss.removeEntry(i, verID); vss.release(VSS::WRITE); vbbm.release(VBBM::WRITE); } CPPUNIT_ASSERT(brm.checkConsistency() == 0); brm.deleteOID(0); vss.lock(VSS::READ); vbbm.lock(VBBM::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); }