HEBench
hebench_report_overview_header.cpp
Go to the documentation of this file.
1 
2 // Copyright (C) 2021 Intel Corporation
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include <bitset>
6 #include <sstream>
7 #include <utility>
8 
9 #include "hebench/modules/general/include/hebench_utilities.h"
10 
12 
13 using namespace std::literals;
14 
15 namespace hebench {
16 namespace ReportGen {
17 
18 std::vector<std::string_view> OverviewHeader::extractInfoFromCSVLine(std::string_view s_row, const std::string_view &s_tag, std::size_t num_values)
19 {
20  std::vector<std::string_view> retval;
21 
22  retval.reserve(num_values);
23  hebench::Utilities::trim(s_row);
24  auto pos = s_row.find(s_tag);
25  if (pos != std::string_view::npos)
26  {
27  s_row.remove_prefix(pos + s_tag.size());
28  while (!s_row.empty() && retval.size() < num_values)
29  {
30  hebench::Utilities::ltrim(s_row);
31  char ch_to_find = ',';
32  if (!s_row.empty() && s_row.front() == '"')
33  {
34  // deal with quotations
35  ch_to_find = '"';
36  s_row.remove_prefix(1);
37  }
38  pos = s_row.find_first_of(ch_to_find);
39  if (pos == std::string_view::npos)
40  {
41  pos = s_row.size();
42  }
43  retval.emplace_back(s_row.substr(0, pos));
44  hebench::Utilities::trim(retval.back());
45  s_row.remove_prefix(pos);
46 
47  if (!s_row.empty())
48  {
49  // remove character delimiter found
50  s_row.remove_prefix(1);
51  if (ch_to_find == '"')
52  {
53  // ignore the rest of the value until next delimiter
54  pos = s_row.find_first_of(',');
55  if (pos == std::string_view::npos)
56  s_row = std::string_view();
57  else
58  s_row.remove_prefix(pos + 1);
59  } // end if
60  } // end if
61  } // end while
62  } // end if
63 
64  return retval;
65 }
66 
67 std::string OverviewHeader::extractCiphertextBitset(std::vector<std::string_view> s_indices)
68 {
69  std::bitset<sizeof(std::uint32_t) << 3> cipher_bits;
70  if (hebench::Utilities::ToLowerCase(s_indices.front()) == "none")
71  cipher_bits.reset();
72  else if (hebench::Utilities::ToLowerCase(s_indices.front()) == "all")
73  cipher_bits.set();
74  else
75  {
76  for (std::size_t i = 0; i < s_indices.size(); ++i)
77  {
78  std::stringstream ss = std::stringstream(std::string(s_indices[i]));
79  std::size_t position;
80  ss >> position;
81  if (!ss)
82  throw std::runtime_error("Invalid value for encrypted parameters index. Expected an integer between 0 and " + std::to_string(sizeof(std::uint32_t) - 1) + ", inclussive, but read \"" + std::string(s_indices[i]) + "\".");
83  cipher_bits.set(position);
84  } // end for
85  } // end else
86 
87  std::string retval = cipher_bits.to_string();
88  hebench::Utilities::ltrim(retval, "0");
89  if (retval.empty())
90  retval = "0";
91  return retval;
92 }
93 
94 void OverviewHeader::parseHeader(const std::string &filename, const std::string &s_header, const std::string &s_end_state)
95 {
96  static const std::string s_trim = std::string(",") + hebench::Utilities::BlankTrim;
97 
98  std::stringstream ss(s_header);
99  std::string s_line;
100  while (std::getline(ss, s_line))
101  {
102  hebench::Utilities::trim(s_line, s_trim.c_str());
103  std::vector<std::string_view> values;
104 
105  if (this->workload_name.empty())
106  {
107  values = extractInfoFromCSVLine(s_line, "Workload,", 1);
108  if (values.size() > 0)
109  this->workload_name.assign(values.front().begin(), values.front().end());
110  } // end if
111  this->end_state = s_end_state;
112  if (this->category.empty())
113  {
114  values = extractInfoFromCSVLine(s_line, "Category,", 1);
115  if (values.size() > 0)
116  this->category.assign(values.front().begin(), values.front().end());
117  } // end if
118  if (this->data_type.empty())
119  {
120  values = extractInfoFromCSVLine(s_line, "Data type,", 1);
121  if (values.size() > 0)
122  this->data_type.assign(values.front().begin(), values.front().end());
123  } // end if
124  if (this->cipher_text.empty())
125  {
126  values = extractInfoFromCSVLine(s_line, "Encrypted op parameters (index),", sizeof(std::uint32_t));
127  if (values.size() > 0)
128  this->cipher_text = extractCiphertextBitset(values);
129  } // end if
130  if (this->scheme.empty())
131  {
132  values = extractInfoFromCSVLine(s_line, "Scheme,", 1);
133  if (values.size() > 0)
134  this->scheme.assign(values.front().begin(), values.front().end());
135  } // end if
136  if (this->security.empty())
137  {
138  values = extractInfoFromCSVLine(s_line, "Security,", 1);
139  if (values.size() > 0)
140  this->security.assign(values.front().begin(), values.front().end());
141  } // end if
142 
143  values = extractInfoFromCSVLine(s_line, "Extra,", 1);
144  if (values.size() > 0)
145  {
146  std::string s_tmp(values.front());
147  std::stringstream ss_value(s_tmp);
148  ss_value >> this->other;
149  if (!ss_value)
150  throw std::runtime_error("Invalid value for \"Extra\" tag. Expected an integer, but read \"" + s_tmp + "\".");
151  } // end if
152  } // end while
153 
154  this->report_file = filename;
155  // extract workload parameters from file name
156  std::string_view s_view = this->report_file;
157  auto pos = s_view.find("wp_");
158  if (pos != std::string_view::npos)
159  {
160  s_view.remove_prefix(pos + "wp_"sv.size());
161  pos = s_view.find_first_of("-/\\");
162  if (pos != std::string_view::npos)
163  s_view.remove_suffix(s_view.size() - pos);
164  // s_view now has only the workload params separated by underscores
165  auto tokens = hebench::Utilities::tokenize(s_view, "_");
166  for (std::size_t i = 0; i < tokens.size(); ++i)
167  this->w_params.emplace_back(tokens[i].begin(), tokens[i].end());
168  } // end if
169 }
170 
171 void OverviewHeader::outputHeader(std::ostream &os, bool new_line)
172 {
173  (this->workload_name.find_first_of(',') == std::string::npos ?
174  os << this->workload_name :
175  os << "\"" << this->workload_name << "\"");
176  os << ",";
177  os << "\"" << this->end_state << "\""
178  << ",";
179  os << "\"" << this->report_file << "\""
180  << ",";
181  (this->category.find_first_of(',') == std::string::npos ?
182  os << this->category :
183  os << "\"" << this->category << "\"");
184  os << ",";
185  (this->data_type.find_first_of(',') == std::string::npos ?
186  os << this->data_type :
187  os << "\"" << this->data_type << "\"");
188  os << ",";
189  (this->cipher_text.find_first_of(',') == std::string::npos ?
190  os << this->cipher_text :
191  os << "\"" << this->cipher_text << "\"");
192  os << ",";
193  (this->scheme.find_first_of(',') == std::string::npos ?
194  os << this->scheme :
195  os << "\"" << this->scheme << "\"");
196  os << ",";
197  (this->security.find_first_of(',') == std::string::npos ?
198  os << this->security :
199  os << "\"" << this->security << "\"");
200  os << "," << this->other;
201  if (new_line)
202  os << std::endl;
203 }
204 
205 } // namespace ReportGen
206 } // namespace hebench
std::string to_string(const std::string_view &s)