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

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: Removed changes to net/dns/ that don't belong to this CL. 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
« no previous file with comments | « net/base/prioritized_dispatcher_unittest.cc ('k') | net/base/priority_queue_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 #include "base/logging.h"
14 #include "base/threading/non_thread_safe.h"
15 #include "net/base/net_export.h"
16
17 #if !defined(NDEBUG)
18 #include "base/hash_tables.h"
19 #endif
20
21 namespace net {
22
23 // A simple priority queue. The order of values is by priority and then FIFO.
24 // Unlike the std::priority_queue, this implementation allows erasing elements
25 // from the queue, and all operations are O(p) time for p priority levels.
26 // The queue is agnostic to priority ordering (whether 0 precedes 1).
27 // If the highest priority is 0, FirstMin() returns the first in order.
28 //
29 // In debug-mode, the internal queues store (id, value) pairs where id is used
30 // to validate Pointers.
31 //
32 template<typename T>
33 class PriorityQueue : public base::NonThreadSafe {
34 private:
35 // This section is up-front for Pointer only.
36 #if !defined(NDEBUG)
37 typedef std::list<std::pair<size_t, T> > List;
38 #else
39 typedef std::list<T> List;
40 #endif
41
42 public:
43 typedef uint32 Priority;
44
45 // A pointer to a value stored in the queue. The pointer becomes invalid
46 // when the queue is destroyed or cleared, or the value is erased.
47 class Pointer {
48 public:
49 // Constructs a null pointer.
50 Pointer() : priority_(kNullPriority) {}
51
52 bool is_null() const { return priority_ == kNullPriority; }
53
54 Priority priority() const { return priority_; }
55
56 #if !defined(NDEBUG)
57 const T& value() const { return iterator_->second; }
58 #else
59 const T& value() const { return *iterator_; }
60 #endif
61
62 // Comparing to Pointer from a different PriorityQueue is undefined.
63 bool Equals(const Pointer& other) const {
64 return (priority_ == other.priority_) && (iterator_ == other.iterator_);
65 }
66
67 private:
68 friend class PriorityQueue;
69
70 // Note that we need iterator not const_iterator to pass to List::erase.
71 // When C++0x comes, this could be changed to const_iterator and const could
72 // be added to First, Last, and OldestLowest.
73 typedef typename PriorityQueue::List::iterator ListIterator;
74
75 static const Priority kNullPriority = static_cast<Priority>(-1);
76
77 Pointer(Priority priority, const ListIterator& iterator)
78 : priority_(priority), iterator_(iterator) {
79 #if !defined(NDEBUG)
80 id_ = iterator_->first;
81 #endif
82 }
83
84 Priority priority_;
85 ListIterator iterator_;
86
87 #if !defined(NDEBUG)
88 // Used by the queue to check if a Pointer is valid.
89 size_t id_;
90 #endif
91 };
92
93 // Creates a new queue for |num_priorities|.
94 explicit PriorityQueue(Priority num_priorities)
95 : lists_(num_priorities), size_(0) {
96 #if !defined(NDEBUG)
97 next_id_ = 0;
98 #endif
99 }
100
101 // Adds |value| with |priority| to the queue. Returns a pointer to the
102 // created element.
103 Pointer Insert(const T& value, Priority priority) {
104 DCHECK(CalledOnValidThread());
105 DCHECK_LT(priority, lists_.size());
106 ++size_;
107 List& list = lists_[priority];
108 #if !defined(NDEBUG)
109 size_t id = next_id_;
110 valid_ids_.insert(id);
111 ++next_id_;
112 return Pointer(priority, list.insert(list.end(),
113 std::make_pair(id, value)));
114 #else
115 return Pointer(priority, list.insert(list.end(), value));
116 #endif
117 }
118
119 // Removes the value pointed by |pointer| from the queue. All pointers to this
120 // value including |pointer| become invalid.
121 void Erase(const Pointer& pointer) {
122 DCHECK(CalledOnValidThread());
123 DCHECK_LT(pointer.priority_, lists_.size());
124 DCHECK_GT(size_, 0u);
125
126 #if !defined(NDEBUG)
127 DCHECK_EQ(1u, valid_ids_.erase(pointer.id_));
128 DCHECK_EQ(pointer.iterator_->first, pointer.id_);
129 #endif
130
131 --size_;
132 lists_[pointer.priority_].erase(pointer.iterator_);
133 }
134
135 // Returns a pointer to the first value of minimum priority or a null-pointer
136 // if empty.
137 Pointer FirstMin() {
138 DCHECK(CalledOnValidThread());
139 for (size_t i = 0; i < lists_.size(); ++i) {
140 if (!lists_[i].empty())
141 return Pointer(i, lists_[i].begin());
142 }
143 return Pointer();
144 }
145
146 // Returns a pointer to the last value of minimum priority or a null-pointer
147 // if empty.
148 Pointer LastMin() {
149 DCHECK(CalledOnValidThread());
150 for (size_t i = 0; i < lists_.size(); ++i) {
151 if (!lists_[i].empty())
152 return Pointer(i, --lists_[i].end());
153 }
154 return Pointer();
155 }
156
157 // Returns a pointer to the first value of maximum priority or a null-pointer
158 // if empty.
159 Pointer FirstMax() {
160 DCHECK(CalledOnValidThread());
161 for (size_t i = lists_.size(); i > 0; --i) {
162 size_t index = i - 1;
163 if (!lists_[index].empty())
164 return Pointer(index, lists_[index].begin());
165 }
166 return Pointer();
167 }
168
169 // Returns a pointer to the last value of maximum priority or a null-pointer
170 // if empty.
171 Pointer LastMax() {
172 DCHECK(CalledOnValidThread());
173 for (size_t i = lists_.size(); i > 0; --i) {
174 size_t index = i - 1;
175 if (!lists_[index].empty())
176 return Pointer(index, --lists_[index].end());
177 }
178 return Pointer();
179 }
180
181 // Empties the queue. All pointers become invalid.
182 void Clear() {
183 DCHECK(CalledOnValidThread());
184 for (size_t i = 0; i < lists_.size(); ++i) {
185 lists_[i].clear();
186 }
187 #if !defined(NDEBUG)
188 valid_ids_.clear();
189 #endif
190 size_ = 0u;
191 }
192
193 // Returns number of queued values.
194 size_t size() const {
195 DCHECK(CalledOnValidThread());
196 return size_;
197 }
198
199 private:
200 typedef std::vector<List> ListVector;
201
202 #if !defined(NDEBUG)
203 size_t next_id_;
204 base::hash_set<size_t> valid_ids_;
205 #endif
206
207 ListVector lists_;
208 size_t size_;
209 };
210
211 } // namespace net
212
213 #endif // NET_BASE_PRIORITY_QUEUE_H_
214
OLDNEW
« no previous file with comments | « net/base/prioritized_dispatcher_unittest.cc ('k') | net/base/priority_queue_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698