1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h" 9cb93a386Sopenharmony_ci#include "src/core/SkTDPQueue.h" 10cb93a386Sopenharmony_ci#include "tests/Test.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_cinamespace { bool intless(const int& a, const int& b) { return a < b; } } 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_cistatic void simple_test(skiatest::Reporter* reporter) { 15cb93a386Sopenharmony_ci SkTDPQueue<int, intless> heap; 16cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 0 == heap.count()); 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ci heap.insert(0); 19cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 1 == heap.count()); 20cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 0 == heap.peek()); 21cb93a386Sopenharmony_ci heap.pop(); 22cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 0 == heap.count()); 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci heap.insert(0); 25cb93a386Sopenharmony_ci heap.insert(1); 26cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 2 == heap.count()); 27cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 0 == heap.peek()); 28cb93a386Sopenharmony_ci heap.pop(); 29cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 1 == heap.count()); 30cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 1 == heap.peek()); 31cb93a386Sopenharmony_ci heap.pop(); 32cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 0 == heap.count()); 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci heap.insert(2); 35cb93a386Sopenharmony_ci heap.insert(1); 36cb93a386Sopenharmony_ci heap.insert(0); 37cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 3 == heap.count()); 38cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 0 == heap.peek()); 39cb93a386Sopenharmony_ci heap.pop(); 40cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 2 == heap.count()); 41cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 1 == heap.peek()); 42cb93a386Sopenharmony_ci heap.pop(); 43cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 1 == heap.count()); 44cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 2 == heap.peek()); 45cb93a386Sopenharmony_ci heap.pop(); 46cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 0 == heap.count()); 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ci heap.insert(2); 49cb93a386Sopenharmony_ci heap.insert(3); 50cb93a386Sopenharmony_ci heap.insert(0); 51cb93a386Sopenharmony_ci heap.insert(1); 52cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 4 == heap.count()); 53cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 0 == heap.peek()); 54cb93a386Sopenharmony_ci heap.pop(); 55cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 3 == heap.count()); 56cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 1 == heap.peek()); 57cb93a386Sopenharmony_ci heap.pop(); 58cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 2 == heap.count()); 59cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 2 == heap.peek()); 60cb93a386Sopenharmony_ci heap.pop(); 61cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 1 == heap.count()); 62cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 3 == heap.peek()); 63cb93a386Sopenharmony_ci heap.pop(); 64cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 0 == heap.count()); 65cb93a386Sopenharmony_ci} 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_cistruct Mock { 68cb93a386Sopenharmony_ci int fValue; 69cb93a386Sopenharmony_ci int fPriority; 70cb93a386Sopenharmony_ci mutable int fIndex; 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci static bool LessP(Mock* const& a, Mock* const& b) { return a->fPriority < b->fPriority; } 73cb93a386Sopenharmony_ci static int* PQIndex(Mock* const& mock) { return &mock->fIndex; } 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci bool operator== (const Mock& that) const { 76cb93a386Sopenharmony_ci return fValue == that.fValue && fPriority == that.fPriority; 77cb93a386Sopenharmony_ci } 78cb93a386Sopenharmony_ci bool operator!= (const Mock& that) const { return !(*this == that); } 79cb93a386Sopenharmony_ci}; 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_civoid random_test(skiatest::Reporter* reporter) { 82cb93a386Sopenharmony_ci SkRandom random; 83cb93a386Sopenharmony_ci static const Mock kSentinel = {-1, -1, -1}; 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci for (int i = 0; i < 100; ++i) { 86cb93a386Sopenharmony_ci // Create a random set of Mock objects. 87cb93a386Sopenharmony_ci int count = random.nextULessThan(100); 88cb93a386Sopenharmony_ci SkTDArray<Mock> array; 89cb93a386Sopenharmony_ci array.setReserve(count); 90cb93a386Sopenharmony_ci for (int j = 0; j < count; ++j) { 91cb93a386Sopenharmony_ci Mock* mock = array.append(); 92cb93a386Sopenharmony_ci mock->fPriority = random.nextS(); 93cb93a386Sopenharmony_ci mock->fValue = random.nextS(); 94cb93a386Sopenharmony_ci mock->fIndex = -1; 95cb93a386Sopenharmony_ci if (*mock == kSentinel) { 96cb93a386Sopenharmony_ci array.pop(); 97cb93a386Sopenharmony_ci --j; 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci } 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ci // Stick the mock objects in the pqueue. 102cb93a386Sopenharmony_ci SkTDPQueue<Mock*, Mock::LessP, Mock::PQIndex> pq; 103cb93a386Sopenharmony_ci for (int j = 0; j < count; ++j) { 104cb93a386Sopenharmony_ci pq.insert(&array[j]); 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pq.count() == array.count()); 107cb93a386Sopenharmony_ci for (int j = 0; j < count; ++j) { 108cb93a386Sopenharmony_ci // every item should have an entry in the queue. 109cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, -1 != array[j].fIndex); 110cb93a386Sopenharmony_ci } 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci // Begin the test. 113cb93a386Sopenharmony_ci while (pq.count()) { 114cb93a386Sopenharmony_ci // Make sure the top of the queue is really the highest priority. 115cb93a386Sopenharmony_ci Mock* top = pq.peek(); 116cb93a386Sopenharmony_ci for (int k = 0; k < count; ++k) { 117cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, kSentinel == array[k] || 118cb93a386Sopenharmony_ci array[k].fPriority >= top->fPriority); 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci // Do one of three random actions: 121cb93a386Sopenharmony_ci unsigned action = random.nextULessThan(3); 122cb93a386Sopenharmony_ci switch (action) { 123cb93a386Sopenharmony_ci case 0: { // pop the top, 124cb93a386Sopenharmony_ci top = pq.peek(); 125cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, array.begin() <= top && top < array.end()); 126cb93a386Sopenharmony_ci pq.pop(); 127cb93a386Sopenharmony_ci *top = kSentinel; 128cb93a386Sopenharmony_ci break; 129cb93a386Sopenharmony_ci } 130cb93a386Sopenharmony_ci case 1: { // remove a random element, 131cb93a386Sopenharmony_ci int item; 132cb93a386Sopenharmony_ci do { 133cb93a386Sopenharmony_ci item = random.nextULessThan(count); 134cb93a386Sopenharmony_ci } while (array[item] == kSentinel); 135cb93a386Sopenharmony_ci pq.remove(&array[item]); 136cb93a386Sopenharmony_ci array[item] = kSentinel; 137cb93a386Sopenharmony_ci break; 138cb93a386Sopenharmony_ci } 139cb93a386Sopenharmony_ci case 2: { // or change an element's priority. 140cb93a386Sopenharmony_ci int item; 141cb93a386Sopenharmony_ci do { 142cb93a386Sopenharmony_ci item = random.nextULessThan(count); 143cb93a386Sopenharmony_ci } while (array[item] == kSentinel); 144cb93a386Sopenharmony_ci array[item].fPriority = random.nextS(); 145cb93a386Sopenharmony_ci pq.priorityDidChange(&array[item]); 146cb93a386Sopenharmony_ci break; 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci } 149cb93a386Sopenharmony_ci } 150cb93a386Sopenharmony_ci } 151cb93a386Sopenharmony_ci} 152cb93a386Sopenharmony_ci 153cb93a386Sopenharmony_civoid sort_test(skiatest::Reporter* reporter) { 154cb93a386Sopenharmony_ci SkRandom random; 155cb93a386Sopenharmony_ci 156cb93a386Sopenharmony_ci SkTDPQueue<Mock *, Mock::LessP, Mock::PQIndex> pqTest; 157cb93a386Sopenharmony_ci SkTDPQueue<Mock *, Mock::LessP, Mock::PQIndex> pqControl; 158cb93a386Sopenharmony_ci 159cb93a386Sopenharmony_ci // Create a random set of Mock objects and populate the test queue. 160cb93a386Sopenharmony_ci int count = random.nextULessThan(100); 161cb93a386Sopenharmony_ci SkTDArray<Mock> testArray; 162cb93a386Sopenharmony_ci testArray.setReserve(count); 163cb93a386Sopenharmony_ci for (int i = 0; i < count; i++) { 164cb93a386Sopenharmony_ci Mock *mock = testArray.append(); 165cb93a386Sopenharmony_ci mock->fPriority = random.nextS(); 166cb93a386Sopenharmony_ci mock->fValue = random.nextS(); 167cb93a386Sopenharmony_ci mock->fIndex = -1; 168cb93a386Sopenharmony_ci pqTest.insert(&testArray[i]); 169cb93a386Sopenharmony_ci } 170cb93a386Sopenharmony_ci 171cb93a386Sopenharmony_ci // Stick equivalent mock objects into the control queue. 172cb93a386Sopenharmony_ci SkTDArray<Mock> controlArray; 173cb93a386Sopenharmony_ci controlArray.setReserve(count); 174cb93a386Sopenharmony_ci for (int i = 0; i < count; i++) { 175cb93a386Sopenharmony_ci Mock *mock = controlArray.append(); 176cb93a386Sopenharmony_ci mock->fPriority = testArray[i].fPriority; 177cb93a386Sopenharmony_ci mock->fValue = testArray[i].fValue; 178cb93a386Sopenharmony_ci mock->fIndex = -1; 179cb93a386Sopenharmony_ci pqControl.insert(&controlArray[i]); 180cb93a386Sopenharmony_ci } 181cb93a386Sopenharmony_ci 182cb93a386Sopenharmony_ci // Sort the queue 183cb93a386Sopenharmony_ci pqTest.sort(); 184cb93a386Sopenharmony_ci 185cb93a386Sopenharmony_ci // Compare elements in the queue to ensure they are in sorted order 186cb93a386Sopenharmony_ci int prevPriority = pqTest.peek()->fPriority; 187cb93a386Sopenharmony_ci for (int i = 0; i < count; i++) { 188cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, i <= pqTest.at(i)->fIndex); 189cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, prevPriority <= pqTest.at(i)->fPriority); 190cb93a386Sopenharmony_ci prevPriority = pqTest.at(i)->fPriority; 191cb93a386Sopenharmony_ci } 192cb93a386Sopenharmony_ci 193cb93a386Sopenharmony_ci // Verify that after sorting the queue still produces the same result as the control queue 194cb93a386Sopenharmony_ci for (int i = 0; i < count; i++) { 195cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, *pqControl.peek() == *pqTest.peek()); 196cb93a386Sopenharmony_ci pqControl.pop(); 197cb93a386Sopenharmony_ci pqTest.pop(); 198cb93a386Sopenharmony_ci } 199cb93a386Sopenharmony_ci} 200cb93a386Sopenharmony_ci 201cb93a386Sopenharmony_ciDEF_TEST(TDPQueueTest, reporter) { 202cb93a386Sopenharmony_ci simple_test(reporter); 203cb93a386Sopenharmony_ci random_test(reporter); 204cb93a386Sopenharmony_ci sort_test(reporter); 205cb93a386Sopenharmony_ci} 206