18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file diff_container.cpp 38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Container for diffed symbols 48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2005 OProfile authors 68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING 78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie 98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon 108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* older glibc has C99 INFINITY in _GNU_SOURCE */ 138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifndef _GNU_SOURCE 148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define _GNU_SOURCE 158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif 168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "diff_container.h" 188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <cmath> 208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddusing namespace std; 228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace { 258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// a comparator suitable for diffing symbols 288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool rough_less(symbol_entry const & lhs, symbol_entry const & rhs) 298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (lhs.image_name != rhs.image_name) 318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return lhs.image_name < rhs.image_name; 328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (lhs.app_name != rhs.app_name) 348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return lhs.app_name < rhs.app_name; 358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (lhs.name != rhs.name) 378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return lhs.name < rhs.name; 388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// possibly add a diff sym 448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid 458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddadd_sym(diff_collection & syms, diff_symbol const & sym, 468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd profile_container::symbol_choice & choice) 478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (choice.match_image 498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd && (image_names.name(sym.image_name) != choice.image_name)) 508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (fabs(sym.diffs[0]) < choice.threshold) 538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd choice.hints = sym.output_hint(choice.hints); 568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd syms.push_back(sym); 578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// add a symbol not present in the new profile 618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid 628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsymbol_old(diff_collection & syms, symbol_entry const & sym, 638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd profile_container::symbol_choice & choice) 648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd diff_symbol symbol(sym); 668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol.diffs.fill(sym.sample.counts.size(), -INFINITY); 678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd add_sym(syms, symbol, choice); 688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// add a symbol not present in the old profile 728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid 738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsymbol_new(diff_collection & syms, symbol_entry const & sym, 748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd profile_container::symbol_choice & choice) 758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd diff_symbol symbol(sym); 778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol.diffs.fill(sym.sample.counts.size(), INFINITY); 788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd add_sym(syms, symbol, choice); 798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// add a diffed symbol 838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid symbol_diff(diff_collection & syms, 848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_entry const & sym1, count_array_t const & total1, 858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_entry const & sym2, count_array_t const & total2, 868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd profile_container::symbol_choice & choice) 878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd diff_symbol symbol(sym2); 898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd size_t size = sym2.sample.counts.size(); 918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (size_t i = 0; i != size; ++i) { 928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd double percent1; 938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd double percent2; 948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd percent1 = op_ratio(sym1.sample.counts[i], total1[i]); 958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd percent2 = op_ratio(sym2.sample.counts[i], total2[i]); 968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol.diffs[i] = op_ratio(percent2 - percent1, percent1); 978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol.diffs[i] *= 100.0; 988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd add_sym(syms, symbol, choice); 1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}; // namespace anon 1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodddiff_container::diff_container(profile_container const & c1, 1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd profile_container const & c2) 1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd : pc1(c1), pc2(c2), 1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd total1(pc1.samples_count()), total2(pc2.samples_count()) 1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodddiff_collection const 1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodddiff_container::get_symbols(profile_container::symbol_choice & choice) const 1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd diff_collection syms; 1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* 1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Do a pairwise comparison of the two symbol sets. We're 1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * relying here on the symbol container being sorted such 1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * that rough_less() is suitable for iterating through the 1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * two lists (see less_symbol). 1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_container::symbols_t::iterator it1 = pc1.begin_symbol(); 1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_container::symbols_t::iterator end1 = pc1.end_symbol(); 1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_container::symbols_t::iterator it2 = pc2.begin_symbol(); 1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_container::symbols_t::iterator end2 = pc2.end_symbol(); 1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd while (it1 != end1 && it2 != end2) { 1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (rough_less(*it1, *it2)) { 1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_old(syms, *it1, choice); 1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ++it1; 1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else if (rough_less(*it2, *it1)) { 1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_new(syms, *it2, choice); 1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ++it2; 1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_diff(syms, *it1, total1, *it2, total2, choice); 1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ++it1; 1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ++it2; 1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (; it1 != end1; ++it1) 1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_old(syms, *it1, choice); 1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (; it2 != end2; ++it2) 1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd symbol_new(syms, *it2, choice); 1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return syms; 1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddcount_array_t const diff_container::samples_count() const 1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return total2; 1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 160