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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/base/intrusive_heap_unittest.cc

Issue 2419793002: [Reland] Optimize blink scheduler with an intrusive heap (Closed)
Patch Set: Fixed perf test and increaced test coverage Created 4 years, 1 month 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 #include "platform/scheduler/base/intrusive_heap.h"
6 #include "testing/gmock/include/gmock/gmock.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8
9 namespace blink {
10 namespace scheduler {
11 namespace {
12
13 struct TestElement {
14 int key;
15 HeapHandle* handle;
16
17 bool operator<=(const TestElement& other) const { return key <= other.key; }
18
19 void SetHeapHandle(HeapHandle h) {
20 if (handle)
21 *handle = h;
22 }
23
24 void ClearHeapHandle() {
25 if (handle)
26 *handle = HeapHandle();
27 }
28 };
29
30 } // namespace
31
32 using IntrusiveHeapTest = ::testing::Test;
33
34 TEST(IntrusiveHeapTest, Basic) {
35 IntrusiveHeap<TestElement> heap;
36
37 EXPECT_TRUE(heap.empty());
38 EXPECT_EQ(0u, heap.size());
39 }
40
41 TEST(IntrusiveHeapTest, Clear) {
42 IntrusiveHeap<TestElement> heap;
43 HeapHandle index1;
44
45 heap.insert({11, &index1});
46 EXPECT_EQ(1u, heap.size());
47 EXPECT_TRUE(index1.IsValid());
48
49 heap.clear();
50 EXPECT_EQ(0u, heap.size());
51 EXPECT_FALSE(index1.IsValid());
52 }
53
54 TEST(IntrusiveHeapTest, Destructor) {
55 HeapHandle index1;
56
57 {
58 IntrusiveHeap<TestElement> heap;
59
60 heap.insert({11, &index1});
61 EXPECT_EQ(1u, heap.size());
62 EXPECT_TRUE(index1.IsValid());
63 }
64
65 EXPECT_FALSE(index1.IsValid());
66 }
67
68 TEST(IntrusiveHeapTest, Min) {
69 IntrusiveHeap<TestElement> heap;
70
71 heap.insert({9, nullptr});
72 heap.insert({10, nullptr});
73 heap.insert({8, nullptr});
74 heap.insert({2, nullptr});
75 heap.insert({7, nullptr});
76 heap.insert({15, nullptr});
77 heap.insert({22, nullptr});
78 heap.insert({3, nullptr});
79
80 EXPECT_FALSE(heap.empty());
81 EXPECT_EQ(8u, heap.size());
82 EXPECT_EQ(2, heap.min().key);
83 }
84
85 TEST(IntrusiveHeapTest, InsertAscending) {
86 IntrusiveHeap<TestElement> heap;
87 HeapHandle index1;
88
89 for (int i = 0; i < 50; i++)
90 heap.insert({i, nullptr});
91
92 EXPECT_EQ(0, heap.min().key);
93 EXPECT_EQ(50u, heap.size());
94 }
95
96 TEST(IntrusiveHeapTest, InsertDescending) {
97 IntrusiveHeap<TestElement> heap;
98
99 for (int i = 0; i < 50; i++)
100 heap.insert({50 - i, nullptr});
101
102 EXPECT_EQ(1, heap.min().key);
103 EXPECT_EQ(50u, heap.size());
104 }
105
106 TEST(IntrusiveHeapTest, HeapIndex) {
107 IntrusiveHeap<TestElement> heap;
108 HeapHandle index5;
109 HeapHandle index4;
110 HeapHandle index3;
111 HeapHandle index2;
112 HeapHandle index1;
113
114 EXPECT_FALSE(index1.IsValid());
115 EXPECT_FALSE(index2.IsValid());
116 EXPECT_FALSE(index3.IsValid());
117 EXPECT_FALSE(index4.IsValid());
118 EXPECT_FALSE(index5.IsValid());
119
120 heap.insert({15, &index5});
121 heap.insert({14, &index4});
122 heap.insert({13, &index3});
123 heap.insert({12, &index2});
124 heap.insert({11, &index1});
125
126 EXPECT_TRUE(index1.IsValid());
127 EXPECT_TRUE(index2.IsValid());
128 EXPECT_TRUE(index3.IsValid());
129 EXPECT_TRUE(index4.IsValid());
130 EXPECT_TRUE(index5.IsValid());
131
132 EXPECT_FALSE(heap.empty());
133 }
134
135 TEST(IntrusiveHeapTest, Pop) {
136 IntrusiveHeap<TestElement> heap;
137 HeapHandle index1;
138 HeapHandle index2;
139
140 heap.insert({11, &index1});
141 heap.insert({12, &index2});
142 EXPECT_EQ(2u, heap.size());
143 EXPECT_TRUE(index1.IsValid());
144 EXPECT_TRUE(index2.IsValid());
145
146 heap.pop();
147 EXPECT_EQ(1u, heap.size());
148 EXPECT_FALSE(index1.IsValid());
149 EXPECT_TRUE(index2.IsValid());
150
151 heap.pop();
152 EXPECT_EQ(0u, heap.size());
153 EXPECT_FALSE(index1.IsValid());
154 EXPECT_FALSE(index2.IsValid());
155 }
156
157 TEST(IntrusiveHeapTest, PopMany) {
158 IntrusiveHeap<TestElement> heap;
159
160 for (int i = 0; i < 500; i++)
161 heap.insert({i, nullptr});
162
163 EXPECT_FALSE(heap.empty());
164 EXPECT_EQ(500u, heap.size());
165 for (int i = 0; i < 500; i++) {
166 EXPECT_EQ(i, heap.min().key);
167 heap.pop();
168 }
169 EXPECT_TRUE(heap.empty());
170 }
171
172 TEST(IntrusiveHeapTest, Erase) {
173 IntrusiveHeap<TestElement> heap;
174
175 HeapHandle index12;
176
177 heap.insert({15, nullptr});
178 heap.insert({14, nullptr});
179 heap.insert({13, nullptr});
180 heap.insert({12, &index12});
181 heap.insert({11, nullptr});
182
183 EXPECT_EQ(5u, heap.size());
184 EXPECT_TRUE(index12.IsValid());
185 heap.erase(index12);
186 EXPECT_EQ(4u, heap.size());
187 EXPECT_FALSE(index12.IsValid());
188
189 EXPECT_EQ(11, heap.min().key);
190 heap.pop();
191 EXPECT_EQ(13, heap.min().key);
192 heap.pop();
193 EXPECT_EQ(14, heap.min().key);
194 heap.pop();
195 EXPECT_EQ(15, heap.min().key);
196 heap.pop();
197 EXPECT_TRUE(heap.empty());
198 }
199
200 TEST(IntrusiveHeapTest, ReplaceMin) {
201 IntrusiveHeap<TestElement> heap;
202
203 for (int i = 0; i < 500; i++)
204 heap.insert({500 - i, nullptr});
205
206 EXPECT_EQ(1, heap.min().key);
207
208 for (int i = 0; i < 500; i++)
209 heap.ReplaceMin({1000 + i, nullptr});
210
211 EXPECT_EQ(1000, heap.min().key);
212 }
213
214 TEST(IntrusiveHeapTest, ReplaceMinWithNonLeafNode) {
215 IntrusiveHeap<TestElement> heap;
216
217 for (int i = 0; i < 50; i++) {
218 heap.insert({i, nullptr});
219 heap.insert({200 + i, nullptr});
220 }
221
222 EXPECT_EQ(0, heap.min().key);
223
224 for (int i = 0; i < 50; i++)
225 heap.ReplaceMin({100 + i, nullptr});
226
227 for (int i = 0; i < 50; i++) {
228 EXPECT_EQ((100 + i), heap.min().key);
229 heap.pop();
230 }
231 for (int i = 0; i < 50; i++) {
232 EXPECT_EQ((200 + i), heap.min().key);
233 heap.pop();
234 }
235 EXPECT_TRUE(heap.empty());
236 }
237
238 TEST(IntrusiveHeapTest, ReplaceMinCheckAllFinalPositions) {
239 HeapHandle index[100];
240
241 for (int j = -1; j <= 201; j += 2) {
242 IntrusiveHeap<TestElement> heap;
243 for (size_t i = 0; i < 100; i++) {
244 heap.insert({static_cast<int>(i) * 2, &index[i]});
245 }
246
247 heap.ReplaceMin({j, &index[40]});
248
249 int prev = -2;
250 while (!heap.empty()) {
251 DCHECK_GT(heap.min().key, prev);
252 DCHECK(heap.min().key == j || (heap.min().key % 2) == 0);
253 DCHECK_NE(heap.min().key, 0);
254 prev = heap.min().key;
255 heap.pop();
256 }
257 }
258 }
259
260 TEST(IntrusiveHeapTest, ChangeKeyUp) {
261 IntrusiveHeap<TestElement> heap;
262 HeapHandle index[10];
263
264 for (size_t i = 0; i < 10; i++) {
265 heap.insert({static_cast<int>(i) * 2, &index[i]});
266 }
267
268 heap.ChangeKey(index[5], {17, &index[5]});
269
270 std::vector<int> results;
271 while (!heap.empty()) {
272 results.push_back(heap.min().key);
273 heap.pop();
274 }
275
276 EXPECT_THAT(results, testing::ElementsAre(0, 2, 4, 6, 8, 12, 14, 16, 17, 18));
277 }
278
279 TEST(IntrusiveHeapTest, ChangeKeyUpButDoesntMove) {
280 IntrusiveHeap<TestElement> heap;
281 HeapHandle index[10];
282
283 for (size_t i = 0; i < 10; i++) {
284 heap.insert({static_cast<int>(i) * 2, &index[i]});
285 }
286
287 heap.ChangeKey(index[5], {11, &index[5]});
288
289 std::vector<int> results;
290 while (!heap.empty()) {
291 results.push_back(heap.min().key);
292 heap.pop();
293 }
294
295 EXPECT_THAT(results, testing::ElementsAre(0, 2, 4, 6, 8, 11, 12, 14, 16, 18));
296 }
297
298 TEST(IntrusiveHeapTest, ChangeKeyDown) {
299 IntrusiveHeap<TestElement> heap;
300 HeapHandle index[10];
301
302 for (size_t i = 0; i < 10; i++) {
303 heap.insert({static_cast<int>(i) * 2, &index[i]});
304 }
305
306 heap.ChangeKey(index[5], {1, &index[5]});
307
308 std::vector<int> results;
309 while (!heap.empty()) {
310 results.push_back(heap.min().key);
311 heap.pop();
312 }
313
314 EXPECT_THAT(results, testing::ElementsAre(0, 1, 2, 4, 6, 8, 12, 14, 16, 18));
315 }
316
317 TEST(IntrusiveHeapTest, ChangeKeyDownButDoesntMove) {
318 IntrusiveHeap<TestElement> heap;
319 HeapHandle index[10];
320
321 for (size_t i = 0; i < 10; i++) {
322 heap.insert({static_cast<int>(i) * 2, &index[i]});
323 }
324
325 heap.ChangeKey(index[5], {9, &index[5]});
326
327 std::vector<int> results;
328 while (!heap.empty()) {
329 results.push_back(heap.min().key);
330 heap.pop();
331 }
332
333 EXPECT_THAT(results, testing::ElementsAre(0, 2, 4, 6, 8, 9, 12, 14, 16, 18));
334 }
335
336 TEST(IntrusiveHeapTest, ChangeKeyCheckAllFinalPositions) {
337 HeapHandle index[100];
338
339 for (int j = -1; j <= 201; j += 2) {
340 IntrusiveHeap<TestElement> heap;
341 for (size_t i = 0; i < 100; i++) {
342 heap.insert({static_cast<int>(i) * 2, &index[i]});
343 }
344
345 heap.ChangeKey(index[40], {j, &index[40]});
346
347 int prev = -2;
348 while (!heap.empty()) {
349 DCHECK_GT(heap.min().key, prev);
350 DCHECK(heap.min().key == j || (heap.min().key % 2) == 0);
351 DCHECK_NE(heap.min().key, 80);
352 prev = heap.min().key;
353 heap.pop();
354 }
355 }
356 }
357
358 } // namespace scheduler
359 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698