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 | |
cbentzel
2012/01/03 19:39:09
It would be nice if this weren't coupled with Requ
szym
2012/01/03 20:48:52
Having NUM_PRIORITIES const allows the compiler to
| |
18 // FIFO. The queue supports changing the priority of its elements. | |
cbentzel
2012/01/03 19:39:09
How do you change the priority of the elements? I
szym
2012/01/03 20:48:52
There used to be Update/Move which essentially Era
| |
19 // All operations are O(1) time (assuming constant NUM_PRIORITIES). | |
cbentzel
2012/01/03 19:39:09
You should document why and where this is needed i
| |
20 template<typename T> | |
21 class PriorityQueue { | |
cbentzel
2012/01/03 19:39:09
This should probably derive from NonThreadSafe or
| |
22 public: | |
23 typedef std::list<T> List; | |
24 // Note that we need iterator not const_iterator to pass to List::erase. | |
25 // When C++0x comes, this could be changed to const_iterator and const could | |
26 // be added to First, Last, and OldestLowest. | |
27 typedef typename std::list<T>::iterator ListIterator; | |
cbentzel
2012/01/03 19:39:09
ListIterator could probably be typedef'd within Po
| |
28 | |
29 // A pointer to a value stored in the queue. The pointer becomes invalid | |
30 // when the queue is destroyed or the value is erased or moved. | |
31 class Pointer { | |
32 public: | |
33 // Constructs a null pointer. | |
34 Pointer() : priority_(NUM_PRIORITIES) {} | |
35 | |
36 bool is_null() const { return priority_ == NUM_PRIORITIES; } | |
37 RequestPriority priority() const { return priority_; } | |
38 | |
39 const T& value() const { return *iterator_; } | |
40 | |
41 // Comparing to Pointer from a different PriorityQueue is undefined. | |
42 bool equals(const Pointer& other) const { | |
43 return (priority_ == other.priority_) && (iterator_ == other.iterator_); | |
44 } | |
45 | |
46 protected: | |
47 friend class PriorityQueue; | |
48 | |
49 Pointer(RequestPriority priority, const ListIterator& iterator) | |
50 : priority_(priority), iterator_(iterator) {} | |
51 | |
52 RequestPriority priority_; | |
53 ListIterator iterator_; | |
54 }; | |
55 | |
56 PriorityQueue() : size_(0) {} | |
57 | |
58 // Adds |value| with |priority| to the queue. Returns a pointer to the | |
59 // created element. | |
60 Pointer Insert(const T& value, RequestPriority priority) { | |
61 ++size_; | |
62 List& list = lists_[priority]; | |
63 return Pointer(priority, list.insert(list.end(), value)); | |
64 } | |
65 | |
66 // Removes the value pointed by |pointer| from the queue. All pointers to this | |
67 // value including |pointer| become invalid. | |
68 void Erase(const Pointer& pointer) { | |
cbentzel
2012/01/03 19:39:09
Should this be a member on Pointer?
Also, should
cbentzel
2012/01/03 19:39:09
It feels like this class could benefit with some d
szym
2012/01/03 20:48:52
Since First returns a temporary, to allow queue.Er
| |
69 --size_; | |
70 lists_[pointer.priority_].erase(pointer.iterator_); | |
71 } | |
72 | |
73 // Returns a pointer to the first value in order or a null-pointer if empty. | |
74 Pointer First() { | |
75 for (size_t priority = 0; priority < NUM_PRIORITIES; ++priority) { | |
76 List& list = lists_[priority]; | |
77 if (!list.empty()) | |
78 return Pointer(static_cast<RequestPriority>(priority), list.begin()); | |
79 } | |
80 return Pointer(); | |
81 } | |
82 | |
83 // Returns a pointer to the last value in order or a null-pointer if empty. | |
84 Pointer Last() { | |
85 for (size_t i = 0; i < NUM_PRIORITIES; ++i) { | |
cbentzel
2012/01/03 19:39:09
Why not do a i = NUM_PRIORITIES; i > 0; --i?
Need
| |
86 size_t priority = NUM_PRIORITIES - i - 1; | |
87 List& list = lists_[priority]; | |
88 if (!list.empty()) | |
89 return Pointer(static_cast<RequestPriority>(priority), --list.end()); | |
90 } | |
91 return Pointer(); | |
92 } | |
93 | |
94 // Returns a pointer to the oldest, lowest value or a null-pointer if empty. | |
95 Pointer OldestLowest() { | |
96 for (size_t i = 0; i < NUM_PRIORITIES; ++i) { | |
97 size_t priority = NUM_PRIORITIES - i - 1; | |
98 List& list = lists_[priority]; | |
99 if (!list.empty()) | |
100 return Pointer(static_cast<RequestPriority>(priority), list.begin()); | |
101 } | |
102 return Pointer(); | |
103 } | |
104 | |
105 // Empties the queue. All pointers become invalid. | |
106 void Clear() { | |
107 for (size_t priority = 0; priority < NUM_PRIORITIES; ++priority) | |
108 lists_[priority].clear(); | |
109 size_ = 0u; | |
110 } | |
111 | |
112 // Returns number of queued values. | |
113 size_t size() const { | |
114 return size_; | |
115 } | |
116 | |
117 private: | |
118 List lists_[NUM_PRIORITIES]; | |
119 size_t size_; | |
120 }; | |
121 | |
122 } // namespace net | |
123 | |
124 #endif // NET_BASE_PRIORITY_QUEUE_H_ | |
125 | |
OLD | NEW |