10
10
#include < shutdown.h>
11
11
#include < ui_interface.h>
12
12
#include < uint256.h>
13
+ #include < util/memory.h>
13
14
#include < util/system.h>
14
15
#include < util/translation.h>
15
16
#include < util/vector.h>
@@ -41,35 +42,45 @@ struct CoinEntry {
41
42
42
43
}
43
44
44
- CCoinsViewDB::CCoinsViewDB (fs::path ldb_path, size_t nCacheSize, bool fMemory , bool fWipe ) : db(ldb_path, nCacheSize, fMemory , fWipe , true )
45
+ CCoinsViewDB::CCoinsViewDB (fs::path ldb_path, size_t nCacheSize, bool fMemory , bool fWipe ) :
46
+ m_db(MakeUnique<CDBWrapper>(ldb_path, nCacheSize, fMemory , fWipe , true )),
47
+ m_ldb_path(ldb_path),
48
+ m_is_memory(fMemory ) { }
49
+
50
+ void CCoinsViewDB::ResizeCache (size_t new_cache_size)
45
51
{
52
+ // Have to do a reset first to get the original `m_db` state to release its
53
+ // filesystem lock.
54
+ m_db.reset ();
55
+ m_db = MakeUnique<CDBWrapper>(
56
+ m_ldb_path, new_cache_size, m_is_memory, /* fWipe*/ false , /* obfuscate*/ true );
46
57
}
47
58
48
59
bool CCoinsViewDB::GetCoin (const COutPoint &outpoint, Coin &coin) const {
49
- return db. Read (CoinEntry (&outpoint), coin);
60
+ return m_db-> Read (CoinEntry (&outpoint), coin);
50
61
}
51
62
52
63
bool CCoinsViewDB::HaveCoin (const COutPoint &outpoint) const {
53
- return db. Exists (CoinEntry (&outpoint));
64
+ return m_db-> Exists (CoinEntry (&outpoint));
54
65
}
55
66
56
67
uint256 CCoinsViewDB::GetBestBlock () const {
57
68
uint256 hashBestChain;
58
- if (!db. Read (DB_BEST_BLOCK, hashBestChain))
69
+ if (!m_db-> Read (DB_BEST_BLOCK, hashBestChain))
59
70
return uint256 ();
60
71
return hashBestChain;
61
72
}
62
73
63
74
std::vector<uint256> CCoinsViewDB::GetHeadBlocks () const {
64
75
std::vector<uint256> vhashHeadBlocks;
65
- if (!db. Read (DB_HEAD_BLOCKS, vhashHeadBlocks)) {
76
+ if (!m_db-> Read (DB_HEAD_BLOCKS, vhashHeadBlocks)) {
66
77
return std::vector<uint256>();
67
78
}
68
79
return vhashHeadBlocks;
69
80
}
70
81
71
82
bool CCoinsViewDB::BatchWrite (CCoinsMap &mapCoins, const uint256 &hashBlock) {
72
- CDBBatch batch (db );
83
+ CDBBatch batch (*m_db );
73
84
size_t count = 0 ;
74
85
size_t changed = 0 ;
75
86
size_t batch_size = (size_t )gArgs .GetArg (" -dbbatchsize" , nDefaultDbBatchSize);
@@ -107,7 +118,7 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
107
118
mapCoins.erase (itOld);
108
119
if (batch.SizeEstimate () > batch_size) {
109
120
LogPrint (BCLog::COINDB, " Writing partial batch of %.2f MiB\n " , batch.SizeEstimate () * (1.0 / 1048576.0 ));
110
- db. WriteBatch (batch);
121
+ m_db-> WriteBatch (batch);
111
122
batch.Clear ();
112
123
if (crash_simulate) {
113
124
static FastRandomContext rng;
@@ -124,14 +135,14 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
124
135
batch.Write (DB_BEST_BLOCK, hashBlock);
125
136
126
137
LogPrint (BCLog::COINDB, " Writing final batch of %.2f MiB\n " , batch.SizeEstimate () * (1.0 / 1048576.0 ));
127
- bool ret = db. WriteBatch (batch);
138
+ bool ret = m_db-> WriteBatch (batch);
128
139
LogPrint (BCLog::COINDB, " Committed %u changed transaction outputs (out of %u) to coin database...\n " , (unsigned int )changed, (unsigned int )count);
129
140
return ret;
130
141
}
131
142
132
143
size_t CCoinsViewDB::EstimateSize () const
133
144
{
134
- return db. EstimateSize (DB_COIN, (char )(DB_COIN+1 ));
145
+ return m_db-> EstimateSize (DB_COIN, (char )(DB_COIN+1 ));
135
146
}
136
147
137
148
CBlockTreeDB::CBlockTreeDB (size_t nCacheSize, bool fMemory , bool fWipe ) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) {
@@ -158,7 +169,7 @@ bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
158
169
159
170
CCoinsViewCursor *CCoinsViewDB::Cursor () const
160
171
{
161
- CCoinsViewDBCursor *i = new CCoinsViewDBCursor (const_cast <CDBWrapper&>(db ).NewIterator (), GetBestBlock ());
172
+ CCoinsViewDBCursor *i = new CCoinsViewDBCursor (const_cast <CDBWrapper&>(*m_db ).NewIterator (), GetBestBlock ());
162
173
/* It seems that there are no "const iterators" for LevelDB. Since we
163
174
only need read operations on it, use a const-cast to get around
164
175
that restriction. */
@@ -338,7 +349,7 @@ class CCoins
338
349
* Currently implemented: from the per-tx utxo model (0.8..0.14.x) to per-txout.
339
350
*/
340
351
bool CCoinsViewDB::Upgrade () {
341
- std::unique_ptr<CDBIterator> pcursor (db. NewIterator ());
352
+ std::unique_ptr<CDBIterator> pcursor (m_db-> NewIterator ());
342
353
pcursor->Seek (std::make_pair (DB_COINS, uint256 ()));
343
354
if (!pcursor->Valid ()) {
344
355
return true ;
@@ -349,7 +360,7 @@ bool CCoinsViewDB::Upgrade() {
349
360
LogPrintf (" [0%%]..." ); /* Continued */
350
361
uiInterface.ShowProgress (_ (" Upgrading UTXO database" ).translated , 0 , true );
351
362
size_t batch_size = 1 << 24 ;
352
- CDBBatch batch (db );
363
+ CDBBatch batch (*m_db );
353
364
int reportDone = 0 ;
354
365
std::pair<unsigned char , uint256> key;
355
366
std::pair<unsigned char , uint256> prev_key = {DB_COINS, uint256 ()};
@@ -384,18 +395,18 @@ bool CCoinsViewDB::Upgrade() {
384
395
}
385
396
batch.Erase (key);
386
397
if (batch.SizeEstimate () > batch_size) {
387
- db. WriteBatch (batch);
398
+ m_db-> WriteBatch (batch);
388
399
batch.Clear ();
389
- db. CompactRange (prev_key, key);
400
+ m_db-> CompactRange (prev_key, key);
390
401
prev_key = key;
391
402
}
392
403
pcursor->Next ();
393
404
} else {
394
405
break ;
395
406
}
396
407
}
397
- db. WriteBatch (batch);
398
- db. CompactRange ({DB_COINS, uint256 ()}, key);
408
+ m_db-> WriteBatch (batch);
409
+ m_db-> CompactRange ({DB_COINS, uint256 ()}, key);
399
410
uiInterface.ShowProgress (" " , 100 , false );
400
411
LogPrintf (" [%s].\n " , ShutdownRequested () ? " CANCELLED" : " DONE" );
401
412
return !ShutdownRequested ();
0 commit comments