bool filterWithDictionary(execplan::erydbSystemCatalog::OID dictOid, uint64_t n) { // if n == 0, no dictionary scan, alway filter with dictionary. if (n == 0) return true; // if n == ulong_max, always use dictionary scan if (n == ULONG_MAX) return false; vector<struct EMEntry> entries; DBRM dbrm; if (dbrm.getExtents(dictOid, entries) != 0) return false; // Just do pdictionaryscan and let job step handle this. vector<struct EMEntry>::iterator it = entries.begin(); bool ret = false; n--; // HWM starts at 0 while (it != entries.end()) { if (it->HWM > n) { ret = true; break; } it++; } return ret; }
void FileBufferMgr::flushPartition(const vector<OID_t> &oids, const set<BRM::LogicalPartition> &partitions) { DBRM dbrm; uint32_t i; vector<EMEntry> extents; int err; uint32_t currentExtent; LBID_t currentLBID; typedef tr1::unordered_multimap<LBID_t, filebuffer_uset_t::iterator> byLBID_t; byLBID_t byLBID; pair<byLBID_t::iterator, byLBID_t::iterator> itList; filebuffer_uset_t::iterator it; uint32_t count = oids.size(); mutex::scoped_lock lk(fWLock); if (fCacheSize == 0 || oids.size() == 0 || partitions.size() == 0) return; /* Index the cache by LBID */ for (it = fbSet.begin(); it != fbSet.end(); it++) byLBID.insert(pair<LBID_t, filebuffer_uset_t::iterator>(it->lbid, it)); for (i = 0; i < count; i++) { extents.clear(); err = dbrm.getExtents(oids[i], extents, true, true,true); // @Bug 3838 Include outofservice extents if (err < 0) { lk.unlock(); flushCache(); // better than returning an error code to the user return; } for (currentExtent = 0; currentExtent < extents.size(); currentExtent++) { EMEntry &range = extents[currentExtent]; LogicalPartition logicalPartNum(range.dbRoot, range.partitionNum, range.segmentNum); if (partitions.find(logicalPartNum) == partitions.end()) continue; LBID_t lastLBID = range.range.start + (range.range.size * 1024); for (currentLBID = range.range.start; currentLBID < lastLBID; currentLBID++) { itList = byLBID.equal_range(currentLBID); for (byLBID_t::iterator tmpIt = itList.first; tmpIt != itList.second; tmpIt++) { fbList.erase(fFBPool[tmpIt->second->poolIdx].listLoc()); fEmptyPoolSlots.push_back(tmpIt->second->poolIdx); fbSet.erase(tmpIt->second); fCacheSize--; } } } } }
void FileBufferMgr::flushOIDs(const uint32_t *oids, uint32_t count) { DBRM dbrm; uint32_t i; vector<EMEntry> extents; int err; uint32_t currentExtent; LBID_t currentLBID; typedef tr1::unordered_multimap<LBID_t, filebuffer_uset_t::iterator> byLBID_t; byLBID_t byLBID; pair<byLBID_t::iterator, byLBID_t::iterator> itList; filebuffer_uset_t::iterator it; // If there are more than this # of extents to drop, the whole cache will be cleared const uint32_t clearThreshold = 50000; mutex::scoped_lock lk(fWLock); if (fCacheSize == 0 || count == 0) return; /* Index the cache by LBID */ for (it = fbSet.begin(); it != fbSet.end(); it++) byLBID.insert(pair<LBID_t, filebuffer_uset_t::iterator>(it->lbid, it)); for (i = 0; i < count; i++) { extents.clear(); err = dbrm.getExtents(oids[i], extents, true,true,true); // @Bug 3838 Include outofservice extents if (err < 0 || (i == 0 && (extents.size() * count) > clearThreshold)) { // (The i == 0 should ensure it's not a dictionary column) lk.unlock(); flushCache(); return; } for (currentExtent = 0; currentExtent < extents.size(); currentExtent++) { EMEntry &range = extents[currentExtent]; LBID_t lastLBID = range.range.start + (range.range.size * 1024); for (currentLBID = range.range.start; currentLBID < lastLBID; currentLBID++) { itList = byLBID.equal_range(currentLBID); for (byLBID_t::iterator tmpIt = itList.first; tmpIt != itList.second; tmpIt++) { fbList.erase(fFBPool[tmpIt->second->poolIdx].listLoc()); fEmptyPoolSlots.push_back(tmpIt->second->poolIdx); fbSet.erase(tmpIt->second); fCacheSize--; } } } } }
/* 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); }
void brm_HWM() { DBRM brm; int err; HWM_t hwm; vector<EMEntry> extents; cerr << "brm_HWM" << 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(extents.size() == 0); err = brm.setHWM(1, 10); CPPUNIT_ASSERT(err != 0); err = brm.getHWM(1, hwm); CPPUNIT_ASSERT(err != 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); }