diff --git a/src/core/model/calendar-scheduler.cc b/src/core/model/calendar-scheduler.cc index abba66811..c98ee26d3 100644 --- a/src/core/model/calendar-scheduler.cc +++ b/src/core/model/calendar-scheduler.cc @@ -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 diff --git a/src/core/model/calendar-scheduler.h b/src/core/model/calendar-scheduler.h index 0aff74fc3..499dbc622 100644 --- a/src/core/model/calendar-scheduler.h +++ b/src/core/model/calendar-scheduler.h @@ -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