Mike Dodd | 8cfa702 | 2010-11-17 11:12:26 -0800 | [diff] [blame^] | 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 | } |