Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
PartitionedDataSource.cs
Go to the documentation of this file.
4
6
7internal sealed class PartitionedDataSource<T> : PartitionedStream<T, int>
8{
9 internal sealed class ArrayIndexRangeEnumerator : QueryOperatorEnumerator<T, int>
10 {
11 private sealed class Mutables
12 {
13 internal int _currentSection;
14
15 internal int _currentChunkSize;
16
18
19 internal int _currentChunkOffset;
20
21 internal Mutables()
22 {
23 _currentSection = -1;
24 }
25 }
26
27 private readonly T[] _data;
28
29 private readonly int _elementCount;
30
31 private readonly int _partitionCount;
32
33 private readonly int _partitionIndex;
34
35 private readonly int _maxChunkSize;
36
37 private readonly int _sectionCount;
38
40
42 {
43 _data = data;
44 _elementCount = data.Length;
48 int num = maxChunkSize * partitionCount;
49 _sectionCount = _elementCount / num + ((_elementCount % num != 0) ? 1 : 0);
50 }
51
52 internal override bool MoveNext([MaybeNullWhen(false)][AllowNull] ref T currentElement, ref int currentKey)
53 {
55 if (mutables == null)
56 {
57 mutables = (_mutables = new Mutables());
58 }
59 if (++mutables._currentPositionInChunk < mutables._currentChunkSize || MoveNextSlowPath())
60 {
61 currentKey = mutables._currentChunkOffset + mutables._currentPositionInChunk;
62 currentElement = _data[currentKey];
63 return true;
64 }
65 return false;
66 }
67
68 private bool MoveNextSlowPath()
69 {
71 int num = ++mutables._currentSection;
72 int num2 = _sectionCount - num;
73 if (num2 <= 0)
74 {
75 return false;
76 }
78 mutables._currentPositionInChunk = 0;
79 if (num2 > 1)
80 {
81 mutables._currentChunkSize = _maxChunkSize;
82 mutables._currentChunkOffset = num3 + _partitionIndex * _maxChunkSize;
83 }
84 else
85 {
86 int num4 = _elementCount - num3;
89 mutables._currentChunkSize = num5;
91 {
92 mutables._currentChunkSize++;
93 }
94 if (mutables._currentChunkSize == 0)
95 {
96 return false;
97 }
98 mutables._currentChunkOffset = num3 + _partitionIndex * num5 + ((_partitionIndex < num6) ? _partitionIndex : num6);
99 }
100 return true;
101 }
102 }
103
105 {
106 private readonly T[] _data;
107
108 private readonly int _startIndex;
109
110 private readonly int _maximumIndex;
111
113
115 {
116 _data = data;
117 int num = data.Length / partitionCount;
118 int num2 = data.Length % partitionCount;
120 _startIndex = num3 - 1;
121 _maximumIndex = num3 + num + ((partitionIndex < num2) ? 1 : 0);
122 }
123
124 internal override bool MoveNext([MaybeNullWhen(false)][AllowNull] ref T currentElement, ref int currentKey)
125 {
126 if (_currentIndex == null)
127 {
129 }
130 int num = ++_currentIndex.Value;
131 if (num < _maximumIndex)
132 {
133 currentKey = num;
134 currentElement = _data[num];
135 return true;
136 }
137 return false;
138 }
139 }
140
141 internal sealed class ListIndexRangeEnumerator : QueryOperatorEnumerator<T, int>
142 {
143 private sealed class Mutables
144 {
145 internal int _currentSection;
146
147 internal int _currentChunkSize;
148
150
152
153 internal Mutables()
154 {
155 _currentSection = -1;
156 }
157 }
158
159 private readonly IList<T> _data;
160
161 private readonly int _elementCount;
162
163 private readonly int _partitionCount;
164
165 private readonly int _partitionIndex;
166
167 private readonly int _maxChunkSize;
168
169 private readonly int _sectionCount;
170
172
183
184 internal override bool MoveNext([MaybeNullWhen(false)][AllowNull] ref T currentElement, ref int currentKey)
185 {
187 if (mutables == null)
188 {
189 mutables = (_mutables = new Mutables());
190 }
191 if (++mutables._currentPositionInChunk < mutables._currentChunkSize || MoveNextSlowPath())
192 {
193 currentKey = mutables._currentChunkOffset + mutables._currentPositionInChunk;
194 currentElement = _data[currentKey];
195 return true;
196 }
197 return false;
198 }
199
200 private bool MoveNextSlowPath()
201 {
203 int num = ++mutables._currentSection;
204 int num2 = _sectionCount - num;
205 if (num2 <= 0)
206 {
207 return false;
208 }
209 int num3 = num * _partitionCount * _maxChunkSize;
210 mutables._currentPositionInChunk = 0;
211 if (num2 > 1)
212 {
213 mutables._currentChunkSize = _maxChunkSize;
214 mutables._currentChunkOffset = num3 + _partitionIndex * _maxChunkSize;
215 }
216 else
217 {
218 int num4 = _elementCount - num3;
219 int num5 = num4 / _partitionCount;
220 int num6 = num4 % _partitionCount;
221 mutables._currentChunkSize = num5;
222 if (_partitionIndex < num6)
223 {
224 mutables._currentChunkSize++;
225 }
226 if (mutables._currentChunkSize == 0)
227 {
228 return false;
229 }
230 mutables._currentChunkOffset = num3 + _partitionIndex * num5 + ((_partitionIndex < num6) ? _partitionIndex : num6);
231 }
232 return true;
233 }
234 }
235
237 {
238 private readonly IList<T> _data;
239
240 private readonly int _startIndex;
241
242 private readonly int _maximumIndex;
243
245
247 {
248 _data = data;
249 int num = data.Count / partitionCount;
250 int num2 = data.Count % partitionCount;
252 _startIndex = num3 - 1;
253 _maximumIndex = num3 + num + ((partitionIndex < num2) ? 1 : 0);
254 }
255
256 internal override bool MoveNext([MaybeNullWhen(false)][AllowNull] ref T currentElement, ref int currentKey)
257 {
258 if (_currentIndex == null)
259 {
261 }
262 int num = ++_currentIndex.Value;
263 if (num < _maximumIndex)
264 {
265 currentKey = num;
266 currentElement = _data[num];
267 return true;
268 }
269 return false;
270 }
271 }
272
274 {
275 private sealed class Mutables
276 {
277 internal readonly T[] _chunkBuffer;
278
279 internal int _nextChunkMaxSize;
280
281 internal int _currentChunkSize;
282
283 internal int _currentChunkIndex;
284
285 internal int _chunkBaseIndex;
286
287 internal int _chunkCounter;
288
289 internal Mutables()
290 {
292 _chunkBuffer = new T[Scheduling.GetDefaultChunkSize<T>()];
295 _chunkBaseIndex = 0;
296 _chunkCounter = 0;
297 }
298 }
299
300 private readonly IEnumerator<T> _source;
301
302 private readonly object _sourceSyncLock;
303
304 private readonly Shared<int> _currentIndex;
305
307
309
311
320
321 internal override bool MoveNext([MaybeNullWhen(false)][AllowNull] ref T currentElement, ref int currentKey)
322 {
324 if (mutables == null)
325 {
326 mutables = (_mutables = new Mutables());
327 }
328 T[] chunkBuffer;
329 int num;
330 while (true)
331 {
332 chunkBuffer = mutables._chunkBuffer;
333 num = ++mutables._currentChunkIndex;
334 if (num < mutables._currentChunkSize)
335 {
336 break;
337 }
339 {
340 int i = 0;
342 {
343 return false;
344 }
345 try
346 {
347 for (; i < mutables._nextChunkMaxSize; i++)
348 {
349 if (!_source.MoveNext())
350 {
351 break;
352 }
354 }
355 }
356 catch
357 {
358 _exceptionTracker.Value = true;
359 throw;
360 }
361 mutables._currentChunkSize = i;
362 if (i == 0)
363 {
364 return false;
365 }
366 mutables._chunkBaseIndex = _currentIndex.Value;
367 checked
368 {
369 _currentIndex.Value += i;
370 }
371 }
372 if (mutables._nextChunkMaxSize < chunkBuffer.Length && (mutables._chunkCounter++ & 7) == 7)
373 {
374 mutables._nextChunkMaxSize *= 2;
375 if (mutables._nextChunkMaxSize > chunkBuffer.Length)
376 {
377 mutables._nextChunkMaxSize = chunkBuffer.Length;
378 }
379 }
380 mutables._currentChunkIndex = -1;
381 }
383 currentKey = mutables._chunkBaseIndex + num;
384 return true;
385 }
386
387 protected override void Dispose(bool disposing)
388 {
390 {
391 _source.Dispose();
392 }
393 }
394 }
395
401
403 {
405 {
406 source = parallelEnumerableWrapper.WrappedEnumerable;
407 }
408 if (source is IList<T> data)
409 {
411 T[] array2 = source as T[];
412 int num = -1;
413 if (useStriping)
414 {
415 num = Scheduling.GetDefaultChunkSize<T>();
416 if (num < 1)
417 {
418 num = 1;
419 }
420 }
421 for (int i = 0; i < partitionCount; i++)
422 {
423 if (array2 != null)
424 {
425 if (useStriping)
426 {
428 }
429 else
430 {
432 }
433 }
434 else if (useStriping)
435 {
436 array[i] = new ListIndexRangeEnumerator(data, partitionCount, i, num);
437 }
438 else
439 {
441 }
442 }
444 }
445 else
446 {
448 }
449 }
450
464}
override bool MoveNext([MaybeNullWhen(false)][AllowNull] ref T currentElement, ref int currentKey)
ArrayContiguousIndexRangeEnumerator(T[] data, int partitionCount, int partitionIndex)
ArrayIndexRangeEnumerator(T[] data, int partitionCount, int partitionIndex, int maxChunkSize)
override bool MoveNext([MaybeNullWhen(false)][AllowNull] ref T currentElement, ref int currentKey)
override bool MoveNext([MaybeNullWhen(false)][AllowNull] ref T currentElement, ref int currentKey)
ContiguousChunkLazyEnumerator(IEnumerator< T > source, Shared< bool > exceptionTracker, object sourceSyncLock, Shared< int > currentIndex, Shared< int > degreeOfParallelism)
ListContiguousIndexRangeEnumerator(IList< T > data, int partitionCount, int partitionIndex)
override bool MoveNext([MaybeNullWhen(false)][AllowNull] ref T currentElement, ref int currentKey)
override bool MoveNext([MaybeNullWhen(false)][AllowNull] ref T currentElement, ref int currentKey)
ListIndexRangeEnumerator(IList< T > data, int partitionCount, int partitionIndex, int maxChunkSize)
void InitializePartitions(IEnumerable< T > source, int partitionCount, bool useStriping)
PartitionedDataSource(IEnumerable< T > source, int partitionCount, bool useStriping)
static QueryOperatorEnumerator< T, int >[] MakePartitions(IEnumerator< T > source, int partitionCount)
QueryOperatorEnumerator< TElement, TKey >[] _partitions
static int Decrement(ref int location)