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