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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/base/intrusive_heap.h

Issue 2419793002: [Reland] Optimize blink scheduler with an intrusive heap (Closed)
Patch Set: Fix bug in MoveHoleDown Created 4 years, 2 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
OLDNEW
(Empty)
1 // Copyright 2016 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 THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_INTRUSIVE_HEAP_H_
6 #define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_INTRUSIVE_HEAP_H_
7
8 #include <vector>
9
10 #include "base/logging.h"
11 #include "public/platform/WebCommon.h"
haraken 2016/10/14 13:12:26 This is unused.
alex clarke (OOO till 29th) 2016/10/14 13:55:35 It's needed for BLINK_PLATFORM_EXPORT
12
13 namespace blink {
14 namespace scheduler {
15
16 // A standard min-heap with the following assumptions:
17 // 1. T has operator <=
18 // 2. T has method void SetHeapIndex(size_t index)
19 template <typename T>
20 class BLINK_PLATFORM_EXPORT IntrusiveHeap {
haraken 2016/10/14 13:12:25 You might want to add a couple of more DCHECKs (to
haraken 2016/10/14 13:12:26 I'm just curious but what's a difference between a
alex clarke (OOO till 29th) 2016/10/14 13:55:35 It's a binary heap that requires the element to st
alex clarke (OOO till 29th) 2016/10/14 14:52:38 Thanks for making that suggestion, it revealed a b
21 public:
22 IntrusiveHeap() : nodes_(4), size_(0) {}
haraken 2016/10/14 13:12:25 Add a comment about why 4.
alex clarke (OOO till 29th) 2016/10/14 13:55:35 Done.
23
24 bool empty() const { return size_ == 0; }
25
26 size_t size() const { return size_; }
27
28 void clear() {
29 nodes_.resize(4);
30 size_ = 0;
31 }
32
33 const T& min() const {
34 DCHECK_GE(size_, 1u);
35 return nodes_[1];
36 }
37
38 void eraseMin() {
Sami 2016/10/14 07:26:16 nit: EraseMin/ExtractMin/etc. (I think we should j
alex clarke (OOO till 29th) 2016/10/14 13:55:35 For containers my preference is stl style where th
39 DCHECK_GE(size_, 1u);
40 size_t top_index = size_--;
41 if (!empty())
42 MoveHoleDown(1u, nodes_[top_index]);
43 }
44
45 T extractMin() {
haraken 2016/10/14 13:12:25 Can we remove eraseMin? extractMin would be enough
alex clarke (OOO till 29th) 2016/10/14 13:55:35 I had thought we'd end up using this but it didn't
46 DCHECK_GE(size_, 1u);
47 T top = std::move(nodes_[1]);
48 size_t top_index = size_--;
49 if (!empty())
50 MoveHoleDown(1u, nodes_[top_index]);
51 return std::move(top);
52 }
53
54 void insert(T element) {
55 size_++;
56 if (size_ >= nodes_.size())
57 nodes_.resize(size_ * 2);
58 HeapifyUp(size_, element);
59 }
60
61 void eraseHeapIndex(size_t index) {
62 DCHECK_GE(index, 1u);
63 DCHECK_LE(index, size_);
64 size_t top_index = size_--;
65 if (empty() || top_index == index)
66 return;
67 if (nodes_[index] <= nodes_[top_index]) {
68 MoveHoleDown(index, nodes_[top_index]);
69 } else {
70 HeapifyUp(index, nodes_[top_index]);
71 }
72 }
73
74 void replaceMin(T element) {
75 // Note |element| might not be a leaf node so we can't use MoveHoleDown.
76 HeapifyDown(1u, element);
77 }
78
79 const std::vector<T>& GetNodesForTesting() const { return nodes_; }
80
81 private:
82 void MoveNode(size_t from, size_t to) {
83 DCHECK_GE(from, 1u);
84 DCHECK_LE(from, size_);
85 DCHECK_GE(to, 1u);
86 DCHECK_LE(to, size_);
87 DCHECK_NE(from, to);
88 nodes_[to] = std::move(nodes_[from]);
89 nodes_[to].SetHeapIndex(to);
90 }
91
92 void HeapifyUp(size_t pos, T& element) {
Sami 2016/10/14 07:26:16 nit: non-const reference maybe should be a pointer
haraken 2016/10/14 13:12:25 MoveElementUp ?
alex clarke (OOO till 29th) 2016/10/14 13:55:35 I ended up calling this MoveHoleUpAndFillWithEleme
alex clarke (OOO till 29th) 2016/10/14 13:55:35 It should probably be an R value, since that bette
93 DCHECK_GE(pos, 1u);
94 DCHECK_LE(pos, size_);
95 while (pos >= 2u) {
96 size_t parent_pos = pos / 2;
97 if (nodes_[parent_pos] <= element)
98 break;
99
100 MoveNode(parent_pos, pos);
101 pos = parent_pos;
102 }
103 nodes_[pos] = std::move(element);
104 nodes_[pos].SetHeapIndex(pos);
105 }
106
107 void HeapifyDown(size_t pos, T& element) {
haraken 2016/10/14 13:12:26 MoveElementDown ?
alex clarke (OOO till 29th) 2016/10/14 13:55:35 I ended up calling this MoveHoleDownAndFillWithEle
108 DCHECK_GE(pos, 1u);
109 DCHECK_LE(pos, size_);
110 size_t child_pos = pos * 2;
111 while (child_pos < size_) {
112 if (nodes_[child_pos + 1] <= nodes_[child_pos])
113 child_pos++;
114
115 if (element <= nodes_[child_pos])
116 break;
117
118 MoveNode(child_pos, pos);
119 pos = child_pos;
120 child_pos *= 2;
121 }
122 if (child_pos == size_ && !(element <= nodes_[child_pos])) {
123 MoveNode(child_pos, pos);
124 pos = child_pos;
125 }
126 nodes_[pos] = std::move(element);
127 nodes_[pos].SetHeapIndex(pos);
128 }
129
130 // NB this is a standard optimization, as used by the STL. HeapifyDown does
haraken 2016/10/14 13:12:25 NB => Note ? BTW, we normally don't write "Note"
alex clarke (OOO till 29th) 2016/10/14 13:55:35 Done.
131 // two comparisons per level, but this only does one.
132 // NOTE |element| is assumed to be a leaf node.
133 void MoveHoleDown(size_t hole, T& element) {
134 size_t new_hole = hole * 2;
135 while (new_hole <= size_) {
136 size_t second_child = new_hole + 1;
137 if (second_child <= size_ && nodes_[second_child] <= nodes_[new_hole])
138 new_hole = second_child;
139 MoveNode(new_hole, hole);
140 hole = new_hole;
141 new_hole *= 2;
142 }
143 HeapifyUp(hole, element);
144 }
145
146 std::vector<T> nodes_; // NOTE we use 1-based indexing
147 size_t size_;
148 };
149
150 } // namespace scheduler
151 } // namespace blink
152
153 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_INTRUSIVE_HEAP_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698