Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Partitioner.cs
Go to the documentation of this file.
4
6
7public abstract class Partitioner<TSource>
8{
9 public virtual bool SupportsDynamicPartitions => false;
10
12
17}
18public static class Partitioner
19{
20 private abstract class DynamicPartitionEnumerator_Abstract<TSource, TSourceReader> : IEnumerator<KeyValuePair<long, TSource>>, IDisposable, IEnumerator
21 {
22 protected readonly TSourceReader _sharedReader;
23
25
27
29
30 private int _doublingCountdown;
31
32 protected readonly int _maxChunkSize;
33
34 protected readonly SharedLong _sharedIndex;
35
36 protected abstract bool HasNoElementsLeft { get; }
37
38 public abstract KeyValuePair<long, TSource> Current { get; }
39
40 object IEnumerator.Current => Current;
41
46
53
54 protected abstract bool GrabNextChunk(int requestedChunkSize);
55
56 public abstract void Dispose();
57
58 public void Reset()
59 {
60 throw new NotSupportedException();
61 }
62
63 public bool MoveNext()
64 {
65 if (_localOffset == null)
66 {
70 }
72 {
74 return true;
75 }
77 if (_currentChunkSize.Value == 0)
78 {
80 }
81 else if (_doublingCountdown > 0)
82 {
84 }
85 else
86 {
89 }
92 {
93 _localOffset.Value = 0;
94 return true;
95 }
96 return false;
97 }
98 }
99
100 private sealed class DynamicPartitionerForIEnumerable<TSource> : OrderablePartitioner<TSource>
101 {
102 private sealed class InternalPartitionEnumerable : IEnumerable<KeyValuePair<long, TSource>>, IEnumerable, IDisposable
103 {
105
106 private readonly SharedLong _sharedIndex;
107
109
110 private volatile int _fillBufferSize;
111
112 private volatile int _fillBufferCurrentPosition;
113
114 private volatile int _activeCopiers;
115
117
118 private readonly SharedBool _sourceDepleted;
119
120 private readonly object _sharedLock;
121
122 private bool _disposed;
123
125
126 private readonly bool _useSingleChunking;
127
129 {
131 _sharedIndex = new SharedLong(-1L);
132 _hasNoElementsLeft = new SharedBool(value: false);
133 _sourceDepleted = new SharedBool(value: false);
134 _sharedLock = new object();
137 {
138 _fillBuffer = new KeyValuePair<long, TSource>[((Environment.ProcessorCount <= 4) ? 1 : 4) * GetDefaultChunkSize<TSource>()];
139 }
141 {
143 }
144 else
145 {
147 }
148 }
149
158
163
181
195
197 {
199 {
201 {
202 return false;
203 }
204 try
205 {
207 {
208 _sharedIndex.Value = checked(_sharedIndex.Value + 1);
211 return true;
212 }
213 _sourceDepleted.Value = true;
214 _hasNoElementsLeft.Value = true;
215 return false;
216 }
217 catch
218 {
219 _sourceDepleted.Value = true;
220 _hasNoElementsLeft.Value = true;
221 throw;
222 }
223 }
224 }
225
227 {
230 {
231 return true;
232 }
234 {
235 _hasNoElementsLeft.Value = true;
236 _fillBuffer = null;
237 return actualNumElementsGrabbed > 0;
238 }
240 {
242 {
243 return actualNumElementsGrabbed > 0;
244 }
245 try
246 {
247 if (_activeCopiers > 0)
248 {
249 SpinWait spinWait = default(SpinWait);
250 while (_activeCopiers > 0)
251 {
252 spinWait.SpinOnce();
253 }
254 }
256 {
258 {
259 _sharedIndex.Value = checked(_sharedIndex.Value + 1);
262 continue;
263 }
264 _sourceDepleted.Value = true;
265 break;
266 }
269 {
270 for (int i = 0; i < fillBuffer.Length; i++)
271 {
273 {
274 _sharedIndex.Value = checked(_sharedIndex.Value + 1);
276 continue;
277 }
278 _sourceDepleted.Value = true;
279 _fillBufferSize = i;
280 break;
281 }
283 }
284 }
285 catch
286 {
287 _sourceDepleted.Value = true;
288 _hasNoElementsLeft.Value = true;
289 throw;
290 }
291 }
292 return actualNumElementsGrabbed > 0;
293 }
294
295 public void Dispose()
296 {
297 if (!_disposed)
298 {
299 _disposed = true;
300 _sharedReader.Dispose();
301 }
302 }
303 }
304
305 private sealed class InternalPartitionEnumerator : DynamicPartitionEnumerator_Abstract<TSource, IEnumerator<TSource>>
306 {
308
310
312
314
315 protected override bool HasNoElementsLeft => _hasNoElementsLeft.Value;
316
318 {
319 get
320 {
321 if (_currentChunkSize == null)
322 {
324 }
326 }
327 }
328
340
341 protected override bool GrabNextChunk(int requestedChunkSize)
342 {
344 {
345 return false;
346 }
347 if (_localList == null)
348 {
350 }
352 }
353
354 public override void Dispose()
355 {
357 {
359 }
360 }
361 }
362
364
365 private readonly bool _useSingleChunking;
366
367 public override bool SupportsDynamicPartitions => true;
368
375
377 {
378 if (partitionCount <= 0)
379 {
380 throw new ArgumentOutOfRangeException("partitionCount");
381 }
384 for (int i = 0; i < partitionCount; i++)
385 {
386 array[i] = enumerable.GetEnumerator();
387 }
388 return array;
389 }
390
395 }
396
431
433 {
434 protected int _startIndex;
435
436 protected abstract int SourceCount { get; }
437
438 protected override bool HasNoElementsLeft => Volatile.Read(ref _sharedIndex.Value) >= SourceCount - 1;
439
444
445 protected override bool GrabNextChunk(int requestedChunkSize)
446 {
447 while (!HasNoElementsLeft)
448 {
449 long num = Volatile.Read(ref _sharedIndex.Value);
451 {
452 return false;
453 }
454 long num2 = Math.Min(SourceCount - 1, num + requestedChunkSize);
456 {
457 _currentChunkSize.Value = (int)(num2 - num);
458 _localOffset.Value = -1;
459 _startIndex = (int)(num + 1);
460 return true;
461 }
462 }
463 return false;
464 }
465
466 public override void Dispose()
467 {
468 }
469 }
470
471 private sealed class DynamicPartitionerForIList<TSource> : DynamicPartitionerForIndexRange_Abstract<TSource, IList<TSource>>
472 {
473 private sealed class InternalPartitionEnumerable : IEnumerable<KeyValuePair<long, TSource>>, IEnumerable
474 {
476
477 private readonly SharedLong _sharedIndex;
478
484
489
494 }
495
497 {
498 protected override int SourceCount => _sharedReader.Count;
499
501 {
502 get
503 {
504 if (_currentChunkSize == null)
505 {
507 }
508 return new KeyValuePair<long, TSource>(_startIndex + _localOffset.Value, _sharedReader[_startIndex + _localOffset.Value]);
509 }
510 }
511
516 }
517
522
527 }
528
529 private sealed class DynamicPartitionerForArray<TSource> : DynamicPartitionerForIndexRange_Abstract<TSource, TSource[]>
530 {
531 private sealed class InternalPartitionEnumerable : IEnumerable<KeyValuePair<long, TSource>>, IEnumerable
532 {
533 private readonly TSource[] _sharedReader;
534
535 private readonly SharedLong _sharedIndex;
536
538 {
540 _sharedIndex = new SharedLong(-1L);
541 }
542
547
552 }
553
555 {
556 protected override int SourceCount => _sharedReader.Length;
557
559 {
560 get
561 {
562 if (_currentChunkSize == null)
563 {
565 }
566 return new KeyValuePair<long, TSource>(_startIndex + _localOffset.Value, _sharedReader[_startIndex + _localOffset.Value]);
567 }
568 }
569
574 }
575
577 : base(source)
578 {
579 }
580
585 }
586
587 private abstract class StaticIndexRangePartitioner<TSource, TCollection> : OrderablePartitioner<TSource>
588 {
589 protected abstract int SourceCount { get; }
590
595
597
599 {
600 if (partitionCount <= 0)
601 {
602 throw new ArgumentOutOfRangeException("partitionCount");
603 }
604 int num = SourceCount / partitionCount;
607 int num3 = -1;
608 for (int i = 0; i < partitionCount; i++)
609 {
610 int num4 = num3 + 1;
611 num3 = ((i >= num2) ? (num4 + num - 1) : (num4 + num));
613 }
614 return array;
615 }
616 }
617
618 private abstract class StaticIndexRangePartition<TSource> : IEnumerator<KeyValuePair<long, TSource>>, IDisposable, IEnumerator
619 {
620 protected readonly int _startIndex;
621
622 protected readonly int _endIndex;
623
624 protected volatile int _offset;
625
626 public abstract KeyValuePair<long, TSource> Current { get; }
627
628 object IEnumerator.Current => Current;
629
636
637 public void Dispose()
638 {
639 }
640
641 public void Reset()
642 {
643 throw new NotSupportedException();
644 }
645
646 public bool MoveNext()
647 {
648 if (_offset < _endIndex)
649 {
650 _offset++;
651 return true;
652 }
653 _offset = _endIndex + 1;
654 return false;
655 }
656 }
657
658 private sealed class StaticIndexRangePartitionerForIList<TSource> : StaticIndexRangePartitioner<TSource, IList<TSource>>
659 {
660 private readonly IList<TSource> _list;
661
662 protected override int SourceCount => _list.Count;
663
668
673 }
674
675 private sealed class StaticIndexRangePartitionForIList<TSource> : StaticIndexRangePartition<TSource>
676 {
677 private readonly IList<TSource> _list;
678
690
696 }
697
698 private sealed class StaticIndexRangePartitionerForArray<TSource> : StaticIndexRangePartitioner<TSource, TSource[]>
699 {
700 private readonly TSource[] _array;
701
702 protected override int SourceCount => _array.Length;
703
705 {
706 _array = array;
707 }
708
713 }
714
715 private sealed class StaticIndexRangePartitionForArray<TSource> : StaticIndexRangePartition<TSource>
716 {
717 private readonly TSource[] _array;
718
730
733 {
734 _array = array;
735 }
736 }
737
738 private sealed class SharedInt
739 {
740 internal volatile int Value;
741
742 internal SharedInt(int value)
743 {
744 Value = value;
745 }
746 }
747
748 private sealed class SharedBool
749 {
750 internal volatile bool Value;
751
752 internal SharedBool(bool value)
753 {
754 Value = value;
755 }
756 }
757
758 private sealed class SharedLong
759 {
760 internal long Value;
761
762 internal SharedLong(long value)
763 {
764 Value = value;
765 }
766 }
767
769 {
770 if (list == null)
771 {
772 throw new ArgumentNullException("list");
773 }
774 if (loadBalance)
775 {
777 }
779 }
780
782 {
783 if (array == null)
784 {
785 throw new ArgumentNullException("array");
786 }
787 if (loadBalance)
788 {
790 }
792 }
793
798
800 {
801 if (source == null)
802 {
803 throw new ArgumentNullException("source");
804 }
805 if (((uint)partitionerOptions & 0xFFFFFFFEu) != 0)
806 {
807 throw new ArgumentOutOfRangeException("partitionerOptions");
808 }
810 }
811
813 {
815 {
816 throw new ArgumentOutOfRangeException("toExclusive");
817 }
818 decimal num = (decimal)toExclusive - (decimal)fromInclusive;
819 long num2 = (long)(num / (decimal)(Environment.ProcessorCount * 3));
820 if (num2 == 0L)
821 {
822 num2 = 1L;
823 }
825 }
826
828 {
830 {
831 throw new ArgumentOutOfRangeException("toExclusive");
832 }
833 if (rangeSize <= 0)
834 {
835 throw new ArgumentOutOfRangeException("rangeSize");
836 }
838 }
839
841 {
842 bool shouldQuit = false;
843 for (long i = fromInclusive; i < toExclusive; i += rangeSize)
844 {
845 if (shouldQuit)
846 {
847 break;
848 }
849 long item = i;
850 long num;
851 try
852 {
853 num = checked(i + rangeSize);
854 }
855 catch (OverflowException)
856 {
857 num = toExclusive;
858 shouldQuit = true;
859 }
860 if (num > toExclusive)
861 {
862 num = toExclusive;
863 }
864 yield return new Tuple<long, long>(item, num);
865 }
866 }
867
869 {
871 {
872 throw new ArgumentOutOfRangeException("toExclusive");
873 }
874 long num = (long)toExclusive - (long)fromInclusive;
875 int num2 = (int)(num / (Environment.ProcessorCount * 3));
876 if (num2 == 0)
877 {
878 num2 = 1;
879 }
881 }
882
884 {
886 {
887 throw new ArgumentOutOfRangeException("toExclusive");
888 }
889 if (rangeSize <= 0)
890 {
891 throw new ArgumentOutOfRangeException("rangeSize");
892 }
894 }
895
897 {
898 bool shouldQuit = false;
899 for (int i = fromInclusive; i < toExclusive; i += rangeSize)
900 {
901 if (shouldQuit)
902 {
903 break;
904 }
905 int item = i;
906 int num;
907 try
908 {
909 num = checked(i + rangeSize);
910 }
911 catch (OverflowException)
912 {
913 num = toExclusive;
914 shouldQuit = true;
915 }
916 if (num > toExclusive)
917 {
918 num = toExclusive;
919 }
920 yield return new Tuple<int, int>(item, num);
921 }
922 }
923
924 private static int GetDefaultChunkSize<TSource>()
925 {
926 if (typeof(TSource).IsValueType)
927 {
928 return 128;
929 }
930 return 512 / IntPtr.Size;
931 }
932}
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
Definition Array.cs:624
DynamicPartitionEnumeratorForIndexRange_Abstract(TSourceReader sharedReader, SharedLong sharedIndex)
DynamicPartitionEnumerator_Abstract(TSourceReader sharedReader, SharedLong sharedIndex, bool useSingleChunking)
DynamicPartitionEnumerator_Abstract(TSourceReader sharedReader, SharedLong sharedIndex)
override IEnumerable< KeyValuePair< long, TSource > > GetOrderableDynamicPartitions_Factory(TSource[] _data)
void TryCopyFromFillBuffer(KeyValuePair< long, TSource >[] destArray, int requestedChunkSize, ref int actualNumElementsGrabbed)
InternalPartitionEnumerable(IEnumerator< TSource > sharedReader, bool useSingleChunking, bool isStaticPartitioning)
bool GrabChunk(KeyValuePair< long, TSource >[] destArray, int requestedChunkSize, ref int actualNumElementsGrabbed)
bool GrabChunk_Single(KeyValuePair< long, TSource >[] destArray, int requestedChunkSize, ref int actualNumElementsGrabbed)
bool GrabChunk_Buffered(KeyValuePair< long, TSource >[] destArray, int requestedChunkSize, ref int actualNumElementsGrabbed)
InternalPartitionEnumerator(IEnumerator< TSource > sharedReader, SharedLong sharedIndex, SharedBool hasNoElementsLeft, SharedInt activePartitionCount, InternalPartitionEnumerable enumerable, bool useSingleChunking)
override IList< IEnumerator< KeyValuePair< long, TSource > > > GetOrderablePartitions(int partitionCount)
DynamicPartitionerForIEnumerable(IEnumerable< TSource > source, EnumerablePartitionerOptions partitionerOptions)
override IEnumerable< KeyValuePair< long, TSource > > GetOrderableDynamicPartitions()
override IEnumerable< KeyValuePair< long, TSource > > GetOrderableDynamicPartitions_Factory(IList< TSource > _data)
override IList< IEnumerator< KeyValuePair< long, TSource > > > GetOrderablePartitions(int partitionCount)
IEnumerable< KeyValuePair< long, TSource > > GetOrderableDynamicPartitions_Factory(TCollection data)
override IEnumerable< KeyValuePair< long, TSource > > GetOrderableDynamicPartitions()
StaticIndexRangePartitionForArray(TSource[] array, int startIndex, int endIndex)
StaticIndexRangePartitionForIList(IList< TSource > list, int startIndex, int endIndex)
override IEnumerator< KeyValuePair< long, TSource > > CreatePartition(int startIndex, int endIndex)
override IEnumerator< KeyValuePair< long, TSource > > CreatePartition(int startIndex, int endIndex)
IEnumerator< KeyValuePair< long, TSource > > CreatePartition(int startIndex, int endIndex)
override IList< IEnumerator< KeyValuePair< long, TSource > > > GetOrderablePartitions(int partitionCount)
static OrderablePartitioner< TSource > Create< TSource >(IList< TSource > list, bool loadBalance)
static OrderablePartitioner< Tuple< int, int > > Create(int fromInclusive, int toExclusive, int rangeSize)
virtual IEnumerable< TSource > GetDynamicPartitions()
IList< IEnumerator< TSource > > GetPartitions(int partitionCount)
static OrderablePartitioner< Tuple< int, int > > Create(int fromInclusive, int toExclusive)
static IEnumerable< Tuple< int, int > > CreateRanges(int fromInclusive, int toExclusive, int rangeSize)
static OrderablePartitioner< Tuple< long, long > > Create(long fromInclusive, long toExclusive)
static IEnumerable< Tuple< long, long > > CreateRanges(long fromInclusive, long toExclusive, long rangeSize)
static OrderablePartitioner< Tuple< long, long > > Create(long fromInclusive, long toExclusive, long rangeSize)
static int ProcessorCount
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static string PartitionerStatic_CanNotCallGetEnumeratorAfterSourceHasBeenDisposed
Definition SR.cs:88
static string Partitioner_DynamicPartitionsNotSupported
Definition SR.cs:86
static string PartitionerStatic_CurrentCalledBeforeMoveNext
Definition SR.cs:90
Definition SR.cs:7
static int CompareExchange(ref int location1, int value, int comparand)
static int Decrement(ref int location)
static int Add(ref int location1, int value)
static int Increment(ref int location)
static bool Read(ref bool location)
Definition Volatile.cs:67
static int Size
Definition IntPtr.cs:21