blob: ded69fe6a745b65057ebeabd09fbbc5aa4ee6948 [file] [log] [blame]
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
Alexander Afanasyev86287992012-12-10 16:11:50 -08004 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08005 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
Alexander Afanasyev86287992012-12-10 16:11:50 -08007 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08008 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
Alexander Afanasyev86287992012-12-10 16:11:50 -080011 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080012 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Alexander Afanasyev86287992012-12-10 16:11:50 -080015 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080016 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
Alexander Afanasyev86287992012-12-10 16:11:50 -080019
Alexander Afanasyev0c395372014-12-20 15:54:02 -080020#include "ndn-cs-tracer.hpp"
Alexander Afanasyev86287992012-12-10 16:11:50 -080021#include "ns3/node.h"
22#include "ns3/packet.h"
23#include "ns3/config.h"
24#include "ns3/names.h"
25#include "ns3/callback.h"
26
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080027#include "apps/ndn-app.hpp"
28#include "model/cs/ndn-content-store.hpp"
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -080029#include "ns3/simulator.h"
30#include "ns3/node-list.h"
31#include "ns3/log.h"
32
33#include <boost/lexical_cast.hpp>
34
35#include <fstream>
36
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080037NS_LOG_COMPONENT_DEFINE("ndn.CsTracer");
Alexander Afanasyev86287992012-12-10 16:11:50 -080038
Alexander Afanasyev86287992012-12-10 16:11:50 -080039namespace ns3 {
40namespace ndn {
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -080041
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080042static std::list<std::tuple<shared_ptr<std::ostream>, std::list<Ptr<CsTracer>>>> g_tracers;
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -080043
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070044void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080045CsTracer::Destroy()
Alexander Afanasyevdb5f3b62013-08-09 17:42:12 -070046{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080047 g_tracers.clear();
Alexander Afanasyevdb5f3b62013-08-09 17:42:12 -070048}
49
50void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080051CsTracer::InstallAll(const std::string& file, Time averagingPeriod /* = Seconds (0.5)*/)
Alexander Afanasyev5352af32013-07-15 09:51:28 -070052{
53 using namespace boost;
54 using namespace std;
55
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080056 std::list<Ptr<CsTracer>> tracers;
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080057 shared_ptr<std::ostream> outputStream;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080058 if (file != "-") {
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080059 shared_ptr<std::ofstream> os(new std::ofstream());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080060 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
Alexander Afanasyev5352af32013-07-15 09:51:28 -070061
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080062 if (!os->is_open()) {
63 NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
64 return;
Alexander Afanasyev5352af32013-07-15 09:51:28 -070065 }
66
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080067 outputStream = os;
68 }
69 else {
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080070 outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080071 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -070072
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080073 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
74 Ptr<CsTracer> trace = Install(*node, outputStream, averagingPeriod);
75 tracers.push_back(trace);
76 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -070077
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080078 if (tracers.size() > 0) {
79 // *m_l3RateTrace << "# "; // not necessary for R's read.table
80 tracers.front()->PrintHeader(*outputStream);
81 *outputStream << "\n";
82 }
83
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080084 g_tracers.push_back(std::make_tuple(outputStream, tracers));
Alexander Afanasyev5352af32013-07-15 09:51:28 -070085}
86
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070087void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080088CsTracer::Install(const NodeContainer& nodes, const std::string& file,
89 Time averagingPeriod /* = Seconds (0.5)*/)
Alexander Afanasyev5352af32013-07-15 09:51:28 -070090{
91 using namespace boost;
92 using namespace std;
93
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080094 std::list<Ptr<CsTracer>> tracers;
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080095 shared_ptr<std::ostream> outputStream;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080096 if (file != "-") {
Spyridon Mastorakisda904f22014-11-05 16:23:33 -080097 shared_ptr<std::ofstream> os(new std::ofstream());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080098 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
Alexander Afanasyev5352af32013-07-15 09:51:28 -070099
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800100 if (!os->is_open()) {
101 NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
102 return;
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700103 }
104
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800105 outputStream = os;
106 }
107 else {
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800108 outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800109 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700110
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800111 for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
112 Ptr<CsTracer> trace = Install(*node, outputStream, averagingPeriod);
113 tracers.push_back(trace);
114 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700115
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800116 if (tracers.size() > 0) {
117 // *m_l3RateTrace << "# "; // not necessary for R's read.table
118 tracers.front()->PrintHeader(*outputStream);
119 *outputStream << "\n";
120 }
121
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800122 g_tracers.push_back(std::make_tuple(outputStream, tracers));
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700123}
124
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800125void
126CsTracer::Install(Ptr<Node> node, const std::string& file,
127 Time averagingPeriod /* = Seconds (0.5)*/)
128{
129 using namespace boost;
130 using namespace std;
131
132 std::list<Ptr<CsTracer>> tracers;
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800133 shared_ptr<std::ostream> outputStream;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800134 if (file != "-") {
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800135 shared_ptr<std::ofstream> os(new std::ofstream());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800136 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
137
138 if (!os->is_open()) {
139 NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
140 return;
141 }
142
143 outputStream = os;
144 }
145 else {
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800146 outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800147 }
148
149 Ptr<CsTracer> trace = Install(node, outputStream, averagingPeriod);
150 tracers.push_back(trace);
151
152 if (tracers.size() > 0) {
153 // *m_l3RateTrace << "# "; // not necessary for R's read.table
154 tracers.front()->PrintHeader(*outputStream);
155 *outputStream << "\n";
156 }
157
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800158 g_tracers.push_back(std::make_tuple(outputStream, tracers));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800159}
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700160
161Ptr<CsTracer>
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800162CsTracer::Install(Ptr<Node> node, shared_ptr<std::ostream> outputStream,
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800163 Time averagingPeriod /* = Seconds (0.5)*/)
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700164{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800165 NS_LOG_DEBUG("Node: " << node->GetId());
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700166
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800167 Ptr<CsTracer> trace = Create<CsTracer>(outputStream, node);
168 trace->SetAveragingPeriod(averagingPeriod);
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700169
170 return trace;
171}
172
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800173//////////////////////////////////////////////////////////////////////////////
174//////////////////////////////////////////////////////////////////////////////
175//////////////////////////////////////////////////////////////////////////////
176
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800177CsTracer::CsTracer(shared_ptr<std::ostream> os, Ptr<Node> node)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800178 : m_nodePtr(node)
179 , m_os(os)
Alexander Afanasyev86287992012-12-10 16:11:50 -0800180{
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800181 m_node = boost::lexical_cast<std::string>(m_nodePtr->GetId());
Alexander Afanasyev86287992012-12-10 16:11:50 -0800182
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800183 Connect();
Alexander Afanasyev86287992012-12-10 16:11:50 -0800184
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800185 std::string name = Names::FindName(node);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800186 if (!name.empty()) {
187 m_node = name;
188 }
Alexander Afanasyev86287992012-12-10 16:11:50 -0800189}
190
Spyridon Mastorakisda904f22014-11-05 16:23:33 -0800191CsTracer::CsTracer(shared_ptr<std::ostream> os, const std::string& node)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800192 : m_node(node)
193 , m_os(os)
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}
197
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800198CsTracer::~CsTracer(){};
Alexander Afanasyev86287992012-12-10 16:11:50 -0800199
200void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800201CsTracer::Connect()
Alexander Afanasyev86287992012-12-10 16:11:50 -0800202{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800203 Ptr<ContentStore> cs = m_nodePtr->GetObject<ContentStore>();
204 cs->TraceConnectWithoutContext("CacheHits", MakeCallback(&CsTracer::CacheHits, this));
205 cs->TraceConnectWithoutContext("CacheMisses", MakeCallback(&CsTracer::CacheMisses, this));
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800206
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800207 Reset();
Alexander Afanasyev86287992012-12-10 16:11:50 -0800208}
209
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800210void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800211CsTracer::SetAveragingPeriod(const Time& period)
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800212{
213 m_period = period;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800214 m_printEvent.Cancel();
215 m_printEvent = Simulator::Schedule(m_period, &CsTracer::PeriodicPrinter, this);
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800216}
217
218void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800219CsTracer::PeriodicPrinter()
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800220{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800221 Print(*m_os);
222 Reset();
223
224 m_printEvent = Simulator::Schedule(m_period, &CsTracer::PeriodicPrinter, this);
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800225}
226
227void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800228CsTracer::PrintHeader(std::ostream& os) const
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800229{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800230 os << "Time"
231 << "\t"
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800232
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800233 << "Node"
234 << "\t"
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800235
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800236 << "Type"
237 << "\t"
238 << "Packets"
239 << "\t";
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800240}
241
242void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800243CsTracer::Reset()
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800244{
245 m_stats.Reset();
246}
247
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800248#define PRINTER(printName, fieldName) \
249 os << time.ToDouble(Time::S) << "\t" << m_node << "\t" << printName << "\t" << m_stats.fieldName \
250 << "\n";
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800251
252void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800253CsTracer::Print(std::ostream& os) const
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800254{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800255 Time time = Simulator::Now();
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800256
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800257 PRINTER("CacheHits", m_cacheHits);
258 PRINTER("CacheMisses", m_cacheMisses);
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800259}
260
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800261void
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700262CsTracer::CacheHits(shared_ptr<const Interest>, shared_ptr<const Data>)
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800263{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800264 m_stats.m_cacheHits++;
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800265}
266
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800267void
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700268CsTracer::CacheMisses(shared_ptr<const Interest>)
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800269{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800270 m_stats.m_cacheMisses++;
Alexander Afanasyevb1d6b032013-01-18 14:11:11 -0800271}
272
Alexander Afanasyev86287992012-12-10 16:11:50 -0800273} // namespace ndn
274} // namespace ns3