Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
EnumerableSorter.cs
Go to the documentation of this file.
2
3namespace System.Linq;
4
5internal abstract class EnumerableSorter<TElement>
6{
7 internal abstract void ComputeKeys(TElement[] elements, int count);
8
9 internal abstract int CompareAnyKeys(int index1, int index2);
10
11 private int[] ComputeMap(TElement[] elements, int count)
12 {
13 ComputeKeys(elements, count);
14 int[] array = new int[count];
15 for (int i = 0; i < array.Length; i++)
16 {
17 array[i] = i;
18 }
19 return array;
20 }
21
22 internal int[] Sort(TElement[] elements, int count)
23 {
24 int[] array = ComputeMap(elements, count);
25 QuickSort(array, 0, count - 1);
26 return array;
27 }
28
29 internal int[] Sort(TElement[] elements, int count, int minIdx, int maxIdx)
30 {
31 int[] array = ComputeMap(elements, count);
33 return array;
34 }
35
36 internal TElement ElementAt(TElement[] elements, int count, int idx)
37 {
38 int[] map = ComputeMap(elements, count);
39 if (idx != 0)
40 {
41 return elements[QuickSelect(map, count - 1, idx)];
42 }
43 return elements[Min(map, count)];
44 }
45
46 protected abstract void QuickSort(int[] map, int left, int right);
47
48 protected abstract void PartialQuickSort(int[] map, int left, int right, int minIdx, int maxIdx);
49
50 protected abstract int QuickSelect(int[] map, int right, int idx);
51
52 protected abstract int Min(int[] map, int count);
53}
54internal sealed class EnumerableSorter<TElement, TKey> : EnumerableSorter<TElement>
55{
57
58 private readonly IComparer<TKey> _comparer;
59
60 private readonly bool _descending;
61
63
64 private TKey[] _keys;
65
73
74 internal override void ComputeKeys(TElement[] elements, int count)
75 {
76 _keys = new TKey[count];
77 for (int i = 0; i < count; i++)
78 {
79 _keys[i] = _keySelector(elements[i]);
80 }
81 _next?.ComputeKeys(elements, count);
82 }
83
84 internal override int CompareAnyKeys(int index1, int index2)
85 {
87 if (num == 0)
88 {
89 if (_next == null)
90 {
91 return index1 - index2;
92 }
94 }
95 if (_descending == num > 0)
96 {
97 return -1;
98 }
99 return 1;
100 }
101
102 private int CompareKeys(int index1, int index2)
103 {
104 if (index1 != index2)
105 {
107 }
108 return 0;
109 }
110
111 protected override void QuickSort(int[] keys, int lo, int hi)
112 {
113 new Span<int>(keys, lo, hi - lo + 1).Sort(CompareAnyKeys);
114 }
115
116 protected override void PartialQuickSort(int[] map, int left, int right, int minIdx, int maxIdx)
117 {
118 do
119 {
120 int num = left;
121 int num2 = right;
122 int index = map[num + (num2 - num >> 1)];
123 while (true)
124 {
125 if (num < map.Length && CompareKeys(index, map[num]) > 0)
126 {
127 num++;
128 continue;
129 }
130 while (num2 >= 0 && CompareKeys(index, map[num2]) < 0)
131 {
132 num2--;
133 }
134 if (num > num2)
135 {
136 break;
137 }
138 if (num < num2)
139 {
140 int num3 = map[num];
141 map[num] = map[num2];
142 map[num2] = num3;
143 }
144 num++;
145 num2--;
146 if (num > num2)
147 {
148 break;
149 }
150 }
151 if (minIdx >= num)
152 {
153 left = num + 1;
154 }
155 else if (maxIdx <= num2)
156 {
157 right = num2 - 1;
158 }
159 if (num2 - left <= right - num)
160 {
161 if (left < num2)
162 {
164 }
165 left = num;
166 }
167 else
168 {
169 if (num < right)
170 {
171 PartialQuickSort(map, num, right, minIdx, maxIdx);
172 }
173 right = num2;
174 }
175 }
176 while (left < right);
177 }
178
179 protected override int QuickSelect(int[] map, int right, int idx)
180 {
181 int num = 0;
182 do
183 {
184 int num2 = num;
185 int num3 = right;
186 int index = map[num2 + (num3 - num2 >> 1)];
187 while (true)
188 {
189 if (num2 < map.Length && CompareKeys(index, map[num2]) > 0)
190 {
191 num2++;
192 continue;
193 }
194 while (num3 >= 0 && CompareKeys(index, map[num3]) < 0)
195 {
196 num3--;
197 }
198 if (num2 > num3)
199 {
200 break;
201 }
202 if (num2 < num3)
203 {
204 int num4 = map[num2];
205 map[num2] = map[num3];
206 map[num3] = num4;
207 }
208 num2++;
209 num3--;
210 if (num2 > num3)
211 {
212 break;
213 }
214 }
215 if (num2 <= idx)
216 {
217 num = num2 + 1;
218 }
219 else
220 {
221 right = num3 - 1;
222 }
223 if (num3 - num <= right - num2)
224 {
225 if (num < num3)
226 {
227 right = num3;
228 }
229 num = num2;
230 }
231 else
232 {
233 if (num2 < right)
234 {
235 num = num2;
236 }
237 right = num3;
238 }
239 }
240 while (num < right);
241 return map[idx];
242 }
243
244 protected override int Min(int[] map, int count)
245 {
246 int num = 0;
247 for (int i = 1; i < count; i++)
248 {
249 if (CompareKeys(map[i], map[num]) < 0)
250 {
251 num = i;
252 }
253 }
254 return map[num];
255 }
256}
override void ComputeKeys(TElement[] elements, int count)
int Min(int[] map, int count)
void PartialQuickSort(int[] map, int left, int right, int minIdx, int maxIdx)
override int Min(int[] map, int count)
readonly IComparer< TKey > _comparer
EnumerableSorter(Func< TElement, TKey > keySelector, IComparer< TKey > comparer, bool descending, EnumerableSorter< TElement > next)
int[] Sort(TElement[] elements, int count)
override void QuickSort(int[] keys, int lo, int hi)
int CompareAnyKeys(int index1, int index2)
override void PartialQuickSort(int[] map, int left, int right, int minIdx, int maxIdx)
override int QuickSelect(int[] map, int right, int idx)
int[] ComputeMap(TElement[] elements, int count)
int QuickSelect(int[] map, int right, int idx)
int CompareKeys(int index1, int index2)
override int CompareAnyKeys(int index1, int index2)
readonly EnumerableSorter< TElement > _next
int[] Sort(TElement[] elements, int count, int minIdx, int maxIdx)
void QuickSort(int[] map, int left, int right)
void ComputeKeys(TElement[] elements, int count)
readonly Func< TElement, TKey > _keySelector
TElement ElementAt(TElement[] elements, int count, int idx)