/// <summary> /// Add a decorator to the enumerable for additional processing /// </summary> /// <param name="operation">The operation.</param> /// <param name="enumerator">The enumerator.</param> /// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> that may be used to cancel the asynchronous iteration.</param> protected override AsyncEnumerableTask <Row> DecorateEnumerableForExecution( IOperation operation, IAsyncEnumerable <Row> enumerator, CancellationToken cancellationToken = default) { ThreadSafeEnumerator <Row> threadedEnumerator = new ThreadSafeEnumerator <Row>(); Task task = Task.Run(async() => { try { IAsyncEnumerable <Row> eventRaisingEnumerator = new EventRaisingEnumerator(operation, enumerator); await eventRaisingEnumerator .ForEachAsync(async t => { await threadedEnumerator.AddItem(t); }, cancellationToken: cancellationToken); } catch (Exception e) { Error(e, "Failed to execute operation {0}", new Tuple <string, object>("Operation", operation)); } finally { await threadedEnumerator.MarkAsFinished(); } }, cancellationToken); return(new AsyncEnumerableTask <Row> { Enumerable = threadedEnumerator, Task = task, }); }
/// <summary> /// Executes this operation /// </summary> /// <param name="rows">Rows in pipeline. These are only used if a left part of the join was not specified.</param> /// <returns></returns> public override IEnumerable<Row> Execute(IEnumerable<Row> rows) { Initialize(); Guard.Against(left == null, "Left branch of a join cannot be null"); Guard.Against(right == null, "Right branch of a join cannot be null"); IEnumerator leftRows = new EventRaisingEnumerator(left, left.Execute(leftRegistered ? null : rows)).GetEnumerator(); leftRows.MoveNext(); Row leftRow = (Row) leftRows.Current; IEnumerator rightRows = new EventRaisingEnumerator(right, right.Execute(null)).GetEnumerator(); rightRows.MoveNext(); Row rightRow = (Row) rightRows.Current; while (leftRow != null || rightRow != null) { Row mergedRow = null; var match = CompareRows(leftRow, rightRow); if (match == 0) { mergedRow = MergeRows(leftRow, rightRow); leftRow = leftRows.MoveNext() ? (Row) leftRows.Current : null; rightRow = rightRows.MoveNext() ? (Row) rightRows.Current : null; } else if (match < 0) { if ((JoinType & JoinType.Left) != 0) mergedRow = MergeRows(leftRow, new Row()); else LeftOrphanRow(leftRow); leftRow = leftRows.MoveNext() ? (Row)leftRows.Current : null; } else if (match > 0) { if ((JoinType & JoinType.Right) != 0) mergedRow = MergeRows(new Row(), rightRow); else RightOrphanRow(rightRow); rightRow = rightRows.MoveNext() ? (Row)rightRows.Current : null; } if (mergedRow != null) yield return mergedRow; } }
/// <summary> /// Executes this operation /// </summary> /// <param name="rows">Rows in pipeline. These are only used if a left part of the join was not specified.</param> /// <returns></returns> public override IEnumerable <Row> Execute(IEnumerable <Row> rows) { Initialize(); Guard.Against(left == null, "Left branch of a join cannot be null"); Guard.Against(right == null, "Right branch of a join cannot be null"); IEnumerator leftRows = new EventRaisingEnumerator(left, left.Execute(leftRegistered ? null : rows)).GetEnumerator(); leftRows.MoveNext(); Row leftRow = (Row)leftRows.Current; IEnumerator rightRows = new EventRaisingEnumerator(right, right.Execute(null)).GetEnumerator(); rightRows.MoveNext(); Row rightRow = (Row)rightRows.Current; while (leftRow != null || rightRow != null) { Row mergedRow = null; var match = CompareRows(leftRow, rightRow); if (match == 0) { mergedRow = MergeRows(leftRow, rightRow); leftRow = leftRows.MoveNext() ? (Row)leftRows.Current : null; rightRow = rightRows.MoveNext() ? (Row)rightRows.Current : null; } else if (match < 0) { if ((JoinType & JoinType.Left) != 0) { mergedRow = MergeRows(leftRow, new Row()); } else { LeftOrphanRow(leftRow); } leftRow = leftRows.MoveNext() ? (Row)leftRows.Current : null; } else if (match > 0) { if ((JoinType & JoinType.Right) != 0) { mergedRow = MergeRows(new Row(), rightRow); } else { RightOrphanRow(rightRow); } rightRow = rightRows.MoveNext() ? (Row)rightRows.Current : null; } if (mergedRow != null) { yield return(mergedRow); } } }
/// <summary> /// Executes this operation /// </summary> /// <param name="rows">Rows in pipeline. These are only used if a left part of the join was not specified.</param> /// <param name="cancellationToken">A CancellationToken to stop execution</param> /// <returns></returns> public override IAsyncEnumerable <Row> Execute(IAsyncEnumerable <Row> rows, CancellationToken cancellationToken = default) { return(new AsyncEnumerable <Row>(async yield => { Initialize(); Guard.Against(left == null, "Left branch of a join cannot be null"); Guard.Against(right == null, "Right branch of a join cannot be null"); IAsyncEnumerator <Row> leftRows = new EventRaisingEnumerator(left, left.Execute(leftRegistered ? null : rows, cancellationToken)).GetAsyncEnumerator(cancellationToken); await leftRows.MoveNextAsync(); Row leftRow = (Row)leftRows.Current; IAsyncEnumerator <Row> rightRows = new EventRaisingEnumerator(right, right.Execute(null, cancellationToken)).GetAsyncEnumerator(cancellationToken); await rightRows.MoveNextAsync(); Row rightRow = (Row)rightRows.Current; while (leftRow != null || rightRow != null) { Row mergedRow = null; var match = CompareRows(leftRow, rightRow); if (match == 0) { mergedRow = MergeRows(leftRow, rightRow); leftRow = await leftRows.MoveNextAsync() ? (Row)leftRows.Current : null; rightRow = await rightRows.MoveNextAsync() ? (Row)rightRows.Current : null; } else if (match < 0) { if ((JoinType & JoinType.Left) != 0) { mergedRow = MergeRows(leftRow, new Row()); } else { LeftOrphanRow(leftRow); } leftRow = await leftRows.MoveNextAsync() ? (Row)leftRows.Current : null; } else if (match > 0) { if ((JoinType & JoinType.Right) != 0) { mergedRow = MergeRows(new Row(), rightRow); } else { RightOrphanRow(rightRow); } rightRow = await rightRows.MoveNextAsync() ? (Row)rightRows.Current : null; } if (mergedRow != null) { await yield.ReturnAsync(mergedRow); } } })); }