2
* @file diff_container.cpp
3
* Container for diffed symbols
5
* @remark Copyright 2005 OProfile authors
6
* @remark Read the file COPYING
8
* @author Philippe Elie
12
/* older glibc has C99 INFINITY in _GNU_SOURCE */
17
#include "diff_container.h"
27
/// a comparator suitable for diffing symbols
28
bool rough_less(symbol_entry const & lhs, symbol_entry const & rhs)
30
if (lhs.image_name != rhs.image_name)
31
return lhs.image_name < rhs.image_name;
33
if (lhs.app_name != rhs.app_name)
34
return lhs.app_name < rhs.app_name;
36
if (lhs.name != rhs.name)
37
return lhs.name < rhs.name;
43
/// possibly add a diff sym
45
add_sym(diff_collection & syms, diff_symbol const & sym,
46
profile_container::symbol_choice & choice)
48
if (choice.match_image
49
&& (image_names.name(sym.image_name) != choice.image_name))
52
if (fabs(sym.diffs[0]) < choice.threshold)
55
choice.hints = sym.output_hint(choice.hints);
60
/// add a symbol not present in the new profile
62
symbol_old(diff_collection & syms, symbol_entry const & sym,
63
profile_container::symbol_choice & choice)
65
diff_symbol symbol(sym);
66
symbol.diffs.fill(sym.sample.counts.size(), -INFINITY);
67
add_sym(syms, symbol, choice);
71
/// add a symbol not present in the old profile
73
symbol_new(diff_collection & syms, symbol_entry const & sym,
74
profile_container::symbol_choice & choice)
76
diff_symbol symbol(sym);
77
symbol.diffs.fill(sym.sample.counts.size(), INFINITY);
78
add_sym(syms, symbol, choice);
82
/// add a diffed symbol
83
void symbol_diff(diff_collection & syms,
84
symbol_entry const & sym1, count_array_t const & total1,
85
symbol_entry const & sym2, count_array_t const & total2,
86
profile_container::symbol_choice & choice)
88
diff_symbol symbol(sym2);
90
size_t size = sym2.sample.counts.size();
91
for (size_t i = 0; i != size; ++i) {
94
percent1 = op_ratio(sym1.sample.counts[i], total1[i]);
95
percent2 = op_ratio(sym2.sample.counts[i], total2[i]);
96
symbol.diffs[i] = op_ratio(percent2 - percent1, percent1);
97
symbol.diffs[i] *= 100.0;
100
add_sym(syms, symbol, choice);
107
diff_container::diff_container(profile_container const & c1,
108
profile_container const & c2)
110
total1(pc1.samples_count()), total2(pc2.samples_count())
115
diff_collection const
116
diff_container::get_symbols(profile_container::symbol_choice & choice) const
118
diff_collection syms;
121
* Do a pairwise comparison of the two symbol sets. We're
122
* relying here on the symbol container being sorted such
123
* that rough_less() is suitable for iterating through the
124
* two lists (see less_symbol).
127
symbol_container::symbols_t::iterator it1 = pc1.begin_symbol();
128
symbol_container::symbols_t::iterator end1 = pc1.end_symbol();
129
symbol_container::symbols_t::iterator it2 = pc2.begin_symbol();
130
symbol_container::symbols_t::iterator end2 = pc2.end_symbol();
132
while (it1 != end1 && it2 != end2) {
133
if (rough_less(*it1, *it2)) {
134
symbol_old(syms, *it1, choice);
136
} else if (rough_less(*it2, *it1)) {
137
symbol_new(syms, *it2, choice);
140
symbol_diff(syms, *it1, total1, *it2, total2, choice);
146
for (; it1 != end1; ++it1)
147
symbol_old(syms, *it1, choice);
149
for (; it2 != end2; ++it2)
150
symbol_new(syms, *it2, choice);
156
count_array_t const diff_container::samples_count() const