src/contrib/stats/sqlite-data-output.cc
changeset 6855 104f16f72979
parent 6854 dc1057c9879d
child 6856 298dbc966811
equal deleted inserted replaced
6854:dc1057c9879d 6855:104f16f72979
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * Copyright (c) 2008 Drexel University
       
     4  *
       
     5  * This program is free software; you can redistribute it and/or modify
       
     6  * it under the terms of the GNU General Public License version 2 as
       
     7  * published by the Free Software Foundation;
       
     8  *
       
     9  * This program is distributed in the hope that it will be useful,
       
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12  * GNU General Public License for more details.
       
    13  *
       
    14  * You should have received a copy of the GNU General Public License
       
    15  * along with this program; if not, write to the Free Software
       
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    17  *
       
    18  * Author: Joe Kopena (tjkopena@cs.drexel.edu)
       
    19  */
       
    20 
       
    21 #include <sstream>
       
    22 
       
    23 #include <sqlite3.h>
       
    24 
       
    25 #include "ns3/log.h"
       
    26 #include "ns3/nstime.h"
       
    27 
       
    28 #include "data-collector.h"
       
    29 #include "data-calculator.h"
       
    30 #include "sqlite-data-output.h"
       
    31 
       
    32 using namespace ns3;
       
    33 
       
    34 NS_LOG_COMPONENT_DEFINE("SqliteDataOutput");
       
    35 
       
    36 //--------------------------------------------------------------
       
    37 //----------------------------------------------
       
    38 SqliteDataOutput::SqliteDataOutput()
       
    39 {
       
    40   m_filePrefix = "data";
       
    41   NS_LOG_FUNCTION_NOARGS();
       
    42 }
       
    43 SqliteDataOutput::~SqliteDataOutput()
       
    44 {
       
    45   NS_LOG_FUNCTION_NOARGS();
       
    46 }
       
    47 void
       
    48 SqliteDataOutput::DoDispose()
       
    49 {
       
    50   NS_LOG_FUNCTION_NOARGS();
       
    51 
       
    52   DataOutputInterface::DoDispose();
       
    53   // end SqliteDataOutput::DoDispose
       
    54 }
       
    55 
       
    56 int
       
    57 SqliteDataOutput::Exec(std::string exe) {
       
    58   int res;
       
    59   char **result;
       
    60   int nrows, ncols;
       
    61   char *errMsg = 0;
       
    62 
       
    63   NS_LOG_INFO("executing '" << exe << "'");
       
    64 
       
    65   res = sqlite3_get_table(m_db,
       
    66                           exe.c_str(),
       
    67                           &result, &nrows, &ncols,
       
    68                           &errMsg);
       
    69 
       
    70   if (res != SQLITE_OK) {
       
    71     NS_LOG_ERROR("sqlite3 error: \"" << errMsg << "\"");
       
    72   /*
       
    73   } else {
       
    74     // std::cout << "nrows " << nrows << " ncols " << ncols << std::endl;
       
    75 
       
    76     if (nrows > 0) {
       
    77       for (int i = 0; i < ncols; i++) {
       
    78         std::cout << "  " << result[i];
       
    79       }
       
    80       std::cout << std::endl;
       
    81 
       
    82       for (int r = 1; r <= nrows; r++) {
       
    83         for (int c = 0; c < ncols; c++) {
       
    84           std::cout << "  " << result[(r*ncols)+c];
       
    85         }
       
    86         std::cout << std::endl;
       
    87       }
       
    88       std::cout << std::endl;
       
    89     }
       
    90   */
       
    91   }
       
    92 
       
    93   sqlite3_free_table(result);
       
    94   return res;
       
    95 
       
    96   // end SqliteDataOutput::Exec
       
    97 }
       
    98 
       
    99 //----------------------------------------------
       
   100 void
       
   101 SqliteDataOutput::Output(DataCollector &dc)
       
   102 {
       
   103   std::string m_dbFile = m_filePrefix + ".db";
       
   104 
       
   105   if (sqlite3_open(m_dbFile.c_str(), &m_db)) {
       
   106     NS_LOG_ERROR("Could not open sqlite3 database \"" << m_dbFile << "\"");
       
   107     NS_LOG_ERROR("sqlite3 error \"" << sqlite3_errmsg(m_db) << "\"");
       
   108     sqlite3_close(m_db);
       
   109     // TODO: Better error reporting, management!
       
   110     return;
       
   111   }
       
   112 
       
   113   std::string run = dc.GetRunLabel();
       
   114 
       
   115   Exec("create table if not exists Experiments (run, experiment, strategy, input, description text)");
       
   116   Exec("insert into Experiments (run,experiment,strategy,input,description) values ('" +
       
   117        run + "', '" +
       
   118        dc.GetExperimentLabel() + "', '" +
       
   119        dc.GetStrategyLabel() + "', '" +
       
   120        dc.GetInputLabel() + "', '" +
       
   121        dc.GetDescription() + "')");
       
   122 
       
   123   Exec("create table if not exists Metadata ( run text, key text, value)");
       
   124 
       
   125   for (MetadataList::iterator i = dc.MetadataBegin();
       
   126        i != dc.MetadataEnd(); i++) {
       
   127     std::pair<std::string, std::string> blob = (*i);
       
   128     Exec("insert into Metadata (run,key,value) values ('" +
       
   129          run + "', '" +
       
   130          blob.first + "', '" +
       
   131          blob.second + "')");
       
   132   }
       
   133 
       
   134   Exec("BEGIN");
       
   135   SqliteOutputCallback callback(this, run);
       
   136   for (DataCalculatorList::iterator i = dc.DataCalculatorBegin();
       
   137        i != dc.DataCalculatorEnd(); i++) {
       
   138     (*i)->Output(callback);
       
   139   }
       
   140   Exec("COMMIT");
       
   141 
       
   142   sqlite3_close(m_db);
       
   143 
       
   144   // end SqliteDataOutput::Output
       
   145 }
       
   146 
       
   147 SqliteDataOutput::SqliteOutputCallback::SqliteOutputCallback
       
   148   (Ptr<SqliteDataOutput> owner, std::string run) :
       
   149     m_owner(owner),
       
   150     m_runLabel(run)
       
   151 {
       
   152 
       
   153   m_owner->Exec("create table if not exists Singletons ( run text, name text, variable text, value )");
       
   154 
       
   155   // end SqliteDataOutput::SqliteOutputCallback::SqliteOutputCallback
       
   156 }
       
   157 
       
   158 void
       
   159 SqliteDataOutput::SqliteOutputCallback::OutputStatistic(std::string key,
       
   160                        std::string variable,
       
   161                        const StatisticalSummary *statSum)
       
   162 {
       
   163 	OutputSingleton(key,variable+"-count", (double)statSum->getCount());
       
   164 	if (!isNaN(statSum->getSum()))
       
   165 		OutputSingleton(key,variable+"-total", statSum->getSum());
       
   166 	if (!isNaN(statSum->getMax()))
       
   167 		OutputSingleton(key,variable+"-max", statSum->getMax());
       
   168 	if (!isNaN(statSum->getMin()))
       
   169 		OutputSingleton(key,variable+"-min", statSum->getMin());
       
   170 	if (!isNaN(statSum->getSqrSum()))
       
   171 		OutputSingleton(key,variable+"-sqrsum", statSum->getSqrSum());
       
   172 	if (!isNaN(statSum->getStddev()))
       
   173 		OutputSingleton(key,variable+"-stddev", statSum->getStddev());
       
   174 }
       
   175 
       
   176 
       
   177 void
       
   178 SqliteDataOutput::SqliteOutputCallback::OutputSingleton(std::string key,
       
   179                                                         std::string variable,
       
   180                                                         int val)
       
   181 {
       
   182 
       
   183   std::stringstream sstr;
       
   184   sstr << "insert into Singletons (run,name,variable,value) values ('" <<
       
   185     m_runLabel << "', '" <<
       
   186     key << "', '" <<
       
   187     variable << "', " <<
       
   188     val << ")";
       
   189   m_owner->Exec(sstr.str());
       
   190 
       
   191   // end SqliteDataOutput::SqliteOutputCallback::OutputSingleton
       
   192 }
       
   193 void
       
   194 SqliteDataOutput::SqliteOutputCallback::OutputSingleton(std::string key,
       
   195                                                         std::string variable,
       
   196                                                         uint32_t val)
       
   197 {
       
   198   std::stringstream sstr;
       
   199   sstr << "insert into Singletons (run,name,variable,value) values ('" <<
       
   200     m_runLabel << "', '" <<
       
   201     key << "', '" <<
       
   202     variable << "', " <<
       
   203     val << ")";
       
   204   m_owner->Exec(sstr.str());
       
   205   // end SqliteDataOutput::SqliteOutputCallback::OutputSingleton
       
   206 }
       
   207 void
       
   208 SqliteDataOutput::SqliteOutputCallback::OutputSingleton(std::string key,
       
   209                                                         std::string variable,
       
   210                                                         double val)
       
   211 {
       
   212   std::stringstream sstr;
       
   213   sstr << "insert into Singletons (run,name,variable,value) values ('" <<
       
   214     m_runLabel << "', '" <<
       
   215     key << "', '" <<
       
   216     variable << "', " <<
       
   217     val << ")";
       
   218   m_owner->Exec(sstr.str());
       
   219   // end SqliteDataOutput::SqliteOutputCallback::OutputSingleton
       
   220 }
       
   221 void
       
   222 SqliteDataOutput::SqliteOutputCallback::OutputSingleton(std::string key,
       
   223                                                         std::string variable,
       
   224                                                         std::string val)
       
   225 {
       
   226   std::stringstream sstr;
       
   227   sstr << "insert into Singletons (run,name,variable,value) values ('" <<
       
   228     m_runLabel << "', '" <<
       
   229     key << "', '" <<
       
   230     variable << "', '" <<
       
   231     val << "')";
       
   232   m_owner->Exec(sstr.str());
       
   233   // end SqliteDataOutput::SqliteOutputCallback::OutputSingleton
       
   234 }
       
   235 void
       
   236 SqliteDataOutput::SqliteOutputCallback::OutputSingleton(std::string key,
       
   237                                                         std::string variable,
       
   238                                                         Time val)
       
   239 {
       
   240   std::stringstream sstr;
       
   241   sstr << "insert into Singletons (run,name,variable,value) values ('" <<
       
   242     m_runLabel << "', '" <<
       
   243     key << "', '" <<
       
   244     variable << "', " <<
       
   245     val.GetTimeStep() << ")";
       
   246   m_owner->Exec(sstr.str());
       
   247   // end SqliteDataOutput::SqliteOutputCallback::OutputSingleton
       
   248 }