A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
sqlite-data-output.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 Drexel University
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Joe Kopena (tjkopena@cs.drexel.edu)
18 */
19
20#include "sqlite-data-output.h"
21
22#include "data-calculator.h"
23#include "data-collector.h"
24#include "sqlite-output.h"
25
26#include "ns3/log.h"
27#include "ns3/nstime.h"
28
29#include <sstream>
30
31namespace ns3
32{
33
34NS_LOG_COMPONENT_DEFINE("SqliteDataOutput");
35
38{
39 NS_LOG_FUNCTION(this);
40
41 m_filePrefix = "data";
42}
43
45{
46 NS_LOG_FUNCTION(this);
47}
48
49/* static */
52{
53 static TypeId tid = TypeId("ns3::SqliteDataOutput")
55 .SetGroupName("Stats")
56 .AddConstructor<SqliteDataOutput>();
57 return tid;
58}
59
60//----------------------------------------------
61void
63{
64 NS_LOG_FUNCTION(this << &dc);
65
66 std::string m_dbFile = m_filePrefix + ".db";
67 std::string run = dc.GetRunLabel();
68 bool res;
69
70 m_sqliteOut = new SQLiteOutput(m_dbFile);
71
72 res = m_sqliteOut->SpinExec("CREATE TABLE IF NOT EXISTS Experiments (run, experiment, "
73 "strategy, input, description text)");
74 NS_ASSERT(res);
75
76 sqlite3_stmt* stmt;
77 res = m_sqliteOut->WaitPrepare(&stmt,
78 "INSERT INTO Experiments "
79 "(run, experiment, strategy, input, description)"
80 "values (?, ?, ?, ?, ?)");
81 NS_ASSERT(res);
82
83 // Create temporary strings to hold their value
84 // throughout the lifetime of the Bind and Step
85 // procedures
86 //
87 // DataCollector could return const std::string&,
88 // but that could break the python bindings
89 res = m_sqliteOut->Bind(stmt, 1, run);
90 NS_ASSERT(res);
91 std::string experimentLabel = dc.GetExperimentLabel();
92 res = m_sqliteOut->Bind(stmt, 2, experimentLabel);
93 NS_ASSERT(res);
94 std::string strategyLabel = dc.GetStrategyLabel();
95 res = m_sqliteOut->Bind(stmt, 3, strategyLabel);
96 NS_ASSERT(res);
97 std::string inputLabel = dc.GetInputLabel();
98 res = m_sqliteOut->Bind(stmt, 4, inputLabel);
99 NS_ASSERT(res);
100 std::string description = dc.GetDescription();
101 res = m_sqliteOut->Bind(stmt, 5, description);
102 NS_ASSERT(res);
103
104 res = m_sqliteOut->SpinStep(stmt);
105 NS_ASSERT(res);
106 res = m_sqliteOut->SpinFinalize(stmt);
107 NS_ASSERT(res == 0);
108
109 res = m_sqliteOut->WaitExec("CREATE TABLE IF NOT EXISTS "
110 "Metadata ( run text, key text, value)");
111 NS_ASSERT(res);
112
113 res = m_sqliteOut->WaitPrepare(&stmt,
114 "INSERT INTO Metadata "
115 "(run, key, value)"
116 "values (?, ?, ?)");
117 NS_ASSERT(res);
118
119 for (MetadataList::iterator i = dc.MetadataBegin(); i != dc.MetadataEnd(); i++)
120 {
121 std::pair<std::string, std::string> blob = (*i);
122 m_sqliteOut->SpinReset(stmt);
123 m_sqliteOut->Bind(stmt, 1, run);
124 m_sqliteOut->Bind(stmt, 2, blob.first);
125 m_sqliteOut->Bind(stmt, 3, blob.second);
126 m_sqliteOut->SpinStep(stmt);
127 }
128
129 m_sqliteOut->SpinFinalize(stmt);
130
131 m_sqliteOut->SpinExec("BEGIN");
132 SqliteOutputCallback callback(m_sqliteOut, run);
133 for (DataCalculatorList::iterator i = dc.DataCalculatorBegin(); i != dc.DataCalculatorEnd();
134 i++)
135 {
136 (*i)->Output(callback);
137 }
138 m_sqliteOut->SpinExec("COMMIT");
139 // end SqliteDataOutput::Output
140 m_sqliteOut->Unref();
141}
142
144 std::string run)
145 : m_db(db),
146 m_runLabel(run)
147{
148 NS_LOG_FUNCTION(this << db << run);
149
150 m_db->WaitExec("CREATE TABLE IF NOT EXISTS Singletons "
151 "( run text, name text, variable text, value )");
152
153 m_db->WaitPrepare(&m_insertSingletonStatement,
154 "INSERT INTO Singletons "
155 "(run, name, variable, value)"
156 "values (?, ?, ?, ?)");
158}
159
161{
162 m_db->SpinFinalize(m_insertSingletonStatement);
163}
164
165void
167 std::string variable,
168 const StatisticalSummary* statSum)
169{
170 NS_LOG_FUNCTION(this << key << variable << statSum);
171
172 OutputSingleton(key, variable + "-count", static_cast<double>(statSum->getCount()));
173 if (!isNaN(statSum->getSum()))
174 {
175 OutputSingleton(key, variable + "-total", statSum->getSum());
176 }
177 if (!isNaN(statSum->getMax()))
178 {
179 OutputSingleton(key, variable + "-max", statSum->getMax());
180 }
181 if (!isNaN(statSum->getMin()))
182 {
183 OutputSingleton(key, variable + "-min", statSum->getMin());
184 }
185 if (!isNaN(statSum->getSqrSum()))
186 {
187 OutputSingleton(key, variable + "-sqrsum", statSum->getSqrSum());
188 }
189 if (!isNaN(statSum->getStddev()))
190 {
191 OutputSingleton(key, variable + "-stddev", statSum->getStddev());
192 }
193}
194
195void
197 std::string variable,
198 int val)
199{
200 NS_LOG_FUNCTION(this << key << variable << val);
201
202 m_db->SpinReset(m_insertSingletonStatement);
203 m_db->Bind(m_insertSingletonStatement, 2, key);
204 m_db->Bind(m_insertSingletonStatement, 3, variable);
205 m_db->Bind(m_insertSingletonStatement, 4, val);
206 m_db->SpinStep(m_insertSingletonStatement);
207}
208
209void
211 std::string variable,
212 uint32_t val)
213{
214 NS_LOG_FUNCTION(this << key << variable << val);
215
216 m_db->SpinReset(m_insertSingletonStatement);
217 m_db->Bind(m_insertSingletonStatement, 2, key);
218 m_db->Bind(m_insertSingletonStatement, 3, variable);
219 m_db->Bind(m_insertSingletonStatement, 4, val);
220 m_db->SpinStep(m_insertSingletonStatement);
221}
222
223void
225 std::string variable,
226 double val)
227{
228 NS_LOG_FUNCTION(this << key << variable << val);
229
230 m_db->SpinReset(m_insertSingletonStatement);
231 m_db->Bind(m_insertSingletonStatement, 2, key);
232 m_db->Bind(m_insertSingletonStatement, 3, variable);
233 m_db->Bind(m_insertSingletonStatement, 4, val);
234 m_db->SpinStep(m_insertSingletonStatement);
235}
236
237void
239 std::string variable,
240 std::string val)
241{
242 NS_LOG_FUNCTION(this << key << variable << val);
243
244 m_db->SpinReset(m_insertSingletonStatement);
245 m_db->Bind(m_insertSingletonStatement, 2, key);
246 m_db->Bind(m_insertSingletonStatement, 3, variable);
247 m_db->Bind(m_insertSingletonStatement, 4, val);
248 m_db->SpinStep(m_insertSingletonStatement);
249}
250
251void
253 std::string variable,
254 Time val)
255{
256 NS_LOG_FUNCTION(this << key << variable << val);
257
258 m_db->SpinReset(m_insertSingletonStatement);
259 m_db->Bind(m_insertSingletonStatement, 2, key);
260 m_db->Bind(m_insertSingletonStatement, 3, variable);
261 m_db->Bind(m_insertSingletonStatement, 4, val.GetTimeStep());
262 m_db->SpinStep(m_insertSingletonStatement);
263}
264
265} // 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:78
A C++ interface towards an SQLITE database.
Definition: sqlite-output.h:47
void OutputStatistic(std::string key, std::string variable, const StatisticalSummary *statSum) override
Generates data statistics.
sqlite3_stmt * m_insertSingletonStatement
Pointer to a Sqlite3 singleton statement.
SqliteOutputCallback(const Ptr< SQLiteOutput > &db, std::string run)
Constructor.
void OutputSingleton(std::string key, std::string variable, int val) override
Generates a single data output.
Outputs data in a format compatible with SQLite.
void Output(DataCollector &dc) override
Outputs information from the provided DataCollector.
static TypeId GetTypeId()
Register this type.
Ptr< SQLiteOutput > m_sqliteOut
Database.
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:105
int64_t GetTimeStep() const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:444
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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