Skip to content

Commit 9e38d0f

Browse files
committed
Separate core memory usage computation in core_memusage.h
1 parent 89289d8 commit 9e38d0f

File tree

11 files changed

+76
-99
lines changed

11 files changed

+76
-99
lines changed

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ BITCOIN_CORE_H = \
9494
consensus/params.h \
9595
consensus/validation.h \
9696
core_io.h \
97+
core_memusage.h \
9798
eccryptoverify.h \
9899
ecwrapper.h \
99100
hash.h \

src/coins.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const
8383
// version as fresh.
8484
ret->second.flags = CCoinsCacheEntry::FRESH;
8585
}
86-
cachedCoinsUsage += memusage::DynamicUsage(ret->second.coins);
86+
cachedCoinsUsage += ret->second.coins.DynamicMemoryUsage();
8787
return ret;
8888
}
8989

@@ -110,7 +110,7 @@ CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
110110
ret.first->second.flags = CCoinsCacheEntry::FRESH;
111111
}
112112
} else {
113-
cachedCoinUsage = memusage::DynamicUsage(ret.first->second.coins);
113+
cachedCoinUsage = ret.first->second.coins.DynamicMemoryUsage();
114114
}
115115
// Assume that whenever ModifyCoins is called, the entry will be modified.
116116
ret.first->second.flags |= CCoinsCacheEntry::DIRTY;
@@ -159,21 +159,21 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
159159
assert(it->second.flags & CCoinsCacheEntry::FRESH);
160160
CCoinsCacheEntry& entry = cacheCoins[it->first];
161161
entry.coins.swap(it->second.coins);
162-
cachedCoinsUsage += memusage::DynamicUsage(entry.coins);
162+
cachedCoinsUsage += entry.coins.DynamicMemoryUsage();
163163
entry.flags = CCoinsCacheEntry::DIRTY | CCoinsCacheEntry::FRESH;
164164
}
165165
} else {
166166
if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) {
167167
// The grandparent does not have an entry, and the child is
168168
// modified and being pruned. This means we can just delete
169169
// it from the parent.
170-
cachedCoinsUsage -= memusage::DynamicUsage(itUs->second.coins);
170+
cachedCoinsUsage -= itUs->second.coins.DynamicMemoryUsage();
171171
cacheCoins.erase(itUs);
172172
} else {
173173
// A normal modification.
174-
cachedCoinsUsage -= memusage::DynamicUsage(itUs->second.coins);
174+
cachedCoinsUsage -= itUs->second.coins.DynamicMemoryUsage();
175175
itUs->second.coins.swap(it->second.coins);
176-
cachedCoinsUsage += memusage::DynamicUsage(itUs->second.coins);
176+
cachedCoinsUsage += itUs->second.coins.DynamicMemoryUsage();
177177
itUs->second.flags |= CCoinsCacheEntry::DIRTY;
178178
}
179179
}
@@ -261,6 +261,6 @@ CCoinsModifier::~CCoinsModifier()
261261
cache.cacheCoins.erase(it);
262262
} else {
263263
// If the coin still exists after the modification, add the new usage
264-
cache.cachedCoinsUsage += memusage::DynamicUsage(it->second.coins);
264+
cache.cachedCoinsUsage += it->second.coins.DynamicMemoryUsage();
265265
}
266266
}

src/coins.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define BITCOIN_COINS_H
88

99
#include "compressor.h"
10+
#include "core_memusage.h"
1011
#include "memusage.h"
1112
#include "serialize.h"
1213
#include "uint256.h"
@@ -257,8 +258,7 @@ class CCoins
257258
size_t DynamicMemoryUsage() const {
258259
size_t ret = memusage::DynamicUsage(vout);
259260
BOOST_FOREACH(const CTxOut &out, vout) {
260-
const std::vector<unsigned char> *script = &out.scriptPubKey;
261-
ret += memusage::DynamicUsage(*script);
261+
ret += RecursiveDynamicUsage(out.scriptPubKey);
262262
}
263263
return ret;
264264
}

