core: make insertion order of CalendarScheduler configurable

This commit is contained in:
kr0n0s (GCI 2019)
2020-03-20 16:55:16 -07:00
committed by Peter D. Barnes, Jr
parent 1f6a710dbd
commit f42687c4f7
2 changed files with 25 additions and 6 deletions

View File

@@ -109,7 +109,7 @@ CalendarScheduler::DoInsert (const Event &ev)
Bucket::iterator end = m_buckets[bucket].end ();
for (Bucket::iterator i = m_buckets[bucket].begin (); i != end; ++i)
{
if (ev.key > i->key)
if ((ev.key < i->key && !m_reverse) || (ev.key > i->key && m_reverse))
{
m_buckets[bucket].insert (i, ev);
return;
@@ -148,7 +148,7 @@ CalendarScheduler::PeekNext (void) const
{
if (!m_buckets[i].empty ())
{
Scheduler::Event next = m_buckets[i].back ();
Scheduler::Event next = m_reverse ? m_buckets[i].back () : m_buckets[i].front ();
if (next.key.m_ts < bucketTop)
{
return next;
@@ -184,13 +184,13 @@ CalendarScheduler::DoRemoveNext (void)
{
if (!m_buckets[i].empty ())
{
Scheduler::Event next = m_buckets[i].back ();
Scheduler::Event next = m_reverse ? m_buckets[i].back () : m_buckets[i].front ();
if (next.key.m_ts < bucketTop)
{
m_lastBucket = i;
m_lastPrio = next.key.m_ts;
m_bucketTop = bucketTop;
m_buckets[i].pop_back ();
m_reverse ? m_buckets[i].pop_back () : m_buckets[i].pop_front ();
return next;
}
if (next.key < minKey)
@@ -208,8 +208,8 @@ CalendarScheduler::DoRemoveNext (void)
m_lastPrio = minKey.m_ts;
m_lastBucket = Hash (minKey.m_ts);
m_bucketTop = (minKey.m_ts / m_width + 1) * m_width;
Scheduler::Event next = m_buckets[minBucket].back ();
m_buckets[minBucket].pop_back ();
Scheduler::Event next = m_reverse ? m_buckets[minBucket].back () : m_buckets[minBucket].front();
m_reverse ? m_buckets[minBucket].pop_back () : m_buckets[minBucket].pop_front ();
return next;
}
@@ -383,4 +383,13 @@ CalendarScheduler::Resize (uint32_t newSize)
DoResize (newSize, newWidth);
}
bool CalendarScheduler::SetReverse (bool reverse)
{
NS_LOG_FUNCTION (this << reverse);
bool old_reverse = m_reverse;
m_reverse = reverse;
return old_reverse;
}
} // namespace ns3

View File

@@ -48,6 +48,12 @@ class EventImpl;
* the original algorithm (to the best of my knowledge).
*
* \note
* This queue is much slower than I expected (much slower than the
* std::map queue) and this seems to be because the original resizing policy
* is horribly bad. This is most likely the reason why there have been
* so many variations published which all slightly tweak the resizing
* heuristics to obtain a better distribution of events across buckets.
*
* While inserion sort is not discussed in the original article, its
* implementation appears to dramatically affect performance.
* CalendarScheduler sorts buckets in \em reverse chronological order.
@@ -77,6 +83,8 @@ public:
virtual Scheduler::Event RemoveNext (void);
virtual void Remove (const Scheduler::Event &ev);
bool SetReverse (bool reverse);
private:
/** Double the number of buckets if necessary. */
void ResizeUp (void);
@@ -150,6 +158,8 @@ private:
uint64_t m_lastPrio;
/** Number of events in queue. */
uint32_t m_qSize;
/** Switch between old and new configuration after bug 2498. */
bool m_reverse = false;
};
} // namespace ns3