Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
PriorityQueue.cs
Go to the documentation of this file.
4
6
7[DebuggerDisplay("Count = {Count}")]
8[DebuggerTypeProxy(typeof(PriorityQueueDebugView<, >))]
9public class PriorityQueue<TElement, TPriority>
10{
11 [DebuggerDisplay("Count = {Count}")]
13 public sealed class UnorderedItemsCollection : IReadOnlyCollection<(TElement Element, TPriority Priority)>, IEnumerable<(TElement Element, TPriority Priority)>, IEnumerable, ICollection
14 {
15 public struct Enumerator : IEnumerator<(TElement Element, TPriority Priority)>, IDisposable, IEnumerator
16 {
18
19 private readonly int _version;
20
21 private int _index;
22
23 private (TElement, TPriority) _current;
24
25 public (TElement Element, TPriority Priority) Current => _current;
26
27 object IEnumerator.Current => _current;
28
30 {
31 _queue = queue;
32 _index = 0;
34 _current = default((TElement, TPriority));
35 }
36
37 public void Dispose()
38 {
39 }
40
41 public bool MoveNext()
42 {
44 if (_version == queue._version && (uint)_index < (uint)queue._size)
45 {
46 _current = queue._nodes[_index];
47 _index++;
48 return true;
49 }
50 return MoveNextRare();
51 }
52
53 private bool MoveNextRare()
54 {
56 {
58 }
59 _index = _queue._size + 1;
60 _current = default((TElement, TPriority));
61 return false;
62 }
63
65 {
67 {
69 }
70 _index = 0;
71 _current = default((TElement, TPriority));
72 }
73 }
74
76
77 public int Count => _queue._size;
78
79 object ICollection.SyncRoot => this;
80
81 bool ICollection.IsSynchronized => false;
82
87
89 {
90 if (array == null)
91 {
92 throw new ArgumentNullException("array");
93 }
94 if (array.Rank != 1)
95 {
97 }
98 if (array.GetLowerBound(0) != 0)
99 {
101 }
102 if (index < 0 || index > array.Length)
103 {
105 }
106 if (array.Length - index < _queue._size)
107 {
109 }
110 try
111 {
112 Array.Copy(_queue._nodes, 0, array, index, _queue._size);
113 }
115 {
117 }
118 }
119
121 {
122 return new Enumerator(_queue);
123 }
124
125 IEnumerator<(TElement Element, TPriority Priority)> IEnumerable<(TElement, TPriority)>.GetEnumerator()
126 {
127 return GetEnumerator();
128 }
129
134 }
135
136 private (TElement Element, TPriority Priority)[] _nodes;
137
139
141
142 private int _size;
143
144 private int _version;
145
146 public int Count => _size;
147
149
151
153 {
154 _nodes = Array.Empty<(TElement, TPriority)>();
156 }
157
159 : this(initialCapacity, (IComparer<TPriority>?)null)
160 {
161 }
162
164 {
165 _nodes = Array.Empty<(TElement, TPriority)>();
167 }
168
170 {
171 if (initialCapacity < 0)
172 {
174 }
175 _nodes = new(TElement, TPriority)[initialCapacity];
177 }
178
179 public PriorityQueue(IEnumerable<(TElement Element, TPriority Priority)> items)
180 : this(items, (IComparer<TPriority>?)null)
181 {
182 }
183
184 public PriorityQueue(IEnumerable<(TElement Element, TPriority Priority)> items, IComparer<TPriority>? comparer)
185 {
186 if (items == null)
187 {
188 throw new ArgumentNullException("items");
189 }
192 if (_size > 1)
193 {
194 Heapify();
195 }
196 }
197
198 public void Enqueue(TElement element, TPriority priority)
199 {
200 int num = _size++;
201 _version++;
202 if (_nodes.Length == num)
203 {
204 Grow(num + 1);
205 }
206 if (_comparer == null)
207 {
208 MoveUpDefaultComparer((Element: element, Priority: priority), num);
209 }
210 else
211 {
212 MoveUpCustomComparer((Element: element, Priority: priority), num);
213 }
214 }
215
216 public TElement Peek()
217 {
218 if (_size == 0)
219 {
221 }
222 return _nodes[0].Element;
223 }
224
225 public TElement Dequeue()
226 {
227 if (_size == 0)
228 {
230 }
231 TElement item = _nodes[0].Element;
233 return item;
234 }
235
236 public bool TryDequeue([MaybeNullWhen(false)] out TElement element, [MaybeNullWhen(false)] out TPriority priority)
237 {
238 if (_size != 0)
239 {
240 (element, priority) = _nodes[0];
242 return true;
243 }
244 element = default(TElement);
245 priority = default(TPriority);
246 return false;
247 }
248
249 public bool TryPeek([MaybeNullWhen(false)] out TElement element, [MaybeNullWhen(false)] out TPriority priority)
250 {
251 if (_size != 0)
252 {
253 (element, priority) = _nodes[0];
254 return true;
255 }
256 element = default(TElement);
257 priority = default(TPriority);
258 return false;
259 }
260
261 public TElement EnqueueDequeue(TElement element, TPriority priority)
262 {
263 if (_size != 0)
264 {
265 (TElement, TPriority) tuple = _nodes[0];
266 if (_comparer == null)
267 {
268 if (Comparer<TPriority>.Default.Compare(priority, tuple.Item2) > 0)
269 {
270 MoveDownDefaultComparer((Element: element, Priority: priority), 0);
271 _version++;
272 return tuple.Item1;
273 }
274 }
275 else if (_comparer.Compare(priority, tuple.Item2) > 0)
276 {
277 MoveDownCustomComparer((Element: element, Priority: priority), 0);
278 _version++;
279 return tuple.Item1;
280 }
281 }
282 return element;
283 }
284
285 public void EnqueueRange(IEnumerable<(TElement Element, TPriority Priority)> items)
286 {
287 if (items == null)
288 {
289 throw new ArgumentNullException("items");
290 }
291 int num = 0;
292 ICollection<(TElement, TPriority)> collection = items as ICollection<(TElement, TPriority)>;
293 if (collection != null && (num = collection.Count) > _nodes.Length - _size)
294 {
295 Grow(_size + num);
296 }
297 if (_size == 0)
298 {
299 if (collection != null)
300 {
301 collection.CopyTo(_nodes, 0);
302 _size = num;
303 }
304 else
305 {
306 int num2 = 0;
307 (TElement, TPriority)[] nodes = _nodes;
308 foreach (var (item, item2) in items)
309 {
310 if (nodes.Length == num2)
311 {
312 Grow(num2 + 1);
313 nodes = _nodes;
314 }
315 nodes[num2++] = (item, item2);
316 }
317 _size = num2;
318 }
319 _version++;
320 if (_size > 1)
321 {
322 Heapify();
323 }
324 return;
325 }
326 foreach (var (element, priority) in items)
327 {
328 Enqueue(element, priority);
329 }
330 }
331
332 public void EnqueueRange(IEnumerable<TElement> elements, TPriority priority)
333 {
334 if (elements == null)
335 {
336 throw new ArgumentNullException("elements");
337 }
338 if (elements is ICollection<(TElement, TPriority)> { Count: var count })
339 {
340 int num = count;
341 if (count > _nodes.Length - _size)
342 {
343 Grow(_size + num);
344 }
345 }
346 if (_size == 0)
347 {
348 int num2 = 0;
349 (TElement, TPriority)[] nodes = _nodes;
350 foreach (TElement element in elements)
351 {
352 if (nodes.Length == num2)
353 {
354 Grow(num2 + 1);
355 nodes = _nodes;
356 }
357 nodes[num2++] = (element, priority);
358 }
359 _size = num2;
360 _version++;
361 if (num2 > 1)
362 {
363 Heapify();
364 }
365 return;
366 }
367 foreach (TElement element2 in elements)
368 {
370 }
371 }
372
373 public void Clear()
374 {
375 if (RuntimeHelpers.IsReferenceOrContainsReferences<(TElement, TPriority)>())
376 {
377 Array.Clear(_nodes, 0, _size);
378 }
379 _size = 0;
380 _version++;
381 }
382
383 public int EnsureCapacity(int capacity)
384 {
385 if (capacity < 0)
386 {
388 }
389 if (_nodes.Length < capacity)
390 {
391 Grow(capacity);
392 _version++;
393 }
394 return _nodes.Length;
395 }
396
397 public void TrimExcess()
398 {
399 int num = (int)((double)_nodes.Length * 0.9);
400 if (_size < num)
401 {
402 Array.Resize(ref _nodes, _size);
403 _version++;
404 }
405 }
406
407 private void Grow(int minCapacity)
408 {
409 int num = 2 * _nodes.Length;
410 if ((uint)num > Array.MaxLength)
411 {
412 num = Array.MaxLength;
413 }
414 num = Math.Max(num, _nodes.Length + 4);
415 if (num < minCapacity)
416 {
417 num = minCapacity;
418 }
419 Array.Resize(ref _nodes, num);
420 }
421
422 private void RemoveRootNode()
423 {
424 int num = --_size;
425 _version++;
426 if (num > 0)
427 {
428 (TElement, TPriority) node = _nodes[num];
429 if (_comparer == null)
430 {
432 }
433 else
434 {
436 }
437 }
438 if (RuntimeHelpers.IsReferenceOrContainsReferences<(TElement, TPriority)>())
439 {
440 _nodes[num] = default((TElement, TPriority));
441 }
442 }
443
444 private int GetParentIndex(int index)
445 {
446 return index - 1 >> 2;
447 }
448
449 private int GetFirstChildIndex(int index)
450 {
451 return (index << 2) + 1;
452 }
453
454 private void Heapify()
455 {
456 (TElement, TPriority)[] nodes = _nodes;
458 if (_comparer == null)
459 {
460 for (int num = parentIndex; num >= 0; num--)
461 {
462 MoveDownDefaultComparer(nodes[num], num);
463 }
464 }
465 else
466 {
467 for (int num2 = parentIndex; num2 >= 0; num2--)
468 {
470 }
471 }
472 }
473
474 private void MoveUpDefaultComparer((TElement Element, TPriority Priority) node, int nodeIndex)
475 {
476 (TElement, TPriority)[] nodes = _nodes;
477 while (nodeIndex > 0)
478 {
480 (TElement, TPriority) tuple = nodes[parentIndex];
481 if (Comparer<TPriority>.Default.Compare(node.Priority, tuple.Item2) >= 0)
482 {
483 break;
484 }
485 nodes[nodeIndex] = tuple;
487 }
488 nodes[nodeIndex] = node;
489 }
490
491 private void MoveUpCustomComparer((TElement Element, TPriority Priority) node, int nodeIndex)
492 {
494 (TElement, TPriority)[] nodes = _nodes;
495 while (nodeIndex > 0)
496 {
498 (TElement, TPriority) tuple = nodes[parentIndex];
499 if (comparer.Compare(node.Priority, tuple.Item2) >= 0)
500 {
501 break;
502 }
503 nodes[nodeIndex] = tuple;
505 }
506 nodes[nodeIndex] = node;
507 }
508
509 private void MoveDownDefaultComparer((TElement Element, TPriority Priority) node, int nodeIndex)
510 {
511 (TElement, TPriority)[] nodes = _nodes;
512 int size = _size;
513 int num;
514 while ((num = GetFirstChildIndex(nodeIndex)) < size)
515 {
516 (TElement, TPriority) tuple = nodes[num];
517 int num2 = num;
518 int num3 = Math.Min(num + 4, size);
519 while (++num < num3)
520 {
521 (TElement, TPriority) tuple2 = nodes[num];
522 if (Comparer<TPriority>.Default.Compare(tuple2.Item2, tuple.Item2) < 0)
523 {
524 tuple = tuple2;
525 num2 = num;
526 }
527 }
528 if (Comparer<TPriority>.Default.Compare(node.Priority, tuple.Item2) <= 0)
529 {
530 break;
531 }
532 nodes[nodeIndex] = tuple;
533 nodeIndex = num2;
534 }
535 nodes[nodeIndex] = node;
536 }
537
538 private void MoveDownCustomComparer((TElement Element, TPriority Priority) node, int nodeIndex)
539 {
541 (TElement, TPriority)[] nodes = _nodes;
542 int size = _size;
543 int num;
544 while ((num = GetFirstChildIndex(nodeIndex)) < size)
545 {
546 (TElement, TPriority) tuple = nodes[num];
547 int num2 = num;
548 int num3 = Math.Min(num + 4, size);
549 while (++num < num3)
550 {
551 (TElement, TPriority) tuple2 = nodes[num];
552 if (comparer.Compare(tuple2.Item2, tuple.Item2) < 0)
553 {
554 tuple = tuple2;
555 num2 = num;
556 }
557 }
558 if (comparer.Compare(node.Priority, tuple.Item2) <= 0)
559 {
560 break;
561 }
562 nodes[nodeIndex] = tuple;
563 nodeIndex = num2;
564 }
565 nodes[nodeIndex] = node;
566 }
567
569 {
570 if (typeof(TPriority).IsValueType)
571 {
573 {
574 return null;
575 }
576 return comparer;
577 }
578 return comparer ?? Comparer<TPriority>.Default;
579 }
580}
static int MaxLength
Definition Array.cs:471
static unsafe void Clear(Array array)
Definition Array.cs:755
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
Definition Array.cs:624
readonly PriorityQueue< TElement, TPriority > _queue
UnorderedItemsCollection(PriorityQueue< TElement, TPriority > queue)
void EnqueueRange(IEnumerable< TElement > elements, TPriority priority)
static IComparer< TPriority > InitializeComparer(IComparer< TPriority > comparer)
TElement EnqueueDequeue(TElement element, TPriority priority)
PriorityQueue(IEnumerable<(TElement Element, TPriority Priority)> items, IComparer< TPriority >? comparer)
PriorityQueue(int initialCapacity, IComparer< TPriority >? comparer)
readonly IComparer< TPriority > _comparer
bool TryDequeue([MaybeNullWhen(false)] out TElement element, [MaybeNullWhen(false)] out TPriority priority)
PriorityQueue(IEnumerable<(TElement Element, TPriority Priority)> items)
UnorderedItemsCollection _unorderedItems
void MoveDownDefaultComparer((TElement Element, TPriority Priority) node, int nodeIndex)
PriorityQueue(IComparer< TPriority >? comparer)
void Enqueue(TElement element, TPriority priority)
void MoveUpDefaultComparer((TElement Element, TPriority Priority) node, int nodeIndex)
TElement TPriority Priority[] _nodes
UnorderedItemsCollection UnorderedItems
void MoveDownCustomComparer((TElement Element, TPriority Priority) node, int nodeIndex)
void EnqueueRange(IEnumerable<(TElement Element, TPriority Priority)> items)
void MoveUpCustomComparer((TElement Element, TPriority Priority) node, int nodeIndex)
bool TryPeek([MaybeNullWhen(false)] out TElement element, [MaybeNullWhen(false)] out TPriority priority)
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static byte Max(byte val1, byte val2)
Definition Math.cs:738
static string ArgumentOutOfRange_Index
Definition SR.cs:30
static string InvalidOperation_EmptyQueue
Definition SR.cs:38
static string Argument_InvalidArrayType
Definition SR.cs:54
static string Arg_NonZeroLowerBound
Definition SR.cs:14
static string InvalidOperation_EnumFailedVersion
Definition SR.cs:44
static string Arg_RankMultiDimNotSupported
Definition SR.cs:18
static string Argument_InvalidOffLen
Definition SR.cs:22
static string ArgumentOutOfRange_NeedNonNegNum
Definition SR.cs:32
Definition SR.cs:7
void CopyTo(T[] array, int arrayIndex)
new IEnumerator< T > GetEnumerator()