Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(675)

Side by Side Diff: net/base/priority_queue.h

Issue 9113022: Adds PriorityQueue and PrioritizedDispatcher. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Applied review. Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef NET_BASE_PRIORITY_QUEUE_H_
6 #define NET_BASE_PRIORITY_QUEUE_H_
7 #pragma once
8
9 #include <list>
10 #include <vector>
11
12 #include "base/basictypes.h"
13 #ifndef NDEBUG
14 #include "base/hash_tables.h"
15 #endif
16 #include "base/logging.h"
17 #include "base/threading/non_thread_safe.h"
18 #include "net/base/net_export.h"
19
20 namespace net {
21
22 // A simple priority queue. The order of values is by priority and then FIFO.
23 // Unlike the std::priority_queue, this implementation allows erasing elements
24 // from the queue, and all operations are O(p) time for p priority levels.
25 // The queue is agnostic to priority ordering (whether 0 precedes 1).
26 // If the highest priority is 0, FirstMin() returns the first in order.
27 //
28 // In debug-mode, the internal queues store (id, value) pairs where id is used
29 // to validate Pointers.
30 //
31 template<typename T>
32 class PriorityQueue : public base::NonThreadSafe {
33 public:
34 typedef uint32 Priority;
35
36 // A pointer to a value stored in the queue. The pointer becomes invalid
37 // when the queue is destroyed or the value is erased.
mmenke 2012/01/06 17:54:37 nit: Or the queue is cleared.
38 class Pointer {
39 public:
40 // Constructs a null pointer.
41 Pointer() : priority_(kNullPriority) {}
42
43 bool is_null() const { return priority_ == kNullPriority; }
44
45 Priority priority() const { return priority_; }
46
47 #if !defined(NDEBUG)
48 const T& value() const { return iterator_->second; }
49 #else
50 const T& value() const { return *iterator_; }
51 #endif
52
53 // Comparing to Pointer from a different PriorityQueue is undefined.
54 bool Equals(const Pointer& other) const {
55 return (priority_ == other.priority_) && (iterator_ == other.iterator_);
56 }
57
58 private:
59 friend class PriorityQueue;
60
61 // Note that we need iterator not const_iterator to pass to List::erase.
62 // When C++0x comes, this could be changed to const_iterator and const could
63 // be added to First, Last, and OldestLowest.
64 typedef typename PriorityQueue::List::iterator ListIterator;
65
66 static const Priority kNullPriority = static_cast<Priority>(-1);
67
68 Pointer(Priority priority, const ListIterator& iterator)
69 : priority_(priority), iterator_(iterator) {
70 #if !defined(NDEBUG)
71 id_ = iterator_->first;
72 #endif
73 }
74
75 Priority priority_;
76 ListIterator iterator_;
77
78 #if !defined(NDEBUG)
79 // Used by the queue to check if a Pointer is valid.
80 size_t id_;
81 #endif
82 };
83
84 // Creates a new queue for |num_priorities|.
85 explicit PriorityQueue(Priority num_priorities)
86 : lists_(num_priorities), size_(0) {
87 #if !defined(NDEBUG)
88 next_id_ = 0;
89 #endif
90 }
91
92 // Adds |value| with |priority| to the queue. Returns a pointer to the
93 // created element.
94 Pointer Insert(const T& value, Priority priority) {
95 DCHECK(CalledOnValidThread());
96 DCHECK_LT(priority, lists_.size());
97 ++size_;
98 List& list = lists_[priority];
99 #if !defined(NDEBUG)
100 size_t id = next_id_;
101 valid_ids_.insert(id);
102 ++next_id_;
103 return Pointer(priority, list.insert(list.end(),
104 std::make_pair(id, value)));
105 #else
106 return Pointer(priority, list.insert(list.end(), value));
107 #endif
108 }
109
110 // Removes the value pointed by |pointer| from the queue. All pointers to this
111 // value including |pointer| become invalid.
112 void Erase(const Pointer& pointer) {
113 DCHECK(CalledOnValidThread());
114 DCHECK_LT(pointer.priority_, lists_.size());
115 DCHECK_GT(size_, 0u);
116
117 #if !defined(NDEBUG)
118 DCHECK_EQ(1u, valid_ids_.erase(pointer.id_));
119 DCHECK_EQ(pointer.iterator_->first, pointer.id_);
120 #endif
121
122 --size_;
123 lists_[pointer.priority_].erase(pointer.iterator_);
124 }
125
126 // Returns a pointer to the first value of minimum priority or a null-pointer
127 // if empty.
128 Pointer FirstMin() {
129 DCHECK(CalledOnValidThread());
130 for (size_t i = 0; i < lists_.size(); ++i) {
131 if (!lists_[i].empty())
132 return Pointer(i, lists_[i].begin());
133 }
134 return Pointer();
135 }
136
137 // Returns a pointer to the last value of minimum priority or a null-pointer
138 // if empty.
139 Pointer LastMin() {
140 DCHECK(CalledOnValidThread());
141 for (size_t i = 0; i < lists_.size(); ++i) {
142 if (!lists_[i].empty())
143 return Pointer(i, --lists_[i].end());
144 }
145 return Pointer();
146 }
147
148 // Returns a pointer to the first value of maximum priority or a null-pointer
149 // if empty.
150 Pointer FirstMax() {
151 DCHECK(CalledOnValidThread());
152 for (size_t i = lists_.size(); i > 0; --i) {
153 size_t index = i - 1;
154 if (!lists_[index].empty())
155 return Pointer(index, lists_[index].begin());
156 }
157 return Pointer();
158 }
159
160 // Returns a pointer to the last value of maximum priority or a null-pointer
161 // if empty.
162 Pointer LastMax() {
163 DCHECK(CalledOnValidThread());
164 for (size_t i = lists_.size(); i > 0; --i) {
165 size_t index = i - 1;
166 if (!lists_[index].empty())
167 return Pointer(index, --lists_[index].end());
168 }
169 return Pointer();
170 }
171
172 // Empties the queue. All pointers become invalid.
173 void Clear() {
174 DCHECK(CalledOnValidThread());
175 for (size_t i = 0; i < lists_.size(); ++i) {
176 lists_[i].clear();
177 }
178 #if !defined(NDEBUG)
179 valid_ids_.clear();
180 #endif
181 size_ = 0u;
182 }
183
184 // Returns number of queued values.
185 size_t size() const {
186 DCHECK(CalledOnValidThread());
187 return size_;
188 }
189
190 private:
191 #if !defined(NDEBUG)
192 typedef std::list<std::pair<size_t, T> > List;
193 #else
194 typedef std::list<T> List;
195 #endif
196 typedef std::vector<List> ListVector;
197
198 #if !defined(NDEBUG)
199 size_t next_id_;
200 base::hash_set<size_t> valid_ids_;
201 #endif
202
203 ListVector lists_;
204 size_t size_;
205 };
206
207 } // namespace net
208
209 #endif // NET_BASE_PRIORITY_QUEUE_H_
210
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698