blob: 88079b9c67266200d1419da3d90e8fcc7f74d6a0 [file] [log] [blame]
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -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 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 */
20
21#include "ndn-l3-rate-tracer.h"
22#include "ns3/node.h"
23#include "ns3/packet.h"
24#include "ns3/config.h"
25#include "ns3/callback.h"
26#include "ns3/simulator.h"
27#include "ns3/log.h"
28#include "ns3/node-list.h"
29
30#include "ns3/ndn-app.h"
31#include "ns3/ndn-face.h"
32#include "ns3/ndn-interest.h"
33#include "ns3/ndn-content-object.h"
Alexander Afanasyev37b84c52013-04-26 13:38:52 -070034#include "ns3/ndn-pit-entry.h"
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -080035
36#include <fstream>
37#include <boost/lexical_cast.hpp>
38
39using namespace boost;
40using namespace std;
41
42NS_LOG_COMPONENT_DEFINE ("ndn.L3RateTracer");
43
44namespace ns3 {
45namespace ndn {
46
47
48boost::tuple< boost::shared_ptr<std::ostream>, std::list<Ptr<L3RateTracer> > >
49L3RateTracer::InstallAll (const std::string &file, Time averagingPeriod/* = Seconds (0.5)*/)
50{
51 std::list<Ptr<L3RateTracer> > tracers;
52 boost::shared_ptr<std::ofstream> outputStream (new std::ofstream ());
53 outputStream->open (file.c_str (), std::ios_base::out | std::ios_base::trunc);
54
55 if (!outputStream->is_open ())
56 return boost::make_tuple (outputStream, tracers);
57
58 for (NodeList::Iterator node = NodeList::Begin ();
59 node != NodeList::End ();
60 node++)
61 {
62 NS_LOG_DEBUG ("Node: " << lexical_cast<string> ((*node)->GetId ()));
63
64 Ptr<L3RateTracer> trace = Create<L3RateTracer> (outputStream, *node);
65 trace->SetAveragingPeriod (averagingPeriod);
66 tracers.push_back (trace);
67 }
68
69 if (tracers.size () > 0)
70 {
71 // *m_l3RateTrace << "# "; // not necessary for R's read.table
72 tracers.front ()->PrintHeader (*outputStream);
73 *outputStream << "\n";
74 }
75
76 return boost::make_tuple (outputStream, tracers);
77}
78
79
80L3RateTracer::L3RateTracer (boost::shared_ptr<std::ostream> os, Ptr<Node> node)
81 : L3Tracer (node)
82 , m_os (os)
83{
84 SetAveragingPeriod (Seconds (1.0));
85}
86
87L3RateTracer::L3RateTracer (boost::shared_ptr<std::ostream> os, const std::string &node)
88 : L3Tracer (node)
89 , m_os (os)
90{
91 SetAveragingPeriod (Seconds (1.0));
92}
93
94L3RateTracer::~L3RateTracer ()
95{
96 m_printEvent.Cancel ();
97}
98
99void
100L3RateTracer::SetAveragingPeriod (const Time &period)
101{
102 m_period = period;
103 m_printEvent.Cancel ();
104 m_printEvent = Simulator::Schedule (m_period, &L3RateTracer::PeriodicPrinter, this);
105}
106
107void
108L3RateTracer::PeriodicPrinter ()
109{
110 Print (*m_os);
111 Reset ();
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700112
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800113 m_printEvent = Simulator::Schedule (m_period, &L3RateTracer::PeriodicPrinter, this);
114}
115
116void
117L3RateTracer::PrintHeader (std::ostream &os) const
118{
119 os << "Time" << "\t"
120
121 << "Node" << "\t"
122 << "FaceId" << "\t"
123 << "FaceDescr" << "\t"
124
125 << "Type" << "\t"
126 << "Packets" << "\t"
127 << "Kilobytes" << "\t"
128 << "PacketRaw" << "\t"
129 << "KilobytesRaw";
130}
131
132void
133L3RateTracer::Reset ()
134{
135 for (std::map<Ptr<const Face>, boost::tuple<Stats, Stats, Stats, Stats> >::iterator stats = m_stats.begin ();
136 stats != m_stats.end ();
137 stats++)
138 {
139 stats->second.get<0> ().Reset ();
140 stats->second.get<1> ().Reset ();
141 }
142}
143
144const double alpha = 0.8;
145
146#define STATS(INDEX) stats->second.get<INDEX> ()
147#define RATE(INDEX, fieldName) STATS(INDEX).fieldName / m_period.ToDouble (Time::S)
148
149#define PRINTER(printName, fieldName) \
150 STATS(2).fieldName = /*new value*/alpha * RATE(0, fieldName) + /*old value*/(1-alpha) * STATS(2).fieldName; \
151 STATS(3).fieldName = /*new value*/alpha * RATE(1, fieldName) / 1024.0 + /*old value*/(1-alpha) * STATS(3).fieldName; \
152 \
153 os << time.ToDouble (Time::S) << "\t" \
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700154 << m_node << "\t"; \
155 if (stats->first) \
156 { \
157 os \
158 << stats->first->GetId () << "\t" \
159 << *stats->first << "\t"; \
160 } \
161 else \
162 { \
163 os << "-1\tall\t"; \
164 } \
165 os \
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800166 << printName << "\t" \
167 << STATS(2).fieldName << "\t" \
168 << STATS(3).fieldName << "\t" \
169 << STATS(0).fieldName << "\t" \
Alexander Afanasyev59314802012-11-26 14:56:04 -0800170 << STATS(1).fieldName / 1024.0 << "\n";
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800171
172void
173L3RateTracer::Print (std::ostream &os) const
174{
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700175 Time time = Simulator::Now ();
176
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800177 for (std::map<Ptr<const Face>, boost::tuple<Stats, Stats, Stats, Stats> >::iterator stats = m_stats.begin ();
178 stats != m_stats.end ();
179 stats++)
180 {
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700181 if (!stats->first)
182 continue;
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800183
184 PRINTER ("InInterests", m_inInterests);
185 PRINTER ("OutInterests", m_outInterests);
Alexander Afanasyevf1a4f1e2013-03-18 08:37:49 -0600186 PRINTER ("DropInterests", m_dropInterests);
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700187
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800188 PRINTER ("InNacks", m_inNacks);
189 PRINTER ("OutNacks", m_outNacks);
Alexander Afanasyevf1a4f1e2013-03-18 08:37:49 -0600190 PRINTER ("DropNacks", m_dropNacks);
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800191
192 PRINTER ("InData", m_inData);
193 PRINTER ("OutData", m_outData);
Alexander Afanasyevf1a4f1e2013-03-18 08:37:49 -0600194 PRINTER ("DropData", m_dropData);
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800195 }
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700196
197 {
198 std::map<Ptr<const Face>, boost::tuple<Stats, Stats, Stats, Stats> >::iterator stats = m_stats.find (Ptr<const Face> (0));
199 PRINTER ("SatisfiedInterests", m_satisfiedInterests);
200 PRINTER ("TimedOutInterests", m_timedOutInterests);
201 }
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800202}
203
204
205void
206L3RateTracer::OutInterests (std::string context,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700207 Ptr<const Interest> header, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800208{
209 m_stats[face].get<0> ().m_outInterests ++;
210 m_stats[face].get<1> ().m_outInterests += header->GetSerializedSize ();
211}
212
213void
214L3RateTracer::InInterests (std::string context,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700215 Ptr<const Interest> header, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800216{
217 m_stats[face].get<0> ().m_inInterests ++;
218 m_stats[face].get<1> ().m_inInterests += header->GetSerializedSize ();
219}
220
221void
222L3RateTracer::DropInterests (std::string context,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700223 Ptr<const Interest> header, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800224{
225 m_stats[face].get<0> ().m_dropInterests ++;
226 m_stats[face].get<1> ().m_dropInterests += header->GetSerializedSize ();
227}
228
229void
230L3RateTracer::OutNacks (std::string context,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700231 Ptr<const Interest> header, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800232{
233 m_stats[face].get<0> ().m_outNacks ++;
234 m_stats[face].get<1> ().m_outNacks += header->GetSerializedSize ();
235}
236
237void
238L3RateTracer::InNacks (std::string context,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700239 Ptr<const Interest> header, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800240{
241 m_stats[face].get<0> ().m_inNacks ++;
242 m_stats[face].get<1> ().m_inNacks += header->GetSerializedSize ();
243}
244
245void
246L3RateTracer::DropNacks (std::string context,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700247 Ptr<const Interest> header, Ptr<const Face> face)
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800248{
249 m_stats[face].get<0> ().m_dropNacks ++;
250 m_stats[face].get<1> ().m_dropNacks += header->GetSerializedSize ();
251}
252
253void
254L3RateTracer::OutData (std::string context,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700255 Ptr<const ContentObject> header, Ptr<const Packet> payload,
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800256 bool fromCache, Ptr<const Face> face)
257{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800258 m_stats[face].get<0> ().m_outData ++;
259 m_stats[face].get<1> ().m_outData += header->GetSerializedSize () + payload->GetSize ();
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800260}
261
262void
263L3RateTracer::InData (std::string context,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700264 Ptr<const ContentObject> header, Ptr<const Packet> payload,
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800265 Ptr<const Face> face)
266{
Alexander Afanasyev59314802012-11-26 14:56:04 -0800267 m_stats[face].get<0> ().m_inData ++;
268 m_stats[face].get<1> ().m_inData += header->GetSerializedSize () + payload->GetSize ();
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800269}
270
271void
272L3RateTracer::DropData (std::string context,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700273 Ptr<const ContentObject> header, Ptr<const Packet> payload,
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800274 Ptr<const Face> face)
275{
276 m_stats[face].get<0> ().m_dropData ++;
277 m_stats[face].get<1> ().m_dropData += header->GetSerializedSize () + payload->GetSize ();
278}
279
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700280void
281L3RateTracer::SatisfiedInterests (Ptr<const pit::Entry>)
282{
283 m_stats[0].get<0> ().m_satisfiedInterests ++;
284 // no "size" stats
285}
286
287void
288L3RateTracer::TimedOutInterests (Ptr<const pit::Entry>)
289{
290 m_stats[0].get<0> ().m_timedOutInterests ++;
291 // no "size" stats
292}
293
294
Alexander Afanasyevc9d5c1a2012-11-21 18:00:26 -0800295} // namespace ndn
296} // namespace ns3