blob: 9982738fd32691cd7481f840c6ba845090ac33de [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"
25#include "ns3/ndn-content-object.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
52 // Alex: q and s are not yet really working
53 //
54 // .AddAttribute ("q", "parameter of improve rank",
55 // StringValue ("0.7"),
56 // MakeDoubleAccessor (&ConsumerZipfMandelbrot::m_q),
57 // MakeDoubleChecker<double>())
58 // .AddAttribute ("s", "parameter of power",
59 // StringValue ("0.7"),
60 // MakeDoubleAccessor (&ConsumerZipfMandelbrot::m_s),
61 // MakeDoubleChecker<double>())
Shockb0f83152012-12-25 14:16:47 +080062 ;
63
64 return tid;
65}
66
67
68ConsumerZipfMandelbrot::ConsumerZipfMandelbrot()
Alexander Afanasyev13800102012-12-25 00:30:31 -080069 : m_q (0.7)
70 , 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
85 m_Pcum = std::vector<double> (m_N + 1);
86
87 m_Pcum[0] = 0.0;
88 for (uint32_t i=1; i<=m_N; i++)
89 {
90 m_Pcum[i] = m_Pcum[i-1] + 1.0/pow(i+m_q, m_s);
91 }
92
93 for (uint32_t i=1; i<=m_N; i++)
94 {
95 m_Pcum[i] = m_Pcum[i] / m_Pcum[m_N];
96 NS_LOG_LOGIC("cum Probability ["<<i<<"]="<<m_Pcum[i]);
97 }
98}
99
100uint32_t
101ConsumerZipfMandelbrot::GetNumberOfContents () const
102{
103 return m_N;
104}
105
106
107void
Shockb0f83152012-12-25 14:16:47 +0800108ConsumerZipfMandelbrot::SendPacket() {
Alexander Afanasyev13800102012-12-25 00:30:31 -0800109 if (!m_active) return;
Shockb0f83152012-12-25 14:16:47 +0800110
Alexander Afanasyev13800102012-12-25 00:30:31 -0800111 NS_LOG_FUNCTION_NOARGS ();
Shockb0f83152012-12-25 14:16:47 +0800112
Alexander Afanasyev13800102012-12-25 00:30:31 -0800113 uint32_t seq=std::numeric_limits<uint32_t>::max (); //invalid
Shockb0f83152012-12-25 14:16:47 +0800114
Alexander Afanasyev13800102012-12-25 00:30:31 -0800115 // std::cout << Simulator::Now ().ToDouble (Time::S) << "s max -> " << m_seqMax << "\n";
Shockb0f83152012-12-25 14:16:47 +0800116
Alexander Afanasyev13800102012-12-25 00:30:31 -0800117 while (m_retxSeqs.size ())
118 {
119 seq = *m_retxSeqs.begin ();
120 m_retxSeqs.erase (m_retxSeqs.begin ());
Shockb0f83152012-12-25 14:16:47 +0800121
Alexander Afanasyev13800102012-12-25 00:30:31 -0800122 // NS_ASSERT (m_seqLifetimes.find (seq) != m_seqLifetimes.end ());
123 // if (m_seqLifetimes.find (seq)->time <= Simulator::Now ())
124 // {
Shockb0f83152012-12-25 14:16:47 +0800125
Alexander Afanasyev13800102012-12-25 00:30:31 -0800126 // NS_LOG_DEBUG ("Expire " << seq);
127 // m_seqLifetimes.erase (seq); // lifetime expired. Trying to find another unexpired sequence number
128 // continue;
129 // }
130 NS_LOG_DEBUG("=interest seq "<<seq<<" from m_retxSeqs");
131 break;
132 }
Shockb0f83152012-12-25 14:16:47 +0800133
Alexander Afanasyev13800102012-12-25 00:30:31 -0800134 if (seq == std::numeric_limits<uint32_t>::max ()) //no retransmission
135 {
136 if (m_seqMax != std::numeric_limits<uint32_t>::max ())
137 {
138 if (m_seq >= m_seqMax)
139 {
140 return; // we are totally done
141 }
142 }
Shockb0f83152012-12-25 14:16:47 +0800143
Alexander Afanasyev13800102012-12-25 00:30:31 -0800144 seq = ConsumerZipfMandelbrot::GetNextSeq();
145 m_seq ++;
146 }
Shockb0f83152012-12-25 14:16:47 +0800147
Alexander Afanasyev13800102012-12-25 00:30:31 -0800148 // std::cout << Simulator::Now ().ToDouble (Time::S) << "s -> " << seq << "\n";
Shockb0f83152012-12-25 14:16:47 +0800149
Alexander Afanasyev13800102012-12-25 00:30:31 -0800150 //
151 Ptr<NameComponents> nameWithSequence = Create<NameComponents> (m_interestName);
152 (*nameWithSequence) (seq);
153 //
Shockb0f83152012-12-25 14:16:47 +0800154
Alexander Afanasyev13800102012-12-25 00:30:31 -0800155 InterestHeader interestHeader;
156 interestHeader.SetNonce (m_rand.GetValue ());
157 interestHeader.SetName (nameWithSequence);
Shockb0f83152012-12-25 14:16:47 +0800158
Alexander Afanasyev13800102012-12-25 00:30:31 -0800159 // NS_LOG_INFO ("Requesting Interest: \n" << interestHeader);
160 NS_LOG_INFO ("> Interest for " << seq<<", Total: "<<m_seq<<", face: "<<m_face->GetId());
Shockb0f83152012-12-25 14:16:47 +0800161
Alexander Afanasyev13800102012-12-25 00:30:31 -0800162 Ptr<Packet> packet = Create<Packet> ();
Shockb0f83152012-12-25 14:16:47 +0800163
Alexander Afanasyev13800102012-12-25 00:30:31 -0800164 //NS_LOG_DEBUG ("= Interest for " << seq<<", Total: "<<m_seq<<", face: "<<m_face->GetId());
165 packet->AddHeader (interestHeader);
166 //NS_LOG_DEBUG ("Interest packet size: " << packet->GetSize ());
Shockb0f83152012-12-25 14:16:47 +0800167
Alexander Afanasyev13800102012-12-25 00:30:31 -0800168 NS_LOG_DEBUG ("Trying to add " << seq << " with " << Simulator::Now () << ". already " << m_seqTimeouts.size () << " items");
Shockb0f83152012-12-25 14:16:47 +0800169
Alexander Afanasyev13800102012-12-25 00:30:31 -0800170 m_seqTimeouts.insert (SeqTimeout (seq, Simulator::Now ()));
Alexander Afanasyev400aae12013-01-19 13:27:52 -0800171 m_seqFullDelay.insert (SeqTimeout (seq, Simulator::Now ()));
172
173 m_seqLastDelay.erase (seq);
174 m_seqLastDelay.insert (SeqTimeout (seq, Simulator::Now ()));
175
176 m_seqRetxCounts[seq] ++;
177
Alexander Afanasyev13800102012-12-25 00:30:31 -0800178 m_transmittedInterests (&interestHeader, this, m_face);
Shockb0f83152012-12-25 14:16:47 +0800179
Alexander Afanasyev13800102012-12-25 00:30:31 -0800180 m_rtt->SentSeq (SequenceNumber32 (seq), 1);
Shockb0f83152012-12-25 14:16:47 +0800181
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800182 FwHopCountTag hopCountTag;
183 packet->AddPacketTag (hopCountTag);
184
Alexander Afanasyev13800102012-12-25 00:30:31 -0800185 m_protocolHandler (packet);
Shockb0f83152012-12-25 14:16:47 +0800186
Alexander Afanasyev13800102012-12-25 00:30:31 -0800187 ConsumerZipfMandelbrot::ScheduleNextPacket ();
Shockb0f83152012-12-25 14:16:47 +0800188}
189
190
191uint32_t
Alexander Afanasyev13800102012-12-25 00:30:31 -0800192ConsumerZipfMandelbrot::GetNextSeq()
193{
194 uint32_t content_index = 1; //[1, m_N]
195 double p_sum = 0;
Shockb0f83152012-12-25 14:16:47 +0800196
Alexander Afanasyev13800102012-12-25 00:30:31 -0800197 double p_random = m_SeqRng.GetValue();
198 while (p_random == 0)
199 {
200 p_random = m_SeqRng.GetValue();
201 }
202 //if (p_random == 0)
203 NS_LOG_LOGIC("p_random="<<p_random);
204 for (uint32_t i=1; i<=m_N; i++)
205 {
206 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]
207 if (p_random <= p_sum)
208 {
209 content_index = i;
210 break;
211 } //if
212 } //for
213 //content_index = 1;
214 NS_LOG_DEBUG("RandomNumber="<<content_index);
215 return content_index;
Shockb0f83152012-12-25 14:16:47 +0800216}
217
218void
219ConsumerZipfMandelbrot::ScheduleNextPacket() {
220
Alexander Afanasyev13800102012-12-25 00:30:31 -0800221 if (m_firstTime)
222 {
223 m_sendEvent = Simulator::Schedule (Seconds (0.0),
224 &ConsumerZipfMandelbrot::SendPacket, this);
225 m_firstTime = false;
226 }
227 else if (!m_sendEvent.IsRunning ())
228 m_sendEvent = Simulator::Schedule (
229 (m_random == 0) ?
230 Seconds(1.0 / m_frequency)
231 :
232 Seconds(m_random->GetValue ()),
233 &ConsumerZipfMandelbrot::SendPacket, this);
Shockb0f83152012-12-25 14:16:47 +0800234}
235
236} /* namespace ndn */
237} /* namespace ns3 */