OLD | NEW |
---|---|
(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 | |
11 #include "base/basictypes.h" | |
12 #include "net/base/net_export.h" | |
13 #include "net/base/request_priority.h" | |
14 | |
15 namespace net { | |
16 | |
17 // A simple priority queue. The order of values is by RequestPriority and then | |
18 // FIFO. The queue supports changing the priority of its elements. | |
19 // All operations are O(1) time (assuming constant NUM_PRIORITIES). | |
20 template<typename T> | |
21 class PriorityQueue { | |
22 public: | |
23 typedef std::list<T> List; | |
24 typedef typename std::list<T>::iterator ListIterator; | |
25 | |
26 // A pointer to a value stored in the queue. The pointer becomes invalid | |
27 // when the queue is destroyed, the value is erased, or moved. | |
mmenke
2011/12/21 16:22:58
nit: "when the queue is destroyed or the value is
szym
2011/12/28 01:24:10
Done.
| |
28 class Pointer { | |
29 public: | |
30 // Constructs a null pointer. | |
31 Pointer() : priority_(NUM_PRIORITIES) {} | |
32 | |
33 bool is_null() const { return iterator_ == ListIterator(); } | |
szym
2011/12/20 16:48:39
This is not allowed in MSVC. Working on fix.
| |
34 RequestPriority priority() const { return priority_; } | |
mmenke
2011/12/21 16:22:58
nit: const
| |
35 | |
36 T& value() { return *iterator_; } | |
37 const T& value() const { return *iterator_; } | |
38 | |
39 bool equals(const Pointer& other) const { | |
40 // list::iterator is unique. | |
41 return iterator_ == other.iterator_; | |
szym
2011/12/20 16:48:39
Ditto, when the iterators are from different lists
| |
42 } | |
43 | |
44 protected: | |
45 friend class PriorityQueue; | |
mmenke
2011/12/21 16:22:58
nit: Could you point a line break here?
szym
2011/12/28 01:24:10
Done.
| |
46 Pointer(RequestPriority priority, const ListIterator& iterator) | |
47 : priority_(priority), iterator_(iterator) {} | |
48 | |
49 RequestPriority priority_; | |
mmenke
2011/12/21 16:22:58
Currently, this can be const. iterator_, too. My
szym
2011/12/21 22:19:34
If this is const, then the default operator= would
| |
50 ListIterator iterator_; | |
51 }; | |
52 | |
53 PriorityQueue() : size_(0) {} | |
54 | |
55 // Adds |value| with |priority| to the queue. Returns a pointer to the | |
56 // created element. | |
57 Pointer Insert(const T& value, RequestPriority priority) { | |
58 ++size_; | |
59 List& list = lists_[priority]; | |
60 return Pointer(priority, list.insert(list.end(), value)); | |
61 } | |
62 | |
63 // Removes the value pointed by |pointer| from the queue. All pointers to this | |
64 // value including |pointer| become invalid. | |
65 void Erase(const Pointer& pointer) { | |
mmenke
2011/12/21 16:22:58
It's kinda odd to take a const reference, and then
szym
2011/12/21 22:19:34
Agreed that invalidating |pointer| would make sens
mmenke
2011/12/21 22:35:42
I believe that |queue.Erase(&queue.Front())| shoul
szym
2011/12/28 01:24:10
Unfortunately, can't take address of a temporary.
| |
66 --size_; | |
67 lists_[pointer.priority_].erase(pointer.iterator_); | |
68 } | |
69 | |
70 // Moves the value pointed by |pointer| to the end of all values with priority | |
71 // |priority| and returns a pointer to the moved value. All pointers to this | |
72 // value become invalid. No-op if priority is not changed. | |
73 Pointer Move(const Pointer& pointer, RequestPriority priority) { | |
mmenke
2011/12/21 16:22:58
I think "ChangePriority" or "Reprioritize" or "Upd
szym
2011/12/28 01:24:10
Removed completely.
| |
74 if (pointer.priority_ == priority) | |
75 return pointer; | |
76 List& list = lists_[priority]; | |
77 list.splice(list.end(), lists_[pointer.priority_], pointer.iterator_); | |
78 return Pointer(priority, --list.end()); | |
79 } | |
80 | |
81 // Returns a pointer to the first value in order or a null-pointer if empty. | |
82 Pointer First() { | |
mmenke
2011/12/21 16:22:58
Believe this and the next two functions can all be
szym
2011/12/28 01:24:10
Unfortunately, then List would have be const and t
| |
83 for (size_t priority = 0; priority < NUM_PRIORITIES; ++priority) { | |
84 List& list = lists_[priority]; | |
85 if (!list.empty()) | |
86 return Pointer(static_cast<RequestPriority>(priority), list.begin()); | |
87 } | |
88 return Pointer(); | |
89 } | |
90 | |
91 // Returns a pointer to the last value in order or a null-pointer if empty. | |
92 Pointer Last() { | |
93 for (size_t priority = 0; priority < NUM_PRIORITIES; ++priority) { | |
94 List& list = lists_[NUM_PRIORITIES - priority - 1]; | |
95 if (!list.empty()) | |
96 return Pointer(static_cast<RequestPriority>(priority), --list.end()); | |
97 } | |
98 return Pointer(); | |
99 } | |
100 | |
101 // Returns a pointer to the oldest, lowest value or a null-pointer if empty. | |
102 Pointer OldestLowest() { | |
103 for (size_t priority = 0; priority < NUM_PRIORITIES; ++priority) { | |
104 List& list = lists_[NUM_PRIORITIES - priority - 1]; | |
105 if (!list.empty()) | |
106 return Pointer(static_cast<RequestPriority>(priority), list.begin()); | |
107 } | |
108 return Pointer(); | |
109 } | |
110 | |
111 // Empties the queue. All pointers become invalid. | |
112 void Clear() { | |
113 for (size_t priority = 0; priority < NUM_PRIORITIES; ++priority) | |
114 lists_[priority].clear(); | |
115 size_ = 0u; | |
116 } | |
117 | |
118 // Returns number of queued values. | |
119 size_t size() const { | |
120 return size_; | |
121 } | |
122 | |
123 private: | |
124 List lists_[NUM_PRIORITIES]; | |
125 size_t size_; | |
126 }; | |
127 | |
128 } // namespace net | |
129 | |
130 #endif // NET_BASE_PRIORITY_QUEUE_H_ | |
131 | |
OLD | NEW |