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