diff_container.cpp

Go to the documentation of this file.
00001 
00012 /* older glibc has C99 INFINITY in _GNU_SOURCE */
00013 #ifndef _GNU_SOURCE
00014 #define _GNU_SOURCE
00015 #endif
00016 
00017 #include "diff_container.h"
00018 
00019 #include <cmath>
00020 
00021 using namespace std;
00022 
00023 
00024 namespace {
00025 
00026 
00028 bool rough_less(symbol_entry const & lhs, symbol_entry const & rhs)
00029 {
00030     if (lhs.image_name != rhs.image_name)
00031         return lhs.image_name < rhs.image_name;
00032 
00033     if (lhs.app_name != rhs.app_name)
00034         return lhs.app_name < rhs.app_name;
00035 
00036     if (lhs.name != rhs.name)
00037         return lhs.name < rhs.name;
00038 
00039     return false;
00040 }
00041 
00042 
00044 void
00045 add_sym(diff_collection & syms, diff_symbol const & sym,
00046         profile_container::symbol_choice & choice)
00047 {
00048     if (choice.match_image
00049         && (image_names.name(sym.image_name) != choice.image_name))
00050         return;
00051 
00052     if (fabs(sym.diffs[0]) < choice.threshold)
00053         return;
00054 
00055     choice.hints = sym.output_hint(choice.hints);
00056     syms.push_back(sym);
00057 }
00058 
00059 
00061 void
00062 symbol_old(diff_collection & syms, symbol_entry const & sym,
00063            profile_container::symbol_choice & choice)
00064 {
00065     diff_symbol symbol(sym);
00066     symbol.diffs.fill(sym.sample.counts.size(), -INFINITY);
00067     add_sym(syms, symbol, choice);
00068 }
00069 
00070 
00072 void
00073 symbol_new(diff_collection & syms, symbol_entry const & sym,
00074            profile_container::symbol_choice & choice)
00075 {
00076     diff_symbol symbol(sym);
00077     symbol.diffs.fill(sym.sample.counts.size(), INFINITY);
00078     add_sym(syms, symbol, choice);
00079 }
00080 
00081 
00083 void symbol_diff(diff_collection & syms,
00084                  symbol_entry const & sym1, count_array_t const & total1,
00085                  symbol_entry const & sym2, count_array_t const & total2,
00086                  profile_container::symbol_choice & choice)
00087 {
00088     diff_symbol symbol(sym2);
00089 
00090     size_t size = sym2.sample.counts.size();
00091     for (size_t i = 0; i != size; ++i) {
00092         double percent1;
00093         double percent2;
00094         percent1 = op_ratio(sym1.sample.counts[i], total1[i]);
00095         percent2 = op_ratio(sym2.sample.counts[i], total2[i]);
00096         symbol.diffs[i] = op_ratio(percent2 - percent1, percent1);
00097         symbol.diffs[i] *= 100.0;
00098     }
00099 
00100     add_sym(syms, symbol, choice);
00101 }
00102 
00103 
00104 }; // namespace anon
00105 
00106 
00107 diff_container::diff_container(profile_container const & c1,
00108                                profile_container const & c2)
00109     : pc1(c1), pc2(c2),
00110       total1(pc1.samples_count()), total2(pc2.samples_count())
00111 {
00112 }
00113 
00114 
00115 diff_collection const
00116 diff_container::get_symbols(profile_container::symbol_choice & choice) const
00117 {
00118     diff_collection syms;
00119 
00120     /*
00121      * Do a pairwise comparison of the two symbol sets. We're
00122      * relying here on the symbol container being sorted such
00123      * that rough_less() is suitable for iterating through the
00124      * two lists (see less_symbol).
00125      */
00126 
00127     symbol_container::symbols_t::iterator it1 = pc1.begin_symbol();
00128     symbol_container::symbols_t::iterator end1 = pc1.end_symbol();
00129     symbol_container::symbols_t::iterator it2 = pc2.begin_symbol();
00130     symbol_container::symbols_t::iterator end2 = pc2.end_symbol();
00131 
00132     while (it1 != end1 && it2 != end2) {
00133         if (rough_less(*it1, *it2)) {
00134             symbol_old(syms, *it1, choice);
00135             ++it1;
00136         } else if (rough_less(*it2, *it1)) {
00137             symbol_new(syms, *it2, choice);
00138             ++it2;
00139         } else {
00140             symbol_diff(syms, *it1, total1, *it2, total2, choice);
00141             ++it1;
00142             ++it2;
00143         }
00144     }
00145 
00146     for (; it1 != end1; ++it1)
00147         symbol_old(syms, *it1, choice);
00148 
00149     for (; it2 != end2; ++it2)
00150         symbol_new(syms, *it2, choice);
00151 
00152     return syms;
00153 }
00154 
00155 
00156 count_array_t const diff_container::samples_count() const
00157 {
00158     return total2;
00159 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1