summaryrefslogtreecommitdiff
path: root/chromium/net/base/priority_queue.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/base/priority_queue.h')
-rw-r--r--chromium/net/base/priority_queue.h86
1 files changed, 69 insertions, 17 deletions
diff --git a/chromium/net/base/priority_queue.h b/chromium/net/base/priority_queue.h
index c6845805354..9b17d61b21e 100644
--- a/chromium/net/base/priority_queue.h
+++ b/chromium/net/base/priority_queue.h
@@ -50,9 +50,16 @@ class PriorityQueue : public base::NonThreadSafe {
#if !defined(NDEBUG)
id_ = static_cast<unsigned>(-1);
#endif
+ // TODO(syzm)
+ // An uninitialized iterator behaves like an uninitialized pointer as per
+ // the STL docs. The fix below is ugly and should possibly be replaced
+ // with a better approach.
+ iterator_ = dummy_empty_list_.end();
}
- Pointer(const Pointer& p) : priority_(p.priority_), iterator_(p.iterator_) {
+ Pointer(const Pointer& p)
+ : priority_(p.priority_),
+ iterator_(p.iterator_) {
#if !defined(NDEBUG)
id_ = p.id_;
#endif
@@ -90,13 +97,16 @@ class PriorityQueue : public base::NonThreadSafe {
private:
friend class PriorityQueue;
- // Note that we need iterator not const_iterator to pass to List::erase.
- // When C++0x comes, this could be changed to const_iterator and const could
- // be added to First, Last, and OldestLowest.
+ // Note that we need iterator and not const_iterator to pass to
+ // List::erase. When C++11 is turned on for Chromium, this could
+ // be changed to const_iterator and the const_casts in the rest of
+ // the file can be removed.
typedef typename PriorityQueue::List::iterator ListIterator;
static const Priority kNullPriority = static_cast<Priority>(-1);
+ // It is guaranteed that Pointer will treat |iterator| as a
+ // const_iterator.
Pointer(Priority priority, const ListIterator& iterator)
: priority_(priority), iterator_(iterator) {
#if !defined(NDEBUG)
@@ -106,6 +116,10 @@ class PriorityQueue : public base::NonThreadSafe {
Priority priority_;
ListIterator iterator_;
+ // The STL iterators when uninitialized are like uninitialized pointers
+ // which cause crashes when assigned to other iterators. We need to
+ // initialize a NULL iterator to the end of a valid list.
+ List dummy_empty_list_;
#if !defined(NDEBUG)
// Used by the queue to check if a Pointer is valid.
@@ -175,50 +189,80 @@ class PriorityQueue : public base::NonThreadSafe {
// Returns a pointer to the first value of minimum priority or a null-pointer
// if empty.
- Pointer FirstMin() {
+ Pointer FirstMin() const {
DCHECK(CalledOnValidThread());
for (size_t i = 0; i < lists_.size(); ++i) {
- if (!lists_[i].empty())
- return Pointer(i, lists_[i].begin());
+ List* list = const_cast<List*>(&lists_[i]);
+ if (!list->empty())
+ return Pointer(i, list->begin());
}
return Pointer();
}
// Returns a pointer to the last value of minimum priority or a null-pointer
// if empty.
- Pointer LastMin() {
+ Pointer LastMin() const {
DCHECK(CalledOnValidThread());
for (size_t i = 0; i < lists_.size(); ++i) {
- if (!lists_[i].empty())
- return Pointer(i, --lists_[i].end());
+ List* list = const_cast<List*>(&lists_[i]);
+ if (!list->empty())
+ return Pointer(i, --list->end());
}
return Pointer();
}
// Returns a pointer to the first value of maximum priority or a null-pointer
// if empty.
- Pointer FirstMax() {
+ Pointer FirstMax() const {
DCHECK(CalledOnValidThread());
for (size_t i = lists_.size(); i > 0; --i) {
size_t index = i - 1;
- if (!lists_[index].empty())
- return Pointer(index, lists_[index].begin());
+ List* list = const_cast<List*>(&lists_[index]);
+ if (!list->empty())
+ return Pointer(index, list->begin());
}
return Pointer();
}
// Returns a pointer to the last value of maximum priority or a null-pointer
// if empty.
- Pointer LastMax() {
+ Pointer LastMax() const {
DCHECK(CalledOnValidThread());
for (size_t i = lists_.size(); i > 0; --i) {
size_t index = i - 1;
- if (!lists_[index].empty())
- return Pointer(index, --lists_[index].end());
+ List* list = const_cast<List*>(&lists_[index]);
+ if (!list->empty())
+ return Pointer(index, --list->end());
}
return Pointer();
}
+ // Given an ordering of the values in this queue by decreasing
+ // priority and then FIFO, returns a pointer to the value following
+ // the value of the given pointer (which must be non-NULL).
+ //
+ // (One could also implement GetNextTowardsFirstMin() [decreasing
+ // priority, then reverse FIFO] as well as
+ // GetNextTowards{First,Last}Max() [increasing priority, then
+ // {,reverse} FIFO].)
+ Pointer GetNextTowardsLastMin(const Pointer& pointer) const {
+ DCHECK(CalledOnValidThread());
+ DCHECK(!pointer.is_null());
+ DCHECK_LT(pointer.priority_, lists_.size());
+
+ typename Pointer::ListIterator it = pointer.iterator_;
+ Priority priority = pointer.priority_;
+ DCHECK(it != lists_[priority].end());
+ ++it;
+ while (it == lists_[priority].end()) {
+ if (priority == 0u)
+ return Pointer();
+ --priority;
+ it = const_cast<List*>(&lists_[priority])->begin();
+ }
+ return Pointer(priority, it);
+ }
+
// Empties the queue. All pointers become invalid.
void Clear() {
DCHECK(CalledOnValidThread());
@@ -232,7 +276,15 @@ class PriorityQueue : public base::NonThreadSafe {
}
// Returns the number of priorities the queue supports.
- size_t num_priorities() const { return lists_.size(); }
+ size_t num_priorities() const {
+ DCHECK(CalledOnValidThread());
+ return lists_.size();
+ }
+
+ bool empty() const {
+ DCHECK(CalledOnValidThread());
+ return size_ == 0;
+ }
// Returns number of queued values.
size_t size() const {