src/core_memusage.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright (c) 2015 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_CORE_MEMUSAGE_H
6+
#define BITCOIN_CORE_MEMUSAGE_H
7+
8+
#include "primitives/transaction.h"
9+
#include "primitives/block.h"
10+
#include "memusage.h"
11+
12+
static inline size_t RecursiveDynamicUsage(const CScript& script) {
13+
return memusage::DynamicUsage(*static_cast<const std::vector<unsigned char>*>(&script));
14+
}
15+
16+
static inline size_t RecursiveDynamicUsage(const COutPoint& out) {
17+
return 0;
18+
}
19+
20+
static inline size_t RecursiveDynamicUsage(const CTxIn& in) {
21+
return RecursiveDynamicUsage(in.scriptSig) + RecursiveDynamicUsage(in.prevout);
22+
}
23+
24+
static inline size_t RecursiveDynamicUsage(const CTxOut& out) {
25+
return RecursiveDynamicUsage(out.scriptPubKey);
26+
}
27+
28+
static inline size_t RecursiveDynamicUsage(const CTransaction& tx) {
29+
size_t mem = memusage::DynamicUsage(tx.vin) + memusage::DynamicUsage(tx.vout);
30+
for (std::vector<CTxIn>::const_iterator it = tx.vin.begin(); it != tx.vin.end(); it++) {
31+
mem += RecursiveDynamicUsage(*it);
32+
}
33+
for (std::vector<CTxOut>::const_iterator it = tx.vout.begin(); it != tx.vout.end(); it++) {
34+
mem += RecursiveDynamicUsage(*it);
35+
}
36+
return mem;
37+
}
38+
39+
static inline size_t RecursiveDynamicUsage(const CMutableTransaction& tx) {
40+
size_t mem = memusage::DynamicUsage(tx.vin) + memusage::DynamicUsage(tx.vout);
41+
for (std::vector<CTxIn>::const_iterator it = tx.vin.begin(); it != tx.vin.end(); it++) {
42+
mem += RecursiveDynamicUsage(*it);
43+
}
44+
for (std::vector<CTxOut>::const_iterator it = tx.vout.begin(); it != tx.vout.end(); it++) {
45+
mem += RecursiveDynamicUsage(*it);
46+
}
47+
return mem;
48+
}
49+
50+
static inline size_t RecursiveDynamicUsage(const CBlock& block) {
51+
size_t mem = memusage::DynamicUsage(block.vtx) + memusage::DynamicUsage(block.vMerkleTree);
52+
for (std::vector<CTransaction>::const_iterator it = block.vtx.begin(); it != block.vtx.end(); it++) {
53+
mem += RecursiveDynamicUsage(*it);
54+
}
55+
return mem;
56+
}
57+
58+
static inline size_t RecursiveDynamicUsage(const CBlockLocator& locator) {
59+
return memusage::DynamicUsage(locator.vHave);
60+
}
61+
62+
#endif // BITCOIN_CORE_MEMUSAGE_H

src/memusage.h

Lines changed: 1 addition & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,14 @@ static inline size_t DynamicUsage(const float& v) { return 0; }
3434
static inline size_t DynamicUsage(const double& v) { return 0; }
3535
template<typename X> static inline size_t DynamicUsage(X * const &v) { return 0; }
3636
template<typename X> static inline size_t DynamicUsage(const X * const &v) { return 0; }
37-
template<typename X, typename Y> static inline size_t DynamicUsage(std::pair<X, Y> &p) { return 0; }
3837

