Skip to content

Commit

Permalink
tools: refactor table-printing code a bit
Browse files Browse the repository at this point in the history
This changes the table-printing code to use a class and add some extra
safety checks that the added columns have matching numbers of rows.

Change-Id: I7e9556a14b6745f6bd07d1aee111bfa5cd9297fe
Reviewed-on: http://gerrit.cloudera.org:8080/7259
Reviewed-by: Adar Dembo <[email protected]>
Tested-by: Kudu Jenkins
  • Loading branch information
toddlipcon committed Jun 27, 2017
1 parent 3c3cd32 commit 96ad3b0
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 29 deletions.
11 changes: 7 additions & 4 deletions src/kudu/tools/ksck.cc
Original file line number Diff line number Diff line change
Expand Up @@ -834,8 +834,7 @@ Ksck::CheckResult Ksck::VerifyTablet(const shared_ptr<KsckTablet>& tablet, int t
Out() << "The consensus matrix is:" << endl;

// Prepare the header and columns for PrintTable.
const vector<string> headers{ "Config source", "Voters", "Current term",
"Config index", "Committed?" };
DataTable table({});

// Seed the columns with the master info.
vector<string> sources{"master"};
Expand Down Expand Up @@ -863,8 +862,12 @@ Ksck::CheckResult Ksck::VerifyTablet(const shared_ptr<KsckTablet>& tablet, int t
committed.emplace_back(replica.consensus_state->type == KsckConsensusConfigType::PENDING ?
"No" : "Yes");
}
vector<vector<string>> columns{ sources, voters, terms, indexes, committed };
PrintTable(headers, columns, Out());
table.AddColumn("Config source", std::move(sources));
table.AddColumn("Voters", std::move(voters));
table.AddColumn("Current term", std::move(terms));
table.AddColumn("Config index", std::move(indexes));
table.AddColumn("Committed?", std::move(committed));
CHECK_OK(table.PrintTo(Out()));
}

return result;
Expand Down
35 changes: 27 additions & 8 deletions src/kudu/tools/tool_action_common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -480,19 +480,38 @@ void PrintTable(const vector<vector<string>>& columns, const string& separator,

} // anonymous namespace

