Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / QuerySubExprEliminator.cs / 1 / QuerySubExprEliminator.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.Dispatcher { using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Xml.XPath; internal class SubExpr { internal int var; internal int refCount; // opcodes internal bool useSpecial; Opcode ops; SubExpr parent; protected Listchildren; internal SubExpr(SubExpr parent, Opcode ops, int var) { this.children = new List (2); this.var = var; this.parent = parent; this.useSpecial = false; if(parent != null) { this.ops = new InternalSubExprOpcode(parent); this.ops.Attach(ops); this.useSpecial = parent is SubExprHeader && ((SelectOpcode)ops).Criteria.Axis.Type == QueryAxisType.Child; } else { this.ops = ops; } } internal Opcode FirstOp { get { if(this.parent == null) { return this.ops; } else { return this.ops.Next; } } } internal int Variable { get { return this.var; } } internal SubExprOpcode Add(Opcode opseq, SubExprEliminator elim) { Opcode start = this.FirstOp; Opcode ops = opseq; while(start != null && ops != null && start.Equals(ops)) { start = start.Next; ops = ops.Next; } if(ops == null) { if(start == null) { return new SubExprOpcode(this); } else { SubExpr e = this.BranchAt(start, elim); return new SubExprOpcode(e); } } else { if(start == null) { ops.DetachFromParent(); for(int i = 0; i < this.children.Count; ++i) { if(this.children[i].FirstOp.Equals(ops)) { return this.children[i].Add(ops, elim); } } SubExpr e = new SubExpr(this, ops, elim.NewVarID()); this.AddChild(e); return new SubExprOpcode(e); } else { SubExpr e = this.BranchAt(start, elim); ops.DetachFromParent(); SubExpr ee = new SubExpr(e, ops, elim.NewVarID()); e.AddChild(ee); return new SubExprOpcode(ee); } } } internal virtual void AddChild(SubExpr expr) { this.children.Add(expr); } SubExpr BranchAt(Opcode op, SubExprEliminator elim) { Opcode firstOp = this.FirstOp; if(this.parent != null) { this.parent.RemoveChild(this); } else { elim.Exprs.Remove(this); } firstOp.DetachFromParent(); op.DetachFromParent(); SubExpr e = new SubExpr(this.parent, firstOp, elim.NewVarID()); if(this.parent != null) { this.parent.AddChild(e); } else { elim.Exprs.Add(e); } e.AddChild(this); this.parent = e; this.ops = new InternalSubExprOpcode(e); this.ops.Attach(op); return e; } internal void CleanUp(SubExprEliminator elim) { if(this.refCount == 0) { if(this.children.Count == 0) { if(this.parent == null) { elim.Exprs.Remove(this); } else { this.parent.RemoveChild(this); this.parent.CleanUp(elim); } } else if(this.children.Count == 1) { SubExpr child = this.children[0]; Opcode op = child.FirstOp; op.DetachFromParent(); Opcode op2 = this.ops; while(op2.Next != null) { op2 = op2.Next; } op2.Attach(op); child.ops = this.ops; if(this.parent == null) { elim.Exprs.Remove(this); elim.Exprs.Add(child); child.parent = null; } else { this.parent.RemoveChild(this); this.parent.AddChild(child); child.parent = this.parent; } } } } internal void DecRef(SubExprEliminator elim) { this.refCount--; CleanUp(elim); } internal void Eval(ProcessingContext context) { int count = 0, marker = context.Processor.CounterMarker; Opcode op = this.ops; if(this.useSpecial) { op.EvalSpecial(context); context.LoadVariable(this.var); //context.Processor.CounterMarker = marker; return; } while(op != null) { op = op.Eval(context); } count = context.Processor.ElapsedCount(marker); //context.Processor.CounterMarker = marker; context.SaveVariable(this.var, count); } internal virtual void EvalSpecial(ProcessingContext context) { this.Eval(context); } internal void IncRef() { this.refCount++; } internal virtual void RemoveChild(SubExpr expr) { this.children.Remove(expr); } internal void Renumber(SubExprEliminator elim) { this.var = elim.NewVarID(); for(int i = 0; i < this.children.Count; ++i) { this.children[i].Renumber(elim); } } internal void Trim() { this.children.Capacity = this.children.Count; this.ops.Trim(); for(int i = 0; i < this.children.Count; ++i) { this.children[i].Trim(); } } #if DEBUG_FILTER internal void Write(TextWriter outStream) { outStream.WriteLine("======================="); outStream.WriteLine("= SubExpr #" + this.var.ToString() + " (" + this.refCount.ToString() + ")"); outStream.WriteLine("======================="); for(Opcode o = this.ops; o != null; o = o.Next) { outStream.WriteLine(o.ToString()); } outStream.WriteLine(""); for(int i = 0; i < this.children.Count; ++i) { this.children[i].Write(outStream); } } #endif } internal class SubExprHeader : SubExpr { // WS, [....], Can probably combine these // WS, [....], Make this data structure less ugly (if possible) Dictionary >> nameLookup; Dictionary indexLookup; internal SubExprHeader(Opcode ops, int var) : base(null, ops, var) { this.nameLookup = new Dictionary >>(); this.indexLookup = new Dictionary (); this.IncRef(); // Prevent cleanup } internal override void AddChild(SubExpr expr) { base.AddChild(expr); RebuildIndex(); if(expr.useSpecial) { NodeQName qname = ((SelectOpcode)(expr.FirstOp)).Criteria.QName; string ns = qname.Namespace; Dictionary > nextLookup; if(!this.nameLookup.TryGetValue(ns, out nextLookup)) { nextLookup = new Dictionary >(); this.nameLookup.Add(ns, nextLookup); } string name = qname.Name; List exprs = new List (); if(!nextLookup.TryGetValue(name, out exprs)) { exprs = new List (); nextLookup.Add(name, exprs); } exprs.Add(expr); } } internal override void EvalSpecial(ProcessingContext context) { int marker = context.Processor.CounterMarker; if(!context.LoadVariable(this.var)) { XPathMessageContext.HeaderFun.InvokeInternal(context,0); context.SaveVariable(this.var, context.Processor.ElapsedCount(marker)); } // WS, [....], see if we can put this array in the processor to save // an allocation. Perhaps we can use the variables slot we're going to fill NodeSequence[] childSequences = new NodeSequence[this.children.Count]; NodeSequence seq = context.Sequences[context.TopSequenceArg.basePtr].Sequence; for(int i = 0; i < this.children.Count; ++i) { childSequences[i] = context.CreateSequence(); childSequences[i].StartNodeset(); } // Perform the index SeekableXPathNavigator nav = seq[0].GetNavigator(); if(nav.MoveToFirstChild()) { do { if(nav.NodeType == XPathNodeType.Element) { List lst; string name = nav.LocalName; string ns = nav.NamespaceURI; Dictionary > nextLookup; if(this.nameLookup.TryGetValue(ns, out nextLookup)) { if(nextLookup.TryGetValue(name, out lst)) { for(int i = 0; i < lst.Count; ++i) { childSequences[this.indexLookup[lst[i]].i].Add(nav); } } if(nextLookup.TryGetValue(QueryDataModel.Wildcard, out lst)) { for(int i = 0; i < lst.Count; ++i) { childSequences[this.indexLookup[lst[i]].i].Add(nav); } } } if(this.nameLookup.TryGetValue(QueryDataModel.Wildcard, out nextLookup)) { if(nextLookup.TryGetValue(QueryDataModel.Wildcard, out lst)) { for(int i = 0; i < lst.Count; ++i) { childSequences[this.indexLookup[lst[i]].i].Add(nav); } } } } }while(nav.MoveToNext()); } int secondMarker = context.Processor.CounterMarker; for(int i = 0; i < this.children.Count; ++i) { if(this.children[i].useSpecial) { childSequences[i].StopNodeset(); context.Processor.CounterMarker = secondMarker; context.PushSequenceFrame(); context.PushSequence(childSequences[i]); Opcode op = this.children[i].FirstOp.Next; while(op != null) { op = op.Eval(context); } context.SaveVariable(this.children[i].var, context.Processor.ElapsedCount(marker)); context.PopSequenceFrame(); } else { context.ReleaseSequence(childSequences[i]); //context.SetVariable(this.children[i].Variable, null, 0); } } context.Processor.CounterMarker = marker; } internal void RebuildIndex() { this.indexLookup.Clear(); for(int i = 0; i < this.children.Count; ++i) { this.indexLookup.Add(this.children[i], new MyInt(i)); } } internal override void RemoveChild(SubExpr expr) { base.RemoveChild(expr); RebuildIndex(); if(expr.useSpecial) { NodeQName qname = ((SelectOpcode)(expr.FirstOp)).Criteria.QName; string ns = qname.Namespace; Dictionary > nextLookup; if(this.nameLookup.TryGetValue(ns, out nextLookup)) { string name = qname.Name; List exprs; if(nextLookup.TryGetValue(name, out exprs)) { exprs.Remove(expr); if(exprs.Count == 0) { nextLookup.Remove(name); } } if(nextLookup.Count == 0) { this.nameLookup.Remove(ns); } } } } internal class MyInt { internal int i; internal MyInt(int i) { this.i = i; } } } internal class SubExprEliminator { List exprList; int nextVar; Dictionary > removalMapping; internal SubExprEliminator() { this.removalMapping = new Dictionary >(); this.exprList = new List (); Opcode op = new XPathMessageFunctionCallOpcode(XPathMessageContext.HeaderFun, 0); SubExprHeader header = new SubExprHeader(op, 0); this.exprList.Add(header); this.nextVar = 1; } internal List Exprs { get { return this.exprList; } } internal int VariableCount { get { return this.nextVar; } } internal Opcode Add(XPathMessageFilter filter, Opcode ops) { List exprs = new List (); this.removalMapping.Add(filter, exprs); while(ops.Next != null) { ops = ops.Next; } Opcode res = ops; while(ops != null) { if(IsExprStarter(ops)) { Opcode start = ops; Opcode p = ops.Prev; ops.DetachFromParent(); ops = ops.Next; while(ops.ID == OpcodeID.Select) { ops = ops.Next; } ops.DetachFromParent(); SubExpr e = null; for(int i = 0; i < this.exprList.Count; ++i) { if(this.exprList[i].FirstOp.Equals(start)) { e = this.exprList[i]; break; } } SubExprOpcode o; if(e == null) { e = new SubExpr(null, start, NewVarID()); this.exprList.Add(e); o = new SubExprOpcode(e); } else { o = e.Add(start, this); } o.Expr.IncRef(); exprs.Add(o.Expr); o.Attach(ops); ops = o; if(p != null) { p.Attach(ops); } } res = ops; ops = ops.Prev; } return res; } internal static bool IsExprStarter(Opcode op) { if(op.ID == OpcodeID.SelectRoot) { return true; } if(op.ID == OpcodeID.XsltInternalFunction) { XPathMessageFunctionCallOpcode fop = (XPathMessageFunctionCallOpcode)op; if(fop.ReturnType == XPathResultType.NodeSet && fop.ArgCount == 0) { return true; } } return false; } internal int NewVarID() { return nextVar++; } internal void Remove(XPathMessageFilter filter) { List exprs; if(this.removalMapping.TryGetValue(filter, out exprs)) { for(int i = 0; i < exprs.Count; ++i) { exprs[i].DecRef(this); } this.removalMapping.Remove(filter); Renumber(); } } void Renumber() { this.nextVar = 0; for(int i = 0; i < this.exprList.Count; ++i) { this.exprList[i].Renumber(this); } } internal void Trim() { this.exprList.Capacity = this.exprList.Count; for(int i = 0; i < this.exprList.Count; ++i) { this.exprList[i].Trim(); } } #if DEBUG_FILTER internal void Write(TextWriter outStream) { for(int i = 0; i < this.exprList.Count; ++i) { this.exprList[i].Write(outStream); } } #endif } internal class SubExprOpcode : Opcode { protected SubExpr expr; internal SubExprOpcode(SubExpr expr) : base(OpcodeID.SubExpr) { this.expr = expr; } internal SubExpr Expr { get { return expr; } } internal override bool Equals(Opcode op) { if(base.Equals(op)) { SubExprOpcode sop = op as SubExprOpcode; if(sop != null) { return this.expr == sop.expr; } } return false; } internal override Opcode Eval(ProcessingContext context) { if(!context.LoadVariable(this.expr.Variable)) { context.PushSequenceFrame(); NodeSequence seq = context.CreateSequence(); seq.Add(context.Processor.ContextNode); context.PushSequence(seq); int marker = context.Processor.CounterMarker; try { this.expr.Eval(context); } catch (XPathNavigatorException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(this)); } catch (NavigatorInvalidBodyAccessException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(this)); } context.Processor.CounterMarker = marker; context.PopSequenceFrame(); context.PopSequenceFrame(); context.LoadVariable(this.expr.Variable); } return this.next; } internal override Opcode EvalSpecial(ProcessingContext context) { try { this.expr.EvalSpecial(context); } catch (XPathNavigatorException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(this)); } catch (NavigatorInvalidBodyAccessException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(this)); } return this.next; } #if DEBUG_FILTER public override string ToString() { return string.Format("{0} #{1}", base.ToString(), this.expr.Variable.ToString()); } #endif } internal class InternalSubExprOpcode : SubExprOpcode { internal InternalSubExprOpcode(SubExpr expr) : base(expr) { } internal override Opcode Eval(ProcessingContext context) { if(!context.LoadVariable(this.expr.Variable)) { this.expr.Eval(context); } return this.next; } internal override Opcode EvalSpecial(ProcessingContext context) { this.expr.EvalSpecial(context); return this.next; } } } // 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
- FormsAuthentication.cs
- LayoutEvent.cs
- ProtectedConfigurationProviderCollection.cs
- FamilyMapCollection.cs
- BuiltInExpr.cs
- DecoderNLS.cs
- TextTreeRootNode.cs
- ChangesetResponse.cs
- ReadWriteControlDesigner.cs
- CursorEditor.cs
- ActivityDesignerAccessibleObject.cs
- ChannelSettingsElement.cs
- MultiDataTrigger.cs
- ByteStack.cs
- NotifyIcon.cs
- _Semaphore.cs
- ManagedCodeMarkers.cs
- BufferedWebEventProvider.cs
- FlagPanel.cs
- ListViewTableCell.cs
- CriticalFinalizerObject.cs
- InternalTypeHelper.cs
- HitTestParameters3D.cs
- Double.cs
- RowVisual.cs
- RTLAwareMessageBox.cs
- SqlDataSource.cs
- CachedPathData.cs
- SrgsToken.cs
- BindingGroup.cs
- DateTime.cs
- BinaryFormatter.cs
- AssociationTypeEmitter.cs
- TypefaceMetricsCache.cs
- CodeTypeParameterCollection.cs
- SafeWaitHandle.cs
- MetadataException.cs
- OleDbMetaDataFactory.cs
- EventPrivateKey.cs
- SiteMapNodeItemEventArgs.cs
- EntityDataSourceEntityTypeFilterConverter.cs
- Html32TextWriter.cs
- StaticTextPointer.cs
- DataGridViewTextBoxCell.cs
- SendKeys.cs
- DiagnosticTraceSchemas.cs
- DeploymentSectionCache.cs
- Point.cs
- StringDictionaryCodeDomSerializer.cs
- ContractReference.cs
- ContainsRowNumberChecker.cs
- PasswordBox.cs
- SequenceRange.cs
- GridItem.cs
- GeneratedContractType.cs
- XmlLanguage.cs
- ConsoleCancelEventArgs.cs
- JsonQueryStringConverter.cs
- OuterGlowBitmapEffect.cs
- ContentTextAutomationPeer.cs
- DocumentOrderComparer.cs
- NoneExcludedImageIndexConverter.cs
- NoneExcludedImageIndexConverter.cs
- HtmlTableCellCollection.cs
- SingletonInstanceContextProvider.cs
- SynchronizedInputPattern.cs
- SessionEndingEventArgs.cs
- ServerProtocol.cs
- ControlCachePolicy.cs
- COAUTHINFO.cs
- OdbcTransaction.cs
- MailMessageEventArgs.cs
- ZipArchive.cs
- DecodeHelper.cs
- SortQuery.cs
- ComplusEndpointConfigContainer.cs
- Validator.cs
- FlowDocumentScrollViewer.cs
- UrlAuthFailedErrorFormatter.cs
- DesignTimeTemplateParser.cs
- SequenceQuery.cs
- CorrelationQueryBehavior.cs
- PropertyItemInternal.cs
- WCFBuildProvider.cs
- GlyphRun.cs
- ScriptManager.cs
- HtmlLink.cs
- FixedTextSelectionProcessor.cs
- EncodingDataItem.cs
- TreeNodeCollectionEditorDialog.cs
- tooltip.cs
- DropTarget.cs
- Console.cs
- XPathBuilder.cs
- PeerInputChannelListener.cs
- Activator.cs
- Registry.cs
- EdmProviderManifest.cs
- PrintDocument.cs
- InkSerializer.cs