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
20using namespace std;
21
22namespace {
23
24// FIXME: efficiency ?
25count_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
36sample_container::samples_iterator sample_container::begin() const
37{
38	return samples.begin();
39}
40
41
42sample_container::samples_iterator sample_container::end() const
43{
44	return samples.end();
45}
46
47
48sample_container::samples_iterator
49sample_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
57sample_container::samples_iterator
58sample_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
66void 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
80count_array_t
81sample_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
100sample_entry const *
101sample_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
112count_array_t
113sample_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
132void 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