From f98871dd5adcf9d9f920f74d3bcebe06131086b2 Mon Sep 17 00:00:00 2001 From: Horst Schirmeier Date: Thu, 28 Aug 2014 11:32:40 +0200 Subject: [PATCH] prune-trace: preserve existing data With this change, prune-trace checks for existing fsppilot/fspgroup entries for each variant to be pruned, and skips the variant in this case. This safety measure can be switched off with --overwrite. Change-Id: I7e758a9853a25685ca176cf1a1810523753cdd4a --- tools/prune-trace/Pruner.cc | 62 ++++++++++++++++++++++++++++-------- tools/prune-trace/Pruner.hpp | 7 ++-- tools/prune-trace/main.cc | 18 +++++++---- 3 files changed, 64 insertions(+), 23 deletions(-) diff --git a/tools/prune-trace/Pruner.cc b/tools/prune-trace/Pruner.cc index 644a9d0b..3e8c7e10 100644 --- a/tools/prune-trace/Pruner.cc +++ b/tools/prune-trace/Pruner.cc @@ -8,38 +8,72 @@ static Logger LOG ("Pruner"); #include "Pruner.hpp" -bool Pruner::init(fail::Database *db, +bool Pruner::init( const std::vector& variants, const std::vector& variants_exclude, const std::vector& benchmarks, - const std::vector& benchmarks_exclude) + const std::vector& benchmarks_exclude, + bool overwrite) { - this->db = db; - m_variants = db->get_variants( variants, variants_exclude, benchmarks, benchmarks_exclude); + + if (!(m_method_id = db->get_fspmethod_id(method_name()))) { + return false; + } + LOG << "Pruning with method " << method_name() << " (ID: " << m_method_id << ")" + << std::endl; + + // make sure we only prune variants that haven't been pruned previously + // (unless we run with --overwrite) + if (!overwrite) { + for (std::vector::iterator it = m_variants.begin(); + it != m_variants.end(); ) { + std::stringstream ss; + MYSQL_RES *res; + ss << "(SELECT variant_id FROM fsppilot WHERE " + << " variant_id = " << it->id << " AND " + << " fspmethod_id = " << m_method_id + << " LIMIT 1)" + << " UNION ALL " + << "(SELECT variant_id FROM fspgroup WHERE " + << " variant_id = " << it->id << " AND " + << " fspmethod_id = " << m_method_id + << " LIMIT 1)"; + if (!(res = db->query(ss.str().c_str(), true))) { + return false; + } + if (mysql_num_rows(res) > 0) { + // skip this variant + LOG << "skipping " << it->variant << "/" << it->benchmark + << " due to existing pruning data (use --overwrite to skip this check)" + << std::endl; + it = m_variants.erase(it); + } else { + ++it; + } + } + } + + // any variants left? if (m_variants.size() == 0) { LOG << "no variants found, nothing to do" << std::endl; return false; } - std::stringstream ss; + // construct comma-separated list usable in SQL "IN (...)" + std::stringstream commalist; for (std::vector::const_iterator it = m_variants.begin(); it != m_variants.end(); ++it) { + if (it != m_variants.begin()) { - ss << ","; + commalist << ","; } - ss << it->id; + commalist << it->id; } - m_variants_sql = ss.str(); + m_variants_sql = commalist.str(); - if (!(m_method_id = db->get_fspmethod_id(method_name()))) { - return false; - } - - LOG << "Pruning with method " << method_name() << " (ID: " << m_method_id << ")" - << std::endl; return true; } diff --git a/tools/prune-trace/Pruner.hpp b/tools/prune-trace/Pruner.hpp index e6e1f5dc..fcc02a61 100644 --- a/tools/prune-trace/Pruner.hpp +++ b/tools/prune-trace/Pruner.hpp @@ -13,11 +13,14 @@ protected: std::string m_variants_sql; public: - bool init(fail::Database *db, + void set_db(fail::Database *db) { this->db = db; } + + bool init( const std::vector& variants, const std::vector& variants_exclude, const std::vector& benchmarks, - const std::vector& benchmarks_exclude); + const std::vector& benchmarks_exclude, + bool overwrite); /** * Callback function that can be used to add command line options diff --git a/tools/prune-trace/main.cc b/tools/prune-trace/main.cc index d276bb5f..fe78cd32 100644 --- a/tools/prune-trace/main.cc +++ b/tools/prune-trace/main.cc @@ -45,6 +45,9 @@ int main(int argc, char *argv[]) { CommandLine::option_handle NO_DELETE = cmd.addOption("", "no-delete", Arg::None, "--no-delete \tAssume there are no DB entries for this variant/benchmark, don't issue a DELETE"); + CommandLine::option_handle OVERWRITE = + cmd.addOption("", "overwrite", Arg::None, + "--overwrite \tOverwrite already existing pruning data (the default is to skip variants with existing entries)"); if (!cmd.parse()) { std::cerr << "Error parsing arguments." << std::endl; @@ -88,6 +91,7 @@ int main(int argc, char *argv[]) { } Database *db = Database::cmdline_connect(); + pruner->set_db(db); std::vector variants, benchmarks, variants_exclude, benchmarks_exclude; if (cmd[VARIANT]) { @@ -124,7 +128,12 @@ int main(int argc, char *argv[]) { benchmarks.push_back("%"); } - if (!pruner->init(db, variants, variants_exclude, benchmarks, benchmarks_exclude)) { + if (!pruner->create_database()) { + LOG << "pruner->create_database() failed" << endl; + exit(-1); + } + + if (!pruner->init(variants, variants_exclude, benchmarks, benchmarks_exclude, cmd[OVERWRITE])) { LOG << "pruner->init() failed" << endl; exit(-1); } @@ -132,12 +141,7 @@ int main(int argc, char *argv[]) { //////////////////////////////////////////////////////////////// // Do the actual import //////////////////////////////////////////////////////////////// - if (!pruner->create_database()) { - LOG << "create_database() failed" << endl; - exit(-1); - } - - if (!cmd[NO_DELETE] && !pruner->clear_database()) { + if (!cmd[NO_DELETE] && cmd[OVERWRITE] && !pruner->clear_database()) { LOG << "clear_database() failed" << endl; exit(-1); }