NS-3 based Named Data Networking (NDN) simulator
ndnSIM: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
ndn-cs-tracer.cc
1 /* -*- 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: Xiaoyan Hu <x......u@gmail.com>
19  * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
20  */
21 
22 #include "ndn-cs-tracer.h"
23 #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 
29 #include "ns3/ndn-app.h"
30 #include "ns3/ndn-interest.h"
31 #include "ns3/ndn-data.h"
32 #include "ns3/ndn-content-store.h"
33 #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 
41 NS_LOG_COMPONENT_DEFINE ("ndn.CsTracer");
42 
43 using namespace std;
44 
45 namespace ns3 {
46 namespace ndn {
47 
48 static std::list< boost::tuple< boost::shared_ptr<std::ostream>, std::list<Ptr<CsTracer> > > > g_tracers;
49 
50 template<class T>
51 static inline void
52 NullDeleter (T *ptr)
53 {
54 }
55 
56 void
57 CsTracer::Destroy ()
58 {
59  g_tracers.clear ();
60 }
61 
62 void
63 CsTracer::InstallAll (const std::string &file, Time averagingPeriod/* = Seconds (0.5)*/)
64 {
65  using namespace boost;
66  using namespace std;
67 
68  std::list<Ptr<CsTracer> > tracers;
69  boost::shared_ptr<std::ostream> outputStream;
70  if (file != "-")
71  {
72  boost::shared_ptr<std::ofstream> os (new std::ofstream ());
73  os->open (file.c_str (), std::ios_base::out | std::ios_base::trunc);
74 
75  if (!os->is_open ())
76  {
77  NS_LOG_ERROR ("File " << file << " cannot be opened for writing. Tracing disabled");
78  return;
79  }
80 
81  outputStream = os;
82  }
83  else
84  {
85  outputStream = boost::shared_ptr<std::ostream> (&std::cout, NullDeleter<std::ostream>);
86  }
87 
88  for (NodeList::Iterator node = NodeList::Begin ();
89  node != NodeList::End ();
90  node++)
91  {
92  Ptr<CsTracer> trace = Install (*node, outputStream, averagingPeriod);
93  tracers.push_back (trace);
94  }
95 
96  if (tracers.size () > 0)
97  {
98  // *m_l3RateTrace << "# "; // not necessary for R's read.table
99  tracers.front ()->PrintHeader (*outputStream);
100  *outputStream << "\n";
101  }
102 
103  g_tracers.push_back (boost::make_tuple (outputStream, tracers));
104 }
105 
106 void
107 CsTracer::Install (const NodeContainer &nodes, const std::string &file, Time averagingPeriod/* = Seconds (0.5)*/)
108 {
109  using namespace boost;
110  using namespace std;
111 
112  std::list<Ptr<CsTracer> > tracers;
113  boost::shared_ptr<std::ostream> outputStream;
114  if (file != "-")
115  {
116  boost::shared_ptr<std::ofstream> os (new std::ofstream ());
117  os->open (file.c_str (), std::ios_base::out | std::ios_base::trunc);
118 
119  if (!os->is_open ())
120  {
121  NS_LOG_ERROR ("File " << file << " cannot be opened for writing. Tracing disabled");
122  return;
123  }
124 
125  outputStream = os;
126  }
127  else
128  {
129  outputStream = boost::shared_ptr<std::ostream> (&std::cout, NullDeleter<std::ostream>);
130  }
131 
132  for (NodeContainer::Iterator node = nodes.Begin ();
133  node != nodes.End ();
134  node++)
135  {
136  Ptr<CsTracer> trace = Install (*node, outputStream, averagingPeriod);
137  tracers.push_back (trace);
138  }
139 
140  if (tracers.size () > 0)
141  {
142  // *m_l3RateTrace << "# "; // not necessary for R's read.table
143  tracers.front ()->PrintHeader (*outputStream);
144  *outputStream << "\n";
145  }
146 
147  g_tracers.push_back (boost::make_tuple (outputStream, tracers));
148 }
149 
150 void
151 CsTracer::Install (Ptr<Node> node, const std::string &file, Time averagingPeriod/* = Seconds (0.5)*/)
152 {
153  using namespace boost;
154  using namespace std;
155 
156  std::list<Ptr<CsTracer> > tracers;
157  boost::shared_ptr<std::ostream> outputStream;
158  if (file != "-")
159  {
160  boost::shared_ptr<std::ofstream> os (new std::ofstream ());
161  os->open (file.c_str (), std::ios_base::out | std::ios_base::trunc);
162 
163  if (!os->is_open ())
164  {
165  NS_LOG_ERROR ("File " << file << " cannot be opened for writing. Tracing disabled");
166  return;
167  }
168 
169  outputStream = os;
170  }
171  else
172  {
173  outputStream = boost::shared_ptr<std::ostream> (&std::cout, NullDeleter<std::ostream>);
174  }
175 
176  Ptr<CsTracer> trace = Install (node, outputStream, averagingPeriod);
177  tracers.push_back (trace);
178 
179  if (tracers.size () > 0)
180  {
181  // *m_l3RateTrace << "# "; // not necessary for R's read.table
182  tracers.front ()->PrintHeader (*outputStream);
183  *outputStream << "\n";
184  }
185 
186  g_tracers.push_back (boost::make_tuple (outputStream, tracers));
187 }
188 
189 
190 Ptr<CsTracer>
191 CsTracer::Install (Ptr<Node> node,
192  boost::shared_ptr<std::ostream> outputStream,
193  Time averagingPeriod/* = Seconds (0.5)*/)
194 {
195  NS_LOG_DEBUG ("Node: " << node->GetId ());
196 
197  Ptr<CsTracer> trace = Create<CsTracer> (outputStream, node);
198  trace->SetAveragingPeriod (averagingPeriod);
199 
200  return trace;
201 }
202 
206 
207 CsTracer::CsTracer (boost::shared_ptr<std::ostream> os, Ptr<Node> node)
208 : m_nodePtr (node)
209 , m_os (os)
210 {
211  m_node = boost::lexical_cast<string> (m_nodePtr->GetId ());
212 
213  Connect ();
214 
215  string name = Names::FindName (node);
216  if (!name.empty ())
217  {
218  m_node = name;
219  }
220 }
221 
222 CsTracer::CsTracer (boost::shared_ptr<std::ostream> os, const std::string &node)
223 : m_node (node)
224 , m_os (os)
225 {
226  Connect ();
227 }
228 
230 {
231 };
232 
233 
234 void
235 CsTracer::Connect ()
236 {
237  Ptr<ContentStore> cs = m_nodePtr->GetObject<ContentStore> ();
238  cs->TraceConnectWithoutContext ("CacheHits", MakeCallback (&CsTracer::CacheHits, this));
239  cs->TraceConnectWithoutContext ("CacheMisses", MakeCallback (&CsTracer::CacheMisses, this));
240 
241  Reset ();
242 }
243 
244 
245 void
246 CsTracer::SetAveragingPeriod (const Time &period)
247 {
248  m_period = period;
249  m_printEvent.Cancel ();
250  m_printEvent = Simulator::Schedule (m_period, &CsTracer::PeriodicPrinter, this);
251 }
252 
253 void
254 CsTracer::PeriodicPrinter ()
255 {
256  Print (*m_os);
257  Reset ();
258 
259  m_printEvent = Simulator::Schedule (m_period, &CsTracer::PeriodicPrinter, this);
260 }
261 
262 void
263 CsTracer::PrintHeader (std::ostream &os) const
264 {
265  os << "Time" << "\t"
266 
267  << "Node" << "\t"
268 
269  << "Type" << "\t"
270  << "Packets" << "\t";
271 }
272 
273 void
274 CsTracer::Reset ()
275 {
276  m_stats.Reset();
277 }
278 
279 #define PRINTER(printName, fieldName) \
280  os << time.ToDouble (Time::S) << "\t" \
281  << m_node << "\t" \
282  << printName << "\t" \
283  << m_stats.fieldName << "\n";
284 
285 
286 void
287 CsTracer::Print (std::ostream &os) const
288 {
289  Time time = Simulator::Now ();
290 
291  PRINTER ("CacheHits", m_cacheHits);
292  PRINTER ("CacheMisses", m_cacheMisses);
293 }
294 
295 void
296 CsTracer::CacheHits (Ptr<const Interest>, Ptr<const Data>)
297 {
298  m_stats.m_cacheHits ++;
299 }
300 
301 void
302 CsTracer::CacheMisses (Ptr<const Interest>)
303 {
304  m_stats.m_cacheMisses ++;
305 }
306 
307 
308 } // namespace ndn
309 } // namespace ns3
Base class for NDN content store.
void Print(std::ostream &os) const
Print current trace data.
~CsTracer()
Destructor.
void PrintHeader(std::ostream &os) const
Print head of the trace (e.g., for post-processing)
CsTracer(boost::shared_ptr< std::ostream > os, Ptr< Node > node)
Trace constructor that attaches to the node using node pointer.