A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
heap-scheduler.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 */
19
20#ifndef HEAP_SCHEDULER_H
21#define HEAP_SCHEDULER_H
22
23#include "scheduler.h"
24
25#include <stdint.h>
26#include <vector>
27
28/**
29 * \file
30 * \ingroup scheduler
31 * ns3::HeapScheduler declaration.
32 */
33
34namespace ns3
35{
36
37/**
38 * \ingroup scheduler
39 * \brief a binary heap event scheduler
40 *
41 * This code started as a c++ translation of a Java-based code written in 2005
42 * to implement a heap sort. So, this binary heap is really a pretty
43 * straightforward implementation of the classic data structure,
44 * implemented on a `std::vector`. This implementation does not make use
45 * of any of the heap functions from the STL. Not much to say
46 * about it.
47 *
48 * What is smart about this code ?
49 * - it does not use the index 0 in the array to avoid having to convert
50 * C-style array indexes (which start at zero) and heap-style indexes
51 * (which start at 1). This is why _all_ indexes start at 1, and that
52 * the index of the root is 1.
53 * - It uses a slightly non-standard while loop for top-down heapify
54 * to move one if statement out of the loop.
55 *
56 * \par Time Complexity
57 *
58 * Operation | Amortized %Time | Reason
59 * :----------- | :-------------- | :-----
60 * Insert() | Logarithmic | Heapify
61 * IsEmpty() | Constant | Explicit queue size
62 * PeekNext() | Constant | Heap kept sorted
63 * Remove() | Logarithmic | Search, heapify
64 * RemoveNext() | Logarithmic | Heapify
65 *
66 * \par Memory Complexity
67 *
68 * Category | Memory | Reason
69 * :-------- | :------------------------------- | :-----
70 * Overhead | 3 x `sizeof (*)`<br/>(24 bytes) | `std::vector`
71 * Per Event | 0 | Events stored in `std::vector` directly
72 */
74{
75 public:
76 /**
77 * Register this type.
78 * \return The object TypeId.
79 */
80 static TypeId GetTypeId();
81
82 /** Constructor. */
84 /** Destructor. */
85 ~HeapScheduler() override;
86
87 // Inherited
88 void Insert(const Scheduler::Event& ev) override;
89 bool IsEmpty() const override;
90 Scheduler::Event PeekNext() const override;
92 void Remove(const Scheduler::Event& ev) override;
93
94 private:
95 /** Event list type: vector of Events, managed as a heap. */
96 typedef std::vector<Scheduler::Event> BinaryHeap;
97
98 /**
99 * Get the parent index of a given entry.
100 *
101 * \param [in] id The child index.
102 * \return The index of the parent of \pname{id}.
103 */
104 inline std::size_t Parent(std::size_t id) const;
105 /**
106 * Get the next sibling of a given entry.
107 *
108 * \param [in] id The starting index.
109 * \returns The next sibling of \pname{id}.
110 */
111 std::size_t Sibling(std::size_t id) const;
112 /**
113 * Get the left child of a given entry.
114 *
115 * \param [in] id The parent index.
116 * \returns The index of the left (first) child.
117 */
118 inline std::size_t LeftChild(std::size_t id) const;
119 /**
120 * Get the right child index of a given entry.
121 *
122 * \param [in] id The parent index.
123 * \returns The index of the right (second) child.
124 */
125 inline std::size_t RightChild(std::size_t id) const;
126 /**
127 * Get the root index of the heap.
128 *
129 * \returns The root index.
130 */
131 inline std::size_t Root() const;
132 /**
133 * Return the index of the last element.
134 * \returns The last index.
135 */
136 std::size_t Last() const;
137 /**
138 * Test if an index is the root.
139 *
140 * \param [in] id The index to test.
141 * \returns \c true if the \pname{id} is the root.
142 */
143 inline bool IsRoot(std::size_t id) const;
144 /**
145 * Test if an index is at the bottom of the heap.
146 *
147 * \param [in] id The index to test.
148 * \returns \c true if the index is at the bottom.
149 */
150 inline bool IsBottom(std::size_t id) const;
151 /**
152 * Compare (less than) two items.
153 *
154 * \param [in] a The first item.
155 * \param [in] b The second item.
156 * \returns \c true if \c a < \c b
157 */
158 inline bool IsLessStrictly(std::size_t a, std::size_t b) const;
159 /**
160 * Minimum of two items.
161 *
162 * \param [in] a The first item.
163 * \param [in] b The second item.
164 * \returns The smaller of the two items.
165 */
166 inline std::size_t Smallest(std::size_t a, std::size_t b) const;
167 /**
168 * Swap two items.
169 *
170 * \param [in] a The first item.
171 * \param [in] b The second item.
172 */
173 inline void Exch(std::size_t a, std::size_t b);
174 /** Percolate a newly inserted Last item to its proper position. */
175 void BottomUp();
176 /**
177 * Percolate a deletion bubble down the heap.
178 *
179 * \param [in] start Starting entry.
180 */
181 void TopDown(std::size_t start);
182
183 /** The event list. */
185};
186
187} // namespace ns3
188
189#endif /* HEAP_SCHEDULER_H */
a binary heap event scheduler
std::size_t Root() const
Get the root index of the heap.
void TopDown(std::size_t start)
Percolate a deletion bubble down the heap.
void Insert(const Scheduler::Event &ev) override
Insert a new Event in the schedule.
~HeapScheduler() override
Destructor.
static TypeId GetTypeId()
Register this type.
Scheduler::Event RemoveNext() override
Remove the earliest event from the event list.
bool IsLessStrictly(std::size_t a, std::size_t b) const
Compare (less than) two items.
HeapScheduler()
Constructor.
std::size_t RightChild(std::size_t id) const
Get the right child index of a given entry.
BinaryHeap m_heap
The event list.
bool IsRoot(std::size_t id) const
Test if an index is the root.
Scheduler::Event PeekNext() const override
Get a pointer to the next event.
void Remove(const Scheduler::Event &ev) override
Remove a specific event from the event list.
std::vector< Scheduler::Event > BinaryHeap
Event list type: vector of Events, managed as a heap.
void Exch(std::size_t a, std::size_t b)
Swap two items.
std::size_t Smallest(std::size_t a, std::size_t b) const
Minimum of two items.
std::size_t Sibling(std::size_t id) const
Get the next sibling of a given entry.
std::size_t Parent(std::size_t id) const
Get the parent index of a given entry.
bool IsBottom(std::size_t id) const
Test if an index is at the bottom of the heap.
std::size_t LeftChild(std::size_t id) const
Get the left child of a given entry.
void BottomUp()
Percolate a newly inserted Last item to its proper position.
std::size_t Last() const
Return the index of the last element.
bool IsEmpty() const override
Test if the schedule is empty.
Maintain the event list.
Definition: scheduler.h:157
a unique identifier for an interface.
Definition: type-id.h:59
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::Scheduler abstract base class, ns3::Scheduler::Event and ns3::Scheduler::EventKey declarations.
Scheduler event.
Definition: scheduler.h:184