OrderBy.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. using Cysharp.Threading.Tasks;
  2. using Cysharp.Threading.Tasks.Internal;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Threading;
  6. namespace Cysharp.Threading.Tasks.Linq
  7. {
  8. public static partial class UniTaskAsyncEnumerable
  9. {
  10. #region OrderBy_OrderByDescending
  11. public static IUniTaskOrderedAsyncEnumerable<TSource> OrderBy<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  12. {
  13. Error.ThrowArgumentNullException(source, nameof(source));
  14. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  15. return new OrderedAsyncEnumerable<TSource, TKey>(source, keySelector, Comparer<TKey>.Default, false, null);
  16. }
  17. public static IUniTaskOrderedAsyncEnumerable<TSource> OrderBy<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
  18. {
  19. Error.ThrowArgumentNullException(source, nameof(source));
  20. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  21. Error.ThrowArgumentNullException(comparer, nameof(comparer));
  22. return new OrderedAsyncEnumerable<TSource, TKey>(source, keySelector, comparer, false, null);
  23. }
  24. public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByAwait<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector)
  25. {
  26. Error.ThrowArgumentNullException(source, nameof(source));
  27. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  28. return new OrderedAsyncEnumerableAwait<TSource, TKey>(source, keySelector, Comparer<TKey>.Default, false, null);
  29. }
  30. public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByAwait<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IComparer<TKey> comparer)
  31. {
  32. Error.ThrowArgumentNullException(source, nameof(source));
  33. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  34. Error.ThrowArgumentNullException(comparer, nameof(comparer));
  35. return new OrderedAsyncEnumerableAwait<TSource, TKey>(source, keySelector, comparer, false, null);
  36. }
  37. public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByAwaitWithCancellation<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector)
  38. {
  39. Error.ThrowArgumentNullException(source, nameof(source));
  40. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  41. return new OrderedAsyncEnumerableAwaitWithCancellation<TSource, TKey>(source, keySelector, Comparer<TKey>.Default, false, null);
  42. }
  43. public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByAwaitWithCancellation<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer)
  44. {
  45. Error.ThrowArgumentNullException(source, nameof(source));
  46. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  47. Error.ThrowArgumentNullException(comparer, nameof(comparer));
  48. return new OrderedAsyncEnumerableAwaitWithCancellation<TSource, TKey>(source, keySelector, comparer, false, null);
  49. }
  50. public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByDescending<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  51. {
  52. Error.ThrowArgumentNullException(source, nameof(source));
  53. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  54. return new OrderedAsyncEnumerable<TSource, TKey>(source, keySelector, Comparer<TKey>.Default, true, null);
  55. }
  56. public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByDescending<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
  57. {
  58. Error.ThrowArgumentNullException(source, nameof(source));
  59. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  60. Error.ThrowArgumentNullException(comparer, nameof(comparer));
  61. return new OrderedAsyncEnumerable<TSource, TKey>(source, keySelector, comparer, true, null);
  62. }
  63. public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByDescendingAwait<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector)
  64. {
  65. Error.ThrowArgumentNullException(source, nameof(source));
  66. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  67. return new OrderedAsyncEnumerableAwait<TSource, TKey>(source, keySelector, Comparer<TKey>.Default, true, null);
  68. }
  69. public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByDescendingAwait<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IComparer<TKey> comparer)
  70. {
  71. Error.ThrowArgumentNullException(source, nameof(source));
  72. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  73. Error.ThrowArgumentNullException(comparer, nameof(comparer));
  74. return new OrderedAsyncEnumerableAwait<TSource, TKey>(source, keySelector, comparer, true, null);
  75. }
  76. public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByDescendingAwaitWithCancellation<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector)
  77. {
  78. Error.ThrowArgumentNullException(source, nameof(source));
  79. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  80. return new OrderedAsyncEnumerableAwaitWithCancellation<TSource, TKey>(source, keySelector, Comparer<TKey>.Default, true, null);
  81. }
  82. public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByDescendingAwaitWithCancellation<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer)
  83. {
  84. Error.ThrowArgumentNullException(source, nameof(source));
  85. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  86. Error.ThrowArgumentNullException(comparer, nameof(comparer));
  87. return new OrderedAsyncEnumerableAwaitWithCancellation<TSource, TKey>(source, keySelector, comparer, true, null);
  88. }
  89. #endregion
  90. #region ThenBy_ThenByDescending
  91. public static IUniTaskOrderedAsyncEnumerable<TSource> ThenBy<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  92. {
  93. Error.ThrowArgumentNullException(source, nameof(source));
  94. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  95. return source.CreateOrderedEnumerable(keySelector, Comparer<TKey>.Default, false);
  96. }
  97. public static IUniTaskOrderedAsyncEnumerable<TSource> ThenBy<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
  98. {
  99. Error.ThrowArgumentNullException(source, nameof(source));
  100. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  101. Error.ThrowArgumentNullException(comparer, nameof(comparer));
  102. return source.CreateOrderedEnumerable(keySelector, comparer, false);
  103. }
  104. public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByAwait<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector)
  105. {
  106. Error.ThrowArgumentNullException(source, nameof(source));
  107. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  108. return source.CreateOrderedEnumerable(keySelector, Comparer<TKey>.Default, false);
  109. }
  110. public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByAwait<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IComparer<TKey> comparer)
  111. {
  112. Error.ThrowArgumentNullException(source, nameof(source));
  113. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  114. Error.ThrowArgumentNullException(comparer, nameof(comparer));
  115. return source.CreateOrderedEnumerable(keySelector, comparer, false);
  116. }
  117. public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByAwaitWithCancellation<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector)
  118. {
  119. Error.ThrowArgumentNullException(source, nameof(source));
  120. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  121. return source.CreateOrderedEnumerable(keySelector, Comparer<TKey>.Default, false);
  122. }
  123. public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByAwaitWithCancellation<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer)
  124. {
  125. Error.ThrowArgumentNullException(source, nameof(source));
  126. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  127. Error.ThrowArgumentNullException(comparer, nameof(comparer));
  128. return source.CreateOrderedEnumerable(keySelector, comparer, false);
  129. }
  130. public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByDescending<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  131. {
  132. Error.ThrowArgumentNullException(source, nameof(source));
  133. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  134. return source.CreateOrderedEnumerable(keySelector, Comparer<TKey>.Default, true);
  135. }
  136. public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByDescending<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
  137. {
  138. Error.ThrowArgumentNullException(source, nameof(source));
  139. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  140. Error.ThrowArgumentNullException(comparer, nameof(comparer));
  141. return source.CreateOrderedEnumerable(keySelector, comparer, true);
  142. }
  143. public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByDescendingAwait<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector)
  144. {
  145. Error.ThrowArgumentNullException(source, nameof(source));
  146. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  147. return source.CreateOrderedEnumerable(keySelector, Comparer<TKey>.Default, true);
  148. }
  149. public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByDescendingAwait<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IComparer<TKey> comparer)
  150. {
  151. Error.ThrowArgumentNullException(source, nameof(source));
  152. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  153. Error.ThrowArgumentNullException(comparer, nameof(comparer));
  154. return source.CreateOrderedEnumerable(keySelector, comparer, true);
  155. }
  156. public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByDescendingAwaitWithCancellation<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector)
  157. {
  158. Error.ThrowArgumentNullException(source, nameof(source));
  159. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  160. return source.CreateOrderedEnumerable(keySelector, Comparer<TKey>.Default, true);
  161. }
  162. public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByDescendingAwaitWithCancellation<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer)
  163. {
  164. Error.ThrowArgumentNullException(source, nameof(source));
  165. Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
  166. Error.ThrowArgumentNullException(comparer, nameof(comparer));
  167. return source.CreateOrderedEnumerable(keySelector, comparer, true);
  168. }
  169. #endregion
  170. }
  171. internal abstract class AsyncEnumerableSorter<TElement>
  172. {
  173. internal abstract UniTask ComputeKeysAsync(TElement[] elements, int count);
  174. internal abstract int CompareKeys(int index1, int index2);
  175. internal async UniTask<int[]> SortAsync(TElement[] elements, int count)
  176. {
  177. await ComputeKeysAsync(elements, count);
  178. int[] map = new int[count];
  179. for (int i = 0; i < count; i++) map[i] = i;
  180. QuickSort(map, 0, count - 1);
  181. return map;
  182. }
  183. void QuickSort(int[] map, int left, int right)
  184. {
  185. do
  186. {
  187. int i = left;
  188. int j = right;
  189. int x = map[i + ((j - i) >> 1)];
  190. do
  191. {
  192. while (i < map.Length && CompareKeys(x, map[i]) > 0) i++;
  193. while (j >= 0 && CompareKeys(x, map[j]) < 0) j--;
  194. if (i > j) break;
  195. if (i < j)
  196. {
  197. int temp = map[i];
  198. map[i] = map[j];
  199. map[j] = temp;
  200. }
  201. i++;
  202. j--;
  203. } while (i <= j);
  204. if (j - left <= right - i)
  205. {
  206. if (left < j) QuickSort(map, left, j);
  207. left = i;
  208. }
  209. else
  210. {
  211. if (i < right) QuickSort(map, i, right);
  212. right = j;
  213. }
  214. } while (left < right);
  215. }
  216. }
  217. internal class SyncSelectorAsyncEnumerableSorter<TElement, TKey> : AsyncEnumerableSorter<TElement>
  218. {
  219. readonly Func<TElement, TKey> keySelector;
  220. readonly IComparer<TKey> comparer;
  221. readonly bool descending;
  222. readonly AsyncEnumerableSorter<TElement> next;
  223. TKey[] keys;
  224. internal SyncSelectorAsyncEnumerableSorter(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending, AsyncEnumerableSorter<TElement> next)
  225. {
  226. this.keySelector = keySelector;
  227. this.comparer = comparer;
  228. this.descending = descending;
  229. this.next = next;
  230. }
  231. internal override async UniTask ComputeKeysAsync(TElement[] elements, int count)
  232. {
  233. keys = new TKey[count];
  234. for (int i = 0; i < count; i++) keys[i] = keySelector(elements[i]);
  235. if (next != null) await next.ComputeKeysAsync(elements, count);
  236. }
  237. internal override int CompareKeys(int index1, int index2)
  238. {
  239. int c = comparer.Compare(keys[index1], keys[index2]);
  240. if (c == 0)
  241. {
  242. if (next == null) return index1 - index2;
  243. return next.CompareKeys(index1, index2);
  244. }
  245. return descending ? -c : c;
  246. }
  247. }
  248. internal class AsyncSelectorEnumerableSorter<TElement, TKey> : AsyncEnumerableSorter<TElement>
  249. {
  250. readonly Func<TElement, UniTask<TKey>> keySelector;
  251. readonly IComparer<TKey> comparer;
  252. readonly bool descending;
  253. readonly AsyncEnumerableSorter<TElement> next;
  254. TKey[] keys;
  255. internal AsyncSelectorEnumerableSorter(Func<TElement, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending, AsyncEnumerableSorter<TElement> next)
  256. {
  257. this.keySelector = keySelector;
  258. this.comparer = comparer;
  259. this.descending = descending;
  260. this.next = next;
  261. }
  262. internal override async UniTask ComputeKeysAsync(TElement[] elements, int count)
  263. {
  264. keys = new TKey[count];
  265. for (int i = 0; i < count; i++) keys[i] = await keySelector(elements[i]);
  266. if (next != null) await next.ComputeKeysAsync(elements, count);
  267. }
  268. internal override int CompareKeys(int index1, int index2)
  269. {
  270. int c = comparer.Compare(keys[index1], keys[index2]);
  271. if (c == 0)
  272. {
  273. if (next == null) return index1 - index2;
  274. return next.CompareKeys(index1, index2);
  275. }
  276. return descending ? -c : c;
  277. }
  278. }
  279. internal class AsyncSelectorWithCancellationEnumerableSorter<TElement, TKey> : AsyncEnumerableSorter<TElement>
  280. {
  281. readonly Func<TElement, CancellationToken, UniTask<TKey>> keySelector;
  282. readonly IComparer<TKey> comparer;
  283. readonly bool descending;
  284. readonly AsyncEnumerableSorter<TElement> next;
  285. CancellationToken cancellationToken;
  286. TKey[] keys;
  287. internal AsyncSelectorWithCancellationEnumerableSorter(Func<TElement, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending, AsyncEnumerableSorter<TElement> next, CancellationToken cancellationToken)
  288. {
  289. this.keySelector = keySelector;
  290. this.comparer = comparer;
  291. this.descending = descending;
  292. this.next = next;
  293. this.cancellationToken = cancellationToken;
  294. }
  295. internal override async UniTask ComputeKeysAsync(TElement[] elements, int count)
  296. {
  297. keys = new TKey[count];
  298. for (int i = 0; i < count; i++) keys[i] = await keySelector(elements[i], cancellationToken);
  299. if (next != null) await next.ComputeKeysAsync(elements, count);
  300. }
  301. internal override int CompareKeys(int index1, int index2)
  302. {
  303. int c = comparer.Compare(keys[index1], keys[index2]);
  304. if (c == 0)
  305. {
  306. if (next == null) return index1 - index2;
  307. return next.CompareKeys(index1, index2);
  308. }
  309. return descending ? -c : c;
  310. }
  311. }
  312. internal abstract class OrderedAsyncEnumerable<TElement> : IUniTaskOrderedAsyncEnumerable<TElement>
  313. {
  314. protected readonly IUniTaskAsyncEnumerable<TElement> source;
  315. public OrderedAsyncEnumerable(IUniTaskAsyncEnumerable<TElement> source)
  316. {
  317. this.source = source;
  318. }
  319. public IUniTaskOrderedAsyncEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending)
  320. {
  321. return new OrderedAsyncEnumerable<TElement, TKey>(source, keySelector, comparer, descending, this);
  322. }
  323. public IUniTaskOrderedAsyncEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending)
  324. {
  325. return new OrderedAsyncEnumerableAwait<TElement, TKey>(source, keySelector, comparer, descending, this);
  326. }
  327. public IUniTaskOrderedAsyncEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending)
  328. {
  329. return new OrderedAsyncEnumerableAwaitWithCancellation<TElement, TKey>(source, keySelector, comparer, descending, this);
  330. }
  331. internal abstract AsyncEnumerableSorter<TElement> GetAsyncEnumerableSorter(AsyncEnumerableSorter<TElement> next, CancellationToken cancellationToken);
  332. public IUniTaskAsyncEnumerator<TElement> GetAsyncEnumerator(CancellationToken cancellationToken = default)
  333. {
  334. return new _OrderedAsyncEnumerator(this, cancellationToken);
  335. }
  336. class _OrderedAsyncEnumerator : MoveNextSource, IUniTaskAsyncEnumerator<TElement>
  337. {
  338. protected readonly OrderedAsyncEnumerable<TElement> parent;
  339. CancellationToken cancellationToken;
  340. TElement[] buffer;
  341. int[] map;
  342. int index;
  343. public _OrderedAsyncEnumerator(OrderedAsyncEnumerable<TElement> parent, CancellationToken cancellationToken)
  344. {
  345. this.parent = parent;
  346. this.cancellationToken = cancellationToken;
  347. TaskTracker.TrackActiveTask(this, 3);
  348. }
  349. public TElement Current { get; private set; }
  350. public UniTask<bool> MoveNextAsync()
  351. {
  352. cancellationToken.ThrowIfCancellationRequested();
  353. if (map == null)
  354. {
  355. completionSource.Reset();
  356. CreateSortSource().Forget();
  357. return new UniTask<bool>(this, completionSource.Version);
  358. }
  359. if (index < buffer.Length)
  360. {
  361. Current = buffer[map[index++]];
  362. return CompletedTasks.True;
  363. }
  364. else
  365. {
  366. return CompletedTasks.False;
  367. }
  368. }
  369. async UniTaskVoid CreateSortSource()
  370. {
  371. try
  372. {
  373. buffer = await parent.source.ToArrayAsync();
  374. if (buffer.Length == 0)
  375. {
  376. completionSource.TrySetResult(false);
  377. return;
  378. }
  379. var sorter = parent.GetAsyncEnumerableSorter(null, cancellationToken);
  380. map = await sorter.SortAsync(buffer, buffer.Length);
  381. sorter = null;
  382. // set first value
  383. Current = buffer[map[index++]];
  384. }
  385. catch (Exception ex)
  386. {
  387. completionSource.TrySetException(ex);
  388. return;
  389. }
  390. completionSource.TrySetResult(true);
  391. }
  392. public UniTask DisposeAsync()
  393. {
  394. TaskTracker.RemoveTracking(this);
  395. return default;
  396. }
  397. }
  398. }
  399. internal class OrderedAsyncEnumerable<TElement, TKey> : OrderedAsyncEnumerable<TElement>
  400. {
  401. readonly Func<TElement, TKey> keySelector;
  402. readonly IComparer<TKey> comparer;
  403. readonly bool descending;
  404. readonly OrderedAsyncEnumerable<TElement> parent;
  405. public OrderedAsyncEnumerable(IUniTaskAsyncEnumerable<TElement> source, Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending, OrderedAsyncEnumerable<TElement> parent)
  406. : base(source)
  407. {
  408. this.keySelector = keySelector;
  409. this.comparer = comparer;
  410. this.descending = descending;
  411. this.parent = parent;
  412. }
  413. internal override AsyncEnumerableSorter<TElement> GetAsyncEnumerableSorter(AsyncEnumerableSorter<TElement> next, CancellationToken cancellationToken)
  414. {
  415. AsyncEnumerableSorter<TElement> sorter = new SyncSelectorAsyncEnumerableSorter<TElement, TKey>(keySelector, comparer, descending, next);
  416. if (parent != null) sorter = parent.GetAsyncEnumerableSorter(sorter, cancellationToken);
  417. return sorter;
  418. }
  419. }
  420. internal class OrderedAsyncEnumerableAwait<TElement, TKey> : OrderedAsyncEnumerable<TElement>
  421. {
  422. readonly Func<TElement, UniTask<TKey>> keySelector;
  423. readonly IComparer<TKey> comparer;
  424. readonly bool descending;
  425. readonly OrderedAsyncEnumerable<TElement> parent;
  426. public OrderedAsyncEnumerableAwait(IUniTaskAsyncEnumerable<TElement> source, Func<TElement, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending, OrderedAsyncEnumerable<TElement> parent)
  427. : base(source)
  428. {
  429. this.keySelector = keySelector;
  430. this.comparer = comparer;
  431. this.descending = descending;
  432. this.parent = parent;
  433. }
  434. internal override AsyncEnumerableSorter<TElement> GetAsyncEnumerableSorter(AsyncEnumerableSorter<TElement> next, CancellationToken cancellationToken)
  435. {
  436. AsyncEnumerableSorter<TElement> sorter = new AsyncSelectorEnumerableSorter<TElement, TKey>(keySelector, comparer, descending, next);
  437. if (parent != null) sorter = parent.GetAsyncEnumerableSorter(sorter, cancellationToken);
  438. return sorter;
  439. }
  440. }
  441. internal class OrderedAsyncEnumerableAwaitWithCancellation<TElement, TKey> : OrderedAsyncEnumerable<TElement>
  442. {
  443. readonly Func<TElement, CancellationToken, UniTask<TKey>> keySelector;
  444. readonly IComparer<TKey> comparer;
  445. readonly bool descending;
  446. readonly OrderedAsyncEnumerable<TElement> parent;
  447. public OrderedAsyncEnumerableAwaitWithCancellation(IUniTaskAsyncEnumerable<TElement> source, Func<TElement, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending, OrderedAsyncEnumerable<TElement> parent)
  448. : base(source)
  449. {
  450. this.keySelector = keySelector;
  451. this.comparer = comparer;
  452. this.descending = descending;
  453. this.parent = parent;
  454. }
  455. internal override AsyncEnumerableSorter<TElement> GetAsyncEnumerableSorter(AsyncEnumerableSorter<TElement> next, CancellationToken cancellationToken)
  456. {
  457. AsyncEnumerableSorter<TElement> sorter = new AsyncSelectorWithCancellationEnumerableSorter<TElement, TKey>(keySelector, comparer, descending, next, cancellationToken);
  458. if (parent != null) sorter = parent.GetAsyncEnumerableSorter(sorter, cancellationToken);
  459. return sorter;
  460. }
  461. }
  462. }