• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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