3938
/** Compute the memory used for dynamically allocated but owned data structures.
4039
* For generic data types, this is *not* recursive. DynamicUsage(vector<vector<int> >)
4140
* will compute the memory used for the vector<int>'s, but not for the ints inside.
4241
* This is for efficiency reasons, as these functions are intended to be fast. If
4342
* application data structures require more accurate inner accounting, they should
44-
* use RecursiveDynamicUsage, iterate themselves, or use more efficient caching +
45-
* updating on modification.
43+
* iterate themselves, or use more efficient caching + updating on modification.
4644
*/
47-
template<typename X> static size_t DynamicUsage(const std::vector<X>& v);
48-
template<typename X> static size_t DynamicUsage(const std::set<X>& s);
49-
template<typename X, typename Y> static size_t DynamicUsage(const std::map<X, Y>& m);
50-
template<typename X, typename Y> static size_t DynamicUsage(const boost::unordered_set<X, Y>& s);
51-
template<typename X, typename Y, typename Z> static size_t DynamicUsage(const boost::unordered_map<X, Y, Z>& s);
52-
template<typename X> static size_t DynamicUsage(const X& x);
53-
54-
template<typename X> static size_t RecursiveDynamicUsage(const std::vector<X>& v);
55-
template<typename X> static size_t RecursiveDynamicUsage(const std::set<X>& v);
56-
template<typename X, typename Y> static size_t RecursiveDynamicUsage(const std::map<X, Y>& v);
57-
template<typename X, typename Y> static size_t RecursiveDynamicUsage(const std::pair<X, Y>& v);
58-
template<typename X> static size_t RecursiveDynamicUsage(const X& v);
5945

6046
static inline size_t MallocUsage(size_t alloc)
6147
{
@@ -88,54 +74,18 @@ static inline size_t DynamicUsage(const std::vector<X>& v)
8874
return MallocUsage(v.capacity() * sizeof(X));
8975
}
9076

91-
template<typename X>
92-
static inline size_t RecursiveDynamicUsage(const std::vector<X>& v)
93-
{
94-
size_t usage = DynamicUsage(v);
95-
BOOST_FOREACH(const X& x, v) {
96-
usage += RecursiveDynamicUsage(x);
97-
}
98-
return usage;
99-
}
100-
10177
template<typename X>
10278
static inline size_t DynamicUsage(const std::set<X>& s)
10379
{
10480
return MallocUsage(sizeof(stl_tree_node<X>)) * s.size();
10581
}
10682

107-
template<typename X>
108-
static inline size_t RecursiveDynamicUsage(const std::set<X>& v)
109-
{
110-
size_t usage = DynamicUsage(v);
111-
BOOST_FOREACH(const X& x, v) {
112-
usage += RecursiveDynamicUsage(x);
113-
}
114-
return usage;
115-
}
116-
11783
template<typename X, typename Y>
11884
static inline size_t DynamicUsage(const std::map<X, Y>& m)
11985
{
12086
return MallocUsage(sizeof(stl_tree_node<std::pair<const X, Y> >)) * m.size();
12187
}
12288

123-
template<typename X, typename Y>
124-
static inline size_t RecursiveDynamicUsage(const std::map<X, Y>& v)
125-
{
126-
size_t usage = DynamicUsage(v);
127-
for (typename std::map<X, Y>::const_iterator it = v.begin(); it != v.end(); it++) {
128-
usage += RecursiveDynamicUsage(*it);
129-
}
130-
return usage;
131-
}
132-
133-
template<typename X, typename Y>
134-
static inline size_t RecursiveDynamicUsage(const std::pair<X, Y>& v)
135-
{
136-
return RecursiveDynamicUsage(v.first) + RecursiveDynamicUsage(v.second);
137-
}
138-
13989
// Boost data structures
14090

14191
template<typename X>
@@ -157,20 +107,6 @@ static inline size_t DynamicUsage(const boost::unordered_map<X, Y, Z>& m)
157107
return MallocUsage(sizeof(boost_unordered_node<std::pair<const X, Y> >)) * m.size() + MallocUsage(sizeof(void*) * m.bucket_count());
158108
}
159109

