private void InitOrderIndex() { OrdinalIndexState childIndexState = Child.OrdinalIndexState; if (_indexedRightChildSelector != null) { // If this is an indexed SelectMany, we need the order keys to be Correct, so that we can pass them // into the user delegate. _prematureMerge = ExchangeUtilities.IsWorseThan(childIndexState, OrdinalIndexState.Correct); _limitsParallelism = _prematureMerge && childIndexState != OrdinalIndexState.Shuffled; } else { if (OutputOrdered) { // If the output of this SelectMany is ordered, the input keys must be at least increasing. The // SelectMany algorithm assumes that there will be no duplicate order keys, so if the order keys // are Shuffled, we need to merge prematurely. _prematureMerge = ExchangeUtilities.IsWorseThan(childIndexState, OrdinalIndexState.Increasing); } } SetOrdinalIndexState(OrdinalIndexState.Increasing); }
private readonly OrdinalIndexState m_indexState; // State of the order keys. internal PartitionedStream(int partitionCount, IComparer <TKey> keyComparer, OrdinalIndexState indexState) { Contract.Assert(partitionCount > 0); m_partitions = new QueryOperatorEnumerator <TElement, TKey> [partitionCount]; m_keyComparer = keyComparer; m_indexState = indexState; }
internal override void WrapPartitionedStream <TKey>( PartitionedStream <TSource, TKey> inputStream, IPartitionedStreamRecipient <TSource> recipient, bool preferStriping, QuerySettings settings) { OrdinalIndexState inputIndexState = inputStream.OrdinalIndexState; PartitionedStream <TSource, int> intKeyStream; int partitionCount = inputStream.PartitionCount; // If the index is not at least increasing, we need to reindex. if (m_prematureMergeNeeded) { ListQueryResults <TSource> listResults = ExecuteAndCollectResults(inputStream, partitionCount, Child.OutputOrdered, preferStriping, settings); intKeyStream = listResults.GetPartitionedStream(); } else { Contract.Assert(typeof(TKey) == typeof(int)); intKeyStream = (PartitionedStream <TSource, int>)(object) inputStream; } // Generate the shared data. Shared <int> sharedFirstCandidate = new Shared <int>(-1); CountdownEvent sharedBarrier = new CountdownEvent(partitionCount); PartitionedStream <TSource, int> outputStream = new PartitionedStream <TSource, int>( partitionCount, Util.GetDefaultComparer <int>(), OrdinalIndexState.Shuffled); for (int i = 0; i < partitionCount; i++) { outputStream[i] = new FirstQueryOperatorEnumerator( intKeyStream[i], m_predicate, sharedFirstCandidate, sharedBarrier, settings.CancellationState.MergedCancellationToken); } recipient.Receive(outputStream); }
/// <summary> /// Determines the order index state for the output operator /// </summary> private OrdinalIndexState OutputOrderIndexState() { // SkipWhile/TakeWhile needs an increasing index. However, if the predicate expression depends on the index, // the index needs to be correct, not just increasing. OrdinalIndexState requiredIndexState = OrdinalIndexState.Increasing; if (m_indexedPredicate != null) { requiredIndexState = OrdinalIndexState.Correct; } OrdinalIndexState indexState = ExchangeUtilities.Worse(Child.OrdinalIndexState, OrdinalIndexState.Correct); if (indexState.IsWorseThan(requiredIndexState)) { m_prematureMerge = true; } if (!m_take) { // If the index was correct, now it is only increasing. indexState = indexState.Worse(OrdinalIndexState.Increasing); } return(indexState); }
public override void WrapPartitionedStream <TLeftKey, TRightKey>(PartitionedStream <TSource, TLeftKey> leftStream, PartitionedStream <TSource, TRightKey> rightStream, IPartitionedStreamRecipient <TSource> outputRecipient, bool preferStriping, QuerySettings settings) { PartitionedStream <TSource, int> stream; PartitionedStream <TSource, int> stream2; OrdinalIndexState ordinalIndexState = leftStream.OrdinalIndexState; int partitionCount = leftStream.PartitionCount; if (this.m_prematureMergeLeft) { stream = QueryOperator <TSource> .ExecuteAndCollectResults <TLeftKey>(leftStream, partitionCount, base.LeftChild.OutputOrdered, preferStriping, settings).GetPartitionedStream(); } else { stream = (PartitionedStream <TSource, int>)leftStream; } if (this.m_prematureMergeRight) { stream2 = QueryOperator <TSource> .ExecuteAndCollectResults <TRightKey>(rightStream, partitionCount, base.LeftChild.OutputOrdered, preferStriping, settings).GetPartitionedStream(); } else { stream2 = (PartitionedStream <TSource, int>)rightStream; } IComparer <ConcatKey <int, int> > keyComparer = ConcatKey <int, int> .MakeComparer(stream.KeyComparer, stream2.KeyComparer); PartitionedStream <TSource, ConcatKey <int, int> > partitionedStream = new PartitionedStream <TSource, ConcatKey <int, int> >(partitionCount, keyComparer, this.OrdinalIndexState); for (int i = 0; i < partitionCount; i++) { partitionedStream[i] = new ConcatQueryOperatorEnumerator <TSource, int, int>(stream[i], stream2[i]); } outputRecipient.Receive <ConcatKey <int, int> >(partitionedStream); }
public OrderingQueryOperator(QueryOperator <TSource> child, bool orderOn) : base(orderOn, child.SpecifiedQuerySettings) { _child = child; _ordinalIndexState = _child.OrdinalIndexState; _orderOn = orderOn; }
/// <summary> /// Determines the order index state for the output operator /// </summary> private void InitOrderIndexState() { // SkipWhile/TakeWhile needs an increasing index. However, if the predicate expression depends on the index, // the index needs to be correct, not just increasing. OrdinalIndexState requiredIndexState = OrdinalIndexState.Increasing; OrdinalIndexState childIndexState = Child.OrdinalIndexState; if (_indexedPredicate != null) { requiredIndexState = OrdinalIndexState.Correct; _limitsParallelism = childIndexState == OrdinalIndexState.Increasing; } OrdinalIndexState indexState = ExchangeUtilities.Worse(childIndexState, OrdinalIndexState.Correct); if (indexState.IsWorseThan(requiredIndexState)) { _prematureMerge = true; } if (!_take) { // If the index was correct, now it is only increasing. indexState = indexState.Worse(OrdinalIndexState.Increasing); } SetOrdinalIndexState(indexState); }
internal static OrdinalIndexState Worse(this OrdinalIndexState state1, OrdinalIndexState state2) { if (state1 <= state2) { return(state2); } return(state1); }
public OrderingQueryOperator(QueryOperator <TSource> child, bool orderOn) : base(orderOn, child.SpecifiedQuerySettings) { m_child = child; m_ordinalIndexState = m_child.OrdinalIndexState; #if !MONO m_orderOn = orderOn; #endif }
private void InitOrdinalIndexState() { OrdinalIndexState ordinalIndexState = base.Child.OrdinalIndexState; if (base.Child.OrdinalIndexState.IsWorseThan(OrdinalIndexState.Correct)) { this.m_prematureMerge = true; ordinalIndexState = OrdinalIndexState.Correct; } base.SetOrdinalIndexState(ordinalIndexState); }
private void InitOrdinalIndexState() { OrdinalIndexState childIndexState = Child.OrdinalIndexState; if (ExchangeUtilities.IsWorseThan(childIndexState, OrdinalIndexState.Correct)) { _prematureMerge = true; _limitsParallelism = childIndexState != OrdinalIndexState.Shuffled; } SetOrdinalIndexState(OrdinalIndexState.Increasing); }
internal override void GivePartitionedStream(IPartitionedStreamRecipient <TElement> recipient) { int partitionCount = this.m_settings.DegreeOfParallelism.Value; OrderablePartitioner <TElement> partitioner = this.m_partitioner as OrderablePartitioner <TElement>; OrdinalIndexState indexState = (partitioner != null) ? PartitionerQueryOperator <TElement> .GetOrdinalIndexState(partitioner) : OrdinalIndexState.Shuffled; PartitionedStream <TElement, int> partitionedStream = new PartitionedStream <TElement, int>(partitionCount, Util.GetDefaultComparer <int>(), indexState); if (partitioner != null) { IList <IEnumerator <KeyValuePair <long, TElement> > > orderablePartitions = partitioner.GetOrderablePartitions(partitionCount); if (orderablePartitions == null) { throw new InvalidOperationException(System.Linq.SR.GetString("PartitionerQueryOperator_NullPartitionList")); } if (orderablePartitions.Count != partitionCount) { throw new InvalidOperationException(System.Linq.SR.GetString("PartitionerQueryOperator_WrongNumberOfPartitions")); } for (int i = 0; i < partitionCount; i++) { IEnumerator <KeyValuePair <long, TElement> > sourceEnumerator = orderablePartitions[i]; if (sourceEnumerator == null) { throw new InvalidOperationException(System.Linq.SR.GetString("PartitionerQueryOperator_NullPartition")); } partitionedStream[i] = new PartitionerQueryOperator <TElement> .OrderablePartitionerEnumerator(sourceEnumerator); } } else { IList <IEnumerator <TElement> > partitions = this.m_partitioner.GetPartitions(partitionCount); if (partitions == null) { throw new InvalidOperationException(System.Linq.SR.GetString("PartitionerQueryOperator_NullPartitionList")); } if (partitions.Count != partitionCount) { throw new InvalidOperationException(System.Linq.SR.GetString("PartitionerQueryOperator_WrongNumberOfPartitions")); } for (int j = 0; j < partitionCount; j++) { IEnumerator <TElement> enumerator2 = partitions[j]; if (enumerator2 == null) { throw new InvalidOperationException(System.Linq.SR.GetString("PartitionerQueryOperator_NullPartition")); } partitionedStream[j] = new PartitionerQueryOperator <TElement> .PartitionerEnumerator(enumerator2); } } recipient.Receive <int>(partitionedStream); }
private SortHelper(QueryOperatorEnumerator <TInputOutput, TKey> source, int partitionCount, int partitionIndex, QueryTaskGroupState groupState, int[][] sharedIndices, OrdinalIndexState indexState, IComparer <TKey> keyComparer, GrowingArray <TKey>[] sharedkeys, TInputOutput[][] sharedValues, Barrier[,] sharedBarriers) { this.m_source = source; this.m_partitionCount = partitionCount; this.m_partitionIndex = partitionIndex; this.m_groupState = groupState; this.m_sharedIndices = sharedIndices; this.m_indexState = indexState; this.m_keyComparer = keyComparer; this.m_sharedKeys = sharedkeys; this.m_sharedValues = sharedValues; this.m_sharedBarriers = sharedBarriers; }
private void InitOrdinalIndexState() { OrdinalIndexState indexState = Child.OrdinalIndexState; if (ExchangeUtilities.IsWorseThan(Child.OrdinalIndexState, OrdinalIndexState.Correct)) { m_prematureMerge = true; indexState = OrdinalIndexState.Correct; } Contract.Assert(!ExchangeUtilities.IsWorseThan(indexState, OrdinalIndexState.Correct)); SetOrdinalIndexState(indexState); }
public override void WrapPartitionedStream <TLeftKey, TRightKey>( PartitionedStream <TSource, TLeftKey> leftStream, PartitionedStream <TSource, TRightKey> rightStream, IPartitionedStreamRecipient <TSource> outputRecipient, bool preferStriping, QuerySettings settings) { OrdinalIndexState leftChildIndexState = leftStream.OrdinalIndexState; int partitionCount = leftStream.PartitionCount; PartitionedStream <TSource, int> leftStreamInc; PartitionedStream <TSource, int> rightStreamInc; // Prematurely merge the left results, if necessary if (m_prematureMergeLeft) { ListQueryResults <TSource> leftStreamResults = ExecuteAndCollectResults(leftStream, partitionCount, LeftChild.OutputOrdered, preferStriping, settings); leftStreamInc = leftStreamResults.GetPartitionedStream(); } else { Contract.Assert(!ExchangeUtilities.IsWorseThan(leftStream.OrdinalIndexState, OrdinalIndexState.Increasing)); leftStreamInc = (PartitionedStream <TSource, int>)(object) leftStream; } // Prematurely merge the right results, if necessary if (m_prematureMergeRight) { ListQueryResults <TSource> rightStreamResults = ExecuteAndCollectResults(rightStream, partitionCount, LeftChild.OutputOrdered, preferStriping, settings); rightStreamInc = rightStreamResults.GetPartitionedStream(); } else { Contract.Assert(!ExchangeUtilities.IsWorseThan(rightStream.OrdinalIndexState, OrdinalIndexState.Increasing)); rightStreamInc = (PartitionedStream <TSource, int>)(object) rightStream; } // Generate the shared data. IComparer <ConcatKey <int, int> > comparer = ConcatKey <int, int> .MakeComparer( leftStreamInc.KeyComparer, rightStreamInc.KeyComparer); var outputStream = new PartitionedStream <TSource, ConcatKey <int, int> >(partitionCount, comparer, OrdinalIndexState); for (int i = 0; i < partitionCount; i++) { outputStream[i] = new ConcatQueryOperatorEnumerator <int, int>(leftStreamInc[i], rightStreamInc[i]); } outputRecipient.Receive(outputStream); }
private readonly bool _limitsParallelism = false; // Whether this operator limits parallelism //--------------------------------------------------------------------------------------- // Constructs a new instance of the contains search operator. // // Arguments: // child - the child tree to enumerate. // index - index we are searching for. // internal ElementAtQueryOperator(IEnumerable <TSource> child, int index) : base(child) { Contract.Assert(child != null, "child data source cannot be null"); Contract.Assert(index >= 0, "index can't be less than 0"); _index = index; OrdinalIndexState childIndexState = Child.OrdinalIndexState; if (ExchangeUtilities.IsWorseThan(childIndexState, OrdinalIndexState.Correct)) { _prematureMerge = true; _limitsParallelism = childIndexState != OrdinalIndexState.Shuffled; } }
private void InitOrdinalIndexState() { OrdinalIndexState childIndexState = Child.OrdinalIndexState; OrdinalIndexState indexState = childIndexState; if (ExchangeUtilities.IsWorseThan(childIndexState, OrdinalIndexState.Correct)) { _prematureMerge = true; _limitsParallelism = childIndexState != OrdinalIndexState.Shuffled; indexState = OrdinalIndexState.Correct; } Debug.Assert(!ExchangeUtilities.IsWorseThan(indexState, OrdinalIndexState.Correct)); SetOrdinalIndexState(indexState); }
private OrdinalIndexState OutputOrdinalIndexState() { OrdinalIndexState ordinalIndexState = base.Child.OrdinalIndexState; if (ordinalIndexState == OrdinalIndexState.Indexible) { return(OrdinalIndexState.Indexible); } if (ordinalIndexState.IsWorseThan(OrdinalIndexState.Increasing)) { this.m_prematureMerge = true; ordinalIndexState = OrdinalIndexState.Correct; } if (!this.m_take && (ordinalIndexState == OrdinalIndexState.Correct)) { ordinalIndexState = OrdinalIndexState.Increasing; } return(ordinalIndexState); }
private OrdinalIndexState OutputOrderIndexState() { OrdinalIndexState increasing = OrdinalIndexState.Increasing; if (this.m_indexedPredicate != null) { increasing = OrdinalIndexState.Correct; } OrdinalIndexState state2 = base.Child.OrdinalIndexState.Worse(OrdinalIndexState.Correct); if (state2.IsWorseThan(increasing)) { this.m_prematureMerge = true; } if (!this.m_take) { state2 = state2.Worse(OrdinalIndexState.Increasing); } return(state2); }
private ZipQueryOperator( QueryOperator <TLeftInput> left, QueryOperator <TRightInput> right, Func <TLeftInput, TRightInput, TOutput> resultSelector) : base(left.SpecifiedQuerySettings.Merge(right.SpecifiedQuerySettings)) { Debug.Assert(resultSelector != null, "operator cannot be null"); _leftChild = left; _rightChild = right; _resultSelector = resultSelector; _outputOrdered = _leftChild.OutputOrdered || _rightChild.OutputOrdered; OrdinalIndexState leftIndexState = _leftChild.OrdinalIndexState; OrdinalIndexState rightIndexState = _rightChild.OrdinalIndexState; _prematureMergeLeft = leftIndexState != OrdinalIndexState.Indexible; _prematureMergeRight = rightIndexState != OrdinalIndexState.Indexible; _limitsParallelism = (_prematureMergeLeft && leftIndexState != OrdinalIndexState.Shuffled) || (_prematureMergeRight && rightIndexState != OrdinalIndexState.Shuffled); }
/// <summary> /// Determines the order index state for the output operator /// </summary> private OrdinalIndexState OutputOrdinalIndexState() { OrdinalIndexState indexState = Child.OrdinalIndexState; if (indexState == OrdinalIndexState.Indexable) { return(OrdinalIndexState.Indexable); } if (indexState.IsWorseThan(OrdinalIndexState.Increasing)) { _prematureMerge = true; indexState = OrdinalIndexState.Correct; } // If the operator is skip and the index was correct, now it is only increasing. if (!_take && indexState == OrdinalIndexState.Correct) { indexState = OrdinalIndexState.Increasing; } return(indexState); }
internal override void WrapPartitionedStream <TKey>(PartitionedStream <TSource, TKey> inputStream, IPartitionedStreamRecipient <TSource> recipient, bool preferStriping, QuerySettings settings) { PartitionedStream <TSource, int> stream; OrdinalIndexState ordinalIndexState = inputStream.OrdinalIndexState; int partitionCount = inputStream.PartitionCount; if (this.m_prematureMergeNeeded) { stream = QueryOperator <TSource> .ExecuteAndCollectResults <TKey>(inputStream, partitionCount, base.Child.OutputOrdered, preferStriping, settings).GetPartitionedStream(); } else { stream = (PartitionedStream <TSource, int>)inputStream; } Shared <int> sharedFirstCandidate = new Shared <int>(-1); CountdownEvent sharedBarrier = new CountdownEvent(partitionCount); PartitionedStream <TSource, int> partitionedStream = new PartitionedStream <TSource, int>(partitionCount, Util.GetDefaultComparer <int>(), OrdinalIndexState.Shuffled); for (int i = 0; i < partitionCount; i++) { partitionedStream[i] = new FirstQueryOperatorEnumerator <TSource>(stream[i], this.m_predicate, sharedFirstCandidate, sharedBarrier, settings.CancellationState.MergedCancellationToken); } recipient.Receive <int>(partitionedStream); }
internal QueryExecutionOption(QueryOperator <TSource> source, QuerySettings settings) : base(source.OutputOrdered, settings.Merge(source.SpecifiedQuerySettings)) { _child = source; _indexState = _child.OrdinalIndexState; }
internal override void GivePartitionedStream(IPartitionedStreamRecipient <TElement> recipient) { Contract.Assert(m_settings.DegreeOfParallelism.HasValue); int partitionCount = m_settings.DegreeOfParallelism.Value; OrderablePartitioner <TElement> orderablePartitioner = m_partitioner as OrderablePartitioner <TElement>; // If the partitioner is not orderable, it will yield zeros as order keys. The order index state // is irrelevant. OrdinalIndexState indexState = (orderablePartitioner != null) ? GetOrdinalIndexState(orderablePartitioner) : OrdinalIndexState.Shuffled; PartitionedStream <TElement, int> partitions = new PartitionedStream <TElement, int>( partitionCount, Util.GetDefaultComparer <int>(), indexState); if (orderablePartitioner != null) { IList <IEnumerator <KeyValuePair <long, TElement> > > partitionerPartitions = orderablePartitioner.GetOrderablePartitions(partitionCount); if (partitionerPartitions == null) { throw new InvalidOperationException(SR.GetString(SR.PartitionerQueryOperator_NullPartitionList)); } if (partitionerPartitions.Count != partitionCount) { throw new InvalidOperationException(SR.GetString(SR.PartitionerQueryOperator_WrongNumberOfPartitions)); } for (int i = 0; i < partitionCount; i++) { IEnumerator <KeyValuePair <long, TElement> > partition = partitionerPartitions[i]; if (partition == null) { throw new InvalidOperationException(SR.GetString(SR.PartitionerQueryOperator_NullPartition)); } partitions[i] = new OrderablePartitionerEnumerator(partition); } } else { IList <IEnumerator <TElement> > partitionerPartitions = m_partitioner.GetPartitions(partitionCount); if (partitionerPartitions == null) { throw new InvalidOperationException(SR.GetString(SR.PartitionerQueryOperator_NullPartitionList)); } if (partitionerPartitions.Count != partitionCount) { throw new InvalidOperationException(SR.GetString(SR.PartitionerQueryOperator_WrongNumberOfPartitions)); } for (int i = 0; i < partitionCount; i++) { IEnumerator <TElement> partition = partitionerPartitions[i]; if (partition == null) { throw new InvalidOperationException(SR.GetString(SR.PartitionerQueryOperator_NullPartition)); } partitions[i] = new PartitionerEnumerator(partition); } } recipient.Receive <int>(partitions); }
internal static bool IsWorseThan(this OrdinalIndexState state1, OrdinalIndexState state2) { return(state1 > state2); }
//--------------------------------------------------------------------------------------- // A helper method that given two OrdinalIndexState values return the "worse" one. For // example, if state1 is valid and state2 is increasing, we will return // OrdinalIndexState.Increasing. // internal static OrdinalIndexState Worse(this OrdinalIndexState state1, OrdinalIndexState state2) { return(state1 > state2 ? state1 : state2); }
protected void SetOrdinalIndex(OrdinalIndexState indexState) { _indexState = indexState; }
private void QuickSortIndicesInPlace(GrowingArray <TKey> keys, List <TInputOutput> values, OrdinalIndexState ordinalIndexState) { int[] indices = new int[values.Count]; for (int i = 0; i < indices.Length; i++) { indices[i] = i; } if ((indices.Length > 1) && ordinalIndexState.IsWorseThan(OrdinalIndexState.Increasing)) { this.QuickSort(0, indices.Length - 1, keys.InternalArray, indices, this.m_groupState.CancellationState.MergedCancellationToken); } if (this.m_partitionCount == 1) { TInputOutput[] localArray = new TInputOutput[values.Count]; for (int j = 0; j < indices.Length; j++) { localArray[j] = values[indices[j]]; } this.m_sharedValues[this.m_partitionIndex] = localArray; } else { this.m_sharedIndices[this.m_partitionIndex] = indices; this.m_sharedKeys[this.m_partitionIndex] = keys; this.m_sharedValues[this.m_partitionIndex] = new TInputOutput[values.Count]; values.CopyTo(this.m_sharedValues[this.m_partitionIndex]); } }