| 989 | } |
| 990 | |
| 991 | void RuntimeProfileBase::AddSkewInfo(RuntimeProfileBase* root, double threshold) { |
| 992 | lock_guard<SpinLock> l(children_lock_); |
| 993 | DCHECK(root); |
| 994 | // A map of specs for profiles and average counters in profiles that can potentially |
| 995 | // harbor skews. Each spec is a pair of a profile name prefix and a list of counter |
| 996 | // names. Lookup of the map for a profile name prefix is O(1). |
| 997 | typedef string NodeNamePrefix; |
| 998 | typedef vector<string> CounterNames; |
| 999 | static const unordered_map<NodeNamePrefix, CounterNames> skew_profile_specs = { |
| 1000 | {"KUDU_SCAN_NODE", {"RowsRead"}}, {"HDFS_SCAN_NODE", {"RowsRead"}}, |
| 1001 | {"HASH_JOIN_NODE", {"ProbeRows", "BuildRows"}}, |
| 1002 | {"GroupingAggregator", {"RowsReturned"}}, {"EXCHANGE_NODE", {"RowsReturned"}}, |
| 1003 | {"SORT_NODE", {"RowsReturned"}}}; |
| 1004 | // If this profile can potentially harbor skews, identify the corresponding counters |
| 1005 | // within it and verify. |
| 1006 | for (auto& skew_profile_it : skew_profile_specs) { |
| 1007 | // Test if the profile name prefix is indeed a prefix of the profile name. |
| 1008 | if (name().find(skew_profile_it.first) == 0) { |
| 1009 | for (auto& counter_name_it : skew_profile_it.second) { |
| 1010 | auto counter_it = counter_map_.find(counter_name_it); |
| 1011 | // Test if the counter name is in the counter spec. |
| 1012 | if (counter_it != counter_map_.end()) { |
| 1013 | auto average_counter = |
| 1014 | dynamic_cast<RuntimeProfile::AveragedCounter*>(counter_it->second); |
| 1015 | string details; |
| 1016 | // Skew detection can only be done for an average counter. |
| 1017 | if (average_counter && average_counter->HasSkew(threshold, &details)) { |
| 1018 | // Skew detected: |
| 1019 | // Log the profile name in the 'root' profile |
| 1020 | root->AddInfoStringInternal(SKEW_SUMMARY, name(), true); |
| 1021 | // Log the counter name and skew details in 'this' profile |
| 1022 | this->AddInfoStringInternal( |
| 1023 | SKEW_DETAILS, StrCat(counter_name_it, " ", details), true); |
| 1024 | } |
| 1025 | } |
| 1026 | } |
| 1027 | } |
| 1028 | } |
| 1029 | // Keep looking from within each child profile. |
| 1030 | for (auto child : children_) { |
| 1031 | child.first->AddSkewInfo(root, threshold); |
| 1032 | } |
| 1033 | } |
| 1034 | |
| 1035 | bool RuntimeProfileBase::ParseVerbosity(const string& str, Verbosity* out) { |
| 1036 | string lower = to_lower_copy(str); |
no test coverage detected