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

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

Issue 8965025: Refactoring of job dispatch in HostResolverImpl in preparation for DnsClient. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixes from try bots. 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 "net/base/net_export.h"
18
19 namespace net {
20
21 // A simple priority queue. The order of values is by priority and then FIFO.
22 // Unlike the std::priority_queue, all operations are O(p) time for p priority
cbentzel 2012/01/05 18:32:20 This also allows erasing of elements in the queue,
23 // levels. The queue is agnostic to priority ordering (whether 0 precedes 1).
24 // If the highest priority is 0, FirstMin() returns the first in order.
25 //
26 // In debug-mode, the internal queues store (id, value) pairs where id is used
27 // to validate Pointers.
28 //
29 template<typename T>
30 class PriorityQueue {
cbentzel 2012/01/05 18:32:20 I think this should derive from NonThreadSafe or h
31 public:
32 // A pointer to a value stored in the queue. The pointer becomes invalid
33 // when the queue is destroyed or the value is erased or moved.
cbentzel 2012/01/05 18:32:20 Nit: remove "or moved". There is no direct support
34 class Pointer {
35 public:
36 // Constructs a null pointer.
37 Pointer() : priority_(kNullPriority) {}
38
39 bool is_null() const { return priority_ == kNullPriority; }
40
41 size_t priority() const { return priority_; }
cbentzel 2012/01/05 18:32:20 I'd argue for just using uint32 rather than a size
42
43 #ifndef NDEBUG
cbentzel 2012/01/05 18:32:20 Nit: #if !defined(NDEBUG) is preferred over #ifnd
44 const T& value() const { return iterator_->second; }
45 #else
46 const T& value() const { return *iterator_; }
47 #endif
48
49 // Comparing to Pointer from a different PriorityQueue is undefined.
50 bool Equals(const Pointer& other) const {
51 return (priority_ == other.priority_) && (iterator_ == other.iterator_);
52 }
53
54 private:
55 friend class PriorityQueue;
56 // Note that we need iterator not const_iterator to pass to List::erase.
57 // When C++0x comes, this could be changed to const_iterator and const could
58 // be added to First, Last, and OldestLowest.
59 #ifndef NDEBUG
60 typedef typename std::list<std::pair<size_t, T> >::iterator ListIterator;
cbentzel 2012/01/05 18:32:20 Could be PriorityQueue::List::iterator to prevent
61 #else
62 typedef typename std::list<T>::iterator ListIterator;
63 #endif
64
65 static const size_t kNullPriority = static_cast<size_t>(-1);
66
67 Pointer(size_t priority, const ListIterator& iterator)
68 : priority_(priority), iterator_(iterator) {
69 #ifndef NDEBUG
70 id_ = iterator_->first;
71 #endif
72 }
73
74 size_t priority_;
75 ListIterator iterator_;
76
77 #ifndef NDEBUG
78 // Used by the queue to check if a Pointer is valid.
79 size_t id_;
80 #endif
81 };
82
83 // Creates a new queue for |num_priorities|.
84 PriorityQueue(size_t num_priorities)
cbentzel 2012/01/05 18:32:20 explicit constructor needed.
85 : lists_(num_priorities), size_(0) {
86 #ifndef NDEBUG
87 next_id_ = 0;
88 #endif
89 }
90
91 // Adds |value| with |priority| to the queue. Returns a pointer to the
92 // created element.
93 Pointer Insert(const T& value, size_t priority) {
94 DCHECK_LT(priority, lists_.size());
95 ++size_;
96 List& list = lists_[priority];
97 #ifndef NDEBUG
98 size_t id = next_id_;
99 valid_ids_.insert(id);
100 ++next_id_;
101 return Pointer(priority, list.insert(list.end(),
cbentzel 2012/01/05 18:32:20 Nit: list.push_back would be clearer than list.ins
szym 2012/01/05 19:00:29 list.push_back returns void.
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_LT(pointer.priority_, lists_.size());
112 DCHECK_GT(size_, 0u);
113
114 #ifndef NDEBUG
115 DCHECK_EQ(1u, valid_ids_.erase(pointer.id_));
116 DCHECK_EQ(pointer.iterator_->first, pointer.id_);
117 #endif
118
119 --size_;
120 lists_[pointer.priority_].erase(pointer.iterator_);
121 }
122
123 // Returns a pointer to the first value of minimum priority or a null-pointer
124 // if empty.
125 Pointer FirstMin() {
126 if (!size()) return Pointer();
cbentzel 2012/01/05 18:32:20 It would be clearer to just remove this line and t
127 for (size_t i = 0; i < lists_.size(); ++i)
cbentzel 2012/01/05 18:32:20 Please use braces in this for loop.
128 if (!lists_[i].empty())
129 return Pointer(i, lists_[i].begin());
130 NOTREACHED();
131 return Pointer();
132 }
133
134 // Returns a pointer to the last value of minimum priority or a null-pointer
135 // if empty.
136 Pointer LastMin() {
137 if (!size()) return Pointer();
138 for (size_t i = 0; i < lists_.size(); ++i)
139 if (!lists_[i].empty())
140 return Pointer(i, --lists_[i].end());
141 NOTREACHED();
142 return Pointer();
143 }
144
145 // Returns a pointer to the first value of maximum priority or a null-pointer
146 // if empty.
147 Pointer FirstMax() {
148 if (!size()) return Pointer();
149 for (size_t i = lists_.size(); i > 0; --i)
150 if (!lists_[i - 1].empty())
151 return Pointer(i - 1, lists_[i - 1].begin());
152 NOTREACHED();
153 return Pointer();
154 }
155
156 // Returns a pointer to the last value of maximum priority or a null-pointer
157 // if empty.
158 Pointer LastMax() {
159 if (!size()) return Pointer();
160 for (size_t i = lists_.size(); i > 0; --i)
cbentzel 2012/01/05 18:32:20 To be pedantic, this should be ListVector::size_ty
161 if (!lists_[i - 1].empty())
cbentzel 2012/01/05 18:32:20 Nit: probably clearer to have a local variable ind
162 return Pointer(i - 1, --lists_[i - 1].end());
163 NOTREACHED();
164 return Pointer();
165 }
166
167 // Empties the queue. All pointers become invalid.
168 void Clear() {
169 for (size_t i = 0; i < lists_.size(); ++i)
cbentzel 2012/01/05 18:32:20 BUG: valid_ids_ needs to be cleared here as well.
170 lists_[i].clear();
171 size_ = 0u;
172 }
173
174 // Returns number of queued values.
175 size_t size() const {
176 return size_;
177 }
178
179 private:
180 #ifndef NDEBUG
181 typedef std::list<std::pair<size_t, T> > List;
182 #else
183 typedef std::list<T> List;
184 #endif
185 typedef std::vector<List> ListVector;
186
187 #ifndef NDEBUG
188 size_t next_id_;
189 base::hash_set<size_t> valid_ids_;
190 #endif
191
192 ListVector lists_;
193 size_t size_;
cbentzel 2012/01/05 18:32:20 Nit: extra new line.
194
cbentzel 2012/01/05 18:32:20 Should copy-and-assignment be disallowed? I don't
szym 2012/01/05 19:00:29 It can be allowed. But for safety Pointers need to
195 };
196
197 } // namespace net
198
199 #endif // NET_BASE_PRIORITY_QUEUE_H_
200
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698