Optimisation: Store transaction list order in memory rather than compute it every need
Huge performance improvement (450%) for zapwallettxes
This commit is contained in:
@@ -588,31 +588,6 @@ int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
|
||||
return nRet;
|
||||
}
|
||||
|
||||
CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
|
||||
{
|
||||
AssertLockHeld(cs_wallet); // mapWallet
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
|
||||
// First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
|
||||
TxItems txOrdered;
|
||||
|
||||
// Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
|
||||
// would make this much faster for applications that do this a lot.
|
||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
{
|
||||
CWalletTx* wtx = &((*it).second);
|
||||
txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
|
||||
}
|
||||
acentries.clear();
|
||||
walletdb.ListAccountCreditDebit(strAccount, acentries);
|
||||
BOOST_FOREACH(CAccountingEntry& entry, acentries)
|
||||
{
|
||||
txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
|
||||
}
|
||||
|
||||
return txOrdered;
|
||||
}
|
||||
|
||||
void CWallet::MarkDirty()
|
||||
{
|
||||
{
|
||||
@@ -629,7 +604,9 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD
|
||||
if (fFromLoadWallet)
|
||||
{
|
||||
mapWallet[hash] = wtxIn;
|
||||
mapWallet[hash].BindWallet(this);
|
||||
CWalletTx& wtx = mapWallet[hash];
|
||||
wtx.BindWallet(this);
|
||||
wtxOrdered.insert(make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0)));
|
||||
AddToSpends(hash);
|
||||
}
|
||||
else
|
||||
@@ -644,6 +621,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD
|
||||
{
|
||||
wtx.nTimeReceived = GetAdjustedTime();
|
||||
wtx.nOrderPos = IncOrderPosNext(pwalletdb);
|
||||
wtxOrdered.insert(make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0)));
|
||||
|
||||
wtx.nTimeSmart = wtx.nTimeReceived;
|
||||
if (!wtxIn.hashBlock.IsNull())
|
||||
@@ -655,9 +633,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD
|
||||
{
|
||||
// Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
|
||||
int64_t latestTolerated = latestNow + 300;
|
||||
std::list<CAccountingEntry> acentries;
|
||||
TxItems txOrdered = OrderedTxItems(acentries);
|
||||
for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
|
||||
const TxItems & txOrdered = wtxOrdered;
|
||||
for (TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
|
||||
{
|
||||
CWalletTx *const pwtx = (*it).second.first;
|
||||
if (pwtx == &wtx)
|
||||
@@ -2118,6 +2095,18 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry, CWalletDB & pwalletdb)
|
||||
{
|
||||
if (!pwalletdb.WriteAccountingEntry_Backend(acentry))
|
||||
return false;
|
||||
|
||||
laccentries.push_back(acentry);
|
||||
CAccountingEntry & entry = laccentries.back();
|
||||
wtxOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CAmount CWallet::GetRequiredFee(unsigned int nTxBytes)
|
||||
{
|
||||
return std::max(minTxFee.GetFee(nTxBytes), ::minRelayTxFee.GetFee(nTxBytes));
|
||||
|
||||
Reference in New Issue
Block a user