blob: 645ba1103ee9ea0d5cc227f0c996551d7a592143 [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"
26#include <math.h>
Shockb0f83152012-12-25 14:16:47 +080027
28
29NS_LOG_COMPONENT_DEFINE ("ndn.ConsumerZipfMandelbrot");
30
31namespace ns3 {
32namespace ndn {
33
34NS_OBJECT_ENSURE_REGISTERED (ConsumerZipfMandelbrot);
35
36TypeId
37ConsumerZipfMandelbrot::GetTypeId (void)
38{
39 static TypeId tid = TypeId ("ns3::ndn::ConsumerZipfMandelbrot")
40 .SetGroupName ("Ndn")
41 .SetParent<ConsumerCbr> ()
42 .AddConstructor<ConsumerZipfMandelbrot> ()
Alexander Afanasyev13800102012-12-25 00:30:31 -080043
44 .AddAttribute ("NumberOfContents", "Number of the Contents in total",
45 StringValue ("100"),
46 MakeUintegerAccessor (&ConsumerZipfMandelbrot::SetNumberOfContents, &ConsumerZipfMandelbrot::GetNumberOfContents),
47 MakeUintegerChecker<uint32_t> ())
48
49 // Alex: q and s are not yet really working
50 //
51 // .AddAttribute ("q", "parameter of improve rank",
52 // StringValue ("0.7"),
53 // MakeDoubleAccessor (&ConsumerZipfMandelbrot::m_q),
54 // MakeDoubleChecker<double>())
55 // .AddAttribute ("s", "parameter of power",
56 // StringValue ("0.7"),
57 // MakeDoubleAccessor (&ConsumerZipfMandelbrot::m_s),
58 // MakeDoubleChecker<double>())
Shockb0f83152012-12-25 14:16:47 +080059 ;
60
61 return tid;
62}
63
64
65ConsumerZipfMandelbrot::ConsumerZipfMandelbrot()
Alexander Afanasyev13800102012-12-25 00:30:31 -080066 : m_q (0.7)
67 , m_s (0.7)
68 , m_SeqRng (0.0, 1.0)
Shockb0f83152012-12-25 14:16:47 +080069{
Alexander Afanasyev13800102012-12-25 00:30:31 -080070 // SetNumberOfContents is called by NS-3 object system during the initialization
Shockb0f83152012-12-25 14:16:47 +080071}
72
Alexander Afanasyev13800102012-12-25 00:30:31 -080073ConsumerZipfMandelbrot::~ConsumerZipfMandelbrot()
74{
Shockb0f83152012-12-25 14:16:47 +080075}
76
77void
Alexander Afanasyev13800102012-12-25 00:30:31 -080078ConsumerZipfMandelbrot::SetNumberOfContents (uint32_t numOfContents)
79{
80 m_N = numOfContents;
81
82 m_Pcum = std::vector<double> (m_N + 1);
83
84 m_Pcum[0] = 0.0;
85 for (uint32_t i=1; i<=m_N; i++)
86 {
87 m_Pcum[i] = m_Pcum[i-1] + 1.0/pow(i+m_q, m_s);
88 }
89
90 for (uint32_t i=1; i<=m_N; i++)
91 {
92 m_Pcum[i] = m_Pcum[i] / m_Pcum[m_N];
93 NS_LOG_LOGIC("cum Probability ["<<i<<"]="<<m_Pcum[i]);
94 }
95}
96
97uint32_t
98ConsumerZipfMandelbrot::GetNumberOfContents () const
99{
100 return m_N;
101}
102
103
104void
Shockb0f83152012-12-25 14:16:47 +0800105ConsumerZipfMandelbrot::SendPacket() {
Alexander Afanasyev13800102012-12-25 00:30:31 -0800106 if (!m_active) return;
Shockb0f83152012-12-25 14:16:47 +0800107
Alexander Afanasyev13800102012-12-25 00:30:31 -0800108 NS_LOG_FUNCTION_NOARGS ();
Shockb0f83152012-12-25 14:16:47 +0800109
Alexander Afanasyev13800102012-12-25 00:30:31 -0800110 uint32_t seq=std::numeric_limits<uint32_t>::max (); //invalid
Shockb0f83152012-12-25 14:16:47 +0800111
Alexander Afanasyev13800102012-12-25 00:30:31 -0800112 // std::cout << Simulator::Now ().ToDouble (Time::S) << "s max -> " << m_seqMax << "\n";
Shockb0f83152012-12-25 14:16:47 +0800113
Alexander Afanasyev13800102012-12-25 00:30:31 -0800114 while (m_retxSeqs.size ())
115 {
116 seq = *m_retxSeqs.begin ();
117 m_retxSeqs.erase (m_retxSeqs.begin ());
Shockb0f83152012-12-25 14:16:47 +0800118
Alexander Afanasyev13800102012-12-25 00:30:31 -0800119 // NS_ASSERT (m_seqLifetimes.find (seq) != m_seqLifetimes.end ());
120 // if (m_seqLifetimes.find (seq)->time <= Simulator::Now ())
121 // {
Shockb0f83152012-12-25 14:16:47 +0800122
Alexander Afanasyev13800102012-12-25 00:30:31 -0800123 // NS_LOG_DEBUG ("Expire " << seq);
124 // m_seqLifetimes.erase (seq); // lifetime expired. Trying to find another unexpired sequence number
125 // continue;
126 // }
127 NS_LOG_DEBUG("=interest seq "<<seq<<" from m_retxSeqs");
128 break;
129 }
Shockb0f83152012-12-25 14:16:47 +0800130
Alexander Afanasyev13800102012-12-25 00:30:31 -0800131 if (seq == std::numeric_limits<uint32_t>::max ()) //no retransmission
132 {
133 if (m_seqMax != std::numeric_limits<uint32_t>::max ())
134 {
135 if (m_seq >= m_seqMax)
136 {
137 return; // we are totally done
138 }
139 }
Shockb0f83152012-12-25 14:16:47 +0800140
Alexander Afanasyev13800102012-12-25 00:30:31 -0800141 seq = ConsumerZipfMandelbrot::GetNextSeq();
142 m_seq ++;
143 }
Shockb0f83152012-12-25 14:16:47 +0800144
Alexander Afanasyev13800102012-12-25 00:30:31 -0800145 // std::cout << Simulator::Now ().ToDouble (Time::S) << "s -> " << seq << "\n";
Shockb0f83152012-12-25 14:16:47 +0800146
Alexander Afanasyev13800102012-12-25 00:30:31 -0800147 //
148 Ptr<NameComponents> nameWithSequence = Create<NameComponents> (m_interestName);
149 (*nameWithSequence) (seq);
150 //
Shockb0f83152012-12-25 14:16:47 +0800151
Alexander Afanasyev13800102012-12-25 00:30:31 -0800152 InterestHeader interestHeader;
153 interestHeader.SetNonce (m_rand.GetValue ());
154 interestHeader.SetName (nameWithSequence);
Shockb0f83152012-12-25 14:16:47 +0800155
Alexander Afanasyev13800102012-12-25 00:30:31 -0800156 // NS_LOG_INFO ("Requesting Interest: \n" << interestHeader);
157 NS_LOG_INFO ("> Interest for " << seq<<", Total: "<<m_seq<<", face: "<<m_face->GetId());
Shockb0f83152012-12-25 14:16:47 +0800158
Alexander Afanasyev13800102012-12-25 00:30:31 -0800159 Ptr<Packet> packet = Create<Packet> ();
Shockb0f83152012-12-25 14:16:47 +0800160
Alexander Afanasyev13800102012-12-25 00:30:31 -0800161 //NS_LOG_DEBUG ("= Interest for " << seq<<", Total: "<<m_seq<<", face: "<<m_face->GetId());
162 packet->AddHeader (interestHeader);
163 //NS_LOG_DEBUG ("Interest packet size: " << packet->GetSize ());
Shockb0f83152012-12-25 14:16:47 +0800164
Alexander Afanasyev13800102012-12-25 00:30:31 -0800165 NS_LOG_DEBUG ("Trying to add " << seq << " with " << Simulator::Now () << ". already " << m_seqTimeouts.size () << " items");
Shockb0f83152012-12-25 14:16:47 +0800166
Alexander Afanasyev13800102012-12-25 00:30:31 -0800167 m_seqTimeouts.insert (SeqTimeout (seq, Simulator::Now ()));
Alexander Afanasyevedf24d92013-01-18 13:35:06 -0800168 m_seqLifetimes.insert (SeqTimeout (seq, Simulator::Now ()));
Alexander Afanasyev13800102012-12-25 00:30:31 -0800169 m_transmittedInterests (&interestHeader, this, m_face);
Shockb0f83152012-12-25 14:16:47 +0800170
Alexander Afanasyev13800102012-12-25 00:30:31 -0800171 m_rtt->SentSeq (SequenceNumber32 (seq), 1);
Shockb0f83152012-12-25 14:16:47 +0800172
Alexander Afanasyev13800102012-12-25 00:30:31 -0800173 m_protocolHandler (packet);
Shockb0f83152012-12-25 14:16:47 +0800174
Alexander Afanasyev13800102012-12-25 00:30:31 -0800175 ConsumerZipfMandelbrot::ScheduleNextPacket ();
Shockb0f83152012-12-25 14:16:47 +0800176}
177
178
179uint32_t
Alexander Afanasyev13800102012-12-25 00:30:31 -0800180ConsumerZipfMandelbrot::GetNextSeq()
181{
182 uint32_t content_index = 1; //[1, m_N]
183 double p_sum = 0;
Shockb0f83152012-12-25 14:16:47 +0800184
Alexander Afanasyev13800102012-12-25 00:30:31 -0800185 double p_random = m_SeqRng.GetValue();
186 while (p_random == 0)
187 {
188 p_random = m_SeqRng.GetValue();
189 }
190 //if (p_random == 0)
191 NS_LOG_LOGIC("p_random="<<p_random);
192 for (uint32_t i=1; i<=m_N; i++)
193 {
194 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]
195 if (p_random <= p_sum)
196 {
197 content_index = i;
198 break;
199 } //if
200 } //for
201 //content_index = 1;
202 NS_LOG_DEBUG("RandomNumber="<<content_index);
203 return content_index;
Shockb0f83152012-12-25 14:16:47 +0800204}
205
206void
207ConsumerZipfMandelbrot::ScheduleNextPacket() {
208
Alexander Afanasyev13800102012-12-25 00:30:31 -0800209 if (m_firstTime)
210 {
211 m_sendEvent = Simulator::Schedule (Seconds (0.0),
212 &ConsumerZipfMandelbrot::SendPacket, this);
213 m_firstTime = false;
214 }
215 else if (!m_sendEvent.IsRunning ())
216 m_sendEvent = Simulator::Schedule (
217 (m_random == 0) ?
218 Seconds(1.0 / m_frequency)
219 :
220 Seconds(m_random->GetValue ()),
221 &ConsumerZipfMandelbrot::SendPacket, this);
Shockb0f83152012-12-25 14:16:47 +0800222}
223
224} /* namespace ndn */
225} /* namespace ns3 */