blob: bc5d8dec6a4c8b44d8f92ef06539ca7a12b069f1 [file] [log] [blame]
Alexander Afanasyev86287992012-12-10 16:11:50 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2011 UCLA
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 *
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -080018 * Author: Xiaoyan Hu <x......u@gmail.com>
19 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
Alexander Afanasyev86287992012-12-10 16:11:50 -080020 */
21
Alexander Afanasyev0c395372014-12-20 15:54:02 -080022#include "ndn-cs-tracer.hpp"
Alexander Afanasyev86287992012-12-10 16:11:50 -080023#include "ns3/node.h"
24#include "ns3/packet.h"
25#include "ns3/config.h"
26#include "ns3/names.h"
27#include "ns3/callback.h"
28
Alexander Afanasyev0c395372014-12-20 15:54:02 -080029#include "ns3/ndn-app.hpp"
30#include "ns3/ndn-interest.hpp"
31#include "ns3/ndn-data.hpp"
32#include "ns3/ndn-content-store.hpp"
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -080033#include "ns3/simulator.h"
34#include "ns3/node-list.h"
35#include "ns3/log.h"
36
37#include <boost/lexical_cast.hpp>
38
39#include <fstream>
40
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080041NS_LOG_COMPONENT_DEFINE("ndn.CsTracer");
Alexander Afanasyev86287992012-12-10 16:11:50 -080042
43using namespace std;
44
45namespace ns3 {
46namespace ndn {
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -080047
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080048static std::list<boost::tuple<boost::shared_ptr<std::ostream>, std::list<Ptr<CsTracer>>>> g_tracers;
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070049
Alexander Afanasyev5352af32013-07-15 09:51:28 -070050template<class T>
51static inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080052NullDeleter(T* ptr)
Alexander Afanasyev5352af32013-07-15 09:51:28 -070053{
54}
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -080055
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070056void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080057CsTracer::Destroy()
Alexander Afanasyevdb5f3b62013-08-09 17:42:12 -070058{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080059 g_tracers.clear();
Alexander Afanasyevdb5f3b62013-08-09 17:42:12 -070060}
61
62void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080063CsTracer::InstallAll(const std::string& file, Time averagingPeriod /* = Seconds (0.5)*/)
Alexander Afanasyev5352af32013-07-15 09:51:28 -070064{
65 using namespace boost;
66 using namespace std;
67
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080068 std::list<Ptr<CsTracer>> tracers;
Alexander Afanasyev5352af32013-07-15 09:51:28 -070069 boost::shared_ptr<std::ostream> outputStream;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080070 if (file != "-") {
71 boost::shared_ptr<std::ofstream> os(new std::ofstream());
72 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
Alexander Afanasyev5352af32013-07-15 09:51:28 -070073
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080074 if (!os->is_open()) {
75 NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
76 return;
Alexander Afanasyev5352af32013-07-15 09:51:28 -070077 }
78
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080079 outputStream = os;
80 }
81 else {
82 outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
83 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -070084
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080085 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
86 Ptr<CsTracer> trace = Install(*node, outputStream, averagingPeriod);
87 tracers.push_back(trace);
88 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -070089
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080090 if (tracers.size() > 0) {
91 // *m_l3RateTrace << "# "; // not necessary for R's read.table
92 tracers.front()->PrintHeader(*outputStream);
93 *outputStream << "\n";
94 }
95
96 g_tracers.push_back(boost::make_tuple(outputStream, tracers));
Alexander Afanasyev5352af32013-07-15 09:51:28 -070097}
98
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070099void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800100CsTracer::Install(const NodeContainer& nodes, const std::string& file,
101 Time averagingPeriod /* = Seconds (0.5)*/)
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700102{
103 using namespace boost;
104 using namespace std;
105
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800106 std::list<Ptr<CsTracer>> tracers;
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700107 boost::shared_ptr<std::ostream> outputStream;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800108 if (file != "-") {
109 boost::shared_ptr<std::ofstream> os(new std::ofstream());
110 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700111
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800112 if (!os->is_open()) {
113 NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
114 return;
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700115 }
116
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800117 outputStream = os;
118 }
119 else {
120 outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
121 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700122
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800123 for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
124 Ptr<CsTracer> trace = Install(*node, outputStream, averagingPeriod);
125 tracers.push_back(trace);
126 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700127
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800128 if (tracers.size() > 0) {
129 // *m_l3RateTrace << "# "; // not necessary for R's read.table
130 tracers.front()->PrintHeader(*outputStream);
131 *outputStream << "\n";
132 }
133
134 g_tracers.push_back(boost::make_tuple(outputStream, tracers));
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700135}
136
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800137void
138CsTracer::Install(Ptr<Node> node, const std::string& file,
139 Time averagingPeriod /* = Seconds (0.5)*/)
140{
141 using namespace boost;
142 using namespace std;
143
144 std::list<Ptr<CsTracer>> tracers;
145 boost::shared_ptr<std::ostream> outputStream;
146 if (file != "-") {
147 boost::shared_ptr<std::ofstream> os(new std::ofstream());
148 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
149
150 if (!os->is_open()) {
151 NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
152 return;
153 }
154
155 outputStream = os;
156 }
157 else {
158 outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
159 }
160
161 Ptr<CsTracer> trace = Install(node, outputStream, averagingPeriod);
162 tracers.push_back(trace);
163
164 if (tracers.size() > 0) {
165 // *m_l3RateTrace << "# "; // not necessary for R's read.table
166 tracers.front()->PrintHeader(*outputStream);
167 *outputStream << "\n";
168 }
169
170 g_tracers.push_back(boost::make_tuple(outputStream, tracers));
171}
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700172
173Ptr<CsTracer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800174CsTracer::Install(Ptr<Node> node, boost::shared_ptr<std::ostream> outputStream,
175 Time averagingPeriod /* = Seconds (0.5)*/)
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700176{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800177 NS_LOG_DEBUG("Node: " << node->GetId());
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700178
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800179 Ptr<CsTracer> trace = Create<CsTracer>(outputStream, node);
180 trace->SetAveragingPeriod(averagingPeriod);
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700181
182 return trace;
183}
184
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800185//////////////////////////////////////////////////////////////////////////////
186//////////////////////////////////////////////////////////////////////////////
187//////////////////////////////////////////////////////////////////////////////
188
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800189CsTracer::CsTracer(boost::shared_ptr<std::ostream> os, Ptr<Node> node)
190 : m_nodePtr(node)
191 , m_os(os)
Alexander Afanasyev86287992012-12-10 16:11:50 -0800192{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800193 m_node = boost::lexical_cast<string>(m_nodePtr->GetId());
Alexander Afanasyev86287992012-12-10 16:11:50 -0800194
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800195 Connect();
Alexander Afanasyev86287992012-12-10 16:11:50 -0800196
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800197 string name = Names::FindName(node);
198 if (!name.empty()) {
199 m_node = name;
200 }
Alexander Afanasyev86287992012-12-10 16:11:50 -0800201}
202
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800203CsTracer::CsTracer(boost::shared_ptr<std::ostream> os, const std::string& node)
204 : m_node(node)
205 , m_os(os)
Alexander Afanasyev86287992012-12-10 16:11:50 -0800206{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800207 Connect();
Alexander Afanasyev86287992012-12-10 16:11:50 -0800208}
209
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800210CsTracer::~CsTracer(){};
Alexander Afanasyev86287992012-12-10 16:11:50 -0800211
212void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800213CsTracer::Connect()
Alexander Afanasyev86287992012-12-10 16:11:50 -0800214{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800215 Ptr<ContentStore> cs = m_nodePtr->GetObject<ContentStore>();
216 cs->TraceConnectWithoutContext("CacheHits", MakeCallback(&CsTracer::CacheHits, this));
217 cs->TraceConnectWithoutContext("CacheMisses", MakeCallback(&CsTracer::CacheMisses, this));
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800218
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800219 Reset();
Alexander Afanasyev86287992012-12-10 16:11:50 -0800220}
221
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800222void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800223CsTracer::SetAveragingPeriod(const Time& period)
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800224{
225 m_period = period;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800226 m_printEvent.Cancel();
227 m_printEvent = Simulator::Schedule(m_period, &CsTracer::PeriodicPrinter, this);
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800228}
229
230void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800231CsTracer::PeriodicPrinter()
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800232{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800233 Print(*m_os);
234 Reset();
235
236 m_printEvent = Simulator::Schedule(m_period, &CsTracer::PeriodicPrinter, this);
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800237}
238
239void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800240CsTracer::PrintHeader(std::ostream& os) const
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800241{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800242 os << "Time"
243 << "\t"
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800244
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800245 << "Node"
246 << "\t"
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800247
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800248 << "Type"
249 << "\t"
250 << "Packets"
251 << "\t";
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800252}
253
254void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800255CsTracer::Reset()
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800256{
257 m_stats.Reset();
258}
259
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800260#define PRINTER(printName, fieldName) \
261 os << time.ToDouble(Time::S) << "\t" << m_node << "\t" << printName << "\t" << m_stats.fieldName \
262 << "\n";
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800263
264void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800265CsTracer::Print(std::ostream& os) const
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800266{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800267 Time time = Simulator::Now();
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800268
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800269 PRINTER("CacheHits", m_cacheHits);
270 PRINTER("CacheMisses", m_cacheMisses);
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800271}
272
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800273void
274CsTracer::CacheHits(Ptr<const Interest>, Ptr<const Data>)
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800275{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800276 m_stats.m_cacheHits++;
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800277}
278
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800279void
280CsTracer::CacheMisses(Ptr<const Interest>)
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800281{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800282 m_stats.m_cacheMisses++;
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800283}
284
Alexander Afanasyev86287992012-12-10 16:11:50 -0800285} // namespace ndn
286} // namespace ns3