mysql.cc
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 948 行 · 第 1/2 页
CC
948 行
/* * Copyright (c) 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Nathan L. Binkert */#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"#include "base/stats/mysql_run.hh"#include "base/stats/statdb.hh"#include "base/stats/types.hh"#include "base/str.hh"#include "base/userinfo.hh"#include "sim/host.hh"using namespace std;namespace Stats {voidMySqlRun::connect(const string &host, const string &user, const string &passwd, const string &db, const string &name, const string &sample, const string &project){ 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); if (mysql.autocommit(false)) panic("could not set autocommit\n%s\n", mysql.error); remove(name); //cleanup(); setup(name, sample, user, project);}voidMySqlRun::setup(const string &name, const string &sample, const string &user, const string &project){ assert(mysql.connected()); stringstream insert; ccprintf(insert, "INSERT INTO " "runs(rn_name,rn_sample,rn_user,rn_project,rn_date,rn_expire)" "values(\"%s\", \"%s\", \"%s\", \"%s\", NOW()," "DATE_ADD(CURDATE(), INTERVAL 31 DAY))", name, sample, user, project); mysql.query(insert); if (mysql.error) panic("could not get a run\n%s\n", mysql.error); run_id = mysql.insert_id(); if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error);}voidMySqlRun::remove(const string &name){ assert(mysql.connected()); stringstream sql; ccprintf(sql, "DELETE FROM runs WHERE rn_name=\"%s\"", name); mysql.query(sql); if (mysql.error) panic("could not delete run\n%s\n", mysql.error); if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error);}voidMySqlRun::cleanup(){ assert(mysql.connected()); mysql.query("DELETE data " "FROM data " "LEFT JOIN runs ON dt_run=rn_id " "WHERE rn_id IS NULL"); if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error); mysql.query("DELETE formula_ref " "FROM formula_ref " "LEFT JOIN runs ON fr_run=rn_id " "WHERE rn_id IS NULL"); if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error); mysql.query("DELETE formulas " "FROM formulas " "LEFT JOIN formula_ref ON fm_stat=fr_stat " "WHERE fr_stat IS NULL"); if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error); mysql.query("DELETE stats " "FROM stats " "LEFT JOIN data ON st_id=dt_stat " "WHERE dt_stat IS NULL"); if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error); mysql.query("DELETE subdata " "FROM subdata " "LEFT JOIN data ON sd_stat=dt_stat " "WHERE dt_stat 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);}voidSetupStat::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;}unsignedSetupStat::setup(MySqlRun *run){ MySQL::Connection &mysql = run->conn(); 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) { int id = mysql.insert_id(); if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error); return id; } stringstream select; ccprintf(select, "SELECT * FROM stats WHERE st_name=\"%s\"", name); mysql.query(select); MySQL::Result result = mysql.store_result(); if (!result) panic("could not find stat\n%s\n", mysql.error); assert(result.num_fields() == 16); MySQL::Row row = result.fetch_row(); if (!row) panic("could not get stat row\n%s\n", mysql.error); 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;}InsertData::InsertData(MySqlRun *_run) : run(_run){ query = new char[maxsize + 1]; size = 0; flush();}InsertData::~InsertData(){ delete [] query;}voidInsertData::flush(){ if (size) { MySQL::Connection &mysql = run->conn(); assert(mysql.connected()); mysql.query(query); if (mysql.error) panic("could not insert data\n%s\n", mysql.error); if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error); } query[0] = '\0'; size = 0; first = true; strcpy(query, "INSERT INTO " "data(dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_data) " "values"); size = strlen(query);}voidInsertData::insert(){ if (size + 1024 > maxsize) flush(); if (!first) { query[size++] = ','; query[size] = '\0'; } first = false; size += sprintf(query + size, "(%u,%d,%d,%u,%llu,\"%f\")", stat, x, y, run->run(), (unsigned long long)tick, data);}InsertEvent::InsertEvent(MySqlRun *_run) : run(_run){ query = new char[maxsize + 1]; size = 0; first = true; flush();}InsertEvent::~InsertEvent(){ flush();}voidInsertEvent::insert(const string &stat){ MySQL::Connection &mysql = run->conn(); assert(mysql.connected()); event_map_t::iterator i = events.find(stat); uint32_t event; if (i == events.end()) { mysql.query( csprintf("SELECT en_id " "from event_names " "where en_name=\"%s\"", stat)); MySQL::Result result = mysql.store_result(); if (!result) panic("could not get a run\n%s\n", mysql.error); assert(result.num_fields() == 1); MySQL::Row row = result.fetch_row(); if (row) { if (!to_number(row[0], event)) panic("invalid event id: %s\n", row[0]); } else { mysql.query( csprintf("INSERT INTO " "event_names(en_name)" "values(\"%s\")", stat)); if (mysql.error) panic("could not get a run\n%s\n", mysql.error); event = mysql.insert_id(); } } else { event = (*i).second; } if (size + 1024 > maxsize) flush(); if (!first) { query[size++] = ','; query[size] = '\0'; } first = false; size += sprintf(query + size, "(%u,%u,%llu)", event, run->run(), (unsigned long long)curTick);}voidInsertEvent::flush(){ static const char query_header[] = "INSERT INTO " "events(ev_event, ev_run, ev_tick)" "values"; MySQL::Connection &mysql = run->conn(); assert(mysql.connected()); if (size) mysql.query(query); query[0] = '\0'; size = sizeof(query_header); first = true; memcpy(query, query_header, size);}struct InsertSubData{ uint16_t stat; int16_t x; int16_t y; string name; string descr; void setup(MySqlRun *run);};voidInsertSubData::setup(MySqlRun *run){ MySQL::Connection &mysql = run->conn(); 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);// if (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);}MySql::MySql() : run(new MySqlRun), newdata(run), newevent(run){}MySql::~MySql(){ delete run;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?