/** * @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); }