Browse Source

Do all block index writes in a batch

0.13
Pieter Wuille 10 years ago
parent
commit
63d1ae5556
  1. 2
      src/chain.h
  2. 23
      src/main.cpp
  3. 25
      src/txdb.cpp
  4. 4
      src/txdb.h

2
src/chain.h

@ -293,7 +293,7 @@ public:
hashPrev = 0; hashPrev = 0;
} }
explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) { explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) {
hashPrev = (pprev ? pprev->GetBlockHash() : 0); hashPrev = (pprev ? pprev->GetBlockHash() : 0);
} }

23
src/main.cpp

@ -1784,24 +1784,23 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
// First make sure all block and undo data is flushed to disk. // First make sure all block and undo data is flushed to disk.
FlushBlockFile(); FlushBlockFile();
// Then update all block file information (which may refer to block and undo files). // Then update all block file information (which may refer to block and undo files).
bool fileschanged = false; {
std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
vFiles.reserve(setDirtyFileInfo.size());
for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) { for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
if (!pblocktree->WriteBlockFileInfo(*it, vinfoBlockFile[*it])) { vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it]));
return state.Abort("Failed to write to block index");
}
fileschanged = true;
setDirtyFileInfo.erase(it++); setDirtyFileInfo.erase(it++);
} }
if (fileschanged && !pblocktree->WriteLastBlockFile(nLastBlockFile)) { std::vector<const CBlockIndex*> vBlocks;
return state.Abort("Failed to write to block index"); vBlocks.reserve(setDirtyBlockIndex.size());
}
for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) { for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(*it))) { vBlocks.push_back(*it);
return state.Abort("Failed to write to block index");
}
setDirtyBlockIndex.erase(it++); setDirtyBlockIndex.erase(it++);
} }
pblocktree->Sync(); if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
return state.Abort("Files to write to block index database");
}
}
// Finally flush the chainstate (which may refer to block index entries). // Finally flush the chainstate (which may refer to block index entries).
if (!pcoinsTip->Flush()) if (!pcoinsTip->Flush())
return state.Abort("Failed to write to coin database"); return state.Abort("Failed to write to coin database");

25
src/txdb.cpp

@ -66,23 +66,10 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevelDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) { CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevelDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) {
} }
bool CBlockTreeDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
{
return Write(make_pair('b', blockindex.GetBlockHash()), blockindex);
}
bool CBlockTreeDB::WriteBlockFileInfo(int nFile, const CBlockFileInfo &info) {
return Write(make_pair('f', nFile), info);
}
bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) { bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) {
return Read(make_pair('f', nFile), info); return Read(make_pair('f', nFile), info);
} }
bool CBlockTreeDB::WriteLastBlockFile(int nFile) {
return Write('l', nFile);
}
bool CBlockTreeDB::WriteReindexing(bool fReindexing) { bool CBlockTreeDB::WriteReindexing(bool fReindexing) {
if (fReindexing) if (fReindexing)
return Write('R', '1'); return Write('R', '1');
@ -152,6 +139,18 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
return true; return true;
} }
bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) {
CLevelDBBatch batch;
for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) {
batch.Write(make_pair('f', it->first), *it->second);
}
batch.Write('l', nLastFile);
for (std::vector<const CBlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) {
batch.Write(make_pair('b', (*it)->GetBlockHash()), CDiskBlockIndex(*it));
}
return WriteBatch(batch, true);
}
bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) { bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) {
return Read(make_pair('t', txid), pos); return Read(make_pair('t', txid), pos);
} }

4
src/txdb.h

@ -48,11 +48,9 @@ private:
CBlockTreeDB(const CBlockTreeDB&); CBlockTreeDB(const CBlockTreeDB&);
void operator=(const CBlockTreeDB&); void operator=(const CBlockTreeDB&);
public: public:
bool WriteBlockIndex(const CDiskBlockIndex& blockindex); bool WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo);
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo); bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo);
bool WriteBlockFileInfo(int nFile, const CBlockFileInfo &fileinfo);
bool ReadLastBlockFile(int &nFile); bool ReadLastBlockFile(int &nFile);
bool WriteLastBlockFile(int nFile);
bool WriteReindexing(bool fReindex); bool WriteReindexing(bool fReindex);
bool ReadReindexing(bool &fReindex); bool ReadReindexing(bool &fReindex);
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos); bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos);

Loading…
Cancel
Save