Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Common / internal / materialization / coordinatorscratchpad.cs / 2 / coordinatorscratchpad.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
// [....]
//-----------------------------------------------------------------------------
using System.Collections.Generic;
using System.Data.Query.InternalTrees;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
namespace System.Data.Common.Internal.Materialization
{
///
/// Used in the Translator to aggregate information about a (nested) reader
/// coordinator. After the translator visits the columnMaps, it will compile
/// the coordinator(s) which produces an immutable CoordinatorFactory that
/// can be shared amongst many query instances.
///
internal class CoordinatorScratchpad
{
#region private state
private Type _elementType;
private int _stateSlotNumber;
private int _depth;
private Expression _element;
private Expression _hasData;
private Expression _setKeys;
private Expression _checkKeys;
private CoordinatorScratchpad _parent;
private readonly List _nestedCoordinatorScratchpads;
///
/// Map from original expressions to expressions with detailed error handling.
///
private readonly Dictionary _expressionWithErrorHandlingMap;
///
/// Expressions that should be precompiled (i.e. reduced to constants in
/// compiled delegates.
///
private readonly HashSet _inlineDelegates;
#endregion
#region constructor
internal CoordinatorScratchpad(Type elementType)
{
_elementType = elementType;
_nestedCoordinatorScratchpads = new List();
_expressionWithErrorHandlingMap = new Dictionary();
_inlineDelegates = new HashSet();
}
#endregion
#region "public" surface area
///
/// For nested collections, returns the parent coordinator.
///
internal CoordinatorScratchpad Parent
{
get { return _parent; }
}
///
/// Gets or sets an Expression setting key values (these keys are used
/// to determine when a collection has entered a new chapter) from the
/// underlying store data reader.
///
internal Expression SetKeys
{
get { return _setKeys; }
set { _setKeys = value; }
}
///
/// Gets or sets an Expression returning 'true' when the key values for
/// the current nested result (see SetKeys) are equal to the current key
/// values on the underlying data reader.
///
internal Expression CheckKeys
{
get { return _checkKeys; }
set { _checkKeys = value; }
}
///
/// Gets or sets an expression returning 'true' if the current row in
/// the underlying data reader contains an element of the collection.
///
internal Expression HasData
{
get { return _hasData; }
set { _hasData = value; }
}
///
/// Gets or sets an Expression yielding an element of the current collection
/// given values in the underlying data reader.
///
internal Expression Element
{
get { return _element; }
set { _element = value; }
}
///
/// Indicates which Shaper.State slot is home for this collection's coordinator.
/// Used by Parent to pull out nested collection aggregators/streamers.
///
internal int StateSlotNumber
{
get { return _stateSlotNumber; }
set { _stateSlotNumber = value; }
}
///
/// Gets or sets the depth of the current coordinator. A root collection has depth 0.
///
internal int Depth
{
get { return _depth; }
set { _depth = value; }
}
///
/// List of all record types that we can return at this level in the query.
///
private List _recordStateScratchpads;
///
/// Allows sub-expressions to register an 'interest' in exceptions thrown when reading elements
/// for this coordinator. When an exception is thrown, we rerun the delegate using the slower
/// but more error-friendly versions of expressions (e.g. reader.GetValue + type check instead
/// of reader.GetInt32())
///
/// The lean and mean raw version of the expression
/// The slower version of the same expression with better
/// error handling
internal void AddExpressionWithErrorHandling(Expression expression, Expression expressionWithErrorHandling)
{
_expressionWithErrorHandlingMap[expression] = expressionWithErrorHandling;
}
///
/// Registers a lambda expression for pre-compilation (i.e. reduction to a constant expression)
/// within materialization expression. Otherwise, the expression will be compiled every time
/// the enclosing delegate is invoked.
///
/// Lambda expression to register.
internal void AddInlineDelegate(LambdaExpression expression)
{
_inlineDelegates.Add(expression);
}
///
/// Registers a coordinator for a nested collection contained in elements of this collection.
///
internal void AddNestedCoordinator(CoordinatorScratchpad nested)
{
Debug.Assert(nested.Depth == this.Depth + 1, "can only nest depth + 1");
nested._parent = this;
_nestedCoordinatorScratchpads.Add(nested);
}
///
/// Use the information stored on the scratchpad to compile an immutable factory used
/// to construct the coordinators used at runtime when materializing results.
///
internal CoordinatorFactory Compile()
{
RecordStateFactory[] recordStateFactories;
if (null != _recordStateScratchpads)
{
recordStateFactories = new RecordStateFactory[_recordStateScratchpads.Count];
for (int i = 0; i < recordStateFactories.Length; i++)
{
recordStateFactories[i] = _recordStateScratchpads[i].Compile();
}
}
else
{
recordStateFactories = new RecordStateFactory[0];
}
CoordinatorFactory[] nestedCoordinators = new CoordinatorFactory[_nestedCoordinatorScratchpads.Count];
for (int i = 0; i < nestedCoordinators.Length; i++)
{
nestedCoordinators[i] = _nestedCoordinatorScratchpads[i].Compile();
}
// compile inline delegates
ReplacementExpressionVisitor replacementVisitor = new ReplacementExpressionVisitor(null, this._inlineDelegates);
Expression element = replacementVisitor.Visit(this.Element);
// substitute expressions that have error handlers into a new expression (used
// when a more detailed exception message is needed)
replacementVisitor = new ReplacementExpressionVisitor(this._expressionWithErrorHandlingMap, this._inlineDelegates);
Expression elementWithErrorHandling = replacementVisitor.Visit(this.Element);
CoordinatorFactory result = (CoordinatorFactory)Activator.CreateInstance(typeof(CoordinatorFactory<>).MakeGenericType(_elementType), new object[] {
this.Depth,
this.StateSlotNumber,
this.HasData,
this.SetKeys,
this.CheckKeys,
nestedCoordinators,
element,
elementWithErrorHandling,
recordStateFactories
});
return result;
}
///
/// Allocates a new RecordStateScratchpad and adds it to the list of the ones we're
/// responsible for; will create the list if it hasn't alread been created.
///
internal RecordStateScratchpad CreateRecordStateScratchpad()
{
RecordStateScratchpad recordStateScratchpad = new RecordStateScratchpad();
if (null == _recordStateScratchpads)
{
_recordStateScratchpads = new List();
}
_recordStateScratchpads.Add(recordStateScratchpad);
return recordStateScratchpad;
}
#endregion
#region Nested types
///
/// Visitor supporting (non-recursive) replacement of LINQ sub-expressions and
/// compilation of inline delegates.
///
private class ReplacementExpressionVisitor : ExpressionVisitor
{
// Map from original expressions to replacement expressions.
private readonly Dictionary _replacementDictionary;
private readonly HashSet _inlineDelegates;
internal ReplacementExpressionVisitor(Dictionary replacementDictionary,
HashSet inlineDelegates)
{
this._replacementDictionary = replacementDictionary;
this._inlineDelegates = inlineDelegates;
}
internal override Expression Visit(Expression expression)
{
if (null == expression)
{
return expression;
}
Expression result;
// check to see if a substitution has been provided for this expression
Expression replacement;
if (null != this._replacementDictionary && this._replacementDictionary.TryGetValue(expression, out replacement))
{
// once a substitution is found, we stop walking the sub-expression and
// return immediately (since recursive replacement is not needed or wanted)
result = replacement;
}
else
{
// check if we need to precompile an inline delegate
bool preCompile = false;
LambdaExpression lambda = null;
if (expression.NodeType == ExpressionType.Lambda &&
null != _inlineDelegates)
{
lambda = (LambdaExpression)expression;
preCompile = _inlineDelegates.Contains(lambda);
}
if (preCompile)
{
// do replacement in the body of the lambda expression
Expression body = Visit(lambda.Body);
// compile to a delegate
result = Expression.Constant(Translator.Compile(body.Type, body));
}
else
{
result = base.Visit(expression);
}
}
return result;
}
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
// [....]
//-----------------------------------------------------------------------------
using System.Collections.Generic;
using System.Data.Query.InternalTrees;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
namespace System.Data.Common.Internal.Materialization
{
///
/// Used in the Translator to aggregate information about a (nested) reader
/// coordinator. After the translator visits the columnMaps, it will compile
/// the coordinator(s) which produces an immutable CoordinatorFactory that
/// can be shared amongst many query instances.
///
internal class CoordinatorScratchpad
{
#region private state
private Type _elementType;
private int _stateSlotNumber;
private int _depth;
private Expression _element;
private Expression _hasData;
private Expression _setKeys;
private Expression _checkKeys;
private CoordinatorScratchpad _parent;
private readonly List _nestedCoordinatorScratchpads;
///
/// Map from original expressions to expressions with detailed error handling.
///
private readonly Dictionary _expressionWithErrorHandlingMap;
///
/// Expressions that should be precompiled (i.e. reduced to constants in
/// compiled delegates.
///
private readonly HashSet _inlineDelegates;
#endregion
#region constructor
internal CoordinatorScratchpad(Type elementType)
{
_elementType = elementType;
_nestedCoordinatorScratchpads = new List();
_expressionWithErrorHandlingMap = new Dictionary();
_inlineDelegates = new HashSet();
}
#endregion
#region "public" surface area
///
/// For nested collections, returns the parent coordinator.
///
internal CoordinatorScratchpad Parent
{
get { return _parent; }
}
///
/// Gets or sets an Expression setting key values (these keys are used
/// to determine when a collection has entered a new chapter) from the
/// underlying store data reader.
///
internal Expression SetKeys
{
get { return _setKeys; }
set { _setKeys = value; }
}
///
/// Gets or sets an Expression returning 'true' when the key values for
/// the current nested result (see SetKeys) are equal to the current key
/// values on the underlying data reader.
///
internal Expression CheckKeys
{
get { return _checkKeys; }
set { _checkKeys = value; }
}
///
/// Gets or sets an expression returning 'true' if the current row in
/// the underlying data reader contains an element of the collection.
///
internal Expression HasData
{
get { return _hasData; }
set { _hasData = value; }
}
///
/// Gets or sets an Expression yielding an element of the current collection
/// given values in the underlying data reader.
///
internal Expression Element
{
get { return _element; }
set { _element = value; }
}
///
/// Indicates which Shaper.State slot is home for this collection's coordinator.
/// Used by Parent to pull out nested collection aggregators/streamers.
///
internal int StateSlotNumber
{
get { return _stateSlotNumber; }
set { _stateSlotNumber = value; }
}
///
/// Gets or sets the depth of the current coordinator. A root collection has depth 0.
///
internal int Depth
{
get { return _depth; }
set { _depth = value; }
}
///
/// List of all record types that we can return at this level in the query.
///
private List _recordStateScratchpads;
///
/// Allows sub-expressions to register an 'interest' in exceptions thrown when reading elements
/// for this coordinator. When an exception is thrown, we rerun the delegate using the slower
/// but more error-friendly versions of expressions (e.g. reader.GetValue + type check instead
/// of reader.GetInt32())
///
/// The lean and mean raw version of the expression
/// The slower version of the same expression with better
/// error handling
internal void AddExpressionWithErrorHandling(Expression expression, Expression expressionWithErrorHandling)
{
_expressionWithErrorHandlingMap[expression] = expressionWithErrorHandling;
}
///
/// Registers a lambda expression for pre-compilation (i.e. reduction to a constant expression)
/// within materialization expression. Otherwise, the expression will be compiled every time
/// the enclosing delegate is invoked.
///
/// Lambda expression to register.
internal void AddInlineDelegate(LambdaExpression expression)
{
_inlineDelegates.Add(expression);
}
///
/// Registers a coordinator for a nested collection contained in elements of this collection.
///
internal void AddNestedCoordinator(CoordinatorScratchpad nested)
{
Debug.Assert(nested.Depth == this.Depth + 1, "can only nest depth + 1");
nested._parent = this;
_nestedCoordinatorScratchpads.Add(nested);
}
///
/// Use the information stored on the scratchpad to compile an immutable factory used
/// to construct the coordinators used at runtime when materializing results.
///
internal CoordinatorFactory Compile()
{
RecordStateFactory[] recordStateFactories;
if (null != _recordStateScratchpads)
{
recordStateFactories = new RecordStateFactory[_recordStateScratchpads.Count];
for (int i = 0; i < recordStateFactories.Length; i++)
{
recordStateFactories[i] = _recordStateScratchpads[i].Compile();
}
}
else
{
recordStateFactories = new RecordStateFactory[0];
}
CoordinatorFactory[] nestedCoordinators = new CoordinatorFactory[_nestedCoordinatorScratchpads.Count];
for (int i = 0; i < nestedCoordinators.Length; i++)
{
nestedCoordinators[i] = _nestedCoordinatorScratchpads[i].Compile();
}
// compile inline delegates
ReplacementExpressionVisitor replacementVisitor = new ReplacementExpressionVisitor(null, this._inlineDelegates);
Expression element = replacementVisitor.Visit(this.Element);
// substitute expressions that have error handlers into a new expression (used
// when a more detailed exception message is needed)
replacementVisitor = new ReplacementExpressionVisitor(this._expressionWithErrorHandlingMap, this._inlineDelegates);
Expression elementWithErrorHandling = replacementVisitor.Visit(this.Element);
CoordinatorFactory result = (CoordinatorFactory)Activator.CreateInstance(typeof(CoordinatorFactory<>).MakeGenericType(_elementType), new object[] {
this.Depth,
this.StateSlotNumber,
this.HasData,
this.SetKeys,
this.CheckKeys,
nestedCoordinators,
element,
elementWithErrorHandling,
recordStateFactories
});
return result;
}
///
/// Allocates a new RecordStateScratchpad and adds it to the list of the ones we're
/// responsible for; will create the list if it hasn't alread been created.
///
internal RecordStateScratchpad CreateRecordStateScratchpad()
{
RecordStateScratchpad recordStateScratchpad = new RecordStateScratchpad();
if (null == _recordStateScratchpads)
{
_recordStateScratchpads = new List();
}
_recordStateScratchpads.Add(recordStateScratchpad);
return recordStateScratchpad;
}
#endregion
#region Nested types
///
/// Visitor supporting (non-recursive) replacement of LINQ sub-expressions and
/// compilation of inline delegates.
///
private class ReplacementExpressionVisitor : ExpressionVisitor
{
// Map from original expressions to replacement expressions.
private readonly Dictionary _replacementDictionary;
private readonly HashSet _inlineDelegates;
internal ReplacementExpressionVisitor(Dictionary replacementDictionary,
HashSet inlineDelegates)
{
this._replacementDictionary = replacementDictionary;
this._inlineDelegates = inlineDelegates;
}
internal override Expression Visit(Expression expression)
{
if (null == expression)
{
return expression;
}
Expression result;
// check to see if a substitution has been provided for this expression
Expression replacement;
if (null != this._replacementDictionary && this._replacementDictionary.TryGetValue(expression, out replacement))
{
// once a substitution is found, we stop walking the sub-expression and
// return immediately (since recursive replacement is not needed or wanted)
result = replacement;
}
else
{
// check if we need to precompile an inline delegate
bool preCompile = false;
LambdaExpression lambda = null;
if (expression.NodeType == ExpressionType.Lambda &&
null != _inlineDelegates)
{
lambda = (LambdaExpression)expression;
preCompile = _inlineDelegates.Contains(lambda);
}
if (preCompile)
{
// do replacement in the body of the lambda expression
Expression body = Visit(lambda.Body);
// compile to a delegate
result = Expression.Constant(Translator.Compile(body.Type, body));
}
else
{
result = base.Visit(expression);
}
}
return result;
}
}
#endregion
}
}
// 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
- KnowledgeBase.cs
- LogicalExpressionEditor.cs
- DataSourceSelectArguments.cs
- Base64Stream.cs
- EventEntry.cs
- SerializationInfoEnumerator.cs
- XamlPoint3DCollectionSerializer.cs
- SocketPermission.cs
- XmlSchemaInferenceException.cs
- DiagnosticTrace.cs
- SplitContainer.cs
- ClientCultureInfo.cs
- DrawTreeNodeEventArgs.cs
- MenuTracker.cs
- ConsumerConnectionPointCollection.cs
- SQLConvert.cs
- BaseUriHelper.cs
- BindToObject.cs
- NavigationPropertyEmitter.cs
- SmtpReplyReaderFactory.cs
- DetailsViewUpdateEventArgs.cs
- ExpressionBuilderContext.cs
- XPathNavigatorReader.cs
- StandardRuntimeEnumValidatorAttribute.cs
- FixedNode.cs
- ExpressionVisitor.cs
- TextModifier.cs
- VectorCollectionConverter.cs
- DbProviderFactories.cs
- TemplateControlParser.cs
- DockAndAnchorLayout.cs
- Operand.cs
- GridViewColumnCollectionChangedEventArgs.cs
- ToolboxItemAttribute.cs
- MSG.cs
- TreeNode.cs
- ZoneMembershipCondition.cs
- DropTarget.cs
- TrackingWorkflowEventArgs.cs
- CodeGenerator.cs
- IdentityValidationException.cs
- EntityContainerRelationshipSetEnd.cs
- ProtectedConfigurationSection.cs
- OdbcConnectionOpen.cs
- Stylus.cs
- Sentence.cs
- DictionaryBase.cs
- PartitionerStatic.cs
- XslVisitor.cs
- TreeIterator.cs
- SoapIncludeAttribute.cs
- DesignerActionVerbItem.cs
- NotSupportedException.cs
- ToolboxComponentsCreatingEventArgs.cs
- CategoryNameCollection.cs
- ImageSourceValueSerializer.cs
- InitializingNewItemEventArgs.cs
- XmlEntityReference.cs
- GridViewDeletedEventArgs.cs
- FileLevelControlBuilderAttribute.cs
- ServiceOperationParameter.cs
- XmlNavigatorFilter.cs
- UIElement.cs
- NumericPagerField.cs
- LabelEditEvent.cs
- RSAPKCS1SignatureDeformatter.cs
- TextDecoration.cs
- ServiceX509SecurityTokenProvider.cs
- HttpEncoderUtility.cs
- AppDomainCompilerProxy.cs
- WriteTimeStream.cs
- DecoderFallback.cs
- BufferedGraphicsContext.cs
- HwndSourceKeyboardInputSite.cs
- SafeProcessHandle.cs
- PageHandlerFactory.cs
- GlyphRunDrawing.cs
- CompiledRegexRunner.cs
- RIPEMD160.cs
- ActivityDesignerResources.cs
- XmlSchemaImport.cs
- ToolStripDesignerAvailabilityAttribute.cs
- ObjectDataSourceSelectingEventArgs.cs
- ElementMarkupObject.cs
- XmlSchemaAnnotated.cs
- EventRouteFactory.cs
- StylusPointProperty.cs
- ToolBar.cs
- ObjectDataProvider.cs
- SessionStateSection.cs
- xsdvalidator.cs
- WebPartCatalogCloseVerb.cs
- TreeViewEvent.cs
- CryptoConfig.cs
- Cursor.cs
- OdbcConnectionHandle.cs
- DataObjectSettingDataEventArgs.cs
- ConsoleKeyInfo.cs
- BindStream.cs
- DataViewManagerListItemTypeDescriptor.cs