Replace curTick global variable with accessor functions.
[gem5.git] / src / base / stats / mysql.cc
index 6d12b4fc14a7ba5d4509571142c472dd5798a001..d257de7434aba62a13584824a67016ac2d1d274b 100644 (file)
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
  */
 
 #include <cassert>
+#include <cstdio>
 #include <map>
 #include <sstream>
 #include <string>
 #include "base/misc.hh"
 #include "base/mysql.hh"
 #include "base/statistics.hh"
-#include "base/stats/flags.hh"
+#include "base/stats/info.hh"
 #include "base/stats/mysql.hh"
 #include "base/stats/mysql_run.hh"
-#include "base/stats/statdb.hh"
 #include "base/stats/types.hh"
 #include "base/str.hh"
-#include "sim/host.hh"
+#include "base/types.hh"
+#include "base/userinfo.hh"
 
 using namespace std;
 
 namespace Stats {
 
-MySqlRun MySqlDB;
-
-bool
-MySqlConnected()
-{
-    return MySqlDB.connected();
-}
-
 void
 MySqlRun::connect(const string &host, const string &user, const string &passwd,
                   const string &db, const string &name, const string &sample,
@@ -155,30 +150,6 @@ MySqlRun::cleanup()
 
     if (mysql.commit())
         panic("could not commit transaction\n%s\n", mysql.error);
-
-    mysql.query("DELETE bins "
-                "FROM bins "
-                "LEFT JOIN data ON bn_id=dt_bin "
-                "WHERE dt_bin IS NULL");
-
-    if (mysql.commit())
-        panic("could not commit transaction\n%s\n", mysql.error);
-
-    mysql.query("DELETE events"
-                "FROM events"
-                "LEFT JOIN runs ON ev_run=rn_id"
-                "WHERE rn_id IS NULL");
-
-    if (mysql.commit())
-        panic("could not commit transaction\n%s\n", mysql.error);
-
-    mysql.query("DELETE event_names"
-                "FROM event_names"
-                "LEFT JOIN events ON en_id=ev_event"
-                "WHERE ev_event IS NULL");
-
-    if (mysql.commit())
-        panic("could not commit transaction\n%s\n", mysql.error);
 }
 
 void
@@ -202,9 +173,9 @@ SetupStat::init()
 }
 
 unsigned
