00001 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 00002 /* 00003 * Copyright (c) 2009 INRIA 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation; 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 * 00018 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> 00019 */ 00020 00021 #ifndef CALENDAR_SCHEDULER_H 00022 #define CALENDAR_SCHEDULER_H 00023 00024 #include "scheduler.h" 00025 #include <stdint.h> 00026 #include <list> 00027 00028 namespace ns3 { 00029 00030 class EventImpl; 00031 00032 /** 00033 * \ingroup scheduler 00034 * \brief a calendar queue event scheduler 00035 * 00036 * This event scheduler is a direct implementation of the algorithm known as a calendar queue. 00037 * first published in 1988 in "Calendar Queues: A Fast O(1) Priority Queue Implementation for 00038 * the Simulation Event Set Problem" by Randy Brown. There are many refinements published 00039 * later but this class implements the original algorithm (to the best of my knowledge). 00040 * 00041 * Note: This queue is much slower than I expected (much slower than the std::map queue) 00042 * and this seems to be because the original resizing policy is horribly bad. This is 00043 * most likely the reason why there have been so many variations published which all 00044 * slightly tweak the resizing heuristics to obtain a better distribution of events 00045 * across buckets. 00046 */ 00047 class CalendarScheduler : public Scheduler 00048 { 00049 public: 00050 static TypeId GetTypeId (void); 00051 00052 CalendarScheduler (); 00053 virtual ~CalendarScheduler (); 00054 00055 virtual void Insert (const Event &ev); 00056 virtual bool IsEmpty (void) const; 00057 virtual Event PeekNext (void) const; 00058 virtual Event RemoveNext (void); 00059 virtual void Remove (const Event &ev); 00060 00061 private: 00062 void ResizeUp (void); 00063 void ResizeDown (void); 00064 void Resize (uint32_t newSize); 00065 uint32_t CalculateNewWidth (void); 00066 void Init (uint32_t nBuckets, 00067 uint64_t width, 00068 uint64_t startPrio); 00069 inline uint32_t Hash (uint64_t key) const; 00070 void PrintInfo (void); 00071 void DoResize (uint32_t newSize, uint32_t newWidth); 00072 Scheduler::Event DoRemoveNext (void); 00073 void DoInsert (const Event &ev); 00074 00075 typedef std::list<Scheduler::Event> Bucket; 00076 Bucket *m_buckets; 00077 // number of buckets in array 00078 uint32_t m_nBuckets; 00079 // duration of a bucket 00080 uint64_t m_width; 00081 // bucket index from which the last event was dequeued 00082 uint32_t m_lastBucket; 00083 // priority at the top of the bucket from which last event was dequeued 00084 uint64_t m_bucketTop; 00085 // the priority of the last event removed 00086 uint64_t m_lastPrio; 00087 // number of events in queue 00088 uint32_t m_qSize; 00089 }; 00090 00091 } // namespace ns3 00092 00093 #endif /* CALENDAR_SCHEDULER_H */