~ubuntu-branches/debian/sid/bitcoin/sid

« back to all changes in this revision

Viewing changes to src/memusage.h

  • Committer: Package Import Robot
  • Author(s): Scott Howard
  • Date: 2015-07-29 15:45:52 UTC
  • mfrom: (1.1.23)
  • Revision ID: package-import@ubuntu.com-20150729154552-p5t8q38o0ekh1f09
Tags: 0.11.0-1
* New upstream release (Closes: #793622)
  - build on all archs, big endian is now supported
* Updated symbols file
* Added bitcoin-cli.1 manpage from contrib/debian/manpages
* Updated debian/copyright

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2015 The Bitcoin 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 <stdlib.h>
 
9
 
 
10
#include <map>
 
11
#include <set>
 
12
#include <vector>
 
13
 
 
14
#include <boost/unordered_set.hpp>
 
15
#include <boost/unordered_map.hpp>
 
16
 
 
17
namespace memusage
 
18
{
 
19
 
 
20
/** Compute the total memory used by allocating alloc bytes. */
 
21
static size_t MallocUsage(size_t alloc);
 
22
 
 
23
/** Compute the memory used for dynamically allocated but owned data structures.
 
24
 *  For generic data types, this is *not* recursive. DynamicUsage(vector<vector<int> >)
 
25
 *  will compute the memory used for the vector<int>'s, but not for the ints inside.
 
26
 *  This is for efficiency reasons, as these functions are intended to be fast. If
 
27
 *  application data structures require more accurate inner accounting, they should
 
28
 *  do the recursion themselves, or use more efficient caching + updating on modification.
 
29
 */
 
30
template<typename X> static size_t DynamicUsage(const std::vector<X>& v);
 
31
template<typename X> static size_t DynamicUsage(const std::set<X>& s);
 
32
template<typename X, typename Y> static size_t DynamicUsage(const std::map<X, Y>& m);
 
33
template<typename X, typename Y> static size_t DynamicUsage(const boost::unordered_set<X, Y>& s);
 
34
template<typename X, typename Y, typename Z> static size_t DynamicUsage(const boost::unordered_map<X, Y, Z>& s);
 
35
template<typename X> static size_t DynamicUsage(const X& x);
 
36
 
 
37
static inline size_t MallocUsage(size_t alloc)
 
38
{
 
39
    // Measured on libc6 2.19 on Linux.
 
40
    if (sizeof(void*) == 8) {
 
41
        return ((alloc + 31) >> 4) << 4;
 
42
    } else if (sizeof(void*) == 4) {
 
43
        return ((alloc + 15) >> 3) << 3;
 
44
    } else {
 
45
        assert(0);
 
46
    }
 
47
}
 
48
 
 
49
// STL data structures
 
50
 
 
51
template<typename X>
 
52
struct stl_tree_node
 
53
{
 
54
private:
 
55
    int color;
 
56
    void* parent;
 
57
    void* left;
 
58
    void* right;
 
59
    X x;
 
60
};
 
61
 
 
62
template<typename X>
 
63
static inline size_t DynamicUsage(const std::vector<X>& v)
 
64
{
 
65
    return MallocUsage(v.capacity() * sizeof(X));
 
66
}
 
67
 
 
68
template<typename X>
 
69
static inline size_t DynamicUsage(const std::set<X>& s)
 
70
{
 
71
    return MallocUsage(sizeof(stl_tree_node<X>)) * s.size();
 
72
}
 
73
 
 
74
template<typename X, typename Y>
 
75
static inline size_t DynamicUsage(const std::map<X, Y>& m)
 
76
{
 
77
    return MallocUsage(sizeof(stl_tree_node<std::pair<const X, Y> >)) * m.size();
 
78
}
 
79
 
 
80
// Boost data structures
 
81
 
 
82
template<typename X>
 
83
struct boost_unordered_node : private X
 
84
{
 
85
private:
 
86
    void* ptr;
 
87
};
 
88
 
 
89
template<typename X, typename Y>
 
90
static inline size_t DynamicUsage(const boost::unordered_set<X, Y>& s)
 
91
{
 
92
    return MallocUsage(sizeof(boost_unordered_node<X>)) * s.size() + MallocUsage(sizeof(void*) * s.bucket_count());
 
93
}
 
94
 
 
95
template<typename X, typename Y, typename Z>
 
96
static inline size_t DynamicUsage(const boost::unordered_map<X, Y, Z>& m)
 
97
{
 
98
    return MallocUsage(sizeof(boost_unordered_node<std::pair<const X, Y> >)) * m.size() + MallocUsage(sizeof(void*) * m.bucket_count());
 
99
}
 
100
 
 
101
// Dispatch to class method as fallback
 
102
 
 
103
template<typename X>
 
104
static inline size_t DynamicUsage(const X& x)
 
105
{
 
106
    return x.DynamicMemoryUsage();
 
107
}
 
108
 
 
109
}
 
110
 
 
111
#endif