Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / QueryTreeBuilder.cs / 1 / QueryTreeBuilder.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Dispatcher { using System.Diagnostics; internal class QueryTreeBuilder { Diverger diverger; Opcode lastOpcode; internal QueryTreeBuilder() { } internal Opcode LastOpcode { get { return this.lastOpcode; } } internal Opcode Build(Opcode tree, OpcodeBlock newBlock) { if (null == tree) { this.lastOpcode = newBlock.Last; return newBlock.First; } this.diverger = new Diverger(tree, newBlock.First); if (!this.diverger.Find()) { // The opcodes in newBlock already have equivalents or identical opcodes // in the query tree that can do the job DiagnosticUtility.DebugAssert(this.diverger.TreePath.Count > 0, ""); this.lastOpcode = this.diverger.TreePath[this.diverger.TreePath.Count - 1]; return tree; } DiagnosticUtility.DebugAssert(this.diverger.TreePath.Count == this.diverger.InsertPath.Count, ""); // We can reuse opcodes upto this.diverger.TreePath[this.diverger.TreePath.Count - 1] // The remainder of the code in newBlock must be executed as is... if (null == this.diverger.TreeOpcode) { // We reached a leaf in the query tree // Simply add the remainder of the inserted code to the end of the tree path.. this.diverger.TreePath[this.diverger.TreePath.Count - 1].Attach(this.diverger.InsertOpcode); } else { // Merge in the remaider of the new code block into the query tree // The first diverging opcodes follow the last entry in each path this.diverger.TreeOpcode.Add(this.diverger.InsertOpcode); } this.lastOpcode = newBlock.Last; if (OpcodeID.MatchMultipleFilterResult == this.diverger.InsertOpcode.ID) { // The complete new block was merged in, except for the the actual result opcode, which never // automatically merges. This means that the new block found all of its opcodes in common with // the tree if (OpcodeID.Branch == this.diverger.TreeOpcode.ID) { OpcodeList branches = (((BranchOpcode) this.diverger.TreeOpcode).Branches); for (int i = 0, count = branches.Count; i < count; ++i) { if (OpcodeID.MatchMultipleFilterResult == branches[i].ID) { this.lastOpcode = branches[i]; break; } } } else if (OpcodeID.MatchMultipleFilterResult == this.diverger.TreeOpcode.ID) { this.lastOpcode = this.diverger.TreeOpcode; } } // Since we'll be diverging, any jumps that preceeded and leapt past the divergence point // will have to be branched this.FixupJumps(); return tree; } void FixupJumps() { QueryBuffertreePath = this.diverger.TreePath; QueryBuffer insertPath = this.diverger.InsertPath; for (int i = 0; i < insertPath.Count; ++i) { if (insertPath[i].TestFlag(OpcodeFlags.Jump)) { DiagnosticUtility.DebugAssert(treePath[i].ID == insertPath[i].ID, ""); JumpOpcode insertJump = (JumpOpcode) insertPath[i]; // Opcodes in 'insertPath' have equivalent opcodes in the query tree: i.e. the query tree contains an // an equivalent execution path (upto the point of divergence naturally) that will produce in an identical // result. The remainder of the query tree (anything that lies beyond the point of divergence) represents // a distinct execution path and is grafted onto the tree as a new branch. In fact, we simply break off // the remainder from the query being inserted and graft it onto the query tree. // If there are jumps on the insert path that jump to opcodes NOT in the insert path, then the jumps // will reach opcodes in the new branch we will add(see above). However, because the actual jump opcodes // are shared (used as is from the query tree), the actual jump must also be branched. One jump will // continue to jump to the original opcode and the second new one will jump to an opcode in the grafted branch. if (-1 == insertPath.IndexOf(insertJump.Jump, i + 1)) { DiagnosticUtility.DebugAssert(insertJump.Jump.ID == OpcodeID.BlockEnd, ""); BlockEndOpcode jumpTo = (BlockEndOpcode) insertJump.Jump; // no longer jumping from insertJump to jumpTo insertJump.RemoveJump(jumpTo); // Instead, jumping from treePath[i] to jumpTo JumpOpcode treeJump = (JumpOpcode) treePath[i]; treeJump.AddJump(jumpTo); } } } } // Can handle queries being merged into trees but not trees merged into trees. // In other words, no branch opcodes in the query being inserted internal struct Diverger { Opcode treeOpcode; QueryBuffer treePath; QueryBuffer insertPath; Opcode insertOpcode; internal Diverger(Opcode tree, Opcode insert) { this.treePath = new QueryBuffer (16); this.insertPath = new QueryBuffer (16); this.treeOpcode = tree; this.insertOpcode = insert; } internal Opcode InsertOpcode { get { return this.insertOpcode; } } internal QueryBuffer InsertPath { get { return this.insertPath; } } internal Opcode TreeOpcode { get { return this.treeOpcode; } } internal QueryBuffer TreePath { get { return this.treePath; } } // Stops at the last common node on each internal bool Find() { Opcode treeNext = null; while (true) { if (null == this.treeOpcode && null == this.insertOpcode) { return false; // no diverge. both ran out at the same time } if (null == this.insertOpcode) { return false; // Ran out before tree did. No divergence. } if (null == this.treeOpcode) { return true; // tree ran out before insert. Divergence } if (this.treeOpcode.TestFlag(OpcodeFlags.Branch)) { treeNext = this.treeOpcode.Locate(this.insertOpcode); if (null == treeNext) { return true; // divergence } this.treeOpcode = treeNext; treeNext = treeNext.Next; } else { if (!this.treeOpcode.Equals(this.insertOpcode)) { return true; // divergence, obviously } treeNext = this.treeOpcode.Next; } // No divergence. Add to paths this.treePath.Add(this.treeOpcode); this.insertPath.Add(this.insertOpcode); this.insertOpcode = this.insertOpcode.Next; this.treeOpcode = treeNext; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataControlFieldHeaderCell.cs
- ItemContainerGenerator.cs
- AppSettingsExpressionBuilder.cs
- ListControlConvertEventArgs.cs
- CompositeActivityValidator.cs
- MouseGesture.cs
- WebControl.cs
- OwnerDrawPropertyBag.cs
- RewritingSimplifier.cs
- arabicshape.cs
- Rectangle.cs
- SchemaSetCompiler.cs
- DBParameter.cs
- CollectionEditorDialog.cs
- SimpleHandlerBuildProvider.cs
- XmlHierarchicalEnumerable.cs
- SQLMoney.cs
- GenericsInstances.cs
- DefaultBinder.cs
- IgnoreDeviceFilterElement.cs
- SymLanguageType.cs
- HostedTransportConfigurationManager.cs
- TextBox.cs
- XmlRootAttribute.cs
- XmlUtil.cs
- PropertyGeneratedEventArgs.cs
- NavigatorInput.cs
- Point3DCollectionConverter.cs
- ProxyHelper.cs
- TextEvent.cs
- DataGridViewCell.cs
- ToolboxItemWrapper.cs
- TableLayoutPanel.cs
- XmlQueryRuntime.cs
- MultiDataTrigger.cs
- ParamArrayAttribute.cs
- SchemaConstraints.cs
- Int16.cs
- TemplatedMailWebEventProvider.cs
- UInt16.cs
- FixedSOMGroup.cs
- compensatingcollection.cs
- StackBuilderSink.cs
- RawStylusActions.cs
- SchemaImporterExtension.cs
- SectionInput.cs
- EventMappingSettings.cs
- XmlNamespaceDeclarationsAttribute.cs
- PropertyGrid.cs
- FilterInvalidBodyAccessException.cs
- DataGridCommandEventArgs.cs
- PhonemeConverter.cs
- SafeCryptHandles.cs
- UnitControl.cs
- Native.cs
- ApplyTemplatesAction.cs
- WebPartDisplayModeCollection.cs
- TaiwanCalendar.cs
- MsmqIntegrationBinding.cs
- XmlWellformedWriter.cs
- InkPresenterAutomationPeer.cs
- Html32TextWriter.cs
- RecommendedAsConfigurableAttribute.cs
- GroupDescription.cs
- VolatileEnlistmentState.cs
- EntityEntry.cs
- PersonalizationState.cs
- Pair.cs
- StyleReferenceConverter.cs
- PeerIPHelper.cs
- PatternMatcher.cs
- keycontainerpermission.cs
- ServiceModelConfigurationSectionCollection.cs
- XmlUtil.cs
- LineServicesCallbacks.cs
- DataGridViewCellStyleChangedEventArgs.cs
- CodeMethodInvokeExpression.cs
- CannotUnloadAppDomainException.cs
- Rotation3D.cs
- Crc32.cs
- webclient.cs
- SystemFonts.cs
- CalendarDay.cs
- SchemaCompiler.cs
- DefaultHttpHandler.cs
- DataMisalignedException.cs
- safemediahandle.cs
- WrapPanel.cs
- NonSerializedAttribute.cs
- IgnorePropertiesAttribute.cs
- FixedBufferAttribute.cs
- CheckBoxStandardAdapter.cs
- AdPostCacheSubstitution.cs
- BaseParagraph.cs
- EnterpriseServicesHelper.cs
- GroupQuery.cs
- XmlExceptionHelper.cs
- XamlSerializationHelper.cs
- MsdtcClusterUtils.cs
- TypeBrowser.xaml.cs