blob: ba5a828783b6f0e666be07ce253ff567ab7d2916 [file] [log] [blame]
Shockb0f83152012-12-25 14:16:47 +08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2012 Tsinghua University, P.R.China
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: Xiaoke Jiang <shock.jiang@gmail.com>
19 */
20
21#include "ndn-consumer-zipf-mandelbrot.h"
22
23#include "ns3/ndn-app-face.h"
24#include "ns3/ndn-interest.h"
Alexander Afanasyev6eba36f2013-08-07 17:42:54 -070025#include "ns3/ndn-data.h"
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -080026
27#include "ns3/ndnSIM/utils/ndn-fw-hop-count-tag.h"
28
Shockb0f83152012-12-25 14:16:47 +080029#include <math.h>
Shockb0f83152012-12-25 14:16:47 +080030
31
32NS_LOG_COMPONENT_DEFINE ("ndn.ConsumerZipfMandelbrot");
33
34namespace ns3 {
35namespace ndn {
36
37NS_OBJECT_ENSURE_REGISTERED (ConsumerZipfMandelbrot);
38
39TypeId
40ConsumerZipfMandelbrot::GetTypeId (void)
41{
42 static TypeId tid = TypeId ("ns3::ndn::ConsumerZipfMandelbrot")
43 .SetGroupName ("Ndn")
44 .SetParent<ConsumerCbr> ()
45 .AddConstructor<ConsumerZipfMandelbrot> ()
Alexander Afanasyev13800102012-12-25 00:30:31 -080046
47 .AddAttribute ("NumberOfContents", "Number of the Contents in total",
48 StringValue ("100"),
49 MakeUintegerAccessor (&ConsumerZipfMandelbrot::SetNumberOfContents, &ConsumerZipfMandelbrot::GetNumberOfContents),
50 MakeUintegerChecker<uint32_t> ())
51
Alexander Afanasyev462a56b2013-03-28 15:00:00 -070052 .AddAttribute ("q", "parameter of improve rank",
53 StringValue ("0.7"),
54 MakeDoubleAccessor (&ConsumerZipfMandelbrot::SetQ, &ConsumerZipfMandelbrot::GetQ),
55 MakeDoubleChecker<double> ())
56
57 .AddAttribute ("s", "parameter of power",
58 StringValue ("0.7"),
59 MakeDoubleAccessor (&ConsumerZipfMandelbrot::SetS, &ConsumerZipfMandelbrot::GetS),
60 MakeDoubleChecker<double> ())
Shockb0f83152012-12-25 14:16:47 +080061 ;
62
63 return tid;
64}
65
66
67ConsumerZipfMandelbrot::ConsumerZipfMandelbrot()
Alexander Afanasyev462a56b2013-03-28 15:00:00 -070068 : m_N (100) // needed here to make sure when SetQ/SetS are called, there is a valid value of N
69 , m_q (0.7)
Alexander Afanasyev13800102012-12-25 00:30:31 -080070 , m_s (0.7)
71 , m_SeqRng (0.0, 1.0)
Shockb0f83152012-12-25 14:16:47 +080072{
Alexander Afanasyev13800102012-12-25 00:30:31 -080073 // SetNumberOfContents is called by NS-3 object system during the initialization
Shockb0f83152012-12-25 14:16:47 +080074}
75
Alexander Afanasyev13800102012-12-25 00:30:31 -080076ConsumerZipfMandelbrot::~ConsumerZipfMandelbrot()
77{
Shockb0f83152012-12-25 14:16:47 +080078}
79
80void
Alexander Afanasyev13800102012-12-25 00:30:31 -080081ConsumerZipfMandelbrot::SetNumberOfContents (uint32_t numOfContents)
82{
83 m_N = numOfContents;
84
Alexander Afanasyev462a56b2013-03-28 15:00:00 -070085 NS_LOG_DEBUG (m_q << " and " << m_s << " and " << m_N);
Saran Tarnoi5cd9a152013-02-15 15:59:15 -080086
Alexander Afanasyev13800102012-12-25 00:30:31 -080087 m_Pcum = std::vector<double> (m_N + 1);
88
89 m_Pcum[0] = 0.0;
90 for (uint32_t i=1; i<=m_N; i++)
91 {
Saran Tarnoi5cd9a152013-02-15 15:59:15 -080092 m_Pcum[i] = m_Pcum[i-1] + 1.0 / std::pow(i+m_q, m_s);
Alexander Afanasyev13800102012-12-25 00:30:31 -080093 }
Saran Tarnoi5cd9a152013-02-15 15:59:15 -080094
Alexander Afanasyev13800102012-12-25 00:30:31 -080095 for (uint32_t i=1; i<=m_N; i++)
96 {
97 m_Pcum[i] = m_Pcum[i] / m_Pcum[m_N];
Saran Tarnoi5cd9a152013-02-15 15:59:15 -080098 NS_LOG_LOGIC ("Cumulative probability [" << i << "]=" << m_Pcum[i]);
Alexander Afanasyev13800102012-12-25 00:30:31 -080099 }
100}
101
102uint32_t
103ConsumerZipfMandelbrot::GetNumberOfContents () const
104{
105 return m_N;
106}
107
Saran Tarnoi5cd9a152013-02-15 15:59:15 -0800108void
109ConsumerZipfMandelbrot::SetQ (double q)
110{
111 m_q = q;
112 SetNumberOfContents (m_N);
113}
114
115double
116ConsumerZipfMandelbrot::GetQ () const
117{
118 return m_q;
119}
120
121void
122ConsumerZipfMandelbrot::SetS (double s)
123{
124 m_s = s;
125 SetNumberOfContents (m_N);
126}
127
128double
129ConsumerZipfMandelbrot::GetS () const
130{
131 return m_s;
132}
Alexander Afanasyev13800102012-12-25 00:30:31 -0800133
134void
Shockb0f83152012-12-25 14:16:47 +0800135ConsumerZipfMandelbrot::SendPacket() {
Alexander Afanasyev13800102012-12-25 00:30:31 -0800136 if (!m_active) return;
Shockb0f83152012-12-25 14:16:47 +0800137
Alexander Afanasyev13800102012-12-25 00:30:31 -0800138 NS_LOG_FUNCTION_NOARGS ();
Shockb0f83152012-12-25 14:16:47 +0800139
Alexander Afanasyev13800102012-12-25 00:30:31 -0800140 uint32_t seq=std::numeric_limits<uint32_t>::max (); //invalid
Shockb0f83152012-12-25 14:16:47 +0800141
Alexander Afanasyev13800102012-12-25 00:30:31 -0800142 // std::cout << Simulator::Now ().ToDouble (Time::S) << "s max -> " << m_seqMax << "\n";
Shockb0f83152012-12-25 14:16:47 +0800143
Alexander Afanasyev13800102012-12-25 00:30:31 -0800144 while (m_retxSeqs.size ())
145 {
146 seq = *m_retxSeqs.begin ();
147 m_retxSeqs.erase (m_retxSeqs.begin ());
Shockb0f83152012-12-25 14:16:47 +0800148
Alexander Afanasyev13800102012-12-25 00:30:31 -0800149 // NS_ASSERT (m_seqLifetimes.find (seq) != m_seqLifetimes.end ());
150 // if (m_seqLifetimes.find (seq)->time <= Simulator::Now ())
151 // {
Shockb0f83152012-12-25 14:16:47 +0800152
Alexander Afanasyev13800102012-12-25 00:30:31 -0800153 // NS_LOG_DEBUG ("Expire " << seq);
154 // m_seqLifetimes.erase (seq); // lifetime expired. Trying to find another unexpired sequence number
155 // continue;
156 // }
157 NS_LOG_DEBUG("=interest seq "<<seq<<" from m_retxSeqs");
158 break;
159 }
Shockb0f83152012-12-25 14:16:47 +0800160
Alexander Afanasyev13800102012-12-25 00:30:31 -0800161 if (seq == std::numeric_limits<uint32_t>::max ()) //no retransmission
162 {
163 if (m_seqMax != std::numeric_limits<uint32_t>::max ())
164 {
165 if (m_seq >= m_seqMax)
166 {
167 return; // we are totally done
168 }
169 }
Shockb0f83152012-12-25 14:16:47 +0800170
Alexander Afanasyev13800102012-12-25 00:30:31 -0800171 seq = ConsumerZipfMandelbrot::GetNextSeq();
172 m_seq ++;
173 }
Shockb0f83152012-12-25 14:16:47 +0800174
Alexander Afanasyev13800102012-12-25 00:30:31 -0800175 // std::cout << Simulator::Now ().ToDouble (Time::S) << "s -> " << seq << "\n";
Shockb0f83152012-12-25 14:16:47 +0800176
Alexander Afanasyev13800102012-12-25 00:30:31 -0800177 //
Alexander Afanasyevcfdc14f2013-03-15 14:38:44 -0700178 Ptr<Name> nameWithSequence = Create<Name> (m_interestName);
Alexander Afanasyev92136012013-07-16 20:36:30 -0700179 nameWithSequence->appendSeqNum (seq);
Alexander Afanasyev13800102012-12-25 00:30:31 -0800180 //
Shockb0f83152012-12-25 14:16:47 +0800181
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700182 Ptr<Interest> interest = Create<Interest> ();
183 interest->SetNonce (m_rand.GetValue ());
184 interest->SetName (nameWithSequence);
Shockb0f83152012-12-25 14:16:47 +0800185
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700186 // NS_LOG_INFO ("Requesting Interest: \n" << *interest);
Alexander Afanasyev13800102012-12-25 00:30:31 -0800187 NS_LOG_INFO ("> Interest for " << seq<<", Total: "<<m_seq<<", face: "<<m_face->GetId());
Alexander Afanasyev13800102012-12-25 00:30:31 -0800188 NS_LOG_DEBUG ("Trying to add " << seq << " with " << Simulator::Now () << ". already " << m_seqTimeouts.size () << " items");
Shockb0f83152012-12-25 14:16:47 +0800189
Alexander Afanasyev13800102012-12-25 00:30:31 -0800190 m_seqTimeouts.insert (SeqTimeout (seq, Simulator::Now ()));
Alexander Afanasyev400aae12013-01-19 13:27:52 -0800191 m_seqFullDelay.insert (SeqTimeout (seq, Simulator::Now ()));
192
193 m_seqLastDelay.erase (seq);
194 m_seqLastDelay.insert (SeqTimeout (seq, Simulator::Now ()));
195
196 m_seqRetxCounts[seq] ++;
Saran Tarnoi5cd9a152013-02-15 15:59:15 -0800197
Alexander Afanasyev13800102012-12-25 00:30:31 -0800198 m_rtt->SentSeq (SequenceNumber32 (seq), 1);
Shockb0f83152012-12-25 14:16:47 +0800199
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800200 FwHopCountTag hopCountTag;
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700201 interest->GetPayload ()->AddPacketTag (hopCountTag);
Saran Tarnoi5cd9a152013-02-15 15:59:15 -0800202
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700203 m_transmittedInterests (interest, this, m_face);
204 m_face->ReceiveInterest (interest);
Shockb0f83152012-12-25 14:16:47 +0800205
Alexander Afanasyev13800102012-12-25 00:30:31 -0800206 ConsumerZipfMandelbrot::ScheduleNextPacket ();
Shockb0f83152012-12-25 14:16:47 +0800207}
208
209
210uint32_t
Alexander Afanasyev13800102012-12-25 00:30:31 -0800211ConsumerZipfMandelbrot::GetNextSeq()
212{
213 uint32_t content_index = 1; //[1, m_N]
214 double p_sum = 0;
Shockb0f83152012-12-25 14:16:47 +0800215
Alexander Afanasyev13800102012-12-25 00:30:31 -0800216 double p_random = m_SeqRng.GetValue();
217 while (p_random == 0)
218 {
219 p_random = m_SeqRng.GetValue();
220 }
221 //if (p_random == 0)
222 NS_LOG_LOGIC("p_random="<<p_random);
223 for (uint32_t i=1; i<=m_N; i++)
224 {
225 p_sum = m_Pcum[i]; //m_Pcum[i] = m_Pcum[i-1] + p[i], p[0] = 0; e.g.: p_cum[1] = p[1], p_cum[2] = p[1] + p[2]
226 if (p_random <= p_sum)
227 {
228 content_index = i;
229 break;
230 } //if
231 } //for
232 //content_index = 1;
233 NS_LOG_DEBUG("RandomNumber="<<content_index);
234 return content_index;
Shockb0f83152012-12-25 14:16:47 +0800235}
236
237void
238ConsumerZipfMandelbrot::ScheduleNextPacket() {
239
Alexander Afanasyev13800102012-12-25 00:30:31 -0800240 if (m_firstTime)
241 {
242 m_sendEvent = Simulator::Schedule (Seconds (0.0),
243 &ConsumerZipfMandelbrot::SendPacket, this);
244 m_firstTime = false;
245 }
246 else if (!m_sendEvent.IsRunning ())
247 m_sendEvent = Simulator::Schedule (
248 (m_random == 0) ?
249 Seconds(1.0 / m_frequency)
250 :
251 Seconds(m_random->GetValue ()),
252 &ConsumerZipfMandelbrot::SendPacket, this);
Shockb0f83152012-12-25 14:16:47 +0800253}
254
255} /* namespace ndn */
256} /* namespace ns3 */