blob: d744143334ce67c9b6003804d1f16a248f3d530d [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>
27//#include <random-variable.h>
28
29
30NS_LOG_COMPONENT_DEFINE ("ndn.ConsumerZipfMandelbrot");
31
32namespace ns3 {
33namespace ndn {
34
35NS_OBJECT_ENSURE_REGISTERED (ConsumerZipfMandelbrot);
36
37TypeId
38ConsumerZipfMandelbrot::GetTypeId (void)
39{
40 static TypeId tid = TypeId ("ns3::ndn::ConsumerZipfMandelbrot")
41 .SetGroupName ("Ndn")
42 .SetParent<ConsumerCbr> ()
43 .AddConstructor<ConsumerZipfMandelbrot> ()
44 .AddAttribute ("N", "Number of the Contents in total",
45 StringValue ("100"),
46 MakeUintegerAccessor (&ConsumerZipfMandelbrot::m_N),
47 MakeUintegerChecker<uint32_t> ())
48 .AddAttribute ("q", "parameter of improve rank",
49 StringValue ("0.7"),
50 MakeDoubleAccessor (&ConsumerZipfMandelbrot::m_q),
51 MakeDoubleChecker<double>())
52 .AddAttribute ("s", "parameter of power",
53 StringValue ("0.7"),
54 MakeDoubleAccessor (&ConsumerZipfMandelbrot::m_s),
55 MakeDoubleChecker<double>())
56 ;
57
58 return tid;
59}
60
61
62ConsumerZipfMandelbrot::ConsumerZipfMandelbrot()
63 : m_N(100)
64 , m_q (0.7)
65 , m_s (0.7)
66{
67 m_Pcum = new double[m_N+1];
68 m_Pcum[0] = 0.0;
69 for (uint32_t i=1; i<=m_N; i++) {
70 m_Pcum[i] = m_Pcum[i-1] + 1.0/pow(i+m_q, m_s);
71 }
72 for (uint32_t i=1; i<=m_N; i++) {
73 m_Pcum[i] = m_Pcum[i] / m_Pcum[m_N];
74 NS_LOG_LOGIC("cum Probability ["<<i<<"]="<<m_Pcum[i]);
75 }
76 //Ptr<UniformRandomVariable> m_SeqRng = CreateObject<UniformRandomVariable> ();
77 m_SeqRng = new UniformVariable(0.0, 1.0); //[1, m_N+1)
78 //m_SeqRng = new UniformVariable ();
79}
80
81ConsumerZipfMandelbrot::~ConsumerZipfMandelbrot() {
82 if (m_Pcum) {
83 delete m_Pcum;
84 m_Pcum = NULL;
85 }
86// if (m_SeqRng) {
87// delete m_SeqRng;
88// m_SeqRng = NULL;
89// }
90}
91
92void
93ConsumerZipfMandelbrot::SendPacket() {
94 if (!m_active) return;
95
96 NS_LOG_FUNCTION_NOARGS ();
97
98 uint32_t seq=std::numeric_limits<uint32_t>::max (); //invalid
99
100 // std::cout << Simulator::Now ().ToDouble (Time::S) << "s max -> " << m_seqMax << "\n";
101
102 while (m_retxSeqs.size ())
103 {
104 seq = *m_retxSeqs.begin ();
105 m_retxSeqs.erase (m_retxSeqs.begin ());
106
107 // NS_ASSERT (m_seqLifetimes.find (seq) != m_seqLifetimes.end ());
108 // if (m_seqLifetimes.find (seq)->time <= Simulator::Now ())
109 // {
110
111 // NS_LOG_DEBUG ("Expire " << seq);
112 // m_seqLifetimes.erase (seq); // lifetime expired. Trying to find another unexpired sequence number
113 // continue;
114 // }
115 NS_LOG_DEBUG("=interest seq "<<seq<<" from m_retxSeqs");
116 break;
117 }
118
119 if (seq == std::numeric_limits<uint32_t>::max ()) //no retransmission
120 {
121 if (m_seqMax != std::numeric_limits<uint32_t>::max ())
122 {
123 if (m_seq >= m_seqMax)
124 {
125 return; // we are totally done
126 }
127 }
128
129 seq = ConsumerZipfMandelbrot::GetNextSeq();
130 m_seq ++;
131 }
132
133 // std::cout << Simulator::Now ().ToDouble (Time::S) << "s -> " << seq << "\n";
134
135 //
136 Ptr<NameComponents> nameWithSequence = Create<NameComponents> (m_interestName);
137 (*nameWithSequence) (seq);
138 //
139
140 InterestHeader interestHeader;
141 interestHeader.SetNonce (m_rand.GetValue ());
142 interestHeader.SetName (nameWithSequence);
143
144 // NS_LOG_INFO ("Requesting Interest: \n" << interestHeader);
145 NS_LOG_INFO ("> Interest for " << seq<<", Total: "<<m_seq<<", face: "<<m_face->GetId());
146
147 Ptr<Packet> packet = Create<Packet> ();
148
149 //NS_LOG_DEBUG ("= Interest for " << seq<<", Total: "<<m_seq<<", face: "<<m_face->GetId());
150 packet->AddHeader (interestHeader);
151 //NS_LOG_DEBUG ("Interest packet size: " << packet->GetSize ());
152
153 NS_LOG_DEBUG ("Trying to add " << seq << " with " << Simulator::Now () << ". already " << m_seqTimeouts.size () << " items");
154
155 m_seqTimeouts.insert (SeqTimeout (seq, Simulator::Now ()));
156 m_seqLifetimes.insert (SeqTimeout (seq, Simulator::Now () + m_interestLifeTime)); // only one insert will work. if entry exists, nothing will happen... nothing should happen
157 m_transmittedInterests (&interestHeader, this, m_face);
158
159 m_rtt->SentSeq (SequenceNumber32 (seq), 1);
160
161 m_protocolHandler (packet);
162
163 ConsumerZipfMandelbrot::ScheduleNextPacket ();
164}
165
166
167uint32_t
168ConsumerZipfMandelbrot::GetNextSeq(){
169 uint32_t content_index = 1; //[1, m_N]
170 double p_sum = 0;
171
172 double p_random = m_SeqRng->GetValue();
173 while (p_random == 0){
174 p_random = m_SeqRng->GetValue();
175 }
176 //if (p_random == 0)
177 NS_LOG_LOGIC("p_random="<<p_random);
178 for (uint32_t i=1; i<=m_N; i++) {
179 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]
180 if (p_random <= p_sum) {
181 content_index = i;
182 break;
183 } //if
184 } //for
185 //content_index = 1;
186 NS_LOG_DEBUG("RandomNumber="<<content_index);
187 return content_index;
188}
189
190void
191ConsumerZipfMandelbrot::ScheduleNextPacket() {
192
193 if (m_firstTime)
194 {
195 m_sendEvent = Simulator::Schedule (Seconds (0.0),
196 &ConsumerZipfMandelbrot::SendPacket, this);
197 m_firstTime = false;
198 }
199 else if (!m_sendEvent.IsRunning ())
200 m_sendEvent = Simulator::Schedule (
201 (m_random == 0) ?
202 Seconds(1.0 / m_frequency)
203 :
204 Seconds(m_random->GetValue ()),
205 &ConsumerZipfMandelbrot::SendPacket, this);
206}
207
208} /* namespace ndn */
209} /* namespace ns3 */