A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
heap-scheduler.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006 INRIA
4  * Copyright (c) 2005 Mathieu Lacage
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  *
21  */
22 
23 #include "heap-scheduler.h"
24 #include "event-impl.h"
25 #include "assert.h"
26 #include "log.h"
27 
28 NS_LOG_COMPONENT_DEFINE ("HeapScheduler");
29 
30 namespace ns3 {
31 
32 NS_OBJECT_ENSURE_REGISTERED (HeapScheduler)
33  ;
34 
35 TypeId
37 {
38  static TypeId tid = TypeId ("ns3::HeapScheduler")
39  .SetParent<Scheduler> ()
40  .AddConstructor<HeapScheduler> ()
41  ;
42  return tid;
43 }
44 
46 {
47  NS_LOG_FUNCTION (this);
48  // we purposedly waste an item at the start of
49  // the array to make sure the indexes in the
50  // array start at one.
51  Scheduler::Event empty = { 0,{ 0,0}};
52  m_heap.push_back (empty);
53 }
54 
56 {
57  NS_LOG_FUNCTION (this);
58 }
59 
60 uint32_t
61 HeapScheduler::Parent (uint32_t id) const
62 {
63  NS_LOG_FUNCTION (this << id);
64  return id / 2;
65 }
66 uint32_t
67 HeapScheduler::Sibling (uint32_t id) const
68 {
69  NS_LOG_FUNCTION (this << id);
70  return id + 1;
71 }
72 uint32_t
73 HeapScheduler::LeftChild (uint32_t id) const
74 {
75  NS_LOG_FUNCTION (this << id);
76  return id * 2;
77 }
78 uint32_t
79 HeapScheduler::RightChild (uint32_t id) const
80 {
81  NS_LOG_FUNCTION (this << id);
82  return id * 2 + 1;
83 }
84 
85 uint32_t
86 HeapScheduler::Root (void) const
87 {
88  NS_LOG_FUNCTION (this);
89  return 1;
90 }
91 
92 bool
93 HeapScheduler::IsRoot (uint32_t id) const
94 {
95  NS_LOG_FUNCTION (this << id);
96  return (id == Root ()) ? true : false;
97 }
98 
99 uint32_t
101 {
102  NS_LOG_FUNCTION (this);
103  return m_heap.size () - 1;
104 }
105 
106 
107 bool
108 HeapScheduler::IsBottom (uint32_t id) const
109 {
110  NS_LOG_FUNCTION (this << id);
111  return (id >= m_heap.size ()) ? true : false;
112 }
113 
114 void
115 HeapScheduler::Exch (uint32_t a, uint32_t b)
116 {
117  NS_LOG_FUNCTION (this << a << b);
118  NS_ASSERT (b < m_heap.size () && a < m_heap.size ());
119  NS_LOG_DEBUG ("Exch " << a << ", " << b);
120  Event tmp (m_heap[a]);
121  m_heap[a] = m_heap[b];
122  m_heap[b] = tmp;
123 }
124 
125 bool
126 HeapScheduler::IsLessStrictly (uint32_t a, uint32_t b) const
127 {
128  NS_LOG_FUNCTION (this << a << b);
129  return m_heap[a] < m_heap[b];
130 }
131 
132 uint32_t
133 HeapScheduler::Smallest (uint32_t a, uint32_t b) const
134 {
135  NS_LOG_FUNCTION (this << a << b);
136  return IsLessStrictly (a,b) ? a : b;
137 }
138 
139 bool
141 {
142  NS_LOG_FUNCTION (this);
143  return (m_heap.size () == 1) ? true : false;
144 }
145 
146 void
148 {
149  NS_LOG_FUNCTION (this);
150  uint32_t index = Last ();
151  while (!IsRoot (index)
152  && IsLessStrictly (index, Parent (index)))
153  {
154  Exch (index, Parent (index));
155  index = Parent (index);
156  }
157 }
158 
159 void
161 {
162  NS_LOG_FUNCTION (this << start);
163  uint32_t index = start;
164  uint32_t right = RightChild (index);
165  while (!IsBottom (right))
166  {
167  uint32_t left = LeftChild (index);
168  uint32_t tmp = Smallest (left, right);
169  if (IsLessStrictly (index, tmp))
170  {
171  return;
172  }
173  Exch (index, tmp);
174  index = tmp;
175  right = RightChild (index);
176  }
177  if (IsBottom (index))
178  {
179  return;
180  }
181  NS_ASSERT (!IsBottom (index));
182  uint32_t left = LeftChild (index);
183  if (IsBottom (left))
184  {
185  return;
186  }
187  if (IsLessStrictly (index, left))
188  {
189  return;
190  }
191  Exch (index, left);
192 }
193 
194 
195 void
196 HeapScheduler::Insert (const Event &ev)
197 {
198  NS_LOG_FUNCTION (this << &ev);
199  m_heap.push_back (ev);
200  BottomUp ();
201 }
202 
205 {
206  NS_LOG_FUNCTION (this);
207  return m_heap[Root ()];
208 }
211 {
212  NS_LOG_FUNCTION (this);
213  Event next = m_heap[Root ()];
214  Exch (Root (), Last ());
215  m_heap.pop_back ();
216  TopDown (Root ());
217  return next;
218 }
219 
220 
221 void
222 HeapScheduler::Remove (const Event &ev)
223 {
224  NS_LOG_FUNCTION (this << &ev);
225  uint32_t uid = ev.key.m_uid;
226  for (uint32_t i = 1; i < m_heap.size (); i++)
227  {
228  if (uid == m_heap[i].key.m_uid)
229  {
230  NS_ASSERT (m_heap[i].impl == ev.impl);
231  Exch (i, Last ());
232  m_heap.pop_back ();
233  TopDown (i);
234  return;
235  }
236  }
237  NS_ASSERT (false);
238 }
239 
240 } // namespace ns3
241 
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
uint32_t Sibling(uint32_t id) const
virtual ~HeapScheduler()
virtual void Insert(const Event &ev)
void TopDown(uint32_t start)
virtual Event RemoveNext(void)
This method cannot be invoked if the list is empty.
bool IsLessStrictly(uint32_t a, uint32_t b) const
#define NS_ASSERT(condition)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
virtual Event PeekNext(void) const
static TypeId GetTypeId(void)
bool IsRoot(uint32_t id) const
virtual void Remove(const Event &ev)
NS_LOG_COMPONENT_DEFINE("HeapScheduler")
void Exch(uint32_t a, uint32_t b)
uint32_t RightChild(uint32_t id) const
make Callback use a separate empty type
Definition: empty.h:8
uint32_t Smallest(uint32_t a, uint32_t b) const
Maintain the event list.
Definition: scheduler.h:57
bool IsBottom(uint32_t id) const
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
uint32_t Last(void) const
virtual bool IsEmpty(void) const
uint32_t Parent(uint32_t id) const
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
uint32_t Root(void) const
uint32_t LeftChild(uint32_t id) const