2004-05-04 23:01:00 +02:00
|
|
|
/*
|
2004-06-08 19:37:27 +02:00
|
|
|
* Copyright (c) 2004 The Regents of The University of Michigan
|
2004-05-04 23:01:00 +02:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are
|
|
|
|
* met: redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer;
|
|
|
|
* redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution;
|
|
|
|
* neither the name of the copyright holders nor the names of its
|
|
|
|
* contributors may be used to endorse or promote products derived from
|
|
|
|
* this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
#include <map>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "base/misc.hh"
|
|
|
|
#include "base/mysql.hh"
|
|
|
|
#include "base/statistics.hh"
|
|
|
|
#include "base/stats/flags.hh"
|
|
|
|
#include "base/stats/mysql.hh"
|
2004-05-21 19:57:44 +02:00
|
|
|
#include "base/stats/mysql_run.hh"
|
2004-05-04 23:01:00 +02:00
|
|
|
#include "base/stats/statdb.hh"
|
|
|
|
#include "base/stats/types.hh"
|
|
|
|
#include "base/str.hh"
|
|
|
|
#include "sim/host.hh"
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2004-05-21 19:03:17 +02:00
|
|
|
namespace Stats {
|
2004-05-04 23:01:00 +02:00
|
|
|
|
2004-05-21 19:57:44 +02:00
|
|
|
MySqlRun MySqlDB;
|
|
|
|
|
|
|
|
bool
|
|
|
|
MySqlConnected()
|
2004-05-04 23:01:00 +02:00
|
|
|
{
|
2004-05-21 19:57:44 +02:00
|
|
|
return MySqlDB.connected();
|
|
|
|
}
|
2004-05-04 23:01:00 +02:00
|
|
|
|
2004-05-21 19:57:44 +02:00
|
|
|
void
|
|
|
|
MySqlRun::connect(const string &host, const string &user, const string &passwd,
|
2004-06-28 21:53:06 +02:00
|
|
|
const string &db, const string &name, const string &sample,
|
|
|
|
const string &project)
|
2004-05-21 19:57:44 +02:00
|
|
|
{
|
|
|
|
if (connected())
|
|
|
|
panic("can only get one database connection at this time!");
|
|
|
|
|
|
|
|
mysql.connect(host, user, passwd, db);
|
|
|
|
if (mysql.error)
|
|
|
|
panic("could not connect to database server\n%s\n", mysql.error);
|
|
|
|
|
2004-07-08 23:48:13 +02:00
|
|
|
mysql.query("LOCK TABLES runs WRITE");
|
|
|
|
if (mysql.error)
|
|
|
|
panic("could not lock tables\n%s\n", mysql.error);
|
|
|
|
|
2004-05-21 19:57:44 +02:00
|
|
|
remove(name);
|
2004-07-08 23:48:13 +02:00
|
|
|
// cleanup();
|
2004-06-28 21:53:06 +02:00
|
|
|
setup(name, sample, user, project);
|
2004-07-08 23:48:13 +02:00
|
|
|
mysql.query("UNLOCK TABLES");
|
|
|
|
if (mysql.error)
|
|
|
|
panic("could not unlock tables\n%s\n", mysql.error);
|
2004-05-21 19:57:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-06-28 21:53:06 +02:00
|
|
|
MySqlRun::setup(const string &name, const string &sample, const string &user,
|
|
|
|
const string &project)
|
2004-05-04 23:01:00 +02:00
|
|
|
{
|
|
|
|
assert(mysql.connected());
|
|
|
|
|
|
|
|
stringstream insert;
|
|
|
|
ccprintf(insert,
|
|
|
|
"INSERT INTO "
|
2004-06-28 21:53:06 +02:00
|
|
|
"runs(rn_name,rn_sample,rn_user,rn_project,rn_date,rn_expire)"
|
|
|
|
"values(\"%s\", \"%s\", \"%s\", \"%s\", NOW(),"
|
2004-05-04 23:01:00 +02:00
|
|
|
"DATE_ADD(CURDATE(), INTERVAL 31 DAY))",
|
2004-06-28 21:53:06 +02:00
|
|
|
name, sample, user, project);
|
2004-05-04 23:01:00 +02:00
|
|
|
|
|
|
|
mysql.query(insert);
|
|
|
|
if (mysql.error)
|
|
|
|
panic("could not get a run\n%s\n", mysql.error);
|
|
|
|
|
2004-05-21 19:57:44 +02:00
|
|
|
run_id = mysql.insert_id();
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-05-21 19:57:44 +02:00
|
|
|
MySqlRun::remove(const string &name)
|
2004-05-04 23:01:00 +02:00
|
|
|
{
|
|
|
|
assert(mysql.connected());
|
|
|
|
stringstream sql;
|
|
|
|
ccprintf(sql, "DELETE FROM runs WHERE rn_name=\"%s\"", name);
|
|
|
|
mysql.query(sql);
|
2004-07-08 23:48:13 +02:00
|
|
|
if (mysql.error)
|
|
|
|
panic("could not delete run\n%s\n", mysql.error);
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-05-21 19:57:44 +02:00
|
|
|
MySqlRun::cleanup()
|
2004-05-04 23:01:00 +02:00
|
|
|
{
|
|
|
|
assert(mysql.connected());
|
|
|
|
|
|
|
|
mysql.query("DELETE data "
|
|
|
|
"FROM data "
|
|
|
|
"LEFT JOIN runs ON dt_run=rn_id "
|
|
|
|
"WHERE rn_id IS NULL");
|
|
|
|
|
|
|
|
mysql.query("DELETE formula_ref "
|
|
|
|
"FROM formula_ref "
|
|
|
|
"LEFT JOIN runs ON fr_run=rn_id "
|
|
|
|
"WHERE rn_id IS NULL");
|
|
|
|
|
|
|
|
mysql.query("DELETE formulas "
|
|
|
|
"FROM formulas "
|
|
|
|
"LEFT JOIN formula_ref ON fm_stat=fr_stat "
|
|
|
|
"WHERE fr_stat IS NULL");
|
|
|
|
|
|
|
|
mysql.query("DELETE stats "
|
|
|
|
"FROM stats "
|
|
|
|
"LEFT JOIN data ON st_id=dt_stat "
|
|
|
|
"WHERE dt_stat IS NULL");
|
|
|
|
|
|
|
|
mysql.query("DELETE subdata "
|
|
|
|
"FROM subdata "
|
|
|
|
"LEFT JOIN data ON sd_stat=dt_stat "
|
|
|
|
"WHERE dt_stat IS NULL");
|
|
|
|
|
|
|
|
mysql.query("DELETE bins "
|
|
|
|
"FROM bins "
|
|
|
|
"LEFT JOIN data ON bn_id=dt_bin "
|
|
|
|
"WHERE dt_bin IS NULL");
|
2004-05-23 18:53:34 +02:00
|
|
|
|
|
|
|
mysql.query("DELETE events"
|
|
|
|
"FROM events"
|
|
|
|
"LEFT JOIN runs ON ev_run=rn_id"
|
|
|
|
"WHERE rn_id IS NULL");
|
|
|
|
|
|
|
|
mysql.query("DELETE event_names"
|
|
|
|
"FROM event_names"
|
|
|
|
"LEFT JOIN events ON en_id=ev_event"
|
|
|
|
"WHERE ev_event IS NULL");
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SetupStat::init()
|
|
|
|
{
|
|
|
|
name = "";
|
|
|
|
descr = "";
|
|
|
|
type = "";
|
|
|
|
print = false;
|
|
|
|
prereq = 0;
|
|
|
|
prec = -1;
|
|
|
|
nozero = false;
|
|
|
|
nonan = false;
|
|
|
|
total = false;
|
|
|
|
pdf = false;
|
|
|
|
cdf = false;
|
|
|
|
min = 0;
|
|
|
|
max = 0;
|
|
|
|
bktsize = 0;
|
|
|
|
size = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned
|
2004-05-21 19:57:44 +02:00
|
|
|
SetupStat::setup()
|
2004-05-04 23:01:00 +02:00
|
|
|
{
|
2004-05-21 19:57:44 +02:00
|
|
|
MySQL::Connection &mysql = MySqlDB.conn();
|
2004-05-04 23:01:00 +02:00
|
|
|
|
|
|
|
stringstream insert;
|
|
|
|
ccprintf(insert,
|
|
|
|
"INSERT INTO "
|
|
|
|
"stats(st_name, st_descr, st_type, st_print, st_prereq, "
|
|
|
|
"st_prec, st_nozero, st_nonan, st_total, st_pdf, st_cdf, "
|
|
|
|
"st_min, st_max, st_bktsize, st_size)"
|
|
|
|
"values(\"%s\",\"%s\",\"%s\","
|
|
|
|
" %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
|
|
|
|
name, descr, type, print, prereq, (int)prec, nozero, nonan,
|
|
|
|
total, pdf, cdf,
|
|
|
|
min, max, bktsize, size);
|
|
|
|
|
|
|
|
mysql.query(insert);
|
|
|
|
if (!mysql.error)
|
|
|
|
return mysql.insert_id();
|
|
|
|
|
|
|
|
stringstream select;
|
|
|
|
ccprintf(select, "SELECT * FROM stats WHERE st_name=\"%s\"", name);
|
|
|
|
|
|
|
|
mysql.query(select);
|
|
|
|
MySQL::Result result = mysql.store_result();
|
|
|
|
if (!result)
|
2004-07-08 23:48:13 +02:00
|
|
|
panic("could not find stat\n%s\n", mysql.error);
|
2004-05-04 23:01:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
assert(result.num_fields() == 16);
|
|
|
|
MySQL::Row row = result.fetch_row();
|
|
|
|
if (!row)
|
2004-07-08 23:48:13 +02:00
|
|
|
panic("could not get stat row\n%s\n", mysql.error);
|
2004-05-04 23:01:00 +02:00
|
|
|
|
|
|
|
bool tb;
|
|
|
|
int8_t ti8;
|
|
|
|
uint16_t tu16;
|
|
|
|
int64_t ti64;
|
|
|
|
uint64_t tu64;
|
|
|
|
|
|
|
|
if (name != (char *)row[1])
|
|
|
|
panic("failed stat check on %s:name. %s != %s\n",
|
|
|
|
name, name, row[1]);
|
|
|
|
|
|
|
|
if (descr != (char *)row[2])
|
|
|
|
panic("failed stat check on %s:descr. %s != %s\n",
|
|
|
|
name, descr, row[2]);
|
|
|
|
|
|
|
|
if (type != (char *)row[3])
|
|
|
|
panic("failed stat check on %s:type. %s != %s\n",
|
|
|
|
name, type, row[3]);
|
|
|
|
|
|
|
|
if (!to_number(row[4], tb) || print != tb)
|
|
|
|
panic("failed stat check on %s:print. %d != %d\n",
|
|
|
|
name, print, tb);
|
|
|
|
|
|
|
|
if (!to_number(row[6], ti8) || prec != ti8)
|
|
|
|
panic("failed stat check on %s:prec. %d != %d\n",
|
|
|
|
name, prec, ti8);
|
|
|
|
|
|
|
|
if (!to_number(row[7], tb) || nozero != tb)
|
|
|
|
panic("failed stat check on %s:nozero. %d != %d\n",
|
|
|
|
name, nozero, tb);
|
|
|
|
|
|
|
|
if (!to_number(row[8], tb) || nonan != tb)
|
|
|
|
panic("failed stat check on %s:nonan. %d != %d\n",
|
|
|
|
name, nonan, tb);
|
|
|
|
|
|
|
|
if (!to_number(row[9], tb) || total != tb)
|
|
|
|
panic("failed stat check on %s:total. %d != %d\n",
|
|
|
|
name, total, tb);
|
|
|
|
|
|
|
|
if (!to_number(row[10], tb) || pdf != tb)
|
|
|
|
panic("failed stat check on %s:pdf. %d != %d\n",
|
|
|
|
name, pdf, tb);
|
|
|
|
|
|
|
|
if (!to_number(row[11], tb) || cdf != tb)
|
|
|
|
panic("failed stat check on %s:cdf. %d != %d\n",
|
|
|
|
name, cdf, tb);
|
|
|
|
|
|
|
|
if (!to_number(row[12], ti64) || min != ti64)
|
|
|
|
panic("failed stat check on %s:min. %d != %d\n",
|
|
|
|
name, min, ti64);
|
|
|
|
|
|
|
|
if (!to_number(row[13], ti64) || max != ti64)
|
|
|
|
panic("failed stat check on %s:max. %d != %d\n",
|
|
|
|
name, max, ti64);
|
|
|
|
|
|
|
|
if (!to_number(row[14], tu64) || bktsize != tu64)
|
|
|
|
panic("failed stat check on %s:bktsize. %d != %d\n",
|
|
|
|
name, bktsize, tu64);
|
|
|
|
|
|
|
|
if (!to_number(row[15], tu16) || size != tu16)
|
|
|
|
panic("failed stat check on %s:size. %d != %d\n",
|
|
|
|
name, size, tu16);
|
|
|
|
|
|
|
|
to_number(row[5], prereq);
|
|
|
|
uint16_t statid;
|
|
|
|
to_number(row[0], statid);
|
|
|
|
return statid;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned
|
2004-05-21 19:57:44 +02:00
|
|
|
SetupBin(const string &bin)
|
2004-05-04 23:01:00 +02:00
|
|
|
{
|
2004-07-08 23:48:13 +02:00
|
|
|
static map<string, int> binmap;
|
2004-05-04 23:01:00 +02:00
|
|
|
|
|
|
|
using namespace MySQL;
|
2004-07-08 23:48:13 +02:00
|
|
|
map<string,int>::const_iterator i = binmap.find(bin);
|
|
|
|
if (i != binmap.end())
|
|
|
|
return (*i).second;
|
|
|
|
|
|
|
|
Connection &mysql = MySqlDB.conn();
|
|
|
|
assert(mysql.connected());
|
|
|
|
|
|
|
|
mysql.query("LOCK TABLES bins WRITE");
|
|
|
|
if (mysql.error)
|
|
|
|
panic("could not lock bin table\n%s\n", mysql.error);
|
|
|
|
|
|
|
|
uint16_t bin_id;
|
|
|
|
|
2004-05-04 23:01:00 +02:00
|
|
|
stringstream select;
|
2004-07-08 23:48:13 +02:00
|
|
|
stringstream insert;
|
2004-05-04 23:01:00 +02:00
|
|
|
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);
|
2004-07-08 23:48:13 +02:00
|
|
|
MySQL::Row row = result.fetch_row();
|
2004-05-04 23:01:00 +02:00
|
|
|
if (row) {
|
|
|
|
to_number(row[0], bin_id);
|
2004-07-08 23:48:13 +02:00
|
|
|
goto exit;
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ccprintf(insert, "INSERT INTO bins(bn_name) values(\"%s\")", bin);
|
|
|
|
|
|
|
|
mysql.query(insert);
|
|
|
|
if (mysql.error)
|
2004-07-08 23:48:13 +02:00
|
|
|
panic("could not get a bin\n%s\n", mysql.error);
|
|
|
|
|
|
|
|
bin_id = mysql.insert_id();
|
|
|
|
binmap.insert(make_pair(bin, bin_id));
|
|
|
|
|
|
|
|
exit:
|
|
|
|
mysql.query("UNLOCK TABLES");
|
|
|
|
if (mysql.error)
|
|
|
|
panic("could not unlock tables\n%s\n", mysql.error);
|
2004-05-04 23:01:00 +02:00
|
|
|
|
2004-07-08 23:48:13 +02:00
|
|
|
return bin_id;
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
InsertData::InsertData()
|
|
|
|
{
|
|
|
|
query = new char[maxsize + 1];
|
|
|
|
size = 0;
|
|
|
|
flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
InsertData::~InsertData()
|
|
|
|
{
|
|
|
|
delete [] query;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
InsertData::flush()
|
|
|
|
{
|
|
|
|
if (size) {
|
2004-05-21 19:57:44 +02:00
|
|
|
MySQL::Connection &mysql = MySqlDB.conn();
|
|
|
|
assert(mysql.connected());
|
|
|
|
mysql.query(query);
|
2004-07-08 23:48:13 +02:00
|
|
|
if (mysql.error)
|
|
|
|
panic("could not insert data\n%s\n", mysql.error);
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
query[0] = '\0';
|
|
|
|
size = 0;
|
|
|
|
first = true;
|
|
|
|
strcpy(query, "INSERT INTO "
|
2004-07-08 23:48:13 +02:00
|
|
|
"data(dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_bin,dt_data) "
|
2004-05-04 23:01:00 +02:00
|
|
|
"values");
|
|
|
|
size = strlen(query);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
InsertData::insert()
|
|
|
|
{
|
|
|
|
if (size + 1024 > maxsize)
|
|
|
|
flush();
|
|
|
|
|
|
|
|
if (!first) {
|
|
|
|
query[size++] = ',';
|
|
|
|
query[size] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
first = false;
|
|
|
|
|
|
|
|
size += sprintf(query + size, "(%u,%d,%d,%u,%llu,%u,\"%f\")",
|
2004-07-08 23:48:13 +02:00
|
|
|
stat, x, y, MySqlDB.run(), (unsigned long long)tick,
|
2004-05-21 19:57:44 +02:00
|
|
|
bin, data);
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
struct InsertSubData
|
|
|
|
{
|
|
|
|
uint16_t stat;
|
|
|
|
int16_t x;
|
|
|
|
int16_t y;
|
|
|
|
string name;
|
|
|
|
string descr;
|
|
|
|
|
2004-05-21 19:57:44 +02:00
|
|
|
void setup();
|
2004-05-04 23:01:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
void
|
2004-05-21 19:57:44 +02:00
|
|
|
InsertSubData::setup()
|
2004-05-04 23:01:00 +02:00
|
|
|
{
|
2004-05-21 19:57:44 +02:00
|
|
|
MySQL::Connection &mysql = MySqlDB.conn();
|
2004-05-04 23:01:00 +02:00
|
|
|
assert(mysql.connected());
|
|
|
|
stringstream insert;
|
|
|
|
ccprintf(insert,
|
|
|
|
"INSERT INTO subdata(sd_stat,sd_x,sd_y,sd_name,sd_descr) "
|
|
|
|
"values(%d,%d,%d,\"%s\",\"%s\")",
|
|
|
|
stat, x, y, name, descr);
|
|
|
|
|
|
|
|
mysql.query(insert);
|
2004-07-08 23:48:13 +02:00
|
|
|
// if (mysql.error)
|
|
|
|
// panic("could not insert subdata\n%s\n", mysql.error);
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-05-21 19:57:44 +02:00
|
|
|
InsertFormula(uint16_t stat, const string &formula)
|
2004-05-04 23:01:00 +02:00
|
|
|
{
|
2004-05-21 19:57:44 +02:00
|
|
|
MySQL::Connection &mysql = MySqlDB.conn();
|
2004-05-04 23:01:00 +02:00
|
|
|
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);
|
2004-07-08 23:48:13 +02:00
|
|
|
// if (mysql.error)
|
|
|
|
// panic("could not insert formula\n%s\n", mysql.error);
|
2004-05-04 23:01:00 +02:00
|
|
|
|
|
|
|
stringstream insert_ref;
|
|
|
|
ccprintf(insert_ref,
|
|
|
|
"INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)",
|
2004-05-21 19:57:44 +02:00
|
|
|
stat, MySqlDB.run());
|
2004-05-04 23:01:00 +02:00
|
|
|
|
2004-07-08 23:48:13 +02:00
|
|
|
mysql.query(insert_ref);
|
|
|
|
// if (mysql.error)
|
|
|
|
// panic("could not insert formula reference\n%s\n", mysql.error);
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-05-21 19:57:44 +02:00
|
|
|
UpdatePrereq(uint16_t stat, uint16_t prereq)
|
2004-05-04 23:01:00 +02:00
|
|
|
{
|
2004-05-21 19:57:44 +02:00
|
|
|
MySQL::Connection &mysql = MySqlDB.conn();
|
2004-05-04 23:01:00 +02:00
|
|
|
assert(mysql.connected());
|
|
|
|
stringstream update;
|
|
|
|
ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d",
|
|
|
|
prereq, stat);
|
|
|
|
mysql.query(update);
|
2004-07-08 23:48:13 +02:00
|
|
|
if (mysql.error)
|
|
|
|
panic("could not update prereq\n%s\n", mysql.error);
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::configure()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* set up all stats!
|
|
|
|
*/
|
|
|
|
using namespace Database;
|
2004-07-08 23:48:13 +02:00
|
|
|
|
|
|
|
MySQL::Connection &mysql = MySqlDB.conn();
|
|
|
|
mysql.query("LOCK TABLES "
|
|
|
|
"stats WRITE, "
|
|
|
|
"bins WRITE, "
|
|
|
|
"subdata WRITE, "
|
|
|
|
"formulas WRITE, "
|
|
|
|
"formula_ref WRITE");
|
|
|
|
if (mysql.error)
|
|
|
|
panic("could not lock tables\n%s\n", mysql.error);
|
|
|
|
|
2004-05-04 23:01:00 +02:00
|
|
|
stat_list_t::const_iterator i, end = stats().end();
|
|
|
|
for (i = stats().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);
|
|
|
|
assert(stat_id && prereq_id);
|
|
|
|
|
2004-05-21 19:57:44 +02:00
|
|
|
UpdatePrereq(stat_id, prereq_id);
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-08 23:48:13 +02:00
|
|
|
mysql.query("UNLOCK TABLES");
|
|
|
|
if (mysql.error)
|
|
|
|
panic("could not unlock tables\n%s\n", mysql.error);
|
|
|
|
|
2004-05-04 23:01:00 +02:00
|
|
|
configured = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-23 05:59:12 +02:00
|
|
|
bool
|
2004-05-04 23:01:00 +02:00
|
|
|
MySql::configure(const StatData &data, string type)
|
|
|
|
{
|
|
|
|
stat.init();
|
|
|
|
stat.name = data.name;
|
|
|
|
stat.descr = data.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;
|
2004-07-23 05:59:12 +02:00
|
|
|
|
|
|
|
return stat.print;
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::configure(const ScalarData &data)
|
|
|
|
{
|
2004-07-23 05:59:12 +02:00
|
|
|
if (!configure(data, "SCALAR"))
|
|
|
|
return;
|
|
|
|
|
2004-05-21 19:57:44 +02:00
|
|
|
insert(data.id, stat.setup());
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::configure(const VectorData &data)
|
|
|
|
{
|
2004-07-23 05:59:12 +02:00
|
|
|
if (!configure(data, "VECTOR"))
|
|
|
|
return;
|
|
|
|
|
2004-05-21 19:57:44 +02:00
|
|
|
uint16_t statid = stat.setup();
|
2004-05-04 23:01:00 +02:00
|
|
|
|
|
|
|
if (!data.subnames.empty()) {
|
|
|
|
InsertSubData subdata;
|
|
|
|
subdata.stat = statid;
|
|
|
|
subdata.y = 0;
|
|
|
|
for (int i = 0; i < data.subnames.size(); ++i) {
|
|
|
|
subdata.x = i;
|
|
|
|
subdata.name = data.subnames[i];
|
|
|
|
subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
|
|
|
|
|
|
|
|
if (!subdata.name.empty() || !subdata.descr.empty())
|
2004-05-21 19:57:44 +02:00
|
|
|
subdata.setup();
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
insert(data.id, statid);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::configure(const DistData &data)
|
|
|
|
{
|
2004-07-23 05:59:12 +02:00
|
|
|
if (!configure(data, "DIST"))
|
|
|
|
return;
|
|
|
|
|
2004-05-04 23:01:00 +02:00
|
|
|
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;
|
|
|
|
}
|
2004-05-21 19:57:44 +02:00
|
|
|
insert(data.id, stat.setup());
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::configure(const VectorDistData &data)
|
|
|
|
{
|
2004-07-23 05:59:12 +02:00
|
|
|
if (!configure(data, "VECTORDIST"))
|
|
|
|
return;
|
2004-05-04 23:01:00 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2004-05-21 19:57:44 +02:00
|
|
|
uint16_t statid = stat.setup();
|
2004-05-04 23:01:00 +02:00
|
|
|
|
|
|
|
if (!data.subnames.empty()) {
|
|
|
|
InsertSubData subdata;
|
|
|
|
subdata.stat = statid;
|
|
|
|
subdata.y = 0;
|
|
|
|
for (int i = 0; i < data.subnames.size(); ++i) {
|
|
|
|
subdata.x = i;
|
|
|
|
subdata.name = data.subnames[i];
|
|
|
|
subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
|
|
|
|
if (!subdata.name.empty() || !subdata.descr.empty())
|
2004-05-21 19:57:44 +02:00
|
|
|
subdata.setup();
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
insert(data.id, statid);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::configure(const Vector2dData &data)
|
|
|
|
{
|
2004-07-23 05:59:12 +02:00
|
|
|
if (!configure(data, "VECTOR2D"))
|
|
|
|
return;
|
|
|
|
|
2004-05-21 19:57:44 +02:00
|
|
|
uint16_t statid = stat.setup();
|
2004-05-04 23:01:00 +02:00
|
|
|
|
|
|
|
if (!data.subnames.empty()) {
|
|
|
|
InsertSubData subdata;
|
|
|
|
subdata.stat = statid;
|
2004-07-08 23:48:13 +02:00
|
|
|
subdata.y = -1;
|
2004-05-04 23:01:00 +02:00
|
|
|
for (int i = 0; i < data.subnames.size(); ++i) {
|
|
|
|
subdata.x = i;
|
|
|
|
subdata.name = data.subnames[i];
|
|
|
|
subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
|
|
|
|
if (!subdata.name.empty() || !subdata.descr.empty())
|
2004-05-21 19:57:44 +02:00
|
|
|
subdata.setup();
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!data.y_subnames.empty()) {
|
|
|
|
InsertSubData subdata;
|
|
|
|
subdata.stat = statid;
|
2004-07-08 23:48:13 +02:00
|
|
|
subdata.x = -1;
|
2004-05-04 23:01:00 +02:00
|
|
|
subdata.descr = "";
|
|
|
|
for (int i = 0; i < data.y_subnames.size(); ++i) {
|
|
|
|
subdata.y = i;
|
|
|
|
subdata.name = data.y_subnames[i];
|
|
|
|
if (!subdata.name.empty())
|
2004-05-21 19:57:44 +02:00
|
|
|
subdata.setup();
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
insert(data.id, statid);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::configure(const FormulaData &data)
|
|
|
|
{
|
|
|
|
configure(data, "FORMULA");
|
2004-05-21 19:57:44 +02:00
|
|
|
insert(data.id, stat.setup());
|
2004-07-08 23:48:13 +02:00
|
|
|
InsertFormula(find(data.id), data.str());
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-07-23 05:59:12 +02:00
|
|
|
MySql::output(MainBin *bin)
|
2004-05-04 23:01:00 +02:00
|
|
|
{
|
2004-07-23 05:59:12 +02:00
|
|
|
if (bin) {
|
|
|
|
bin->activate();
|
|
|
|
newdata.bin = SetupBin(bin->name());
|
|
|
|
} else {
|
|
|
|
newdata.bin = 0;
|
|
|
|
}
|
2004-05-04 23:01:00 +02:00
|
|
|
|
|
|
|
Database::stat_list_t::const_iterator i, end = Database::stats().end();
|
2004-07-23 05:59:12 +02:00
|
|
|
for (i = Database::stats().begin(); i != end; ++i) {
|
|
|
|
StatData *stat = *i;
|
|
|
|
if (bin && stat->binned() || !bin && !stat->binned())
|
|
|
|
stat->visit(*this);
|
|
|
|
}
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
2004-05-21 19:57:44 +02:00
|
|
|
bool
|
|
|
|
MySql::valid() const
|
|
|
|
{
|
|
|
|
return MySqlDB.connected();
|
|
|
|
}
|
|
|
|
|
2004-05-04 23:01:00 +02:00
|
|
|
void
|
|
|
|
MySql::output()
|
|
|
|
{
|
|
|
|
using namespace Database;
|
|
|
|
assert(valid());
|
|
|
|
|
|
|
|
if (!configured)
|
|
|
|
configure();
|
|
|
|
|
|
|
|
// store sample #
|
2004-07-08 23:48:13 +02:00
|
|
|
newdata.tick = curTick;
|
2004-05-04 23:01:00 +02:00
|
|
|
|
2004-07-23 05:59:12 +02:00
|
|
|
output(NULL);
|
|
|
|
if (!bins().empty()) {
|
2004-05-04 23:01:00 +02:00
|
|
|
bin_list_t::iterator i, end = bins().end();
|
2004-07-23 05:59:12 +02:00
|
|
|
for (i = bins().begin(); i != end; ++i)
|
|
|
|
output(*i);
|
2004-05-04 23:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
newdata.flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::output(const ScalarData &data)
|
|
|
|
{
|
2004-07-23 05:59:12 +02:00
|
|
|
if (!(data.flags & print))
|
|
|
|
return;
|
|
|
|
|
2004-05-04 23:01:00 +02:00
|
|
|
newdata.stat = find(data.id);
|
|
|
|
newdata.x = 0;
|
|
|
|
newdata.y = 0;
|
|
|
|
newdata.data = data.value();
|
|
|
|
|
|
|
|
newdata.insert();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::output(const VectorData &data)
|
|
|
|
{
|
2004-07-23 05:59:12 +02:00
|
|
|
if (!(data.flags & print))
|
|
|
|
return;
|
|
|
|
|
2004-05-04 23:01:00 +02:00
|
|
|
newdata.stat = find(data.id);
|
|
|
|
newdata.y = 0;
|
|
|
|
|
|
|
|
const VCounter &cvec = data.value();
|
|
|
|
int size = data.size();
|
|
|
|
for (int x = 0; x < size; x++) {
|
|
|
|
newdata.x = x;
|
|
|
|
newdata.data = cvec[x];
|
|
|
|
newdata.insert();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::output(const DistDataData &data)
|
|
|
|
{
|
|
|
|
const int db_sum = -1;
|
|
|
|
const int db_squares = -2;
|
|
|
|
const int db_samples = -3;
|
|
|
|
const int db_min_val = -4;
|
|
|
|
const int db_max_val = -5;
|
|
|
|
const int db_underflow = -6;
|
|
|
|
const int db_overflow = -7;
|
|
|
|
|
|
|
|
newdata.x = db_sum;
|
|
|
|
newdata.data = data.sum;
|
|
|
|
newdata.insert();
|
|
|
|
|
|
|
|
newdata.x = db_squares;
|
|
|
|
newdata.data = data.squares;
|
|
|
|
newdata.insert();
|
|
|
|
|
|
|
|
newdata.x = db_samples;
|
|
|
|
newdata.data = data.samples;
|
|
|
|
newdata.insert();
|
|
|
|
|
|
|
|
if (data.samples && !data.fancy) {
|
|
|
|
newdata.x = db_min_val;
|
|
|
|
newdata.data = data.min_val;
|
|
|
|
newdata.insert();
|
|
|
|
|
|
|
|
newdata.x = db_max_val;
|
|
|
|
newdata.data = data.max_val;
|
|
|
|
newdata.insert();
|
|
|
|
|
|
|
|
newdata.x = db_underflow;
|
|
|
|
newdata.data = data.underflow;
|
|
|
|
newdata.insert();
|
|
|
|
|
|
|
|
newdata.x = db_overflow;
|
|
|
|
newdata.data = data.overflow;
|
|
|
|
newdata.insert();
|
|
|
|
|
|
|
|
int size = data.cvec.size();
|
|
|
|
for (int x = 0; x < size; x++) {
|
|
|
|
newdata.x = x;
|
|
|
|
newdata.data = data.cvec[x];
|
|
|
|
newdata.insert();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::output(const DistData &data)
|
|
|
|
{
|
2004-07-23 05:59:12 +02:00
|
|
|
if (!(data.flags & print))
|
|
|
|
return;
|
|
|
|
|
2004-05-04 23:01:00 +02:00
|
|
|
newdata.stat = find(data.id);
|
|
|
|
newdata.y = 0;
|
|
|
|
output(data.data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::output(const VectorDistData &data)
|
|
|
|
{
|
2004-07-23 05:59:12 +02:00
|
|
|
if (!(data.flags & print))
|
|
|
|
return;
|
|
|
|
|
2004-05-04 23:01:00 +02:00
|
|
|
newdata.stat = find(data.id);
|
|
|
|
|
|
|
|
int size = data.data.size();
|
|
|
|
for (int y = 0; y < size; ++y) {
|
|
|
|
newdata.y = y;
|
|
|
|
output(data.data[y]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::output(const Vector2dData &data)
|
|
|
|
{
|
2004-07-23 05:59:12 +02:00
|
|
|
if (!(data.flags & print))
|
|
|
|
return;
|
|
|
|
|
2004-05-04 23:01:00 +02:00
|
|
|
newdata.stat = find(data.id);
|
|
|
|
|
|
|
|
int index = 0;
|
|
|
|
for (int x = 0; x < data.x; x++) {
|
|
|
|
newdata.x = x;
|
|
|
|
for (int y = 0; y < data.y; y++) {
|
|
|
|
newdata.y = y;
|
|
|
|
newdata.data = data.cvec[index++];
|
|
|
|
newdata.insert();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::output(const FormulaData &data)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Implement the visitor
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
MySql::visit(const ScalarData &data)
|
|
|
|
{
|
|
|
|
if (!configured)
|
|
|
|
configure(data);
|
|
|
|
else
|
|
|
|
output(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::visit(const VectorData &data)
|
|
|
|
{
|
|
|
|
if (!configured)
|
|
|
|
configure(data);
|
|
|
|
else
|
|
|
|
output(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::visit(const DistData &data)
|
|
|
|
{
|
|
|
|
if (!configured)
|
|
|
|
configure(data);
|
|
|
|
else
|
|
|
|
output(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::visit(const VectorDistData &data)
|
|
|
|
{
|
|
|
|
if (!configured)
|
|
|
|
configure(data);
|
|
|
|
else
|
|
|
|
output(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::visit(const Vector2dData &data)
|
|
|
|
{
|
|
|
|
if (!configured)
|
|
|
|
configure(data);
|
|
|
|
else
|
|
|
|
output(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MySql::visit(const FormulaData &data)
|
|
|
|
{
|
|
|
|
if (!configured)
|
|
|
|
configure(data);
|
|
|
|
else
|
|
|
|
output(data);
|
|
|
|
}
|
|
|
|
|
2004-05-21 19:03:17 +02:00
|
|
|
/* namespace Stats */ }
|