22 #include "ns3/packet.h"
23 #include "ns3/config.h"
24 #include "ns3/callback.h"
25 #include "ns3/simulator.h"
27 #include "ns3/node-list.h"
28 #include "ns3/ndnSIM/model/ndn-l3-protocol.hpp"
33 #include <boost/lexical_cast.hpp>
35 NS_LOG_COMPONENT_DEFINE(
"ndn.L3RateTracer");
40 static std::list<std::tuple<shared_ptr<std::ostream>, std::list<Ptr<L3RateTracer>>>>
52 std::list<Ptr<L3RateTracer>> tracers;
53 shared_ptr<std::ostream> outputStream;
55 shared_ptr<std::ofstream> os(
new std::ofstream());
56 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
59 NS_LOG_ERROR(
"File " << file <<
" cannot be opened for writing. Tracing disabled");
66 outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
69 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
70 Ptr<L3RateTracer> trace =
Install(*node, outputStream, averagingPeriod);
71 tracers.push_back(trace);
74 if (tracers.size() > 0) {
76 tracers.front()->PrintHeader(*outputStream);
77 *outputStream <<
"\n";
80 g_tracers.push_back(std::make_tuple(outputStream, tracers));
85 Time averagingPeriod )
87 using namespace boost;
90 std::list<Ptr<L3RateTracer>> tracers;
91 shared_ptr<std::ostream> outputStream;
93 shared_ptr<std::ofstream> os(
new std::ofstream());
94 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
97 NS_LOG_ERROR(
"File " << file <<
" cannot be opened for writing. Tracing disabled");
104 outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
107 for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
108 Ptr<L3RateTracer> trace =
Install(*node, outputStream, averagingPeriod);
109 tracers.push_back(trace);
112 if (tracers.size() > 0) {
114 tracers.front()->PrintHeader(*outputStream);
115 *outputStream <<
"\n";
118 g_tracers.push_back(std::make_tuple(outputStream, tracers));
123 Time averagingPeriod )
125 using namespace boost;
128 std::list<Ptr<L3RateTracer>> tracers;
129 shared_ptr<std::ostream> outputStream;
131 shared_ptr<std::ofstream> os(
new std::ofstream());
132 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
134 if (!os->is_open()) {
135 NS_LOG_ERROR(
"File " << file <<
" cannot be opened for writing. Tracing disabled");
142 outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
145 Ptr<L3RateTracer> trace =
Install(node, outputStream, averagingPeriod);
146 tracers.push_back(trace);
148 if (tracers.size() > 0) {
150 tracers.front()->PrintHeader(*outputStream);
151 *outputStream <<
"\n";
154 g_tracers.push_back(std::make_tuple(outputStream, tracers));
159 Time averagingPeriod )
161 NS_LOG_DEBUG(
"Node: " << node->GetId());
163 Ptr<L3RateTracer> trace = Create<L3RateTracer>(outputStream, node);
164 trace->SetAveragingPeriod(averagingPeriod);
173 SetAveragingPeriod(Seconds(1.0));
180 SetAveragingPeriod(Seconds(1.0));
185 m_printEvent.Cancel();
189 L3RateTracer::SetAveragingPeriod(
const Time& period)
192 m_printEvent.Cancel();
193 m_printEvent = Simulator::Schedule(m_period, &L3RateTracer::PeriodicPrinter,
this);
197 L3RateTracer::PeriodicPrinter()
202 m_printEvent = Simulator::Schedule(m_period, &L3RateTracer::PeriodicPrinter,
this);
230 L3RateTracer::Reset()
232 for (
auto& stats : m_stats) {
233 std::get<0>(stats.second).Reset();
234 std::get<1>(stats.second).Reset();
240 #define STATS(INDEX) std::get<INDEX>(stats.second)
241 #define RATE(INDEX, fieldName) STATS(INDEX).fieldName / m_period.ToDouble(Time::S)
243 #define PRINTER(printName, fieldName) \
244 STATS(2).fieldName = \
245 alpha * RATE(0, fieldName) + (1 - alpha) * STATS(2).fieldName; \
246 STATS(3).fieldName = alpha * RATE(1, fieldName) / 1024.0 \
247 + (1 - alpha) * STATS(3).fieldName; \
249 os << time.ToDouble(Time::S) << "\t" << m_node << "\t"; \
250 if (stats.first != nfd::face::INVALID_FACEID) { \
251 os << stats.first << "\t"; \
252 NS_ASSERT(m_faceInfos.find(stats.first) != m_faceInfos.end()); \
253 os << m_faceInfos.find(stats.first)->second << "\t"; \
258 os << printName << "\t" << STATS(2).fieldName << "\t" << STATS(3).fieldName << "\t" \
259 << STATS(0).fieldName << "\t" << STATS(1).fieldName / 1024.0 << "\n";
264 Time
time = Simulator::Now();
266 for (
auto& stats : m_stats) {
270 PRINTER(
"InInterests", m_inInterests);
271 PRINTER(
"OutInterests", m_outInterests);
277 PRINTER(
"OutNacks", m_outNack);
279 PRINTER(
"InSatisfiedInterests", m_satisfiedInterests);
280 PRINTER(
"InTimedOutInterests", m_timedOutInterests);
282 PRINTER(
"OutSatisfiedInterests", m_outSatisfiedInterests);
283 PRINTER(
"OutTimedOutInterests", m_outTimedOutInterests);
288 if (i != m_stats.end()) {
290 PRINTER(
"SatisfiedInterests", m_satisfiedInterests);
291 PRINTER(
"TimedOutInterests", m_timedOutInterests);
300 std::get<0>(m_stats[face.getId()]).m_outInterests++;
301 if (interest.hasWire()) {
302 std::get<1>(m_stats[face.getId()]).m_outInterests +=
303 interest.wireEncode().size();
311 std::get<0>(m_stats[face.getId()]).m_inInterests++;
312 if (interest.hasWire()) {
313 std::get<1>(m_stats[face.getId()]).m_inInterests +=
314 interest.wireEncode().size();
322 std::get<0>(m_stats[face.getId()]).m_outData++;
323 if (data.hasWire()) {
324 std::get<1>(m_stats[face.getId()]).m_outData +=
325 data.wireEncode().size();
333 std::get<0>(m_stats[face.getId()]).m_inData++;
334 if (data.hasWire()) {
335 std::get<1>(m_stats[face.getId()]).m_inData +=
336 data.wireEncode().size();
344 std::get<0>(m_stats[face.getId()]).m_outNack++;
346 std::get<1>(m_stats[face.getId()]).m_outNack +=
355 std::get<0>(m_stats[face.getId()]).m_inNack++;
357 std::get<1>(m_stats[face.getId()]).m_inNack +=
369 AddInfo(in.getFace());
370 std::get<0>(m_stats[(in.getFace()).getId()]).m_satisfiedInterests ++;
374 AddInfo(out.getFace());
375 std::get<0>(m_stats[(out.getFace()).getId()]).m_outSatisfiedInterests ++;
386 AddInfo(in.getFace());
387 std::get<0>(m_stats[(in.getFace()).getId()]).m_timedOutInterests++;
391 AddInfo(out.getFace());
392 std::get<0>(m_stats[(out.getFace()).getId()]).m_outTimedOutInterests++;
397 L3RateTracer::AddInfo(
const Face& face)
399 if (m_faceInfos.find(face.getId()) == m_faceInfos.end()) {
400 m_faceInfos.insert(make_pair(face.getId(), boost::lexical_cast<std::string>(face.getLocalUri())));