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