define Scheduler::Event and use it in Scheduler::Insert

This commit is contained in:
Mathieu Lacage
2008-10-15 10:33:43 +02:00
parent 64c11d222a
commit 253fecb82e
7 changed files with 66 additions and 72 deletions

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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 */

View File

@@ -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