define Scheduler::Event and use it in Scheduler::Insert
This commit is contained in:
@@ -46,8 +46,8 @@ HeapScheduler::HeapScheduler ()
|
||||
// we purposedly waste an item at the start of
|
||||
// the array to make sure the indexes in the
|
||||
// array start at one.
|
||||
Scheduler::EventKey emptyKey = {0,0};
|
||||
m_heap.push_back (std::make_pair (static_cast<EventImpl *>(0), emptyKey));
|
||||
Scheduler::Event empty = {0,{0,0}};
|
||||
m_heap.push_back (empty);
|
||||
}
|
||||
|
||||
HeapScheduler::~HeapScheduler ()
|
||||
@@ -104,7 +104,7 @@ HeapScheduler::Exch (uint32_t a, uint32_t b)
|
||||
{
|
||||
NS_ASSERT (b < m_heap.size () && a < m_heap.size ());
|
||||
TRACE ("Exch " << a << ", " << b);
|
||||
std::pair<EventImpl*, Scheduler::EventKey> tmp (m_heap[a]);
|
||||
Event tmp (m_heap[a]);
|
||||
m_heap[a] = m_heap[b];
|
||||
m_heap[b] = tmp;
|
||||
}
|
||||
@@ -112,7 +112,7 @@ HeapScheduler::Exch (uint32_t a, uint32_t b)
|
||||
bool
|
||||
HeapScheduler::IsLessStrictly (uint32_t a, uint32_t b) const
|
||||
{
|
||||
return m_heap[a].second < m_heap[b].second;
|
||||
return m_heap[a] < m_heap[b];
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -175,32 +175,28 @@ HeapScheduler::TopDown (uint32_t start)
|
||||
|
||||
|
||||
void
|
||||
HeapScheduler::Insert (const EventId &id)
|
||||
HeapScheduler::Insert (const Event &ev)
|
||||
{
|
||||
// acquire single ref
|
||||
EventImpl *event = id.PeekEventImpl ();
|
||||
event->Ref ();
|
||||
Scheduler::EventKey key;
|
||||
key.m_ts = id.GetTs ();
|
||||
key.m_uid = id.GetUid ();
|
||||
m_heap.push_back (std::make_pair (event, key));
|
||||
ev.impl->Ref ();
|
||||
m_heap.push_back (ev);
|
||||
BottomUp ();
|
||||
}
|
||||
|
||||
EventId
|
||||
HeapScheduler::PeekNext (void) const
|
||||
{
|
||||
std::pair<EventImpl *,Scheduler::EventKey> next = m_heap[Root ()];
|
||||
return EventId (next.first, next.second.m_ts, next.second.m_uid);
|
||||
Event next = m_heap[Root ()];
|
||||
return EventId (next.impl, next.key.m_ts, next.key.m_uid);
|
||||
}
|
||||
EventId
|
||||
HeapScheduler::RemoveNext (void)
|
||||
{
|
||||
std::pair<EventImpl *,Scheduler::EventKey> next = m_heap[Root ()];
|
||||
Event next = m_heap[Root ()];
|
||||
Exch (Root (), Last ());
|
||||
m_heap.pop_back ();
|
||||
TopDown (Root ());
|
||||
return EventId (Ptr<EventImpl> (next.first, false), next.second.m_ts, next.second.m_uid);
|
||||
return EventId (Ptr<EventImpl> (next.impl, false), next.key.m_ts, next.key.m_uid);
|
||||
}
|
||||
|
||||
|
||||
@@ -210,12 +206,11 @@ HeapScheduler::Remove (const EventId &id)
|
||||
uint32_t uid = id.GetUid ();
|
||||
for (uint32_t i = 1; i < m_heap.size (); i++)
|
||||
{
|
||||
if (uid == m_heap[i].second.m_uid)
|
||||
if (uid == m_heap[i].key.m_uid)
|
||||
{
|
||||
NS_ASSERT (m_heap[i].first == id.PeekEventImpl ());
|
||||
std::pair<EventImpl *,Scheduler::EventKey> next = m_heap[i];
|
||||
NS_ASSERT (m_heap[i].impl == id.PeekEventImpl ());
|
||||
// release single ref
|
||||
next.first->Unref ();
|
||||
m_heap[i].impl->Unref ();
|
||||
Exch (i, Last ());
|
||||
m_heap.pop_back ();
|
||||
TopDown (i);
|
||||
@@ -227,5 +222,5 @@ HeapScheduler::Remove (const EventId &id)
|
||||
return false;
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef SCHEDULER_HEAP_H
|
||||
#define SCHEDULER_HEAP_H
|
||||
#ifndef HEAP_SCHEDULER_H
|
||||
#define HEAP_SCHEDULER_H
|
||||
|
||||
#include "scheduler.h"
|
||||
#include <stdint.h>
|
||||
@@ -46,19 +46,20 @@ class EventHolder;
|
||||
* - It uses a slightly non-standard while loop for top-down heapify
|
||||
* to move one if statement out of the loop.
|
||||
*/
|
||||
class HeapScheduler : public Scheduler {
|
||||
class HeapScheduler : public Scheduler
|
||||
{
|
||||
public:
|
||||
HeapScheduler ();
|
||||
virtual ~HeapScheduler ();
|
||||
|
||||
virtual void Insert (const EventId &id);
|
||||
virtual void Insert (const Event &ev);
|
||||
virtual bool IsEmpty (void) const;
|
||||
virtual EventId PeekNext (void) const;
|
||||
virtual EventId RemoveNext (void);
|
||||
virtual bool Remove (const EventId &ev);
|
||||
|
||||
private:
|
||||
typedef std::vector<std::pair<EventImpl *, Scheduler::EventKey> > BinaryHeap;
|
||||
typedef std::vector<Event> BinaryHeap;
|
||||
|
||||
inline uint32_t Parent (uint32_t id) const;
|
||||
uint32_t Sibling (uint32_t id) const;
|
||||
@@ -79,7 +80,6 @@ private:
|
||||
BinaryHeap m_heap;
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
#endif /* SCHEDULER_HEAP_H */
|
||||
#endif /* HEAP_SCHEDULER_H */
|
||||
|
||||
@@ -33,23 +33,19 @@ ListScheduler::~ListScheduler ()
|
||||
{}
|
||||
|
||||
void
|
||||
ListScheduler::Insert (const EventId &id)
|
||||
ListScheduler::Insert (const Event &ev)
|
||||
{
|
||||
Scheduler::EventKey key;
|
||||
// acquire refcount on EventImpl
|
||||
EventImpl *event = id.PeekEventImpl ();
|
||||
event->Ref ();
|
||||
key.m_ts = id.GetTs ();
|
||||
key.m_uid = id.GetUid ();
|
||||
ev.impl->Ref ();
|
||||
for (EventsI i = m_events.begin (); i != m_events.end (); i++)
|
||||
{
|
||||
if (key < i->second)
|
||||
if (ev.key < i->key)
|
||||
{
|
||||
m_events.insert (i, std::make_pair (event, key));
|
||||
m_events.insert (i, ev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_events.push_back (std::make_pair (event, key));
|
||||
m_events.push_back (ev);
|
||||
}
|
||||
bool
|
||||
ListScheduler::IsEmpty (void) const
|
||||
@@ -59,16 +55,16 @@ ListScheduler::IsEmpty (void) const
|
||||
EventId
|
||||
ListScheduler::PeekNext (void) const
|
||||
{
|
||||
std::pair<EventImpl *, EventKey> next = m_events.front ();
|
||||
return EventId (next.first, next.second.m_ts, next.second.m_uid);
|
||||
Event next = m_events.front ();
|
||||
return EventId (next.impl, next.key.m_ts, next.key.m_uid);
|
||||
}
|
||||
|
||||
EventId
|
||||
ListScheduler::RemoveNext (void)
|
||||
{
|
||||
std::pair<EventImpl *, EventKey> next = m_events.front ();
|
||||
Event next = m_events.front ();
|
||||
m_events.pop_front ();
|
||||
return EventId (Ptr<EventImpl> (next.first,false), next.second.m_ts, next.second.m_uid);
|
||||
return EventId (Ptr<EventImpl> (next.impl,false), next.key.m_ts, next.key.m_uid);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -76,11 +72,11 @@ ListScheduler::Remove (const EventId &id)
|
||||
{
|
||||
for (EventsI i = m_events.begin (); i != m_events.end (); i++)
|
||||
{
|
||||
if (i->second.m_uid == id.GetUid ())
|
||||
if (i->key.m_uid == id.GetUid ())
|
||||
{
|
||||
NS_ASSERT (id.PeekEventImpl () == i->first);
|
||||
NS_ASSERT (id.PeekEventImpl () == i->impl);
|
||||
// release single acquire ref.
|
||||
i->first->Unref ();
|
||||
i->impl->Unref ();
|
||||
m_events.erase (i);
|
||||
return true;
|
||||
}
|
||||
@@ -89,4 +85,4 @@ ListScheduler::Remove (const EventId &id)
|
||||
return false;
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
} // namespace ns3
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef SCHEDULER_LIST_H
|
||||
#define SCHEDULER_LIST_H
|
||||
#ifndef LIST_SCHEDULER_H
|
||||
#define LIST_SCHEDULER_H
|
||||
|
||||
#include "scheduler.h"
|
||||
#include "event-id.h"
|
||||
@@ -38,12 +38,13 @@ class EventImpl;
|
||||
* This class implements the an event scheduler using an std::list
|
||||
* data structure, that is, a double linked-list.
|
||||
*/
|
||||
class ListScheduler : public Scheduler {
|
||||
class ListScheduler : public Scheduler
|
||||
{
|
||||
public:
|
||||
ListScheduler ();
|
||||
virtual ~ListScheduler ();
|
||||
|
||||
virtual void Insert (const EventId &id);
|
||||
virtual void Insert (const Event &ev);
|
||||
virtual bool IsEmpty (void) const;
|
||||
virtual EventId PeekNext (void) const;
|
||||
virtual EventId RemoveNext (void);
|
||||
@@ -51,12 +52,11 @@ class ListScheduler : public Scheduler {
|
||||
|
||||
private:
|
||||
|
||||
typedef std::list<std::pair<EventImpl*, EventKey> > Events;
|
||||
typedef std::list<std::pair<EventImpl*, EventKey> >::iterator EventsI;
|
||||
typedef std::list<Event> Events;
|
||||
typedef std::list<Event>::iterator EventsI;
|
||||
Events m_events;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
#endif /* SCHEDULER_LIST_H */
|
||||
#endif /* LIST_SCHEDULER_H */
|
||||
|
||||
@@ -43,16 +43,12 @@ MapScheduler::~MapScheduler ()
|
||||
{}
|
||||
|
||||
void
|
||||
MapScheduler::Insert (const EventId &id)
|
||||
MapScheduler::Insert (const Event &ev)
|
||||
{
|
||||
// acquire a single ref
|
||||
EventImpl *event = id.PeekEventImpl ();
|
||||
event->Ref ();
|
||||
Scheduler::EventKey key;
|
||||
key.m_ts = id.GetTs ();
|
||||
key.m_uid = id.GetUid ();
|
||||
ev.impl->Ref ();
|
||||
std::pair<EventMapI,bool> result;
|
||||
result = m_list.insert (std::make_pair (key, event));
|
||||
result = m_list.insert (std::make_pair (ev.key, ev.impl));
|
||||
NS_ASSERT (result.second);
|
||||
}
|
||||
|
||||
@@ -93,4 +89,4 @@ MapScheduler::Remove (const EventId &id)
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
} // namespace ns3
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef SCHEDULER_MAP_H
|
||||
#define SCHEDULER_MAP_H
|
||||
#ifndef MAP_SCHEDULER_H
|
||||
#define MAP_SCHEDULER_H
|
||||
|
||||
#include "scheduler.h"
|
||||
#include <stdint.h>
|
||||
@@ -37,12 +37,13 @@ class EventImpl;
|
||||
* This class implements the an event scheduler using an std::map
|
||||
* data structure.
|
||||
*/
|
||||
class MapScheduler : public Scheduler {
|
||||
class MapScheduler : public Scheduler
|
||||
{
|
||||
public:
|
||||
MapScheduler ();
|
||||
virtual ~MapScheduler ();
|
||||
|
||||
virtual void Insert (const EventId &id);
|
||||
virtual void Insert (const Event &ev);
|
||||
virtual bool IsEmpty (void) const;
|
||||
virtual EventId PeekNext (void) const;
|
||||
virtual EventId RemoveNext (void);
|
||||
@@ -57,7 +58,6 @@ private:
|
||||
EventMap m_list;
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
#endif /* SCHEDULER_MAP_H */
|
||||
#endif /* MAP_SCHEDULER_H */
|
||||
|
||||
@@ -55,15 +55,17 @@ class Scheduler : public Object
|
||||
uint64_t m_ts;
|
||||
uint32_t m_uid;
|
||||
};
|
||||
struct Event {
|
||||
EventImpl *impl;
|
||||
EventKey key;
|
||||
};
|
||||
|
||||
virtual ~Scheduler () = 0;
|
||||
|
||||
/**
|
||||
* \param id event to store in the event list
|
||||
*
|
||||
* This method takes ownership of the event pointer.
|
||||
* \param ev event to store in the event list
|
||||
*/
|
||||
virtual void Insert (const EventId &id) = 0;
|
||||
virtual void Insert (const Event &ev) = 0;
|
||||
/**
|
||||
* \returns true if the event list is empty and false otherwise.
|
||||
*/
|
||||
@@ -112,6 +114,11 @@ inline bool operator < (const Scheduler::EventKey &a, const Scheduler::EventKey
|
||||
}
|
||||
}
|
||||
|
||||
inline bool operator < (const Scheduler::Event &a, const Scheduler::Event &b)
|
||||
{
|
||||
return a.key < b.key;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
Reference in New Issue
Block a user