1 /**
2 * @file sample_container.cpp
3 * Internal container for samples
4 *
5 * @remark Copyright 2002, 2003 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author Philippe Elie
9 * @author John Levon
10 */
11
12 #include <climits>
13 #include <set>
14 #include <numeric>
15 #include <algorithm>
16 #include <vector>
17
18 #include "sample_container.h"
19
20 using namespace std;
21
22 namespace {
23
24 // FIXME: efficiency ?
add_counts(count_array_t const & counts,sample_entry const * s)25 count_array_t add_counts(count_array_t const & counts,
26 sample_entry const * s)
27 {
28 count_array_t temp(counts);
29 temp += s->counts;
30 return temp;
31 }
32
33 } // namespace anon
34
35
begin() const36 sample_container::samples_iterator sample_container::begin() const
37 {
38 return samples.begin();
39 }
40
41
end() const42 sample_container::samples_iterator sample_container::end() const
43 {
44 return samples.end();
45 }
46
47
48 sample_container::samples_iterator
begin(symbol_entry const * symbol) const49 sample_container::begin(symbol_entry const * symbol) const
50 {
51 samples_storage::key_type key(symbol, 0);
52
53 return samples.lower_bound(key);
54 }
55
56
57 sample_container::samples_iterator
end(symbol_entry const * symbol) const58 sample_container::end(symbol_entry const * symbol) const
59 {
60 samples_storage::key_type key(symbol, ~bfd_vma(0));
61
62 return samples.upper_bound(key);
63 }
64
65
insert(symbol_entry const * symbol,sample_entry const & sample)66 void sample_container::insert(symbol_entry const * symbol,
67 sample_entry const & sample)
68 {
69 samples_storage::key_type key(symbol, sample.vma);
70
71 samples_storage::iterator it = samples.find(key);
72 if (it != samples.end()) {
73 it->second.counts += sample.counts;
74 } else {
75 samples[key] = sample;
76 }
77 }
78
79
80 count_array_t
accumulate_samples(debug_name_id filename_id) const81 sample_container::accumulate_samples(debug_name_id filename_id) const
82 {
83 build_by_loc();
84
85 sample_entry lower, upper;
86
87 lower.file_loc.filename = upper.file_loc.filename = filename_id;
88 lower.file_loc.linenr = 0;
89 upper.file_loc.linenr = INT_MAX;
90
91 typedef samples_by_loc_t::const_iterator iterator;
92
93 iterator it1 = samples_by_loc.lower_bound(&lower);
94 iterator it2 = samples_by_loc.upper_bound(&upper);
95
96 return accumulate(it1, it2, count_array_t(), add_counts);
97 }
98
99
100 sample_entry const *
find_by_vma(symbol_entry const * symbol,bfd_vma vma) const101 sample_container::find_by_vma(symbol_entry const * symbol, bfd_vma vma) const
102 {
103 sample_index_t key(symbol, vma);
104 samples_iterator it = samples.find(key);
105 if (it != samples.end())
106 return &it->second;
107
108 return 0;
109 }
110
111
112 count_array_t
accumulate_samples(debug_name_id filename,size_t linenr) const113 sample_container::accumulate_samples(debug_name_id filename,
114 size_t linenr) const
115 {
116 build_by_loc();
117
118 sample_entry sample;
119
120 sample.file_loc.filename = filename;
121 sample.file_loc.linenr = linenr;
122
123 typedef pair<samples_by_loc_t::const_iterator,
124 samples_by_loc_t::const_iterator> it_pair;
125
126 it_pair itp = samples_by_loc.equal_range(&sample);
127
128 return accumulate(itp.first, itp.second, count_array_t(), add_counts);
129 }
130
131
build_by_loc() const132 void sample_container::build_by_loc() const
133 {
134 if (!samples_by_loc.empty())
135 return;
136
137 samples_iterator cit = samples.begin();
138 samples_iterator end = samples.end();
139 for (; cit != end; ++cit)
140 samples_by_loc.insert(&cit->second);
141 }
142