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 TypeId
36 {
37  static TypeId tid = TypeId ("ns3::HeapScheduler")
38  .SetParent<Scheduler> ()
39  .AddConstructor<HeapScheduler> ()
40  ;
41  return tid;
42 }
43 
45 {
46  // we purposedly waste an item at the start of
47  // the array to make sure the indexes in the
48  // array start at one.
49  Scheduler::Event empty = { 0,{ 0,0}};
50  m_heap.push_back (empty);
51 }
52 
54 {
55 }
56 
57 uint32_t
58 HeapScheduler::Parent (uint32_t id) const
59 {
60  return id / 2;
61 }
62 uint32_t
63 HeapScheduler::Sibling (uint32_t id) const
64 {
65  return id + 1;
66 }
67 uint32_t
68 HeapScheduler::LeftChild (uint32_t id) const
69 {
70  return id * 2;
71 }
72 uint32_t
73 HeapScheduler::RightChild (uint32_t id) const
74 {
75  return id * 2 + 1;
76 }
77 
78 uint32_t
79 HeapScheduler::Root (void) const
80 {
81  return 1;
82 }
83 
84 bool
85 HeapScheduler::IsRoot (uint32_t id) const
86 {
87  return (id == Root ()) ? true : false;
88 }
89 
90 uint32_t
91 HeapScheduler::Last (void) const
92 {
93  return m_heap.size () - 1;
94 }
95 
96 
97 bool
98 HeapScheduler::IsBottom (uint32_t id) const
99 {
100  return (id >= m_heap.size ()) ? true : false;
101 }
102 
103 void
104 HeapScheduler::Exch (uint32_t a, uint32_t b)
105 {
106  NS_ASSERT (b < m_heap.size () && a < m_heap.size ());
107  NS_LOG_DEBUG ("Exch " << a << ", " << b);
108  Event tmp (m_heap[a]);
109  m_heap[a] = m_heap[b];
110  m_heap[b] = tmp;
111 }
112 
113 bool
114 HeapScheduler::IsLessStrictly (uint32_t a, uint32_t b) const
115 {
116  return m_heap[a] < m_heap[b];
117 }
118 
119 uint32_t
120 HeapScheduler::Smallest (uint32_t a, uint32_t b) const
121 {
122  return IsLessStrictly (a,b) ? a : b;
123 }
124 
125 bool
127 {
128  return (m_heap.size () == 1) ? true : false;
129 }
130 
131 void
133 {
134  uint32_t index = Last ();
135  while (!IsRoot (index)
136  && IsLessStrictly (index, Parent (index)))
137  {
138  Exch (index, Parent (index));
139  index = Parent (index);
140  }
141 }
142 
143 void
145 {
146  uint32_t index = start;
147  uint32_t right = RightChild (index);
148  while (!IsBottom (right))
149  {
150  uint32_t left = LeftChild (index);
151  uint32_t tmp = Smallest (left, right);
152  if (IsLessStrictly (index, tmp))
153  {
154  return;
155  }
156  Exch (index, tmp);
157  index = tmp;
158  right = RightChild (index);
159  }
160  if (IsBottom (index))
161  {
162  return;
163  }
164  NS_ASSERT (!IsBottom (index));
165  uint32_t left = LeftChild (index);
166  if (IsBottom (left))
167  {
168  return;
169  }
170  if (IsLessStrictly (index, left))
171  {
172  return;
173  }
174  Exch (index, left);
175 }
176 
177 
178 void
179 HeapScheduler::Insert (const Event &ev)
180 {
181  m_heap.push_back (ev);
182  BottomUp ();
183 }
184 
187 {
188  return m_heap[Root ()];
189 }
192 {
193  Event next = m_heap[Root ()];
194  Exch (Root (), Last ());
195  m_heap.pop_back ();
196  TopDown (Root ());
197  return next;
198 }
199 
200 
201 void
202 HeapScheduler::Remove (const Event &ev)
203 {
204  uint32_t uid = ev.key.m_uid;
205  for (uint32_t i = 1; i < m_heap.size (); i++)
206  {
207  if (uid == m_heap[i].key.m_uid)
208  {
209  NS_ASSERT (m_heap[i].impl == ev.impl);
210  Exch (i, Last ());
211  m_heap.pop_back ();
212  TopDown (i);
213  return;
214  }
215  }
216  NS_ASSERT (false);
217 }
218 
219 } // namespace ns3
220