Bitcoin ABC  0.26.3
P2P Digital Currency
memusage.h
Go to the documentation of this file.
1 // Copyright (c) 2015-2016 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_MEMUSAGE_H
6 #define BITCOIN_MEMUSAGE_H
7 
8 #include <indirectmap.h>
9 #include <prevector.h>
10 
11 #include <cassert>
12 #include <cstdlib>
13 #include <map>
14 #include <memory>
15 #include <set>
16 #include <unordered_map>
17 #include <unordered_set>
18 #include <vector>
19 
20 namespace memusage {
21 
23 static size_t MallocUsage(size_t alloc);
24 
26 static inline size_t DynamicUsage(const int8_t &v) {
27  return 0;
28 }
29 static inline size_t DynamicUsage(const uint8_t &v) {
30  return 0;
31 }
32 static inline size_t DynamicUsage(const int16_t &v) {
33  return 0;
34 }
35 static inline size_t DynamicUsage(const uint16_t &v) {
36  return 0;
37 }
38 static inline size_t DynamicUsage(const int32_t &v) {
39  return 0;
40 }
41 static inline size_t DynamicUsage(const uint32_t &v) {
42  return 0;
43 }
44 static inline size_t DynamicUsage(const int64_t &v) {
45  return 0;
46 }
47 static inline size_t DynamicUsage(const uint64_t &v) {
48  return 0;
49 }
50 static inline size_t DynamicUsage(const float &v) {
51  return 0;
52 }
53 static inline size_t DynamicUsage(const double &v) {
54  return 0;
55 }
56 template <typename X> static inline size_t DynamicUsage(X *const &v) {
57  return 0;
58 }
59 template <typename X> static inline size_t DynamicUsage(const X *const &v) {
60  return 0;
61 }
62 
72 static inline size_t MallocUsage(size_t alloc) {
73  // Measured on libc6 2.19 on Linux.
74  if (alloc == 0) {
75  return 0;
76  } else if (sizeof(void *) == 8) {
77  return ((alloc + 31) >> 4) << 4;
78  } else if (sizeof(void *) == 4) {
79  return ((alloc + 15) >> 3) << 3;
80  } else {
81  assert(0);
82  }
83 }
84 
85 // STL data structures
86 
87 template <typename X> struct stl_tree_node {
88 private:
89  int color;
90  void *parent;
91  void *left;
92  void *right;
93  X x;
94 };
95 
101  void *class_type;
102  size_t use_count;
103  size_t weak_count;
104 };
105 
106 template <typename X>
107 static inline size_t DynamicUsage(const std::vector<X> &v) {
108  return MallocUsage(v.capacity() * sizeof(X));
109 }
110 
111 template <unsigned int N, typename X, typename S, typename D>
112 static inline size_t DynamicUsage(const prevector<N, X, S, D> &v) {
113  return MallocUsage(v.allocated_memory());
114 }
115 
116 template <typename X, typename Y>
117 static inline size_t DynamicUsage(const std::set<X, Y> &s) {
118  return MallocUsage(sizeof(stl_tree_node<X>)) * s.size();
119 }
120 
121 template <typename X, typename Y>
122 static inline size_t IncrementalDynamicUsage(const std::set<X, Y> &s) {
123  return MallocUsage(sizeof(stl_tree_node<X>));
124 }
125 
126 template <typename X, typename Y, typename Z>
127 static inline size_t DynamicUsage(const std::map<X, Y, Z> &m) {
128  return MallocUsage(sizeof(stl_tree_node<std::pair<const X, Y>>)) * m.size();
129 }
130 
131 template <typename X, typename Y, typename Z>
132 static inline size_t IncrementalDynamicUsage(const std::map<X, Y, Z> &m) {
133  return MallocUsage(sizeof(stl_tree_node<std::pair<const X, Y>>));
134 }
135 
136 // indirectmap has underlying map with pointer as key
137 
138 template <typename X, typename Y>
139 static inline size_t DynamicUsage(const indirectmap<X, Y> &m) {
140  return MallocUsage(sizeof(stl_tree_node<std::pair<const X *, Y>>)) *
141  m.size();
142 }
143 
144 template <typename X, typename Y>
145 static inline size_t IncrementalDynamicUsage(const indirectmap<X, Y> &m) {
146  return MallocUsage(sizeof(stl_tree_node<std::pair<const X *, Y>>));
147 }
148 
149 template <typename X>
150 static inline size_t DynamicUsage(const std::unique_ptr<X> &p) {
151  return p ? MallocUsage(sizeof(X)) : 0;
152 }
153 
154 template <typename X>
155 static inline size_t DynamicUsage(const std::shared_ptr<X> &p) {
156  // A shared_ptr can either use a single continuous memory block for both the
157  // counter and the storage (when using std::make_shared), or separate. We
158  // can't observe the difference, however, so assume the worst.
159  return p ? MallocUsage(sizeof(X)) + MallocUsage(sizeof(stl_shared_counter))
160  : 0;
161 }
162 
163 // Boost data structures
164 
165 template <typename X> struct unordered_node : private X {
166 private:
167  void *ptr;
168 };
169 
170 template <typename X, typename Y>
171 static inline size_t DynamicUsage(const std::unordered_set<X, Y> &s) {
172  return MallocUsage(sizeof(unordered_node<X>)) * s.size() +
173  MallocUsage(sizeof(void *) * s.bucket_count());
174 }
175 
176 template <typename X, typename Y, typename Z>
177 static inline size_t DynamicUsage(const std::unordered_map<X, Y, Z> &m) {
178  return MallocUsage(sizeof(unordered_node<std::pair<const X, Y>>)) *
179  m.size() +
180  MallocUsage(sizeof(void *) * m.bucket_count());
181 }
182 } // namespace memusage
183 
184 #endif // BITCOIN_MEMUSAGE_H
Map whose keys are pointers, but are compared by their dereferenced values.
Definition: indirectmap.h:26
size_type size() const
Definition: indirectmap.h:54
Implements a drop-in replacement for std::vector<T> which stores up to N elements directly (without h...
Definition: prevector.h:38
size_t allocated_memory() const
Definition: prevector.h:602
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition: memusage.h:26
static size_t IncrementalDynamicUsage(const std::set< X, Y > &s)
Definition: memusage.h:122
static size_t MallocUsage(size_t alloc)
Compute the total memory used by allocating alloc bytes.
Definition: memusage.h:72
void * class_type
Various platforms use different sized counters here.
Definition: memusage.h:101
assert(!tx.IsCoinBase())