| /** |
| * @file sample_container.cpp |
| * Internal container for samples |
| * |
| * @remark Copyright 2002, 2003 OProfile authors |
| * @remark Read the file COPYING |
| * |
| * @author Philippe Elie |
| * @author John Levon |
| */ |
| |
| #include <climits> |
| #include <set> |
| #include <numeric> |
| #include <algorithm> |
| #include <vector> |
| |
| #include "sample_container.h" |
| |
| using namespace std; |
| |
| namespace { |
| |
| // FIXME: efficiency ? |
| count_array_t add_counts(count_array_t const & counts, |
| sample_entry const * s) |
| { |
| count_array_t temp(counts); |
| temp += s->counts; |
| return temp; |
| } |
| |
| } // namespace anon |
| |
| |
| sample_container::samples_iterator sample_container::begin() const |
| { |
| return samples.begin(); |
| } |
| |
| |
| sample_container::samples_iterator sample_container::end() const |
| { |
| return samples.end(); |
| } |
| |
| |
| sample_container::samples_iterator |
| sample_container::begin(symbol_entry const * symbol) const |
| { |
| samples_storage::key_type key(symbol, 0); |
| |
| return samples.lower_bound(key); |
| } |
| |
| |
| sample_container::samples_iterator |
| sample_container::end(symbol_entry const * symbol) const |
| { |
| samples_storage::key_type key(symbol, ~bfd_vma(0)); |
| |
| return samples.upper_bound(key); |
| } |
| |
| |
| void sample_container::insert(symbol_entry const * symbol, |
| sample_entry const & sample) |
| { |
| samples_storage::key_type key(symbol, sample.vma); |
| |
| samples_storage::iterator it = samples.find(key); |
| if (it != samples.end()) { |
| it->second.counts += sample.counts; |
| } else { |
| samples[key] = sample; |
| } |
| } |
| |
| |
| count_array_t |
| sample_container::accumulate_samples(debug_name_id filename_id) const |
| { |
| build_by_loc(); |
| |
| sample_entry lower, upper; |
| |
| lower.file_loc.filename = upper.file_loc.filename = filename_id; |
| lower.file_loc.linenr = 0; |
| upper.file_loc.linenr = INT_MAX; |
| |
| typedef samples_by_loc_t::const_iterator iterator; |
| |
| iterator it1 = samples_by_loc.lower_bound(&lower); |
| iterator it2 = samples_by_loc.upper_bound(&upper); |
| |
| return accumulate(it1, it2, count_array_t(), add_counts); |
| } |
| |
| |
| sample_entry const * |
| sample_container::find_by_vma(symbol_entry const * symbol, bfd_vma vma) const |
| { |
| sample_index_t key(symbol, vma); |
| samples_iterator it = samples.find(key); |
| if (it != samples.end()) |
| return &it->second; |
| |
| return 0; |
| } |
| |
| |
| count_array_t |
| sample_container::accumulate_samples(debug_name_id filename, |
| size_t linenr) const |
| { |
| build_by_loc(); |
| |
| sample_entry sample; |
| |
| sample.file_loc.filename = filename; |
| sample.file_loc.linenr = linenr; |
| |
| typedef pair<samples_by_loc_t::const_iterator, |
| samples_by_loc_t::const_iterator> it_pair; |
| |
| it_pair itp = samples_by_loc.equal_range(&sample); |
| |
| return accumulate(itp.first, itp.second, count_array_t(), add_counts); |
| } |
| |
| |
| void sample_container::build_by_loc() const |
| { |
| if (!samples_by_loc.empty()) |
| return; |
| |
| samples_iterator cit = samples.begin(); |
| samples_iterator end = samples.end(); |
| for (; cit != end; ++cit) |
| samples_by_loc.insert(&cit->second); |
| } |