A Discrete-Event Network Simulator
API
sqlite-data-output.cc
Go to the documentation of this file.
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 "sqlite-data-output.h"
22 #include <sstream>
23 
24 #include "ns3/log.h"
25 #include "ns3/nstime.h"
26 
27 #include "data-collector.h"
28 #include "data-calculator.h"
29 #include "sqlite-output.h"
30 
31 namespace ns3 {
32 
33 NS_LOG_COMPONENT_DEFINE ("SqliteDataOutput");
34 
37 {
38  NS_LOG_FUNCTION (this);
39 
40  m_filePrefix = "data";
41 }
43 {
44  NS_LOG_FUNCTION (this);
45 }
46 /* static */
47 TypeId
49 {
50  static TypeId tid = TypeId ("ns3::SqliteDataOutput")
52  .SetGroupName ("Stats")
53  .AddConstructor<SqliteDataOutput> ();
54  return tid;
55 }
56 
57 //----------------------------------------------
58 void
60 {
61  NS_LOG_FUNCTION (this << &dc);
62 
63  std::string m_dbFile = m_filePrefix + ".db";
64  std::string run = dc.GetRunLabel ();
65  bool res;
66 
67  m_sqliteOut = new SQLiteOutput (m_dbFile);
68 
69  res = m_sqliteOut->SpinExec ("CREATE TABLE IF NOT EXISTS Experiments (run, experiment, strategy, input, description text)");
70  NS_ASSERT (res);
71 
72  sqlite3_stmt *stmt;
73  res = m_sqliteOut->WaitPrepare (&stmt,
74  "INSERT INTO Experiments " \
75  "(run, experiment, strategy, input, description)" \
76  "values (?, ?, ?, ?, ?)");
77  NS_ASSERT (res);
78 
79  // Create temporary strings to hold their value
80  // throughout the lifetime of the Bind and Step
81  // procedures
82  //
83  // DataCollector could return const std::string&,
84  // but that could break the python bindings
85  res = m_sqliteOut->Bind (stmt, 1, run);
86  NS_ASSERT (res);
87  std::string experimentLabel = dc.GetExperimentLabel ();
88  res = m_sqliteOut->Bind (stmt, 2, experimentLabel);
89  NS_ASSERT (res);
90  std::string strategyLabel = dc.GetStrategyLabel ();
91  res = m_sqliteOut->Bind (stmt, 3, strategyLabel);
92  NS_ASSERT (res);
93  std::string inputLabel = dc.GetInputLabel();
94  res = m_sqliteOut->Bind (stmt, 4, inputLabel);
95  NS_ASSERT (res);
96  std::string description = dc.GetDescription ();
97  res = m_sqliteOut->Bind (stmt, 5, description);
98  NS_ASSERT (res);
99 
100  res = m_sqliteOut->SpinStep (stmt);
101  NS_ASSERT (res);
102  res = m_sqliteOut->SpinFinalize (stmt);
103  NS_ASSERT (res == 0);
104 
105  res = m_sqliteOut->WaitExec ("CREATE TABLE IF NOT EXISTS " \
106  "Metadata ( run text, key text, value)");
107  NS_ASSERT (res);
108 
109  res = m_sqliteOut->WaitPrepare (&stmt,
110  "INSERT INTO Metadata " \
111  "(run, key, value)" \
112  "values (?, ?, ?)");
113  NS_ASSERT (res);
114 
115  for (MetadataList::iterator i = dc.MetadataBegin ();
116  i != dc.MetadataEnd (); i++)
117  {
118  std::pair<std::string, std::string> blob = (*i);
119  m_sqliteOut->SpinReset (stmt);
120  m_sqliteOut->Bind (stmt, 1, run);
121  m_sqliteOut->Bind (stmt, 2, blob.first);
122  m_sqliteOut->Bind (stmt, 3, blob.second);
123  m_sqliteOut->SpinStep (stmt);
124  }
125 
126  m_sqliteOut->SpinFinalize (stmt);
127 
128  m_sqliteOut->SpinExec ("BEGIN");
129  SqliteOutputCallback callback (m_sqliteOut, run);
130  for (DataCalculatorList::iterator i = dc.DataCalculatorBegin ();
131  i != dc.DataCalculatorEnd (); i++)
132  {
133  (*i)->Output (callback);
134  }
135  m_sqliteOut->SpinExec ("COMMIT");
136  // end SqliteDataOutput::Output
137  m_sqliteOut->Unref();
138 }
139 
141  (const Ptr<SQLiteOutput> &db, std::string run)
142  : m_db (db),
143  m_runLabel (run)
144 {
145  NS_LOG_FUNCTION (this << db << run);
146 
147  m_db->WaitExec ("CREATE TABLE IF NOT EXISTS Singletons " \
148  "( run text, name text, variable text, value )");
149 
150  m_db->WaitPrepare (&m_insertSingletonStatement, "INSERT INTO Singletons " \
151  "(run, name, variable, value)" \
152  "values (?, ?, ?, ?)");
154 }
155 
157 {
158  m_db->SpinFinalize (m_insertSingletonStatement);
159 }
160 
161 void
163  std::string variable,
164  const StatisticalSummary *statSum)
165 {
166  NS_LOG_FUNCTION (this << key << variable << statSum);
167 
168  OutputSingleton (key,variable + "-count", static_cast<double> (statSum->getCount ()));
169  if (!isNaN (statSum->getSum ()))
170  {
171  OutputSingleton (key,variable + "-total", statSum->getSum ());
172  }
173  if (!isNaN (statSum->getMax ()))
174  {
175  OutputSingleton (key,variable + "-max", statSum->getMax ());
176  }
177  if (!isNaN (statSum->getMin ()))
178  {
179  OutputSingleton (key,variable + "-min", statSum->getMin ());
180  }
181  if (!isNaN (statSum->getSqrSum ()))
182  {
183  OutputSingleton (key,variable + "-sqrsum", statSum->getSqrSum ());
184  }
185  if (!isNaN (statSum->getStddev ()))
186  {
187  OutputSingleton (key,variable + "-stddev", statSum->getStddev ());
188  }
189 }
190 
191 
192 void
194  std::string variable,
195  int val)
196 {
197  NS_LOG_FUNCTION (this << key << variable << val);
198 
199  m_db->SpinReset (m_insertSingletonStatement);
200  m_db->Bind (m_insertSingletonStatement, 2, key);
201  m_db->Bind (m_insertSingletonStatement, 3, variable);
202  m_db->Bind (m_insertSingletonStatement, 4, val);
203  m_db->SpinStep (m_insertSingletonStatement);
204 }
205 void
207  std::string variable,
208  uint32_t val)
209 {
210  NS_LOG_FUNCTION (this << key << variable << val);
211 
212  m_db->SpinReset (m_insertSingletonStatement);
213  m_db->Bind (m_insertSingletonStatement, 2, key);
214  m_db->Bind (m_insertSingletonStatement, 3, variable);
215  m_db->Bind (m_insertSingletonStatement, 4, val);
216  m_db->SpinStep (m_insertSingletonStatement);
217 }
218 
219 void
221  std::string variable,
222  double val)
223 {
224  NS_LOG_FUNCTION (this << key << variable << val);
225 
226  m_db->SpinReset (m_insertSingletonStatement);
227  m_db->Bind (m_insertSingletonStatement, 2, key);
228  m_db->Bind (m_insertSingletonStatement, 3, variable);
229  m_db->Bind (m_insertSingletonStatement, 4, val);
230  m_db->SpinStep (m_insertSingletonStatement);
231 }
232 
233 void
235  std::string variable,
236  std::string val)
237 {
238  NS_LOG_FUNCTION (this << key << variable << val);
239 
240  m_db->SpinReset (m_insertSingletonStatement);
241  m_db->Bind (m_insertSingletonStatement, 2, key);
242  m_db->Bind (m_insertSingletonStatement, 3, variable);
243  m_db->Bind (m_insertSingletonStatement, 4, val);
244  m_db->SpinStep (m_insertSingletonStatement);
245 }
246 
247 void
249  std::string variable,
250  Time val)
251 {
252  NS_LOG_FUNCTION (this << key << variable << val);
253 
254  m_db->SpinReset (m_insertSingletonStatement);
255  m_db->Bind (m_insertSingletonStatement, 2, key);
256  m_db->Bind (m_insertSingletonStatement, 3, variable);
257  m_db->Bind (m_insertSingletonStatement, 4, val.GetTimeStep ());
258  m_db->SpinStep (m_insertSingletonStatement);
259 }
260 
261 } // namespace ns3
Collects data.
std::string GetExperimentLabel() const
Return the experiment label.
DataCalculatorList::iterator DataCalculatorBegin()
Returns an iterator to the beginning of the DataCalculator list.
DataCalculatorList::iterator DataCalculatorEnd()
Returns an iterator to the past-the-end of the DataCalculator list.
std::string GetDescription() const
Return the description label.
MetadataList::iterator MetadataBegin()
Returns an iterator to the beginning of the metadata list.
MetadataList::iterator MetadataEnd()
Returns an iterator to the past-the-end of the metadata list.
std::string GetStrategyLabel() const
Return the strategy label.
std::string GetRunLabel() const
Return the runID label.
std::string GetInputLabel() const
Return the input label.
Abstract Data Output Interface class s.
std::string m_filePrefix
File prefix for the DataOutputInterface.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
A C++ interface towards an SQLITE database.
Definition: sqlite-output.h:46
sqlite3_stmt * m_insertSingletonStatement
Pointer to a Sqlite3 singleton statement.
void OutputSingleton(std::string key, std::string variable, int val)
Generates a single data output.
SqliteOutputCallback(const Ptr< SQLiteOutput > &db, std::string run)
Constructor.
void OutputStatistic(std::string key, std::string variable, const StatisticalSummary *statSum)
Generates data statistics.
Outputs data in a format compatible with SQLite.
virtual void Output(DataCollector &dc) override
Outputs information from the provided DataCollector.
Ptr< SQLiteOutput > m_sqliteOut
Database.
virtual ~SqliteDataOutput() override
static TypeId GetTypeId(void)
Register this type.
Abstract class for calculating statistical data.
virtual double getMax() const =0
Returns the maximum of the values.
virtual double getStddev() const =0
Returns the standard deviation of the (weighted) observations.
virtual long getCount() const =0
Returns the number of observations.
virtual double getMin() const =0
Returns the minimum of the values.
virtual double getSum() const =0
virtual double getSqrSum() const =0
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
int64_t GetTimeStep(void) const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:415
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool isNaN(double x)
true if x is NaN