OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2015 Google Inc. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. |
| 6 */ |
| 7 |
| 8 #include "SkTDPQueue.h" |
| 9 #include "SkRandom.h" |
| 10 #include "Test.h" |
| 11 |
| 12 namespace { bool intless(const int& a, const int& b) { return a < b; } } |
| 13 |
| 14 static void simple_test(skiatest::Reporter* reporter) { |
| 15 SkTDPQueue<int, intless> heap; |
| 16 REPORTER_ASSERT(reporter, 0 == heap.count()); |
| 17 |
| 18 heap.insert(0); |
| 19 REPORTER_ASSERT(reporter, 1 == heap.count()); |
| 20 REPORTER_ASSERT(reporter, 0 == heap.peek()); |
| 21 heap.pop(); |
| 22 REPORTER_ASSERT(reporter, 0 == heap.count()); |
| 23 |
| 24 heap.insert(0); |
| 25 heap.insert(1); |
| 26 REPORTER_ASSERT(reporter, 2 == heap.count()); |
| 27 REPORTER_ASSERT(reporter, 0 == heap.peek()); |
| 28 heap.pop(); |
| 29 REPORTER_ASSERT(reporter, 1 == heap.count()); |
| 30 REPORTER_ASSERT(reporter, 1 == heap.peek()); |
| 31 heap.pop(); |
| 32 REPORTER_ASSERT(reporter, 0 == heap.count()); |
| 33 |
| 34 heap.insert(2); |
| 35 heap.insert(1); |
| 36 heap.insert(0); |
| 37 REPORTER_ASSERT(reporter, 3 == heap.count()); |
| 38 REPORTER_ASSERT(reporter, 0 == heap.peek()); |
| 39 heap.pop(); |
| 40 REPORTER_ASSERT(reporter, 2 == heap.count()); |
| 41 REPORTER_ASSERT(reporter, 1 == heap.peek()); |
| 42 heap.pop(); |
| 43 REPORTER_ASSERT(reporter, 1 == heap.count()); |
| 44 REPORTER_ASSERT(reporter, 2 == heap.peek()); |
| 45 heap.pop(); |
| 46 REPORTER_ASSERT(reporter, 0 == heap.count()); |
| 47 |
| 48 heap.insert(2); |
| 49 heap.insert(3); |
| 50 heap.insert(0); |
| 51 heap.insert(1); |
| 52 REPORTER_ASSERT(reporter, 4 == heap.count()); |
| 53 REPORTER_ASSERT(reporter, 0 == heap.peek()); |
| 54 heap.pop(); |
| 55 REPORTER_ASSERT(reporter, 3 == heap.count()); |
| 56 REPORTER_ASSERT(reporter, 1 == heap.peek()); |
| 57 heap.pop(); |
| 58 REPORTER_ASSERT(reporter, 2 == heap.count()); |
| 59 REPORTER_ASSERT(reporter, 2 == heap.peek()); |
| 60 heap.pop(); |
| 61 REPORTER_ASSERT(reporter, 1 == heap.count()); |
| 62 REPORTER_ASSERT(reporter, 3 == heap.peek()); |
| 63 heap.pop(); |
| 64 REPORTER_ASSERT(reporter, 0 == heap.count()); |
| 65 } |
| 66 |
| 67 struct Dummy { |
| 68 int fValue; |
| 69 int fPriority; |
| 70 mutable int fIndex; |
| 71 |
| 72 static bool LessP(Dummy* const& a, Dummy* const& b) { return a->fPriority <
b->fPriority; } |
| 73 static int* PQIndex(Dummy* const& dummy) { return &dummy->fIndex; } |
| 74 |
| 75 bool operator== (const Dummy& that) const { |
| 76 return fValue == that.fValue && fPriority == that.fPriority; |
| 77 } |
| 78 bool operator!= (const Dummy& that) const { return !(*this == that); } |
| 79 }; |
| 80 |
| 81 void random_test(skiatest::Reporter* reporter) { |
| 82 SkRandom random; |
| 83 static const Dummy kSentinel = {-1, -1, -1}; |
| 84 |
| 85 for (int i = 0; i < 100; ++i) { |
| 86 // Create a random set of Dummy objects. |
| 87 int count = random.nextULessThan(100); |
| 88 SkTDArray<Dummy> array; |
| 89 array.setReserve(count); |
| 90 for (int j = 0; j < count; ++j) { |
| 91 Dummy* dummy = array.append(); |
| 92 dummy->fPriority = random.nextS(); |
| 93 dummy->fValue = random.nextS(); |
| 94 dummy->fIndex = -1; |
| 95 if (*dummy == kSentinel) { |
| 96 array.pop(); |
| 97 --j; |
| 98 } |
| 99 } |
| 100 |
| 101 // Stick the dummy objects in the pqueue. |
| 102 SkTDPQueue<Dummy*, Dummy::LessP, Dummy::PQIndex> pq; |
| 103 for (int j = 0; j < count; ++j) { |
| 104 pq.insert(&array[j]); |
| 105 } |
| 106 REPORTER_ASSERT(reporter, pq.count() == array.count()); |
| 107 for (int j = 0; j < count; ++j) { |
| 108 // every item should have an entry in the queue. |
| 109 REPORTER_ASSERT(reporter, -1 != array[j].fIndex); |
| 110 } |
| 111 |
| 112 // Begin the test. |
| 113 while (pq.count()) { |
| 114 // Make sure the top of the queue is really the highest priority. |
| 115 Dummy* top = pq.peek(); |
| 116 for (int k = 0; k < count; ++k) { |
| 117 REPORTER_ASSERT(reporter, kSentinel == array[k] || |
| 118 array[k].fPriority >= top->fPriority
); |
| 119 } |
| 120 // Do one of three random actions: |
| 121 unsigned action = random.nextULessThan(3); |
| 122 switch (action) { |
| 123 case 0: { // pop the top, |
| 124 Dummy* top = pq.peek(); |
| 125 REPORTER_ASSERT(reporter, array.begin() <= top && top < arra
y.end()); |
| 126 pq.pop(); |
| 127 *top = kSentinel; |
| 128 break; |
| 129 } |
| 130 case 1: { // remove a random element, |
| 131 int item; |
| 132 do { |
| 133 item = random.nextULessThan(count); |
| 134 } while (array[item] == kSentinel); |
| 135 pq.remove(&array[item]); |
| 136 array[item] = kSentinel; |
| 137 break; |
| 138 } |
| 139 case 2: { // or change an element's priority. |
| 140 int item; |
| 141 do { |
| 142 item = random.nextULessThan(count); |
| 143 } while (array[item] == kSentinel); |
| 144 array[item].fPriority = random.nextS(); |
| 145 pq.priorityDidChange(&array[item]); |
| 146 break; |
| 147 } |
| 148 } |
| 149 } |
| 150 } |
| 151 } |
| 152 |
| 153 DEF_TEST(TDPQueueTest, reporter) { |
| 154 simple_test(reporter); |
| 155 random_test(reporter); |
| 156 } |
OLD | NEW |