Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
pretty-printer.h
Go to the documentation of this file.
1 // Copyright 2015 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef IMPALA_UTIL_PRETTY_PRINTER_H
16 #define IMPALA_UTIL_PRETTY_PRINTER_H
17 
18 #include <boost/algorithm/string.hpp>
19 #include <cmath>
20 #include <sstream>
21 #include <iomanip>
22 
23 #include "gen-cpp/RuntimeProfile_types.h"
24 #include "util/cpu-info.h"
25 #include "util/template-util.h"
26 
27 namespace impala {
28 
32  public:
33  static std::string Print(bool value, TUnit::type ignored, bool verbose = false) {
34  std::stringstream ss;
35  ss << std::boolalpha << value;
36  return ss.str();
37  }
38 
43  template<typename T>
44  static ENABLE_IF_ARITHMETIC(T, std::string)
45  Print(T value, TUnit::type unit, bool verbose = false) {
46  std::stringstream ss;
47  ss.flags(std::ios::fixed);
48  switch (unit) {
49  case TUnit::NONE: {
50  ss << value;
51  return ss.str();
52  }
53 
54  case TUnit::UNIT: {
55  std::string unit;
56  double output = GetUnit(value, &unit);
57  if (unit.empty()) {
58  ss << value;
59  } else {
60  ss << std::setprecision(PRECISION) << output << unit;
61  }
62  if (verbose) ss << " (" << value << ")";
63  break;
64  }
65 
66  case TUnit::UNIT_PER_SECOND: {
67  std::string unit;
68  double output = GetUnit(value, &unit);
69  if (output == 0) {
70  ss << "0";
71  } else {
72  ss << std::setprecision(PRECISION) << output << " " << unit << "/sec";
73  }
74  break;
75  }
76 
77  case TUnit::CPU_TICKS: {
78  if (value < CpuInfo::cycles_per_ms()) {
79  ss << std::setprecision(PRECISION) << (value / 1000.) << "K clock cycles";
80  } else {
81  value /= CpuInfo::cycles_per_ms();
82  PrintTimeMs(value, &ss);
83  }
84  break;
85  }
86 
87  case TUnit::TIME_NS: {
88  if (value >= BILLION) {
90  value /= MILLION;
91  PrintTimeMs(value, &ss);
92  } else if (value >= MILLION) {
94  value /= 1000;
95  ss << value / 1000 << "." << Mod(value, 1000) << "ms";
96  } else if (value > 1000) {
98  ss << value / 1000 << "." << Mod(value, 1000) << "us";
99  } else {
100  ss << value << "ns";
101  }
102  break;
103  }
104 
105  case TUnit::TIME_MS: {
106  PrintTimeMs(value, &ss);
107  break;
108  }
109 
110  case TUnit::TIME_S: {
111  PrintTimeMs(value * 1000, &ss);
112  break;
113  }
114 
115  case TUnit::BYTES: {
116  std::string unit;
117  double output = GetByteUnit(value, &unit);
118  if (output == 0) {
119  ss << "0";
120  } else {
121  ss << std::setprecision(PRECISION) << output << " " << unit;
122  if (verbose) ss << " (" << value << ")";
123  }
124  break;
125  }
126 
127  case TUnit::BYTES_PER_SECOND: {
128  std::string unit;
129  double output = GetByteUnit(value, &unit);
130  ss << std::setprecision(PRECISION) << output << " " << unit << "/sec";
131  break;
132  }
133 
135  case TUnit::DOUBLE_VALUE: {
136  double output = *reinterpret_cast<double*>(&value);
137  ss << std::setprecision(PRECISION) << output << " ";
138  break;
139  }
140 
141  default:
142  DCHECK(false) << "Unsupported TUnit: " << value;
143  break;
144  }
145  return ss.str();
146  }
147 
149  //
152  template<typename T>
153  static ENABLE_IF_NOT_ARITHMETIC(T, std::string)
154  Print(const T& value, TUnit::type unit) {
155  std::stringstream ss;
156  ss << std::boolalpha << value;
157  return ss.str();
158  }
159 
161  template <typename I>
162  static void PrintStringList(const I& iterable, TUnit::type unit,
163  std::stringstream* out) {
164  std::vector<std::string> strings;
165  for (typename I::const_iterator it = iterable.begin(); it != iterable.end(); ++it) {
166  std::stringstream ss;
167  ss << PrettyPrinter::Print(*it, unit);
168  strings.push_back(ss.str());
169  }
170 
171  (*out) <<"[" << boost::algorithm::join(strings, ", ") << "]";
172  }
173 
175  static std::string PrintBytes(int64_t value) {
176  return PrettyPrinter::Print(value, TUnit::BYTES);
177  }
178 
179  private:
180  static const int PRECISION = 2;
181  static const int64_t KILOBYTE = 1024;
182  static const int64_t MEGABYTE = KILOBYTE * 1024;
183  static const int64_t GIGABYTE = MEGABYTE * 1024;
184 
185  static const int64_t SECOND = 1000;
186  static const int64_t MINUTE = SECOND * 60;
187  static const int64_t HOUR = MINUTE * 60;
188 
189  static const int64_t THOUSAND = 1000;
190  static const int64_t MILLION = THOUSAND * 1000;
191  static const int64_t BILLION = MILLION * 1000;
192 
193  template <typename T>
194  static double GetByteUnit(T value, std::string* unit) {
195  if (value == 0) {
196  *unit = "";
197  return value;
198  } else if (value >= GIGABYTE) {
199  *unit = "GB";
200  return value / (double) GIGABYTE;
201  } else if (value >= MEGABYTE ) {
202  *unit = "MB";
203  return value / (double) MEGABYTE;
204  } else if (value >= KILOBYTE) {
205  *unit = "KB";
206  return value / (double) KILOBYTE;
207  } else {
208  *unit = "B";
209  return value;
210  }
211  }
212 
213  template <typename T>
214  static double GetUnit(T value, std::string* unit) {
215  if (value >= BILLION) {
216  *unit = "B";
217  return value / (1. * BILLION);
218  } else if (value >= MILLION) {
219  *unit = "M";
220  return value / (1. * MILLION);
221  } else if (value >= THOUSAND) {
222  *unit = "K";
223  return value / (1. * THOUSAND);
224  } else {
225  *unit = "";
226  return value;
227  }
228  }
229 
231  template <typename T>
232  static ENABLE_IF_INTEGRAL(T, int64_t) Mod(const T& value, const int modulus) {
233  return value % modulus;
234  }
235 
236  template <typename T>
237  static ENABLE_IF_FLOAT(T, double) Mod(const T& value, int modulus) {
238  return fmod(value, 1. * modulus);
239  }
240 
242  template <typename T>
243  static void PrintTimeMs(T value, std::stringstream* ss) {
244  DCHECK_GE(value, static_cast<T>(0));
245  if (value == 0) {
246  *ss << "0";
247  } else {
248  bool hour = false;
249  bool minute = false;
250  bool second = false;
251  if (value >= HOUR) {
252  *ss << static_cast<int64_t>(value / HOUR) << "h";
253  value = Mod(value, HOUR);
254  hour = true;
255  }
256  if (value >= MINUTE) {
257  *ss << static_cast<int64_t>(value / MINUTE) << "m";
258  value = Mod(value, MINUTE);
259  minute = true;
260  }
261  if (!hour && value >= SECOND) {
262  *ss << static_cast<int64_t>(value / SECOND) << "s";
263  value = Mod(value, SECOND);
264  second = true;
265  }
266  if (!hour && !minute) {
267  if (second) *ss << std::setw(3) << std::setfill('0');
268  *ss << static_cast<int64_t>(value) << "ms";
269  }
270  }
271  }
272 };
273 
274 }
275 
276 #endif
static ENABLE_IF_ARITHMETIC(T, std::string) Print(T value
static void PrintTimeMs(T value, std::stringstream *ss)
Print the value (time in ms) to ss.
static const int64_t KILOBYTE
#define ENABLE_IF_NOT_ARITHMETIC(type_param, return_type)
Definition: template-util.h:37
static const int64_t MINUTE
static TUnit::type bool verbose
static const int64_t GIGABYTE
static double GetByteUnit(T value, std::string *unit)
static const int64_t BILLION
static std::string Print(bool value, TUnit::type ignored, bool verbose=false)
static TUnit::type unit
static int64_t cycles_per_ms()
Returns the number of cpu cycles per millisecond.
Definition: cpu-info.h:74
static const int64_t SECOND
static const int64_t MILLION
static const int64_t MEGABYTE
static const int64_t HOUR
static const int modulus return value modulus
static ENABLE_IF_INTEGRAL(T, int64_t) Mod(const T &value
Utility to perform integer modulo if T is integral, otherwise to use fmod().
static ENABLE_IF_FLOAT(T, double) Mod(const T &value
static double GetUnit(T value, std::string *unit)
static const int64_t THOUSAND