-SetupStat::setup()
+SetupStat::setup(MySqlRun *run)
 {
-    MySQL::Connection &mysql = MySqlDB.conn();
+    MySQL::Connection &mysql = run->conn();
 
     stringstream insert;
     ccprintf(insert,
@@ -307,53 +278,8 @@ SetupStat::setup()
     return statid;
 }
 
-unsigned
-SetupBin(const string &bin)
-{
-    static map<string, int> binmap;
-
-    using namespace MySQL;
-    map<string,int>::const_iterator i = binmap.find(bin);
-    if (i != binmap.end())
-        return (*i).second;
-
-    Connection &mysql = MySqlDB.conn();
-    assert(mysql.connected());
-
-    uint16_t bin_id;
-
-    stringstream select;
-    stringstream insert;
-    ccprintf(select, "SELECT bn_id FROM bins WHERE bn_name=\"%s\"", bin);
-
-    mysql.query(select);
-    MySQL::Result result = mysql.store_result();
-    if (result) {
-        assert(result.num_fields() == 1);
-        MySQL::Row row = result.fetch_row();
-        if (row) {
-            to_number(row[0], bin_id);
-            goto exit;
-        }
-    }
-
-    ccprintf(insert, "INSERT INTO bins(bn_name) values(\"%s\")", bin);
-
-    mysql.query(insert);
-    if (mysql.error)
-        panic("could not get a bin\n%s\n", mysql.error);
-
-    bin_id = mysql.insert_id();
-    if (mysql.commit())
-        panic("could not commit transaction\n%s\n", mysql.error);
-
-    binmap.insert(make_pair(bin, bin_id));
-
-  exit:
-    return bin_id;
-}
-
-InsertData::InsertData()
+InsertData::InsertData(MySqlRun *_run)
+    : run(_run)
 {
     query = new char[maxsize + 1];
     size = 0;
@@ -369,7 +295,7 @@ void
 InsertData::flush()
 {
     if (size) {
-        MySQL::Connection &mysql = MySqlDB.conn();
+        MySQL::Connection &mysql = run->conn();
         assert(mysql.connected());
         mysql.query(query);
         if (mysql.error)
@@ -382,7 +308,7 @@ InsertData::flush()
     size = 0;
     first = true;
     strcpy(query, "INSERT INTO "
-           "data(dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_bin,dt_data) "
+           "data(dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_data) "
            "values");
     size = strlen(query);
 }
@@ -400,9 +326,9 @@ InsertData::insert()
 
     first = false;
 
-    size += sprintf(query + size, "(%u,%d,%d,%u,%llu,%u,\"%f\")",
-                    stat, x, y, MySqlDB.run(), (unsigned long long)tick,
-                    bin, data);
+    size += sprintf(query + size, "(%u,%d,%d,%u,%llu,\"%f\")",
+                    stat, x, y, run->run(), (unsigned long long)tick,
+                    data);
 }
 
 struct InsertSubData
@@ -413,13 +339,13 @@ struct InsertSubData
     string name;
     string descr;
 
-    void setup();
+    void setup(MySqlRun *run);
 };
 
 void
-InsertSubData::setup()
+InsertSubData::setup(MySqlRun *run)
 {
-    MySQL::Connection &mysql = MySqlDB.conn();
+    MySQL::Connection &mysql = run->conn();
     assert(mysql.connected());
     stringstream insert;
     ccprintf(insert,
@@ -429,53 +355,33 @@ InsertSubData::setup()
 
     mysql.query(insert);
 //    if (mysql.error)
-//     panic("could not insert subdata\n%s\n", mysql.error);
+//      panic("could not insert subdata\n%s\n", mysql.error);
 
     if (mysql.commit())
         panic("could not commit transaction\n%s\n", mysql.error);
 }
 
-void
-InsertFormula(uint16_t stat, const string &formula)
-{
-    MySQL::Connection &mysql = MySqlDB.conn();
-    assert(mysql.connected());
-    stringstream insert_formula;
-    ccprintf(insert_formula,
-             "INSERT INTO formulas(fm_stat,fm_formula) values(%d, \"%s\")",
-             stat, formula);
-
-    mysql.query(insert_formula);
-//    if (mysql.error)
-//     panic("could not insert formula\n%s\n", mysql.error);
+MySql::MySql()
+    : run(new MySqlRun), newdata(run)
+{}
 
-    stringstream insert_ref;
-    ccprintf(insert_ref,
-             "INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)",
-             stat, MySqlDB.run());
-
-    mysql.query(insert_ref);
-//    if (mysql.error)
-//     panic("could not insert formula reference\n%s\n", mysql.error);
-
-    if (mysql.commit())
-        panic("could not commit transaction\n%s\n", mysql.error);
+MySql::~MySql()
+{
+    delete run;
 }
 
 void
-UpdatePrereq(uint16_t stat, uint16_t prereq)
+MySql::connect(const string &host, const string &user, const string &passwd,
+               const string &db, const string &name, const string &sample,
+               const string &project)
 {
-    MySQL::Connection &mysql = MySqlDB.conn();
-    assert(mysql.connected());
-    stringstream update;
-    ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d",
-             prereq, stat);
-    mysql.query(update);
-    if (mysql.error)
-        panic("could not update prereq\n%s\n", mysql.error);
+    run->connect(host, user, passwd, db, name, sample, project);
+}
 
-    if (mysql.commit())
-        panic("could not commit transaction\n%s\n", mysql.error);
+bool
+MySql::connected() const
+{
+    return run->connected();
 }
 
 void
@@ -484,23 +390,30 @@ MySql::configure()
     /*
      * set up all stats!
      */
-    using namespace Database;
+    MySQL::Connection &mysql = run->conn();
 
-    MySQL::Connection &mysql = MySqlDB.conn();
-
-    stat_list_t::const_iterator i, end = stats().end();
-    for (i = stats().begin(); i != end; ++i) {
+    list<Info *>::const_iterator i, end = statsList().end();
+    for (i = statsList().begin(); i != end; ++i) {
         (*i)->visit(*this);
     }
 
-    for (i = stats().begin(); i != end; ++i) {
-        StatData *data = *i;
-        if (data->prereq) {
-            uint16_t stat_id = find(data->id);
-            uint16_t prereq_id = find(data->prereq->id);
+    for (i = statsList().begin(); i != end; ++i) {
+        Info *info = *i;
+        if (info->prereq) {
+            // update the prerequisite
+            uint16_t stat_id = find(info->id);
+            uint16_t prereq_id = find(info->prereq->id);
             assert(stat_id && prereq_id);
 
-            UpdatePrereq(stat_id, prereq_id);
+            stringstream update;
+            ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d",
+                     prereq_id, stat_id);
+            mysql.query(update);
+            if (mysql.error)
+                panic("could not update prereq\n%s\n", mysql.error);
+
+            if (mysql.commit())
+                panic("could not commit transaction\n%s\n", mysql.error);
         }
     }
 
@@ -510,227 +423,237 @@ MySql::configure()
     configured = true;
 }
 
-
 bool
-MySql::configure(const StatData &data, string type)
+MySql::configure(const Info &info, string type)
 {
     stat.init();
-    stat.name = data.name;
-    stat.descr = data.desc;
+    stat.name = info.name;
+    stat.descr = info.desc;
     stat.type = type;
-    stat.print = data.flags & print;
-    stat.prec = data.precision;
-    stat.nozero = data.flags & nozero;
-    stat.nonan = data.flags & nonan;
-    stat.total = data.flags & total;
-    stat.pdf = data.flags & pdf;
-    stat.cdf = data.flags & cdf;
+    stat.print = info.flags & display;
+    stat.prec = info.precision;
+    stat.nozero = info.flags & nozero;
+    stat.nonan = info.flags & nonan;
+    stat.total = info.flags & total;
+    stat.pdf = info.flags & pdf;
+    stat.cdf = info.flags & cdf;
 
     return stat.print;
 }
 
 void
-MySql::configure(const ScalarData &data)
+MySql::configure(const ScalarInfo &info)
 {
-    if (!configure(data, "SCALAR"))
+    if (!configure(info, "SCALAR"))
         return;
 
-    insert(data.id, stat.setup());
+    insert(info.id, stat.setup(run));
 }
 
 void
-MySql::configure(const VectorData &data)
+MySql::configure(const VectorInfo &info)
 {
-    if (!configure(data, "VECTOR"))
+    if (!configure(info, "VECTOR"))
         return;
 
-    uint16_t statid = stat.setup();
+    uint16_t statid = stat.setup(run);
 
-    if (!data.subnames.empty()) {
+    if (!info.subnames.empty()) {
         InsertSubData subdata;
         subdata.stat = statid;
         subdata.y = 0;
-        for (int i = 0; i < data.subnames.size(); ++i) {
+        for (off_type i = 0; i < info.subnames.size(); ++i) {
             subdata.x = i;
-            subdata.name = data.subnames[i];
-            subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
+            subdata.name = info.subnames[i];
+            subdata.descr = info.subdescs.empty() ? "" : info.subdescs[i];
 
             if (!subdata.name.empty() || !subdata.descr.empty())
-                subdata.setup();
+                subdata.setup(run);
         }
     }
 
-    insert(data.id, statid);
+    insert(info.id, statid);
 }
 
 void
-MySql::configure(const DistData &data)
+MySql::configure(const DistInfo &info)
 {
-    if (!configure(data, "DIST"))
+    if (!configure(info, "DIST"))
         return;
 
-    if (!data.data.fancy) {
-        stat.size = data.data.size;
-        stat.min = data.data.min;
-        stat.max = data.data.max;
-        stat.bktsize = data.data.bucket_size;
+    const DistStor::Params *params =
+        dynamic_cast<const DistStor::Params *>(info.storageParams);
+    if (params) {
+        assert(params->type == Dist);
+        stat.size = params->buckets;
+        stat.min = params->min;
+        stat.max = params->max;
+        stat.bktsize = params->bucket_size;
     }
-    insert(data.id, stat.setup());
+    insert(info.id, stat.setup(run));
 }
 
 void
-MySql::configure(const VectorDistData &data)
+MySql::configure(const VectorDistInfo &info)
 {
-    if (!configure(data, "VECTORDIST"))
+    if (!configure(info, "VECTORDIST"))
         return;
 
-    if (!data.data[0].fancy) {
-        stat.size = data.data[0].size;
-        stat.min = data.data[0].min;
-        stat.max = data.data[0].max;
-        stat.bktsize = data.data[0].bucket_size;
+    const DistStor::Params *params =
+        dynamic_cast<const DistStor::Params *>(info.storageParams);
+    if (params) {
+        assert(params->type == Dist);
+        stat.size = params->buckets;
+        stat.min = params->min;
+        stat.max = params->max;
+        stat.bktsize = params->bucket_size;
     }
 
-    uint16_t statid = stat.setup();
+    uint16_t statid = stat.setup(run);
 
-    if (!data.subnames.empty()) {
+    if (!info.subnames.empty()) {
         InsertSubData subdata;
         subdata.stat = statid;
         subdata.y = 0;
-        for (int i = 0; i < data.subnames.size(); ++i) {
+        for (off_type i = 0; i < info.subnames.size(); ++i) {
             subdata.x = i;
-            subdata.name = data.subnames[i];
-            subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
+            subdata.name = info.subnames[i];
+            subdata.descr = info.subdescs.empty() ? "" : info.subdescs[i];
             if (!subdata.name.empty() || !subdata.descr.empty())
-                subdata.setup();
+                subdata.setup(run);
         }
     }
 
-    insert(data.id, statid);
+    insert(info.id, statid);
 }
 
 void
-MySql::configure(const Vector2dData &data)
+MySql::configure(const Vector2dInfo &info)
 {
-    if (!configure(data, "VECTOR2D"))
+    if (!configure(info, "VECTOR2D"))
         return;
 
-    uint16_t statid = stat.setup();
+    uint16_t statid = stat.setup(run);
 
-    if (!data.subnames.empty()) {
+    if (!info.subnames.empty()) {
         InsertSubData subdata;
         subdata.stat = statid;
         subdata.y = -1;
-        for (int i = 0; i < data.subnames.size(); ++i) {
+        for (off_type i = 0; i < info.subnames.size(); ++i) {
             subdata.x = i;
-            subdata.name = data.subnames[i];
-            subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
+            subdata.name = info.subnames[i];
+            subdata.descr = info.subdescs.empty() ? "" : info.subdescs[i];
             if (!subdata.name.empty() || !subdata.descr.empty())
-                subdata.setup();
+                subdata.setup(run);
         }
     }
 
-    if (!data.y_subnames.empty()) {
+    if (!info.y_subnames.empty()) {
         InsertSubData subdata;
         subdata.stat = statid;
         subdata.x = -1;
         subdata.descr = "";
-        for (int i = 0; i < data.y_subnames.size(); ++i) {
+        for (off_type i = 0; i < info.y_subnames.size(); ++i) {
             subdata.y = i;
-            subdata.name = data.y_subnames[i];
+            subdata.name = info.y_subnames[i];
             if (!subdata.name.empty())
-                subdata.setup();
+                subdata.setup(run);
         }
     }
 
-    insert(data.id, statid);
+    insert(info.id, statid);
 }
 
 void
-MySql::configure(const FormulaData &data)
+MySql::configure(const FormulaInfo &info)
 {
-    configure(data, "FORMULA");
-    insert(data.id, stat.setup());
-    InsertFormula(find(data.id), data.str());
-}
+    MySQL::Connection &mysql = run->conn();
+    assert(mysql.connected());
 
-void
-MySql::output(MainBin *bin)
-{
-    MySQL::Connection &mysql = MySqlDB.conn();
+    configure(info, "FORMULA");
+    insert(info.id, stat.setup(run));
 
-    if (bin) {
-        bin->activate();
-        newdata.bin = SetupBin(bin->name());
-    } else {
-        newdata.bin = 0;
-    }
+    uint16_t stat = find(info.id);
+    string formula = info.str();
 
-    Database::stat_list_t::const_iterator i, end = Database::stats().end();
-    for (i = Database::stats().begin(); i != end; ++i) {
-        StatData *stat = *i;
-        if (bin && stat->binned() || !bin && !stat->binned()) {
-            stat->visit(*this);
-            if (mysql.commit())
-                panic("could not commit transaction\n%s\n", mysql.error);
-        }
-    }
+    stringstream insert_formula;
+    ccprintf(insert_formula,
+             "INSERT INTO formulas(fm_stat,fm_formula) values(%d, \"%s\")",
+             stat, formula);
+
+    mysql.query(insert_formula);
+//    if (mysql.error)
+//      panic("could not insert formula\n%s\n", mysql.error);
+
+    stringstream insert_ref;
+    ccprintf(insert_ref,
+             "INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)",
+             stat, run->run());
+
+    mysql.query(insert_ref);
+//    if (mysql.error)
+//      panic("could not insert formula reference\n%s\n", mysql.error);
+
+    if (mysql.commit())
+        panic("could not commit transaction\n%s\n", mysql.error);
 }
 
 bool
 MySql::valid() const
 {
-    return MySqlDB.connected();
+    return run->connected();
 }
 
 void
 MySql::output()
 {
-    using namespace Database;
     assert(valid());
 
     if (!configured)
         configure();
 
     // store sample #
-    newdata.tick = curTick;
+    newdata.tick = curTick();
+
+    MySQL::Connection &mysql = run->conn();
 
-    output(NULL);
-    if (!bins().empty()) {
-        bin_list_t::iterator i, end = bins().end();
-        for (i = bins().begin(); i != end; ++i)
-            output(*i);
+    list<Info *>::const_iterator i, end = statsList().end();
+    for (i = statsList().begin(); i != end; ++i) {
+        Info *stat = *i;
+        stat->visit(*this);
+        if (mysql.commit())
+            panic("could not commit transaction\n%s\n", mysql.error);
     }
 
     newdata.flush();
 }
 
 void
-MySql::output(const ScalarData &data)
+MySql::output(const ScalarInfo &info)
 {
-    if (!(data.flags & print))
+    if (!(info.flags & display))
         return;
 
-    newdata.stat = find(data.id);
+    newdata.stat = find(info.id);
     newdata.x = 0;
     newdata.y = 0;
-    newdata.data = data.value();
+    newdata.data = info.value();
 
     newdata.insert();
 }
 
 void
-MySql::output(const VectorData &data)
+MySql::output(const VectorInfo &info)
 {
-    if (!(data.flags & print))
+    if (!(info.flags & display))
         return;
 
-    newdata.stat = find(data.id);
+    newdata.stat = find(info.id);
     newdata.y = 0;
 
-    const VCounter &cvec = data.value();
-    int size = data.size();
-    for (int x = 0; x < size; x++) {
+    const VCounter &cvec = info.value();
+    size_type size = info.size();
+    for (off_type x = 0; x < size; x++) {
         newdata.x = x;
         newdata.data = cvec[x];
         newdata.insert();
@@ -738,7 +661,7 @@ MySql::output(const VectorData &data)
 }
 
 void
-MySql::output(const DistDataData &data)
+MySql::output(const DistData &data, const DistParams *params)
 {
     const int db_sum = -1;
     const int db_squares = -2;
@@ -760,7 +683,7 @@ MySql::output(const DistDataData &data)
     newdata.data = data.samples;
     newdata.insert();
 
-    if (data.samples && !data.fancy) {
+    if (data.samples && params->type == Dist) {
         newdata.x = db_min_val;
         newdata.data = data.min_val;
         newdata.insert();
@@ -777,8 +700,8 @@ MySql::output(const DistDataData &data)
         newdata.data = data.overflow;
         newdata.insert();
 
-        int size = data.cvec.size();
-        for (int x = 0; x < size; x++) {
+        size_type size = data.cvec.size();
+        for (off_type x = 0; x < size; x++) {
             newdata.x = x;
             newdata.data = data.cvec[x];
             newdata.insert();
@@ -786,54 +709,54 @@ MySql::output(const DistDataData &data)
     }
 }
 
-
 void
-MySql::output(const DistData &data)
+MySql::output(const DistInfo &info)
 {
-    if (!(data.flags & print))
+    if (!(info.flags & display))
         return;
 
-    newdata.stat = find(data.id);
+    newdata.stat = find(info.id);
     newdata.y = 0;
-    output(data.data);
+    output(info.data, safe_cast<const DistParams *>(info.storageParams));
 }
 
 void
-MySql::output(const VectorDistData &data)
+MySql::output(const VectorDistInfo &info)
 {
-    if (!(data.flags & print))
+    if (!(info.flags & display))
         return;
 
-    newdata.stat = find(data.id);
+    newdata.stat = find(info.id);
 
-    int size = data.data.size();
-    for (int y = 0; y < size; ++y) {
+    size_type size = info.data.size();
+    for (off_type y = 0; y < size; ++y) {
         newdata.y = y;
-        output(data.data[y]);
+        output(info.data[y],
+               safe_cast<const DistParams *>(info.storageParams));
     }
 }
 
 void
-MySql::output(const Vector2dData &data)
+MySql::output(const Vector2dInfo &info)
 {
-    if (!(data.flags & print))
+    if (!(info.flags & display))
         return;
 
-    newdata.stat = find(data.id);
+    newdata.stat = find(info.id);
 
-    int index = 0;
-    for (int x = 0; x < data.x; x++) {
+    off_type index = 0;
+    for (off_type x = 0; x < info.x; x++) {
         newdata.x = x;
-        for (int y = 0; y < data.y; y++) {
+        for (off_type y = 0; y < info.y; y++) {
             newdata.y = y;
-            newdata.data = data.cvec[index++];
+            newdata.data = info.cvec[index++];
             newdata.insert();
         }
     }
 }
 
 void
-MySql::output(const FormulaData &data)
+MySql::output(const FormulaInfo &info)
 {
 }
 
@@ -841,60 +764,76 @@ MySql::output(const FormulaData &data)
  * Implement the visitor
  */
 void
-MySql::visit(const ScalarData &data)
+MySql::visit(const ScalarInfo &info)
 {
     if (!configured)
-        configure(data);
+        configure(info);
     else
-        output(data);
+        output(info);
 }
 
 void
-MySql::visit(const VectorData &data)
+MySql::visit(const VectorInfo &info)
 {
     if (!configured)
-        configure(data);
+        configure(info);
     else
-        output(data);
+        output(info);
 }
 
 void
-MySql::visit(const DistData &data)
+MySql::visit(const DistInfo &info)
 {
     return;
     if (!configured)
-        configure(data);
+        configure(info);
     else
-        output(data);
+        output(info);
 }
 
 void
-MySql::visit(const VectorDistData &data)
+MySql::visit(const VectorDistInfo &info)
 {
     return;
     if (!configured)
-        configure(data);
+        configure(info);
     else
-        output(data);
+        output(info);
 }
 
 void
-MySql::visit(const Vector2dData &data)
+MySql::visit(const Vector2dInfo &info)
 {
     return;
     if (!configured)
-        configure(data);
+        configure(info);
     else
-        output(data);
+        output(info);
 }
 
 void
-MySql::visit(const FormulaData &data)
+MySql::visit(const FormulaInfo &info)
 {
     if (!configured)
-        configure(data);
+        configure(info);
     else
-        output(data);
+        output(info);
+}
+
+bool
+initMySQL(string host, string user, string password, string database,
+    string project, string name, string sample)
+{
+    extern list<Output *> OutputList;
+    static MySql mysql;
+
+    if (mysql.connected())
+        return false;
+
+    mysql.connect(host, user, password, database, name, sample, project);
+    OutputList.push_back(&mysql);
+
+    return true;
 }
 
-/* namespace Stats */ }
+} // namespace Stats