diff_container.cpp
Go to the documentation of this file.00001
00012
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 };
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
00122
00123
00124
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 }