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
- FirstMatchCodeGroup.cs
- TextElementEditingBehaviorAttribute.cs
- AliasGenerator.cs
- EncryptedXml.cs
- Internal.cs
- HttpClientCertificate.cs
- ActivitySurrogate.cs
- HttpRuntimeSection.cs
- _NtlmClient.cs
- ExpressionBuilder.cs
- FigureParaClient.cs
- TemplateComponentConnector.cs
- VerificationException.cs
- UICuesEvent.cs
- SqlRecordBuffer.cs
- DeflateStreamAsyncResult.cs
- IndexOutOfRangeException.cs
- XmlDataImplementation.cs
- HotSpot.cs
- MethodBody.cs
- PrincipalPermission.cs
- Decimal.cs
- JsonEncodingStreamWrapper.cs
- RootProfilePropertySettingsCollection.cs
- DataGridViewCellValueEventArgs.cs
- ComboBoxAutomationPeer.cs
- AutomationEventArgs.cs
- UriTemplateEquivalenceComparer.cs
- CallbackException.cs
- NegotiateStream.cs
- OdbcTransaction.cs
- HttpBrowserCapabilitiesWrapper.cs
- CollectionEditorDialog.cs
- HttpCapabilitiesEvaluator.cs
- EntityTypeEmitter.cs
- NumericUpDownAccelerationCollection.cs
- WsrmMessageInfo.cs
- ServiceBuildProvider.cs
- RegexInterpreter.cs
- CompareValidator.cs
- InvokeWebService.cs
- ReadOnlyDictionary.cs
- SupportingTokenProviderSpecification.cs
- WebPartActionVerb.cs
- PointCollectionConverter.cs
- OracleString.cs
- DataSourceHelper.cs
- Thickness.cs
- DescendentsWalkerBase.cs
- MobileResource.cs
- HighlightVisual.cs
- BehaviorDragDropEventArgs.cs
- GenericsInstances.cs
- DivideByZeroException.cs
- Package.cs
- IdentityNotMappedException.cs
- FilteredReadOnlyMetadataCollection.cs
- Privilege.cs
- HtmlLink.cs
- HwndHost.cs
- PrinterUnitConvert.cs
- ReferencedAssemblyResolver.cs
- MessageQueuePermissionEntry.cs
- ConfigurationProperty.cs
- CurrentChangedEventManager.cs
- SessionEndedEventArgs.cs
- ProcessModuleDesigner.cs
- HttpResponseHeader.cs
- CreateUserErrorEventArgs.cs
- Avt.cs
- EntityDataSourceConfigureObjectContextPanel.cs
- HtmlTableRowCollection.cs
- ScrollViewerAutomationPeer.cs
- ValueTable.cs
- DataGridViewRowPrePaintEventArgs.cs
- DrawingImage.cs
- HttpInputStream.cs
- BufferBuilder.cs
- HtmlWindowCollection.cs
- Style.cs
- EnumValidator.cs
- TabControl.cs
- ParserOptions.cs
- HttpValueCollection.cs
- DispatcherOperation.cs
- SByte.cs
- ReachPageContentSerializer.cs
- DropShadowBitmapEffect.cs
- ElementUtil.cs
- InstalledFontCollection.cs
- FrameworkPropertyMetadata.cs
- HelpKeywordAttribute.cs
- FieldAccessException.cs
- BindingExpressionUncommonField.cs
- prompt.cs
- TransformerTypeCollection.cs
- Funcletizer.cs
- HtmlInputButton.cs
- DataTable.cs
- OleDbConnection.cs