blob: c6358c09cffa8ba50eda963d0e16e14e011b471f [file] [log] [blame]
Shockb0f83152012-12-25 14:16:47 +08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08002/**
3 * Copyright (c) 2011-2015 Tsinghua University, P.R.China.
Shockb0f83152012-12-25 14:16:47 +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.
Shockb0f83152012-12-25 14:16:47 +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.
Shockb0f83152012-12-25 14:16:47 +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.
Shockb0f83152012-12-25 14:16:47 +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 *
19 * @author Xiaoke Jiang <shock.jiang@gmail.com>
20 **/
Shockb0f83152012-12-25 14:16:47 +080021
Alexander Afanasyev0c395372014-12-20 15:54:02 -080022#include "ndn-consumer-zipf-mandelbrot.hpp"
Shockb0f83152012-12-25 14:16:47 +080023
Mickey Sweatt89046c12014-11-16 20:32:27 -080024#include "utils/ndn-fw-hop-count-tag.hpp"
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -080025
Shockb0f83152012-12-25 14:16:47 +080026#include <math.h>
Shockb0f83152012-12-25 14:16:47 +080027
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080028NS_LOG_COMPONENT_DEFINE("ndn.ConsumerZipfMandelbrot");
Shockb0f83152012-12-25 14:16:47 +080029
30namespace ns3 {
31namespace ndn {
32
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080033NS_OBJECT_ENSURE_REGISTERED(ConsumerZipfMandelbrot);
Shockb0f83152012-12-25 14:16:47 +080034
35TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080036ConsumerZipfMandelbrot::GetTypeId(void)
Shockb0f83152012-12-25 14:16:47 +080037{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080038 static TypeId tid =
39 TypeId("ns3::ndn::ConsumerZipfMandelbrot")
40 .SetGroupName("Ndn")
41 .SetParent<ConsumerCbr>()
42 .AddConstructor<ConsumerZipfMandelbrot>()
Alexander Afanasyev13800102012-12-25 00:30:31 -080043
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080044 .AddAttribute("NumberOfContents", "Number of the Contents in total", StringValue("100"),
45 MakeUintegerAccessor(&ConsumerZipfMandelbrot::SetNumberOfContents,
46 &ConsumerZipfMandelbrot::GetNumberOfContents),
47 MakeUintegerChecker<uint32_t>())
Alexander Afanasyev13800102012-12-25 00:30:31 -080048
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080049 .AddAttribute("q", "parameter of improve rank", StringValue("0.7"),
50 MakeDoubleAccessor(&ConsumerZipfMandelbrot::SetQ,
51 &ConsumerZipfMandelbrot::GetQ),
52 MakeDoubleChecker<double>())
53
54 .AddAttribute("s", "parameter of power", StringValue("0.7"),
55 MakeDoubleAccessor(&ConsumerZipfMandelbrot::SetS,
56 &ConsumerZipfMandelbrot::GetS),
57 MakeDoubleChecker<double>());
Shockb0f83152012-12-25 14:16:47 +080058
59 return tid;
60}
61
Shockb0f83152012-12-25 14:16:47 +080062ConsumerZipfMandelbrot::ConsumerZipfMandelbrot()
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080063 : m_N(100) // needed here to make sure when SetQ/SetS are called, there is a valid value of N
64 , m_q(0.7)
65 , m_s(0.7)
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -070066 , m_seqRng(CreateObject<UniformRandomVariable>())
Shockb0f83152012-12-25 14:16:47 +080067{
Alexander Afanasyev13800102012-12-25 00:30:31 -080068 // SetNumberOfContents is called by NS-3 object system during the initialization
Shockb0f83152012-12-25 14:16:47 +080069}
70
Alexander Afanasyev13800102012-12-25 00:30:31 -080071ConsumerZipfMandelbrot::~ConsumerZipfMandelbrot()
72{
Shockb0f83152012-12-25 14:16:47 +080073}
74
75void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080076ConsumerZipfMandelbrot::SetNumberOfContents(uint32_t numOfContents)
Alexander Afanasyev13800102012-12-25 00:30:31 -080077{
78 m_N = numOfContents;
79
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080080 NS_LOG_DEBUG(m_q << " and " << m_s << " and " << m_N);
Saran Tarnoi5cd9a152013-02-15 15:59:15 -080081
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080082 m_Pcum = std::vector<double>(m_N + 1);
Alexander Afanasyev13800102012-12-25 00:30:31 -080083
84 m_Pcum[0] = 0.0;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080085 for (uint32_t i = 1; i <= m_N; i++) {
86 m_Pcum[i] = m_Pcum[i - 1] + 1.0 / std::pow(i + m_q, m_s);
87 }
Saran Tarnoi5cd9a152013-02-15 15:59:15 -080088
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080089 for (uint32_t i = 1; i <= m_N; i++) {
90 m_Pcum[i] = m_Pcum[i] / m_Pcum[m_N];
91 NS_LOG_LOGIC("Cumulative probability [" << i << "]=" << m_Pcum[i]);
Alexander Afanasyev13800102012-12-25 00:30:31 -080092 }
93}
94
95uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080096ConsumerZipfMandelbrot::GetNumberOfContents() const
Alexander Afanasyev13800102012-12-25 00:30:31 -080097{
98 return m_N;
99}
100
Saran Tarnoi5cd9a152013-02-15 15:59:15 -0800101void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800102ConsumerZipfMandelbrot::SetQ(double q)
Saran Tarnoi5cd9a152013-02-15 15:59:15 -0800103{
104 m_q = q;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800105 SetNumberOfContents(m_N);
Saran Tarnoi5cd9a152013-02-15 15:59:15 -0800106}
107
108double
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800109ConsumerZipfMandelbrot::GetQ() const
Saran Tarnoi5cd9a152013-02-15 15:59:15 -0800110{
111 return m_q;
112}
113
114void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800115ConsumerZipfMandelbrot::SetS(double s)
Saran Tarnoi5cd9a152013-02-15 15:59:15 -0800116{
117 m_s = s;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800118 SetNumberOfContents(m_N);
Saran Tarnoi5cd9a152013-02-15 15:59:15 -0800119}
120
121double
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800122ConsumerZipfMandelbrot::GetS() const
Saran Tarnoi5cd9a152013-02-15 15:59:15 -0800123{
124 return m_s;
125}
Alexander Afanasyev13800102012-12-25 00:30:31 -0800126
127void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800128ConsumerZipfMandelbrot::SendPacket()
129{
130 if (!m_active)
131 return;
Shockb0f83152012-12-25 14:16:47 +0800132
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800133 NS_LOG_FUNCTION_NOARGS();
Shockb0f83152012-12-25 14:16:47 +0800134
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800135 uint32_t seq = std::numeric_limits<uint32_t>::max(); // invalid
Shockb0f83152012-12-25 14:16:47 +0800136
Alexander Afanasyev13800102012-12-25 00:30:31 -0800137 // std::cout << Simulator::Now ().ToDouble (Time::S) << "s max -> " << m_seqMax << "\n";
Shockb0f83152012-12-25 14:16:47 +0800138
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800139 while (m_retxSeqs.size()) {
140 seq = *m_retxSeqs.begin();
141 m_retxSeqs.erase(m_retxSeqs.begin());
Shockb0f83152012-12-25 14:16:47 +0800142
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800143 // NS_ASSERT (m_seqLifetimes.find (seq) != m_seqLifetimes.end ());
144 // if (m_seqLifetimes.find (seq)->time <= Simulator::Now ())
145 // {
Shockb0f83152012-12-25 14:16:47 +0800146
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800147 // NS_LOG_DEBUG ("Expire " << seq);
148 // m_seqLifetimes.erase (seq); // lifetime expired. Trying to find another unexpired
149 // sequence number
150 // continue;
151 // }
152 NS_LOG_DEBUG("=interest seq " << seq << " from m_retxSeqs");
153 break;
154 }
155
156 if (seq == std::numeric_limits<uint32_t>::max()) // no retransmission
157 {
158 if (m_seqMax != std::numeric_limits<uint32_t>::max()) {
159 if (m_seq >= m_seqMax) {
160 return; // we are totally done
161 }
Alexander Afanasyev13800102012-12-25 00:30:31 -0800162 }
Shockb0f83152012-12-25 14:16:47 +0800163
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800164 seq = ConsumerZipfMandelbrot::GetNextSeq();
165 m_seq++;
166 }
Shockb0f83152012-12-25 14:16:47 +0800167
Alexander Afanasyev13800102012-12-25 00:30:31 -0800168 // std::cout << Simulator::Now ().ToDouble (Time::S) << "s -> " << seq << "\n";
Shockb0f83152012-12-25 14:16:47 +0800169
Alexander Afanasyev13800102012-12-25 00:30:31 -0800170 //
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700171 shared_ptr<Name> nameWithSequence = make_shared<Name>(m_interestName);
Mickey Sweatt89046c12014-11-16 20:32:27 -0800172 nameWithSequence->appendSequenceNumber(seq);
Alexander Afanasyev13800102012-12-25 00:30:31 -0800173 //
Shockb0f83152012-12-25 14:16:47 +0800174
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700175 shared_ptr<Interest> interest = make_shared<Interest>();
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -0700176 interest->setNonce(m_rand->GetValue(0, std::numeric_limits<uint32_t>::max()));
Mickey Sweatt89046c12014-11-16 20:32:27 -0800177 interest->setName(*nameWithSequence);
Shockb0f83152012-12-25 14:16:47 +0800178
Alexander Afanasyevfaa01f92013-07-10 18:34:31 -0700179 // NS_LOG_INFO ("Requesting Interest: \n" << *interest);
Mickey Sweatt89046c12014-11-16 20:32:27 -0800180 NS_LOG_INFO("> Interest for " << seq << ", Total: " << m_seq << ", face: " << m_face->getId());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800181 NS_LOG_DEBUG("Trying to add " << seq << " with " << Simulator::Now() << ". already "
182 << m_seqTimeouts.size() << " items");
Shockb0f83152012-12-25 14:16:47 +0800183
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800184 m_seqTimeouts.insert(SeqTimeout(seq, Simulator::Now()));
185 m_seqFullDelay.insert(SeqTimeout(seq, Simulator::Now()));
Alexander Afanasyev400aae12013-01-19 13:27:52 -0800186
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800187 m_seqLastDelay.erase(seq);
188 m_seqLastDelay.insert(SeqTimeout(seq, Simulator::Now()));
Alexander Afanasyev400aae12013-01-19 13:27:52 -0800189
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800190 m_seqRetxCounts[seq]++;
Saran Tarnoi5cd9a152013-02-15 15:59:15 -0800191
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800192 m_rtt->SentSeq(SequenceNumber32(seq), 1);
Shockb0f83152012-12-25 14:16:47 +0800193
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800194 m_transmittedInterests(interest, this, m_face);
Alexander Afanasyev50ea1a32016-09-08 15:44:08 -0700195 m_appLink->onReceiveInterest(*interest);
Shockb0f83152012-12-25 14:16:47 +0800196
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800197 ConsumerZipfMandelbrot::ScheduleNextPacket();
Shockb0f83152012-12-25 14:16:47 +0800198}
199
Shockb0f83152012-12-25 14:16:47 +0800200uint32_t
Alexander Afanasyev13800102012-12-25 00:30:31 -0800201ConsumerZipfMandelbrot::GetNextSeq()
202{
203 uint32_t content_index = 1; //[1, m_N]
204 double p_sum = 0;
Shockb0f83152012-12-25 14:16:47 +0800205
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -0700206 double p_random = m_seqRng->GetValue();
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800207 while (p_random == 0) {
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -0700208 p_random = m_seqRng->GetValue();
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800209 }
210 // if (p_random == 0)
211 NS_LOG_LOGIC("p_random=" << p_random);
212 for (uint32_t i = 1; i <= m_N; i++) {
213 p_sum = m_Pcum[i]; // m_Pcum[i] = m_Pcum[i-1] + p[i], p[0] = 0; e.g.: p_cum[1] = p[1],
214 // p_cum[2] = p[1] + p[2]
215 if (p_random <= p_sum) {
216 content_index = i;
217 break;
218 } // if
219 } // for
220 // content_index = 1;
221 NS_LOG_DEBUG("RandomNumber=" << content_index);
Alexander Afanasyev13800102012-12-25 00:30:31 -0800222 return content_index;
Shockb0f83152012-12-25 14:16:47 +0800223}
224
225void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800226ConsumerZipfMandelbrot::ScheduleNextPacket()
227{
Shockb0f83152012-12-25 14:16:47 +0800228
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800229 if (m_firstTime) {
230 m_sendEvent = Simulator::Schedule(Seconds(0.0), &ConsumerZipfMandelbrot::SendPacket, this);
231 m_firstTime = false;
232 }
233 else if (!m_sendEvent.IsRunning())
234 m_sendEvent = Simulator::Schedule((m_random == 0) ? Seconds(1.0 / m_frequency)
235 : Seconds(m_random->GetValue()),
236 &ConsumerZipfMandelbrot::SendPacket, this);
Shockb0f83152012-12-25 14:16:47 +0800237}
238
239} /* namespace ndn */
240} /* namespace ns3 */