00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "heap-scheduler.h"
00024 #include "event-impl.h"
00025 #include "ns3/assert.h"
00026 #include "ns3/log.h"
00027
00028 NS_LOG_COMPONENT_DEFINE ("HeapScheduler");
00029
00030 namespace ns3 {
00031
00032 NS_OBJECT_ENSURE_REGISTERED (HeapScheduler);
00033
00034 TypeId
00035 HeapScheduler::GetTypeId (void)
00036 {
00037 static TypeId tid = TypeId ("ns3::HeapScheduler")
00038 .SetParent<Scheduler> ()
00039 .AddConstructor<HeapScheduler> ()
00040 ;
00041 return tid;
00042 }
00043
00044 HeapScheduler::HeapScheduler ()
00045 {
00046
00047
00048
00049 Scheduler::Event empty = {0,{0,0}};
00050 m_heap.push_back (empty);
00051 }
00052
00053 HeapScheduler::~HeapScheduler ()
00054 {}
00055
00056 uint32_t
00057 HeapScheduler::Parent (uint32_t id) const
00058 {
00059 return id / 2;
00060 }
00061 uint32_t
00062 HeapScheduler::Sibling (uint32_t id) const
00063 {
00064 return id + 1;
00065 }
00066 uint32_t
00067 HeapScheduler::LeftChild (uint32_t id) const
00068 {
00069 return id * 2;
00070 }
00071 uint32_t
00072 HeapScheduler::RightChild (uint32_t id) const
00073 {
00074 return id * 2 + 1;
00075 }
00076
00077 uint32_t
00078 HeapScheduler::Root (void) const
00079 {
00080 return 1;
00081 }
00082
00083 bool
00084 HeapScheduler::IsRoot (uint32_t id) const
00085 {
00086 return (id == Root ())?true:false;
00087 }
00088
00089 uint32_t
00090 HeapScheduler::Last (void) const
00091 {
00092 return m_heap.size () - 1;
00093 }
00094
00095
00096 bool
00097 HeapScheduler::IsBottom (uint32_t id) const
00098 {
00099 return (id >= m_heap.size ())?true:false;
00100 }
00101
00102 void
00103 HeapScheduler::Exch (uint32_t a, uint32_t b)
00104 {
00105 NS_ASSERT (b < m_heap.size () && a < m_heap.size ());
00106 NS_LOG_DEBUG ("Exch " << a << ", " << b);
00107 Event tmp (m_heap[a]);
00108 m_heap[a] = m_heap[b];
00109 m_heap[b] = tmp;
00110 }
00111
00112 bool
00113 HeapScheduler::IsLessStrictly (uint32_t a, uint32_t b) const
00114 {
00115 return m_heap[a] < m_heap[b];
00116 }
00117
00118 uint32_t
00119 HeapScheduler::Smallest (uint32_t a, uint32_t b) const
00120 {
00121 return IsLessStrictly (a,b)?a:b;
00122 }
00123
00124 bool
00125 HeapScheduler::IsEmpty (void) const
00126 {
00127 return (m_heap.size () == 1)?true:false;
00128 }
00129
00130 void
00131 HeapScheduler::BottomUp (void)
00132 {
00133 uint32_t index = Last ();
00134 while (!IsRoot (index) &&
00135 IsLessStrictly (index, Parent (index)))
00136 {
00137 Exch(index, Parent (index));
00138 index = Parent (index);
00139 }
00140 }
00141
00142 void
00143 HeapScheduler::TopDown (uint32_t start)
00144 {
00145 uint32_t index = start;
00146 uint32_t right = RightChild (index);
00147 while (!IsBottom (right))
00148 {
00149 uint32_t left = LeftChild (index);
00150 uint32_t tmp = Smallest (left, right);
00151 if (IsLessStrictly (index, tmp))
00152 {
00153 return;
00154 }
00155 Exch (index, tmp);
00156 index = tmp;
00157 right = RightChild (index);
00158 }
00159 if (IsBottom (index))
00160 {
00161 return;
00162 }
00163 NS_ASSERT (!IsBottom (index));
00164 uint32_t left = LeftChild (index);
00165 if (IsBottom (left))
00166 {
00167 return;
00168 }
00169 if (IsLessStrictly (index, left))
00170 {
00171 return;
00172 }
00173 Exch (index, left);
00174 }
00175
00176
00177 void
00178 HeapScheduler::Insert (const Event &ev)
00179 {
00180 m_heap.push_back (ev);
00181 BottomUp ();
00182 }
00183
00184 Scheduler::Event
00185 HeapScheduler::PeekNext (void) const
00186 {
00187 return m_heap[Root ()];
00188 }
00189 Scheduler::Event
00190 HeapScheduler::RemoveNext (void)
00191 {
00192 Event next = m_heap[Root ()];
00193 Exch (Root (), Last ());
00194 m_heap.pop_back ();
00195 TopDown (Root ());
00196 return next;
00197 }
00198
00199
00200 void
00201 HeapScheduler::Remove (const Event &ev)
00202 {
00203 uint32_t uid = ev.key.m_uid;
00204 for (uint32_t i = 1; i < m_heap.size (); i++)
00205 {
00206 if (uid == m_heap[i].key.m_uid)
00207 {
00208 NS_ASSERT (m_heap[i].impl == ev.impl);
00209 Exch (i, Last ());
00210 m_heap.pop_back ();
00211 TopDown (i);
00212 return;
00213 }
00214 }
00215 NS_ASSERT (false);
00216 }
00217
00218 }
00219