Status PrintTable(const vector<string>& headers,
const vector<vector<string>>& columns,
ostream& out) {
DataTable::DataTable(std::vector<string> col_names)
: column_names_(std::move(col_names)),
columns_(column_names_.size()) {
}

void DataTable::AddRow(std::vector<string> row) {
CHECK_EQ(row.size(), columns_.size());
int i = 0;
for (auto& v : row) {
columns_[i++].emplace_back(std::move(v));
}
}

void DataTable::AddColumn(string name, vector<string> column) {
if (!columns_.empty()) {
CHECK_EQ(column.size(), columns_[0].size());
}
column_names_.emplace_back(std::move(name));
columns_.emplace_back(std::move(column));
}

Status DataTable::PrintTo(ostream& out) const {
if (boost::iequals(FLAGS_format, "pretty")) {
PrettyPrintTable(headers, columns, out);
PrettyPrintTable(column_names_, columns_, out);
} else if (boost::iequals(FLAGS_format, "space")) {
PrintTable(columns, " ", out);
PrintTable(columns_, " ", out);
} else if (boost::iequals(FLAGS_format, "tsv")) {
PrintTable(columns, " ", out);
PrintTable(columns_, " ", out);
} else if (boost::iequals(FLAGS_format, "csv")) {
PrintTable(columns, ",", out);
PrintTable(columns_, ",", out);
} else if (boost::iequals(FLAGS_format, "json")) {
JsonPrintTable(headers, columns, out);
JsonPrintTable(column_names_, columns_, out);
} else {
return Status::InvalidArgument("unknown format (--format)", FLAGS_format);
}
Expand Down
39 changes: 35 additions & 4 deletions src/kudu/tools/tool_action_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,41 @@ Status PrintServerTimestamp(const std::string& address, uint16_t default_port);
Status SetServerFlag(const std::string& address, uint16_t default_port,
const std::string& flag, const std::string& value);

// Prints a table.
Status PrintTable(const std::vector<std::string>& headers,
const std::vector<std::vector<std::string>>& columns,
std::ostream& out);
// A table of data to present to the user.
//
// Supports formatting based on the --format flag.
// All data is buffered in memory before being output.
//
// Example usage:
// DataTable table({"person", "favorite color"});
// vector<string> cols(2);
// AddTableRow({"joe", "red"}, &cols);
// AddTableRow({"bob", "green"}, &cols);
// AddTableRow({"alice", "yellow"}, &cols);
// PrintTable(headers, cols, cout);
class DataTable {
public:
// Construct a table with the given column names.
explicit DataTable(std::vector<std::string> col_names);

// Add a row of data to the table.
//
// REQUIRES: 'row.size()' matches the number of column names specified
// in the constructor.
void AddRow(std::vector<std::string> row);

// Add a column of data to the right side of the table.
//
// REQUIRES: if any rows have been added already, the length of this column
// must match the length of all existing columns.
void AddColumn(std::string name, std::vector<std::string> column);

// Print the table to 'out'.
Status PrintTo(std::ostream& out) const WARN_UNUSED_RESULT;
private:
std::vector<std::string> column_names_;
std::vector<std::vector<std::string>> columns_;
};

// Wrapper around a Kudu client which allows calling proxy methods on the leader
// master.
Expand Down
9 changes: 3 additions & 6 deletions src/kudu/tools/tool_action_master.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ Status ListMasters(const RunnerContext& context) {
return StatusFromPB(resp.error().status());
}

vector<string> headers;
vector<vector<string>> columns;
DataTable table({});

vector<ServerEntryPB> masters;
std::copy_if(resp.masters().begin(), resp.masters().end(), std::back_inserter(masters),
Expand All @@ -107,7 +106,6 @@ Status ListMasters(const RunnerContext& context) {
};

for (const auto& column : strings::Split(FLAGS_columns, ",", strings::SkipEmpty())) {
headers.push_back(column.ToString());
vector<string> values;
if (boost::iequals(column, "uuid")) {
for (const auto& master : masters) {
Expand Down Expand Up @@ -136,11 +134,10 @@ Status ListMasters(const RunnerContext& context) {
} else {
return Status::InvalidArgument("unknown column (--columns)", column);
}

columns.emplace_back(std::move(values));
table.AddColumn(column.ToString(), std::move(values));
}

RETURN_NOT_OK(PrintTable(headers, columns, cout));
RETURN_NOT_OK(table.PrintTo(cout));
return Status::OK();
}

Expand Down
10 changes: 3 additions & 7 deletions src/kudu/tools/tool_action_tserver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,14 @@ Status ListTServers(const RunnerContext& context) {
return StatusFromPB(resp.error().status());
}

vector<string> headers;
vector<vector<string>> columns;

DataTable table({});
const auto& servers = resp.servers();

auto hostport_to_string = [](const HostPortPB& hostport) {
return strings::Substitute("$0:$1", hostport.host(), hostport.port());
};

for (const auto& column : strings::Split(FLAGS_columns, ",", strings::SkipEmpty())) {
headers.emplace_back(column.ToString());
vector<string> values;
if (boost::iequals(column, "uuid")) {
for (const auto& server : servers) {
Expand Down Expand Up @@ -134,11 +131,10 @@ Status ListTServers(const RunnerContext& context) {
} else {
return Status::InvalidArgument("unknown column (--columns)", column);
}

columns.emplace_back(std::move(values));
table.AddColumn(column.ToString(), std::move(values));
}

RETURN_NOT_OK(PrintTable(headers, columns, cout));
RETURN_NOT_OK(table.PrintTo(cout));
return Status::OK();
}

Expand Down

0 comments on commit 96ad3b0

Please sign in to comment.