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

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: . 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 // A pointer to a value stored in the queue. The pointer becomes invalid
cbentzel 2012/01/06 16:03:05 Nit: add a newline before this comment.
36 // when the queue is destroyed or the value is erased.
37 class Pointer {
38 public:
39 // Constructs a null pointer.
40 Pointer() : priority_(kNullPriority) {}
41
42 bool is_null() const { return priority_ == kNullPriority; }
43
44 Priority priority() const { return priority_; }
45
46 #if !defined(NDEBUG)
47 const T& value() const { return iterator_->second; }
48 #else
49 const T& value() const { return *iterator_; }
50 #endif
51
52 // Comparing to Pointer from a different PriorityQueue is undefined.
53 bool Equals(const Pointer& other) const {
54 return (priority_ == other.priority_) && (iterator_ == other.iterator_);
55 }
56
57 private:
58 friend class PriorityQueue;
59 // Note that we need iterator not const_iterator to pass to List::erase.
cbentzel 2012/01/06 16:03:05 Nit: add a newline before this comment.
60 // When C++0x comes, this could be changed to const_iterator and const could
61 // be added to First, Last, and OldestLowest.
62 typedef typename PriorityQueue::List::iterator ListIterator;
63
64 static const Priority kNullPriority = static_cast<Priority>(-1);
65
66 Pointer(Priority priority, const ListIterator& iterator)
67 : priority_(priority), iterator_(iterator) {
68 #if !defined(NDEBUG)
69 id_ = iterator_->first;
70 #endif
71 }
72
73 Priority priority_;
74 ListIterator iterator_;
75
76 #if !defined(NDEBUG)
77 // Used by the queue to check if a Pointer is valid.
78 size_t id_;
79 #endif
80 };
81
82 // Creates a new queue for |num_priorities|.
83 explicit PriorityQueue(Priority num_priorities)
84 : lists_(num_priorities), size_(0) {
85 #if !defined(NDEBUG)
86 next_id_ = 0;
87 #endif
88 }
89
90 // Adds |value| with |priority| to the queue. Returns a pointer to the
91 // created element.
92 Pointer Insert(const T& value, Priority priority) {
93 DCHECK(CalledOnValidThread());
94 DCHECK_LT(priority, lists_.size());
95 ++size_;
96 List& list = lists_[priority];
97 #if !defined(NDEBUG)
98 size_t id = next_id_;
99 valid_ids_.insert(id);
100 ++next_id_;
101 return Pointer(priority, list.insert(list.end(),
102 std::make_pair(id, value)));
103 #else
104 return Pointer(priority, list.insert(list.end(), value));
105 #endif
106 }
107
108 // Removes the value pointed by |pointer| from the queue. All pointers to this
109 // value including |pointer| become invalid.
110 void Erase(const Pointer& pointer) {
111 DCHECK(CalledOnValidThread());
112 DCHECK_LT(pointer.priority_, lists_.size());
113 DCHECK_GT(size_, 0u);
114
115 #if !defined(NDEBUG)
116 DCHECK_EQ(1u, valid_ids_.erase(pointer.id_));
117 DCHECK_EQ(pointer.iterator_->first, pointer.id_);
118 #endif
119
120 --size_;
121 lists_[pointer.priority_].erase(pointer.iterator_);
122 }
123
124 // Returns a pointer to the first value of minimum priority or a null-pointer
125 // if empty.
126 Pointer FirstMin() {
127 DCHECK(CalledOnValidThread());
128 for (size_t i = 0; i < lists_.size(); ++i) {
129 if (!lists_[i].empty())
130 return Pointer(i, lists_[i].begin());
131 }
132 return Pointer();
133 }
134
135 // Returns a pointer to the last value of minimum priority or a null-pointer
136 // if empty.
137 Pointer LastMin() {
138 DCHECK(CalledOnValidThread());
139 for (size_t i = 0; i < lists_.size(); ++i) {
140 if (!lists_[i].empty())
141 return Pointer(i, --lists_[i].end());
142 }
143 return Pointer();
144 }
145
146 // Returns a pointer to the first value of maximum priority or a null-pointer
147 // if empty.
148 Pointer FirstMax() {
149 DCHECK(CalledOnValidThread());
150 for (size_t i = lists_.size(); i > 0; --i) {
151 size_t index = i - 1;
152 if (!lists_[index].empty())
153 return Pointer(index, lists_[index].begin());
154 }
155 return Pointer();
156 }
157
158 // Returns a pointer to the last value of maximum priority or a null-pointer
159 // if empty.
160 Pointer LastMax() {
161 DCHECK(CalledOnValidThread());
162 for (size_t i = lists_.size(); i > 0; --i) {
163 size_t index = i - 1;
164 if (!lists_[index].empty())
165 return Pointer(index, --lists_[index].end());
166 }
167 return Pointer();
168 }
169
170 // Empties the queue. All pointers become invalid.
171 void Clear() {
172 DCHECK(CalledOnValidThread());
173 for (size_t i = 0; i < lists_.size(); ++i) {
174 lists_[i].clear();
175 }
176 valid_ids_.clear();
cbentzel 2012/01/06 16:03:05 valid_ids_ needs to be wrapped in NDEBUG condition
177 size_ = 0u;
178 }
179
180 // Returns number of queued values.
181 size_t size() const {
182 DCHECK(CalledOnValidThread());
183 return size_;
184 }
185
186 private:
187 #if !defined(NDEBUG)
188 typedef std::list<std::pair<size_t, T> > List;
189 #else
190 typedef std::list<T> List;
191 #endif
192 typedef std::vector<List> ListVector;
193
194 #if !defined(NDEBUG)
195 size_t next_id_;
196 base::hash_set<size_t> valid_ids_;
197 #endif
198
199 ListVector lists_;
200 size_t size_;
201 };
202
203 } // namespace net
204
205 #endif // NET_BASE_PRIORITY_QUEUE_H_
206
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698