symbol_sort.cpp

Go to the documentation of this file.
00001 
00012 #include "symbol_sort.h"
00013 #include "symbol_functors.h"
00014 
00015 #include "name_storage.h"
00016 #include "op_exception.h"
00017 
00018 #include <algorithm>
00019 #include <sstream>
00020 
00021 using namespace std;
00022 
00023 namespace {
00024 
00025 bool long_filenames;
00026 
00027 int image_compare(image_name_id l, image_name_id r)
00028 {
00029     if (long_filenames)
00030         return image_names.name(l).compare(image_names.name(r));
00031     return image_names.basename(l).compare(image_names.basename(r));
00032 }
00033 
00034 
00035 int debug_compare(debug_name_id l, debug_name_id r)
00036 {
00037     if (long_filenames)
00038         return debug_names.name(l).compare(debug_names.name(r));
00039     return debug_names.basename(l).compare(debug_names.basename(r));
00040 }
00041 
00042 
00043 int compare_by(sort_options::sort_order order,
00044                symbol_entry const & lhs, symbol_entry const & rhs)
00045 {
00046     switch (order) {
00047         case sort_options::sample:
00048             if (lhs.sample.counts[0] < rhs.sample.counts[0])
00049                 return 1;
00050             if (lhs.sample.counts[0] > rhs.sample.counts[0])
00051                 return -1;
00052             return 0;
00053 
00054         case sort_options::symbol:
00055             return symbol_names.demangle(lhs.name).compare(
00056                 symbol_names.demangle(rhs.name));
00057 
00058         case sort_options::image:
00059             return image_compare(lhs.image_name, rhs.image_name);
00060 
00061         case sort_options::app_name:
00062             return image_compare(lhs.app_name, rhs.app_name);
00063 
00064         case sort_options::vma:
00065             if (lhs.sample.vma < rhs.sample.vma)
00066                 return -1;
00067             if (lhs.sample.vma > rhs.sample.vma)
00068                 return 1;
00069             return 0;
00070 
00071         case sort_options::debug: {
00072             file_location const & f1 = lhs.sample.file_loc;
00073             file_location const & f2 = rhs.sample.file_loc;
00074             int ret = debug_compare(f1.filename, f2.filename);
00075             if (ret == 0)
00076                 ret = f1.linenr - f2.linenr;
00077             return ret;
00078         }
00079 
00080         default: {
00081             // static_cast<> to shut up g++ 2.91.66 which warn
00082             // about ambiguity between <<(int) and <<(long int)
00083             ostringstream os;
00084             os << "compare_by(): unknown sort option: "
00085                << static_cast<int>(order) << endl;
00086             throw op_fatal_error(os.str());
00087         }
00088     }
00089 
00090     return 0;
00091 }
00092 
00093 
00094 struct symbol_compare {
00095     symbol_compare(vector<sort_options::sort_order> const & order,
00096                    bool reverse)
00097         : compare_order(order), reverse_sort(reverse) {}
00098 
00099     bool operator()(symbol_entry const * lhs,
00100             symbol_entry const * rhs) const {
00101         return operator()(*lhs, *rhs);
00102     }
00103 
00104     bool operator()(symbol_entry const & lhs,
00105             symbol_entry const & rhs) const;
00106 
00107 protected:
00108     vector<sort_options::sort_order> const & compare_order;
00109     bool reverse_sort;
00110 };
00111 
00112 
00113 bool symbol_compare::operator()(symbol_entry const & lhs,
00114                 symbol_entry const & rhs) const
00115 {
00116     for (size_t i = 0; i < compare_order.size(); ++i) {
00117         int ret = compare_by(compare_order[i], lhs, rhs);
00118 
00119         if (reverse_sort)
00120             ret = -ret;
00121         if (ret != 0)
00122             return ret < 0;
00123     }
00124     return false;
00125 }
00126 
00127 
00128 } // anonymous namespace
00129 
00130 
00131 void sort_options::
00132 sort(symbol_collection & syms, bool reverse_sort, bool lf) const
00133 {
00134     long_filenames = lf;
00135 
00136     vector<sort_order> sort_option(options);
00137     for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) {
00138         if (find(sort_option.begin(), sort_option.end(), cur) ==
00139             sort_option.end())
00140             sort_option.push_back(cur);
00141     }
00142 
00143     stable_sort(syms.begin(), syms.end(),
00144                 symbol_compare(sort_option, reverse_sort));
00145 }
00146 
00147 
00148 void sort_options::
00149 sort(diff_collection & syms, bool reverse_sort, bool lf) const
00150 {
00151     long_filenames = lf;
00152 
00153     vector<sort_order> sort_option(options);
00154     for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) {
00155         if (find(sort_option.begin(), sort_option.end(), cur) ==
00156             sort_option.end())
00157             sort_option.push_back(cur);
00158     }
00159 
00160     stable_sort(syms.begin(), syms.end(),
00161                 symbol_compare(sort_option, reverse_sort));
00162 }
00163 
00164 
00165 void sort_options::add_sort_option(string const & name)
00166 {
00167     if (name == "vma") {
00168         options.push_back(vma);
00169     } else if (name == "sample") {
00170         options.push_back(sample);
00171     } else if (name == "symbol") {
00172         options.push_back(symbol);
00173     } else if (name == "debug") {
00174         options.push_back(debug);
00175     } else if (name == "image") {
00176         options.push_back(image);
00177     } else if (name == "app-name") {
00178         options.push_back(app_name);
00179     } else {
00180         ostringstream os;
00181         os << "unknown sort option: " << name << endl;
00182         throw op_fatal_error(os.str());
00183     }
00184 }
00185 
00186 
00187 void sort_options::add_sort_option(sort_options::sort_order order)
00188 {
00189     options.push_back(order);
00190 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1