@@ -10,8 +10,6 @@ using namespace swift;
10
10
11
11
namespace {
12
12
13
- enum EntryOrder { priorityOrder, reverseCreationOrder };
14
-
15
13
struct Entry {
16
14
unsigned id;
17
15
unsigned value;
@@ -42,24 +40,18 @@ class EntryFactory {
42
40
// / \param reverseCreationOrder - if true, then order equal-value
43
41
// / nodes in the reverse of creation order; otherwise
44
42
// / creator order of creation order
45
- void sort (EntryOrder order) {
46
- if (order == priorityOrder) {
47
- std::sort (entries.begin (), entries.end (),
48
- [=](const std::unique_ptr<Entry> &lhs,
49
- const std::unique_ptr<Entry> &rhs) {
50
- if (lhs->value != rhs->value )
51
- return lhs->value < rhs->value ;
52
- return lhs->id < rhs->id ;
53
- });
54
- } else {
55
- std::sort (
56
- entries.begin (), entries.end (),
57
- [=](const std::unique_ptr<Entry> &lhs,
58
- const std::unique_ptr<Entry> &rhs) { return lhs->id > rhs->id ; });
59
- }
43
+ void sort () {
44
+ std::sort (entries.begin (), entries.end (),
45
+ [=](const std::unique_ptr<Entry> &lhs,
46
+ const std::unique_ptr<Entry> &rhs) {
47
+ if (lhs->value != rhs->value )
48
+ return lhs->value < rhs->value ;
49
+ return lhs->id < rhs->id ;
50
+ });
60
51
}
61
52
62
- void checkSameAs (Entry *list) {
53
+ void checkSameAs (Entry *list, unsigned line) {
54
+ std::cout << " <<< check " << line << std::endl;
63
55
for (auto &entry : entries) {
64
56
std::cout << " " << list->value << " (" << list->id << " )\n " ;
65
57
assert (list == entry.get ());
@@ -79,34 +71,29 @@ struct EntryListTraits {
79
71
}
80
72
};
81
73
82
- using EntrySimpleQueue = SimpleQueue<Entry *, EntryListTraits>;
83
74
using EntryPriorityQueue = PriorityQueue<Entry *, EntryListTraits>;
84
75
85
- static void runPrependTest () {
86
- std::cout << " runPrependTest()" << std::endl;
87
- EntryFactory entries;
88
- EntrySimpleQueue queue;
89
- assert (!queue.head );
90
- assert (!queue.tail );
91
-
92
- auto first = entries.create (3 );
93
- queue.prepend (first);
94
- assert (queue.head == first);
95
- assert (queue.tail == first);
76
+ struct ListBuilder {
77
+ Entry *head;
78
+ Entry **pTail;
96
79
97
- auto second = entries.create (0 );
98
- queue.prepend (second);
99
- assert (queue.head == second);
100
- assert (queue.tail == first);
80
+ ListBuilder (): head(), pTail(&head) {}
81
+ ListBuilder (ListBuilder const &) = delete ;
82
+ ListBuilder (ListBuilder &&) = delete ;
101
83
102
- auto third = entries.create (2 );
103
- queue.prepend (third);
104
- assert (queue.head == third);
105
- assert (queue.tail == first);
84
+ void append (Entry *e) {
85
+ *pTail = e;
86
+ e->next = nullptr ;
87
+ pTail = &e->next ;
88
+ }
106
89
107
- entries.sort (reverseCreationOrder);
108
- entries.checkSameAs (queue.head );
109
- }
90
+ Entry *take () {
91
+ Entry* result = head;
92
+ head = nullptr ;
93
+ pTail = &head;
94
+ return result;
95
+ }
96
+ };
110
97
111
98
static void runEnqueueDequeueTest () {
112
99
std::cout << " runEnqueueDequeueTest()" << std::endl;
@@ -150,15 +137,15 @@ static void runEnqueueDequeueTest() {
150
137
assert (queue.tails [2 ] == fourth);
151
138
assert (queue.tails [3 ] == second);
152
139
153
- entries.sort (priorityOrder );
154
- entries.checkSameAs (queue.head );
140
+ entries.sort ();
141
+ entries.checkSameAs (queue.head , __LINE__ );
155
142
156
143
auto pop = [&](Entry *expected) {
157
144
auto e = queue.dequeue ();
158
145
assert (e == expected);
159
146
entries.remove (e);
160
- entries.sort (priorityOrder );
161
- entries.checkSameAs (queue.head );
147
+ entries.sort ();
148
+ entries.checkSameAs (queue.head , __LINE__ );
162
149
};
163
150
164
151
pop (third);
@@ -197,24 +184,73 @@ static void runEnqueueDequeueTest() {
197
184
assert (!queue.tails [3 ]);
198
185
}
199
186
200
- static void runConcreteTests () {
201
- runPrependTest ();
202
- runEnqueueDequeueTest ();
203
- }
187
+ static void runEnqueueContentsOfTest () {
188
+ std::cout << " runEnqueueContentsOfTest()" << std::endl;
189
+ EntryFactory entries;
190
+ EntryPriorityQueue queue;
191
+ ListBuilder builder;
192
+ assert (!queue.head );
193
+ assert (!queue.tails [0 ]);
194
+ assert (!queue.tails [1 ]);
195
+ assert (!queue.tails [2 ]);
196
+ assert (!queue.tails [3 ]);
204
197
205
- struct TestConfig {
206
- unsigned numTests;
207
- unsigned maxEntries;
208
- };
198
+ queue.enqueueContentsOf (builder.take ());
199
+ assert (!queue.head );
200
+ assert (!queue.tails [0 ]);
201
+ assert (!queue.tails [1 ]);
202
+ assert (!queue.tails [2 ]);
203
+ assert (!queue.tails [3 ]);
204
+
205
+ auto first = entries.create (3 );
206
+ builder.append (first);
207
+ auto second = entries.create (3 );
208
+ builder.append (second);
209
+ auto third = entries.create (1 );
210
+ builder.append (third);
211
+ auto fourth = entries.create (2 );
212
+ builder.append (fourth);
213
+ auto fifth = entries.create (2 );
214
+ builder.append (fifth);
215
+ auto sixth = entries.create (1 );
216
+ builder.append (sixth);
217
+
218
+ queue.enqueueContentsOf (builder.take ());
219
+ assert (queue.head == third);
220
+ assert (!queue.tails [0 ]);
221
+ assert (queue.tails [1 ] == sixth);
222
+ assert (queue.tails [2 ] == fifth);
223
+ assert (queue.tails [3 ] == second);
224
+ entries.sort ();
225
+ entries.checkSameAs (queue.head , __LINE__);
226
+
227
+ auto seventh = entries.create (0 );
228
+ builder.append (seventh);
229
+ auto eighth = entries.create (0 );
230
+ builder.append (eighth);
231
+ auto ninth = entries.create (0 );
232
+ builder.append (ninth);
233
+ auto tenth = entries.create (3 );
234
+ builder.append (tenth);
235
+ queue.enqueueContentsOf (builder.take ());
236
+
237
+ assert (queue.head == seventh);
238
+ assert (queue.tails [0 ] == ninth);
239
+ assert (queue.tails [1 ] == sixth);
240
+ assert (queue.tails [2 ] == fifth);
241
+ assert (queue.tails [3 ] == tenth);
242
+ entries.sort ();
243
+ entries.checkSameAs (queue.head , __LINE__);
244
+ }
209
245
210
- static void runEnqueueDequeueTests (const TestConfig &config ) {
246
+ static void runEnqueueDequeueTests (unsigned numTests, unsigned maxEntries ) {
211
247
std::random_device randomDevice;
212
248
std::default_random_engine e (randomDevice ());
213
249
std::uniform_int_distribution<unsigned > valueDist (
214
250
0 , EntryListTraits::prioritiesCount - 1 );
215
- std::uniform_int_distribution<unsigned > numEntriesDist (0 , config. maxEntries );
251
+ std::uniform_int_distribution<unsigned > numEntriesDist (0 , maxEntries);
216
252
217
- for (unsigned testN = 0 ; testN < config. numTests ; ++testN) {
253
+ for (unsigned testN = 0 ; testN < numTests; ++testN) {
218
254
std::cout << " runEnqueueDequeueTests() #" << testN << std::endl;
219
255
EntryFactory entries;
220
256
EntryPriorityQueue queue;
@@ -225,22 +261,63 @@ static void runEnqueueDequeueTests(const TestConfig &config) {
225
261
std::cout << " -- " << value << std::endl;
226
262
queue.enqueue (entries.create (value));
227
263
}
228
- entries.sort (priorityOrder );
229
- entries.checkSameAs (queue.head );
264
+ entries.sort ();
265
+ entries.checkSameAs (queue.head , __LINE__ );
230
266
for (unsigned i = 0 ; i < numEntries; ++i) {
231
267
auto e = queue.dequeue ();
232
268
std::cout << " pop " << e->value << std::endl;
233
269
entries.remove (e);
234
- entries.sort (priorityOrder);
235
- entries.checkSameAs (queue.head );
270
+ entries.sort ();
271
+ entries.checkSameAs (queue.head , __LINE__);
272
+ }
273
+ }
274
+ }
275
+
276
+ static void runEnqueueContentsOfTests (unsigned numTests, unsigned maxChains, unsigned maxEntries) {
277
+ std::random_device randomDevice;
278
+ std::default_random_engine e (randomDevice ());
279
+ std::uniform_int_distribution<unsigned > valueDist (
280
+ 0 , EntryListTraits::prioritiesCount - 1 );
281
+ std::uniform_int_distribution<unsigned > numChainsDist (1 , maxChains);
282
+ std::uniform_int_distribution<unsigned > numEntriesDist (0 , maxEntries);
283
+
284
+ for (unsigned testN = 0 ; testN < numTests; ++testN) {
285
+ std::cout << " runEnqueueContentsOfTests() #" << testN << std::endl;
286
+ EntryFactory entries;
287
+ EntryPriorityQueue queue;
288
+ unsigned totalEntries = 0 ;
289
+ unsigned numChains = numChainsDist (e);
290
+ std::cout << " numChains = " << numChains << std::endl;
291
+ for (unsigned i = 0 ; i < numChains; ++i) {
292
+ unsigned numEntries = numEntriesDist (e);
293
+ std::cout << " numEntries = " << numEntries << std::endl;
294
+ totalEntries += numEntries;
295
+
296
+ ListBuilder builder;
297
+ for (unsigned j = 0 ; j < numEntries; ++j) {
298
+ auto value = valueDist (e);
299
+ std::cout << " -- " << value << std::endl;
300
+ builder.append (entries.create (value));
301
+ }
302
+ queue.enqueueContentsOf (builder.take ());
303
+ }
304
+ entries.sort ();
305
+ entries.checkSameAs (queue.head , __LINE__);
306
+ for (unsigned i = 0 ; i < totalEntries; ++i) {
307
+ auto e = queue.dequeue ();
308
+ std::cout << " pop " << e->value << std::endl;
309
+ entries.remove (e);
310
+ entries.sort ();
311
+ entries.checkSameAs (queue.head , __LINE__);
236
312
}
237
313
}
238
314
}
239
315
240
316
} // namespace
241
317
242
318
int main () {
243
- runConcreteTests ();
244
- TestConfig config = {.numTests = 1000 , .maxEntries = 20 };
245
- runEnqueueDequeueTests (config);
319
+ runEnqueueDequeueTest ();
320
+ runEnqueueContentsOfTest ();
321
+ runEnqueueDequeueTests (1000 , 20 );
322
+ runEnqueueContentsOfTests (1000 , 10 , 20 );
246
323
}
0 commit comments