Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Linq / Parallel / QueryOperators / BinaryQueryOperator.cs / 1305376 / BinaryQueryOperator.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// BinaryQueryOperator.cs
//
// [....]
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace System.Linq.Parallel
{
///
/// The base class from which all binary query operators derive, that is, those that
/// have two child operators. This introduces some convenience methods for those
/// classes, as well as any state common to all subclasses.
///
///
///
///
internal abstract class BinaryQueryOperator : QueryOperator
{
// A set of child operators for the current node.
private readonly QueryOperator m_leftChild;
private readonly QueryOperator m_rightChild;
private OrdinalIndexState m_indexState = OrdinalIndexState.Shuffled;
//----------------------------------------------------------------------------------------
// Stores a set of child operators on this query node.
//
internal BinaryQueryOperator(ParallelQuery leftChild, ParallelQuery rightChild)
:this(QueryOperator.AsQueryOperator(leftChild), QueryOperator.AsQueryOperator(rightChild))
{
}
internal BinaryQueryOperator(QueryOperator leftChild, QueryOperator rightChild)
: base(false, leftChild.SpecifiedQuerySettings.Merge(rightChild.SpecifiedQuerySettings))
{
Contract.Assert(leftChild != null && rightChild != null);
m_leftChild = leftChild;
m_rightChild = rightChild;
}
internal QueryOperator LeftChild
{
get { return m_leftChild; }
}
internal QueryOperator RightChild
{
get { return m_rightChild; }
}
internal override sealed OrdinalIndexState OrdinalIndexState
{
get { return m_indexState; }
}
protected void SetOrdinalIndex(OrdinalIndexState indexState)
{
m_indexState = indexState;
}
//---------------------------------------------------------------------------------------
// This method wraps accepts two child partitioned streams, and constructs an output
// partitioned stream. However, instead of returning the transformed partitioned
// stream, we pass it to a recipient object by calling recipient.Give(..). That
// way, we can "return" a partitioned stream that uses an order key selected by the operator.
//
public abstract void WrapPartitionedStream(
PartitionedStream leftPartitionedStream, PartitionedStream rightPartitionedStream,
IPartitionedStreamRecipient outputRecipient, bool preferStriping, QuerySettings settings);
//---------------------------------------------------------------------------------------
// Implementation of QueryResults for a binary operator. The results will not be indexible
// unless a derived class provides that functionality.
//
internal class BinaryQueryOperatorResults : QueryResults
{
protected QueryResults m_leftChildQueryResults; // Results of the left child query
protected QueryResults m_rightChildQueryResults; // Results of the right child query
private BinaryQueryOperator m_op; // Operator that generated these results
private QuerySettings m_settings; // Settings collected from the query
private bool m_preferStriping; // If the results are indexible, should we use striping when partitioning them
internal BinaryQueryOperatorResults(
QueryResults leftChildQueryResults, QueryResults rightChildQueryResults,
BinaryQueryOperator op, QuerySettings settings,
bool preferStriping)
{
m_leftChildQueryResults = leftChildQueryResults;
m_rightChildQueryResults = rightChildQueryResults;
m_op = op;
m_settings = settings;
m_preferStriping = preferStriping;
}
internal override void GivePartitionedStream(IPartitionedStreamRecipient recipient)
{
Contract.Assert(IsIndexible == (m_op.OrdinalIndexState == OrdinalIndexState.Indexible));
if (m_settings.ExecutionMode.Value == ParallelExecutionMode.Default && m_op.LimitsParallelism)
{
// We need to run the query sequentially up to and including this operator
IEnumerable opSequential = m_op.AsSequentialQuery(m_settings.CancellationState.ExternalCancellationToken);
PartitionedStream result = ExchangeUtilities.PartitionDataSource(
opSequential, m_settings.DegreeOfParallelism.Value, m_preferStriping);
recipient.Receive(result);
}
else if (IsIndexible)
{
// The output of this operator is indexible. Pass the partitioned output into the IPartitionedStreamRecipient.
PartitionedStream result = ExchangeUtilities.PartitionDataSource(this, m_settings.DegreeOfParallelism.Value, m_preferStriping);
recipient.Receive(result);
}
else
{
// The common case: get partitions from the child and wrap each partition.
m_leftChildQueryResults.GivePartitionedStream(new LeftChildResultsRecipient(recipient, this, m_preferStriping, m_settings));
}
}
//---------------------------------------------------------------------------------------
// LeftChildResultsRecipient is a recipient of a partitioned stream. It receives a partitioned
// stream from the left child operator, and passes the results along to a
// RightChildResultsRecipient.
//
private class LeftChildResultsRecipient : IPartitionedStreamRecipient
{
IPartitionedStreamRecipient m_outputRecipient;
BinaryQueryOperatorResults m_results;
bool m_preferStriping;
QuerySettings m_settings;
internal LeftChildResultsRecipient(IPartitionedStreamRecipient outputRecipient, BinaryQueryOperatorResults results,
bool preferStriping, QuerySettings settings)
{
m_outputRecipient = outputRecipient;
m_results = results;
m_preferStriping = preferStriping;
m_settings = settings;
}
public void Receive(PartitionedStream source)
{
RightChildResultsRecipient rightChildRecipient =
new RightChildResultsRecipient(m_outputRecipient, m_results.m_op, source, m_preferStriping, m_settings);
m_results.m_rightChildQueryResults.GivePartitionedStream(rightChildRecipient);
}
}
//----------------------------------------------------------------------------------------
// RightChildResultsRecipient receives a partitioned from the right child operator. Also,
// the partitioned stream from the left child operator is passed into the constructor.
// So, Receive has partitioned streams for both child operators, and also is called in
// a context where it has access to both TLeftKey and TRightKey. Then, it passes both
// streams (as arguments) and key types (as type arguments) to the operator's
// WrapPartitionedStream method.
//
private class RightChildResultsRecipient : IPartitionedStreamRecipient
{
IPartitionedStreamRecipient m_outputRecipient;
PartitionedStream m_leftPartitionedStream;
BinaryQueryOperator m_op;
bool m_preferStriping;
QuerySettings m_settings;
internal RightChildResultsRecipient(
IPartitionedStreamRecipient outputRecipient, BinaryQueryOperator op,
PartitionedStream leftPartitionedStream, bool preferStriping, QuerySettings settings)
{
m_outputRecipient = outputRecipient;
m_op = op;
m_preferStriping = preferStriping;
m_leftPartitionedStream = leftPartitionedStream;
m_settings = settings;
}
public void Receive(PartitionedStream rightPartitionedStream)
{
m_op.WrapPartitionedStream(m_leftPartitionedStream, rightPartitionedStream, m_outputRecipient, m_preferStriping, m_settings);
}
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// BinaryQueryOperator.cs
//
// [....]
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace System.Linq.Parallel
{
///
/// The base class from which all binary query operators derive, that is, those that
/// have two child operators. This introduces some convenience methods for those
/// classes, as well as any state common to all subclasses.
///
///
///
///
internal abstract class BinaryQueryOperator : QueryOperator
{
// A set of child operators for the current node.
private readonly QueryOperator m_leftChild;
private readonly QueryOperator m_rightChild;
private OrdinalIndexState m_indexState = OrdinalIndexState.Shuffled;
//----------------------------------------------------------------------------------------
// Stores a set of child operators on this query node.
//
internal BinaryQueryOperator(ParallelQuery leftChild, ParallelQuery rightChild)
:this(QueryOperator.AsQueryOperator(leftChild), QueryOperator.AsQueryOperator(rightChild))
{
}
internal BinaryQueryOperator(QueryOperator leftChild, QueryOperator rightChild)
: base(false, leftChild.SpecifiedQuerySettings.Merge(rightChild.SpecifiedQuerySettings))
{
Contract.Assert(leftChild != null && rightChild != null);
m_leftChild = leftChild;
m_rightChild = rightChild;
}
internal QueryOperator LeftChild
{
get { return m_leftChild; }
}
internal QueryOperator RightChild
{
get { return m_rightChild; }
}
internal override sealed OrdinalIndexState OrdinalIndexState
{
get { return m_indexState; }
}
protected void SetOrdinalIndex(OrdinalIndexState indexState)
{
m_indexState = indexState;
}
//---------------------------------------------------------------------------------------
// This method wraps accepts two child partitioned streams, and constructs an output
// partitioned stream. However, instead of returning the transformed partitioned
// stream, we pass it to a recipient object by calling recipient.Give(..). That
// way, we can "return" a partitioned stream that uses an order key selected by the operator.
//
public abstract void WrapPartitionedStream(
PartitionedStream leftPartitionedStream, PartitionedStream rightPartitionedStream,
IPartitionedStreamRecipient outputRecipient, bool preferStriping, QuerySettings settings);
//---------------------------------------------------------------------------------------
// Implementation of QueryResults for a binary operator. The results will not be indexible
// unless a derived class provides that functionality.
//
internal class BinaryQueryOperatorResults : QueryResults
{
protected QueryResults m_leftChildQueryResults; // Results of the left child query
protected QueryResults m_rightChildQueryResults; // Results of the right child query
private BinaryQueryOperator m_op; // Operator that generated these results
private QuerySettings m_settings; // Settings collected from the query
private bool m_preferStriping; // If the results are indexible, should we use striping when partitioning them
internal BinaryQueryOperatorResults(
QueryResults leftChildQueryResults, QueryResults rightChildQueryResults,
BinaryQueryOperator op, QuerySettings settings,
bool preferStriping)
{
m_leftChildQueryResults = leftChildQueryResults;
m_rightChildQueryResults = rightChildQueryResults;
m_op = op;
m_settings = settings;
m_preferStriping = preferStriping;
}
internal override void GivePartitionedStream(IPartitionedStreamRecipient recipient)
{
Contract.Assert(IsIndexible == (m_op.OrdinalIndexState == OrdinalIndexState.Indexible));
if (m_settings.ExecutionMode.Value == ParallelExecutionMode.Default && m_op.LimitsParallelism)
{
// We need to run the query sequentially up to and including this operator
IEnumerable opSequential = m_op.AsSequentialQuery(m_settings.CancellationState.ExternalCancellationToken);
PartitionedStream result = ExchangeUtilities.PartitionDataSource(
opSequential, m_settings.DegreeOfParallelism.Value, m_preferStriping);
recipient.Receive(result);
}
else if (IsIndexible)
{
// The output of this operator is indexible. Pass the partitioned output into the IPartitionedStreamRecipient.
PartitionedStream result = ExchangeUtilities.PartitionDataSource(this, m_settings.DegreeOfParallelism.Value, m_preferStriping);
recipient.Receive(result);
}
else
{
// The common case: get partitions from the child and wrap each partition.
m_leftChildQueryResults.GivePartitionedStream(new LeftChildResultsRecipient(recipient, this, m_preferStriping, m_settings));
}
}
//---------------------------------------------------------------------------------------
// LeftChildResultsRecipient is a recipient of a partitioned stream. It receives a partitioned
// stream from the left child operator, and passes the results along to a
// RightChildResultsRecipient.
//
private class LeftChildResultsRecipient : IPartitionedStreamRecipient
{
IPartitionedStreamRecipient m_outputRecipient;
BinaryQueryOperatorResults m_results;
bool m_preferStriping;
QuerySettings m_settings;
internal LeftChildResultsRecipient(IPartitionedStreamRecipient outputRecipient, BinaryQueryOperatorResults results,
bool preferStriping, QuerySettings settings)
{
m_outputRecipient = outputRecipient;
m_results = results;
m_preferStriping = preferStriping;
m_settings = settings;
}
public void Receive(PartitionedStream source)
{
RightChildResultsRecipient rightChildRecipient =
new RightChildResultsRecipient(m_outputRecipient, m_results.m_op, source, m_preferStriping, m_settings);
m_results.m_rightChildQueryResults.GivePartitionedStream(rightChildRecipient);
}
}
//----------------------------------------------------------------------------------------
// RightChildResultsRecipient receives a partitioned from the right child operator. Also,
// the partitioned stream from the left child operator is passed into the constructor.
// So, Receive has partitioned streams for both child operators, and also is called in
// a context where it has access to both TLeftKey and TRightKey. Then, it passes both
// streams (as arguments) and key types (as type arguments) to the operator's
// WrapPartitionedStream method.
//
private class RightChildResultsRecipient : IPartitionedStreamRecipient
{
IPartitionedStreamRecipient m_outputRecipient;
PartitionedStream m_leftPartitionedStream;
BinaryQueryOperator m_op;
bool m_preferStriping;
QuerySettings m_settings;
internal RightChildResultsRecipient(
IPartitionedStreamRecipient outputRecipient, BinaryQueryOperator op,
PartitionedStream leftPartitionedStream, bool preferStriping, QuerySettings settings)
{
m_outputRecipient = outputRecipient;
m_op = op;
m_preferStriping = preferStriping;
m_leftPartitionedStream = leftPartitionedStream;
m_settings = settings;
}
public void Receive(PartitionedStream rightPartitionedStream)
{
m_op.WrapPartitionedStream(m_leftPartitionedStream, rightPartitionedStream, m_outputRecipient, m_preferStriping, m_settings);
}
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- GiveFeedbackEventArgs.cs
- RegexCaptureCollection.cs
- SqlClientMetaDataCollectionNames.cs
- ILGenerator.cs
- SchemaMapping.cs
- TimeSpan.cs
- VectorConverter.cs
- MailBnfHelper.cs
- HtmlHead.cs
- TrackingMemoryStreamFactory.cs
- AppDomainAttributes.cs
- HtmlElementErrorEventArgs.cs
- QilUnary.cs
- SerializationStore.cs
- LabelEditEvent.cs
- SortedDictionary.cs
- SafeNativeMemoryHandle.cs
- GridViewColumnHeader.cs
- UIHelper.cs
- _TransmitFileOverlappedAsyncResult.cs
- BinaryReader.cs
- NativeMethods.cs
- VisualBasic.cs
- Symbol.cs
- LowerCaseStringConverter.cs
- HuffCodec.cs
- PropertyPathConverter.cs
- SecurityTokenReferenceStyle.cs
- ToolStripMenuItemDesigner.cs
- Helpers.cs
- MergeExecutor.cs
- SQLResource.cs
- LineProperties.cs
- PeerNameRecordCollection.cs
- DataBoundControlActionList.cs
- SafeWaitHandle.cs
- BaseCodeDomTreeGenerator.cs
- QueuePathEditor.cs
- HeaderLabel.cs
- Trace.cs
- SqlMultiplexer.cs
- TypeConverterValueSerializer.cs
- GetPageNumberCompletedEventArgs.cs
- Mouse.cs
- DataGridParentRows.cs
- LocatorBase.cs
- HighContrastHelper.cs
- TextShapeableCharacters.cs
- UriTemplatePathSegment.cs
- NamedServiceModelExtensionCollectionElement.cs
- WebMessageEncodingElement.cs
- IdnMapping.cs
- PinnedBufferMemoryStream.cs
- UpdatePanelTriggerCollection.cs
- DataRow.cs
- NetMsmqBindingCollectionElement.cs
- MaterializeFromAtom.cs
- StringCollection.cs
- PaperSize.cs
- Emitter.cs
- IndependentAnimationStorage.cs
- DataControlFieldCell.cs
- ServicePoint.cs
- InkCanvas.cs
- NullableIntSumAggregationOperator.cs
- DeferredReference.cs
- XmlWriterTraceListener.cs
- ProcessModuleCollection.cs
- BlurEffect.cs
- WindowCollection.cs
- UndirectedGraph.cs
- DetailsViewUpdateEventArgs.cs
- Style.cs
- ResourceExpressionEditor.cs
- ResourceExpressionBuilder.cs
- SymLanguageVendor.cs
- PrimitiveRenderer.cs
- Cursor.cs
- InvokeMethod.cs
- DeleteIndexBinder.cs
- TextOnlyOutput.cs
- StringUtil.cs
- EncryptedKeyHashIdentifierClause.cs
- ComponentEvent.cs
- MethodRental.cs
- CodeSubDirectory.cs
- WpfWebRequestHelper.cs
- WebPartAddingEventArgs.cs
- _ListenerResponseStream.cs
- EUCJPEncoding.cs
- DataGridParentRows.cs
- TypeContext.cs
- ManipulationStartingEventArgs.cs
- SQlBooleanStorage.cs
- ApplicationInfo.cs
- DeploymentExceptionMapper.cs
- WsatConfiguration.cs
- XmlnsDefinitionAttribute.cs
- DataKey.cs
- GlyphRun.cs