160-
// Dispatch to class method as fallback
161-
162-
template<typename X>
163-
static inline size_t DynamicUsage(const X& x)
164-
{
165-
return x.DynamicMemoryUsage();
166-
}
167-
168-
template<typename X>
169-
static inline size_t RecursiveDynamicUsage(const X& x)
170-
{
171-
return DynamicUsage(x);
172-
}
173-
174110
}
175111

176112
#endif

src/primitives/transaction.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,6 @@ void CTransaction::UpdateHash() const
7272
*const_cast<uint256*>(&hash) = SerializeHash(*this);
7373
}
7474

75-
size_t CTransaction::DynamicMemoryUsage() const
76-
{
77-
return memusage::RecursiveDynamicUsage(vin) + memusage::RecursiveDynamicUsage(vout);
78-
}
79-
8075
CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { }
8176

8277
CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {

src/primitives/transaction.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#define BITCOIN_PRIMITIVES_TRANSACTION_H
88

99
#include "amount.h"
10-
#include "memusage.h"
1110
#include "script/script.h"
1211
#include "serialize.h"
1312
#include "uint256.h"
@@ -49,8 +48,6 @@ class COutPoint
4948
}
5049

5150
std::string ToString() const;
52-
53-
size_t DynamicMemoryUsage() const { return 0; }
5451
};
5552

5653
/** An input of a transaction. It contains the location of the previous
@@ -99,8 +96,6 @@ class CTxIn
9996
}
10097

10198
std::string ToString() const;
102-
103-
size_t DynamicMemoryUsage() const { return scriptSig.DynamicMemoryUsage(); }
10499
};
105100

106101
/** An output of a transaction. It contains the public key that the next input
@@ -171,8 +166,6 @@ class CTxOut
171166
}
172167

173168
std::string ToString() const;
174-
175-
size_t DynamicMemoryUsage() const { return scriptPubKey.DynamicMemoryUsage(); }
176169
};
177170

178171
struct CMutableTransaction;
@@ -256,8 +249,6 @@ class CTransaction
256249
}
257250

258251
std::string ToString() const;
259-
260-
size_t DynamicMemoryUsage() const;
261252
};
262253

263254
/** A mutable version of CTransaction. */

src/script/script.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,3 @@ std::string CScript::ToString() const
260260
}
261261
return str;
262262
}
263-
264-
size_t CScript::DynamicMemoryUsage() const
265-
{
266-
return memusage::DynamicUsage(*(static_cast<const std::vector<unsigned char>*>(this)));
267-
}

src/script/script.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#ifndef BITCOIN_SCRIPT_SCRIPT_H
77
#define BITCOIN_SCRIPT_SCRIPT_H
88

9-
#include "memusage.h"
109
#include "crypto/common.h"
1110

1211
#include <assert.h>
@@ -608,8 +607,6 @@ class CScript : public std::vector<unsigned char>
608607
// The default std::vector::clear() does not release memory.
609608
std::vector<unsigned char>().swap(*this);
610609
}
611-
612-
size_t DynamicMemoryUsage() const;
613610
};
614611

615612
class CReserveScript

src/test/coins_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ class CCoinsViewCacheTest : public CCoinsViewCache
7070
// Manually recompute the dynamic usage of the whole data, and compare it.
7171
size_t ret = memusage::DynamicUsage(cacheCoins);
7272
for (CCoinsMap::iterator it = cacheCoins.begin(); it != cacheCoins.end(); it++) {
73-
ret += memusage::DynamicUsage(it->second.coins);
73+
ret += it->second.coins.DynamicMemoryUsage();
7474
}
75-
BOOST_CHECK_EQUAL(memusage::DynamicUsage(*this), ret);
75+
BOOST_CHECK_EQUAL(DynamicMemoryUsage(), ret);
7676
}
7777

7878
};

0 commit comments

Comments
 (0)