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, "ns-3-sqlite-data-output-sem");
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  res = m_sqliteOut->Bind (stmt, 1, run);
80  NS_ASSERT (res);
81  res = m_sqliteOut->Bind (stmt, 2, dc.GetExperimentLabel ());
82  NS_ASSERT (res);
83  res = m_sqliteOut->Bind (stmt, 3, dc.GetStrategyLabel ());
84  NS_ASSERT (res);
85  res = m_sqliteOut->Bind (stmt, 4, dc.GetInputLabel ());
86  NS_ASSERT (res);
87  res = m_sqliteOut->Bind (stmt, 5, dc.GetDescription ());
88  NS_ASSERT (res);
89 
90  res = m_sqliteOut->SpinStep (stmt);
91  NS_ASSERT (res);
92  res = m_sqliteOut->SpinFinalize (stmt);
93  NS_ASSERT (res);
94 
95  res = m_sqliteOut->WaitExec ("CREATE TABLE IF NOT EXISTS " \
96  "Metadata ( run text, key text, value)");
97  NS_ASSERT (res);
98 
99  res = m_sqliteOut->WaitPrepare (&stmt,
100  "INSERT INTO Metadata " \
101  "(run, key, value)" \
102  "values (?, ?, ?)");
103  NS_ASSERT (res);
104 
105  for (MetadataList::iterator i = dc.MetadataBegin ();
106  i != dc.MetadataEnd (); i++)
107  {
108  std::pair<std::string, std::string> blob = (*i);
109  m_sqliteOut->SpinReset (stmt);
110  m_sqliteOut->Bind (stmt, 1, run);
111  m_sqliteOut->Bind (stmt, 2, blob.first);
112  m_sqliteOut->Bind (stmt, 3, blob.second);
113  m_sqliteOut->SpinStep (stmt);
114  }
115 
116  m_sqliteOut->SpinFinalize (stmt);
117 
118  m_sqliteOut->SpinExec ("BEGIN");
119  SqliteOutputCallback callback (m_sqliteOut, run);
120  for (DataCalculatorList::iterator i = dc.DataCalculatorBegin ();
121  i != dc.DataCalculatorEnd (); i++)
122  {
123  (*i)->Output (callback);
124  }
125  m_sqliteOut->SpinExec ("COMMIT");
126  // end SqliteDataOutput::Output
127 }
128 
130  (const Ptr<SQLiteOutput> &db, std::string run)
131  : m_db (db),
132  m_runLabel (run)
133 {
134  NS_LOG_FUNCTION (this << db << run);
135 
136  m_db->WaitExec ("CREATE TABLE IF NOT EXISTS Singletons " \
137  "( run text, name text, variable text, value )");
138 
139  m_db->WaitPrepare (&m_insertSingletonStatement, "INSERT INTO Singletons " \
140  "(run, name, variable, value)" \
141  "values (?, ?, ?, ?)");
142  m_db->Bind (m_insertSingletonStatement, 1, m_runLabel);
143 }
144 
146 {
147  m_db->SpinFinalize (m_insertSingletonStatement);
148 }
149 
150 void
152  std::string variable,
153  const StatisticalSummary *statSum)
154 {
155  NS_LOG_FUNCTION (this << key << variable << statSum);
156 
157  OutputSingleton (key,variable + "-count", static_cast<double> (statSum->getCount ()));
158  if (!isNaN (statSum->getSum ()))
159  {
160  OutputSingleton (key,variable + "-total", statSum->getSum ());
161  }
162  if (!isNaN (statSum->getMax ()))
163  {
164  OutputSingleton (key,variable + "-max", statSum->getMax ());
165  }
166  if (!isNaN (statSum->getMin ()))
167  {
168  OutputSingleton (key,variable + "-min", statSum->getMin ());
169  }
170  if (!isNaN (statSum->getSqrSum ()))
171  {
172  OutputSingleton (key,variable + "-sqrsum", statSum->getSqrSum ());
173  }
174  if (!isNaN (statSum->getStddev ()))
175  {
176  OutputSingleton (key,variable + "-stddev", statSum->getStddev ());
177  }
178 }
179 
180 
181 void
183  std::string variable,
184  int val)
185 {
186  NS_LOG_FUNCTION (this << key << variable << val);
187 
188  m_db->SpinReset (m_insertSingletonStatement);
189  m_db->Bind (m_insertSingletonStatement, 2, key);
190  m_db->Bind (m_insertSingletonStatement, 3, variable);
191  m_db->Bind (m_insertSingletonStatement, 4, val);
192  m_db->SpinStep (m_insertSingletonStatement);
193 }
194 void
196  std::string variable,
197  uint32_t val)
198 {
199  NS_LOG_FUNCTION (this << key << variable << val);
200 
201  m_db->SpinReset (m_insertSingletonStatement);
202  m_db->Bind (m_insertSingletonStatement, 2, key);
203  m_db->Bind (m_insertSingletonStatement, 3, variable);
204  m_db->Bind (m_insertSingletonStatement, 4, val);
205  m_db->SpinStep (m_insertSingletonStatement);
206 }
207 
208 void
210  std::string variable,
211  double val)
212 {
213  NS_LOG_FUNCTION (this << key << variable << val);
214 
215  m_db->SpinReset (m_insertSingletonStatement);
216  m_db->Bind (m_insertSingletonStatement, 2, key);
217  m_db->Bind (m_insertSingletonStatement, 3, variable);
218  m_db->Bind (m_insertSingletonStatement, 4, val);
219  m_db->SpinStep (m_insertSingletonStatement);
220 }
221 
222 void
224  std::string variable,
225  std::string val)
226 {
227  NS_LOG_FUNCTION (this << key << variable << val);
228 
229  m_db->SpinReset (m_insertSingletonStatement);
230  m_db->Bind (m_insertSingletonStatement, 2, key);
231  m_db->Bind (m_insertSingletonStatement, 3, variable);
232  m_db->Bind (m_insertSingletonStatement, 4, val);
233  m_db->SpinStep (m_insertSingletonStatement);
234 }
235 
236 void
238  std::string variable,
239  Time val)
240 {
241  NS_LOG_FUNCTION (this << key << variable << val);
242 
243  m_db->SpinReset (m_insertSingletonStatement);
244  m_db->Bind (m_insertSingletonStatement, 2, key);
245  m_db->Bind (m_insertSingletonStatement, 3, variable);
246  m_db->Bind (m_insertSingletonStatement, 4, val.GetTimeStep ());
247  m_db->SpinStep (m_insertSingletonStatement);
248 }
249 
250 } // namespace ns3
DataCalculatorList::iterator DataCalculatorEnd()
Returns an iterator to the past-the-end of the DataCalculator list.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
Abstract Data Output Interface class s
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual double getMin() const =0
Returns the minimum of the values.
A C++ interface towards an SQLITE database.
Definition: sqlite-output.h:45
Abstract class for calculating statistical data.
virtual double getSqrSum() const =0
#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
virtual void Output(DataCollector &dc) override
Outputs information from the provided DataCollector.
std::string GetInputLabel() const
Return the input label.
std::string GetStrategyLabel() const
Return the strategy label.
Class to generate OMNeT output.
virtual double getStddev() const =0
Returns the standard deviation of the (weighted) observations.
void OutputStatistic(std::string key, std::string variable, const StatisticalSummary *statSum)
Generates data statistics.
MetadataList::iterator MetadataBegin()
Returns an iterator to the beginning of the metadata list.
virtual double getMax() const =0
Returns the maximum of the values.
std::string GetExperimentLabel() const
Return the experiment label.
virtual ~SqliteDataOutput() override
std::string GetDescription() const
Return the description label.
std::string GetRunLabel() const
Return the runID label.
void OutputSingleton(std::string key, std::string variable, int val)
Generates a single data output.
std::string m_filePrefix
File prefix for the DataOutputInterface.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Outputs data in a format compatible with SQLite.
virtual double getSum() const =0
static TypeId GetTypeId(void)
Register this type.
Collects data.
DataCalculatorList::iterator DataCalculatorBegin()
Returns an iterator to the beginning of the DataCalculator list.
SqliteOutputCallback(const Ptr< SQLiteOutput > &db, std::string run)
Constructor.
bool isNaN(double x)
true if x is NaN
virtual long getCount() const =0
Returns the number of observations.
a unique identifier for an interface.
Definition: type-id.h:58
MetadataList::iterator MetadataEnd()
Returns an iterator to the past-the-end of the metadata list.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
Ptr< SQLiteOutput > m_sqliteOut
Database.
int64_t GetTimeStep(void) const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:416