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