internal override void Add(Opcode opcode) { LiteralRelationOpcode literal = this.ValidateOpcode(opcode); if (null == literal) { base.Add(opcode); return; } // Was this literal already added to the index? QueryBranch queryBranch = this.branchIndex[literal.Literal]; if (null == queryBranch) { // First time. New branch this.nextID++; queryBranch = new QueryBranch(literal, this.nextID); literal.Prev = this; this.branchIndex[literal.Literal] = queryBranch; } else { Fx.Assert(!object.ReferenceEquals(queryBranch.Branch, literal), ""); Fx.Assert(literal.ID == queryBranch.Branch.ID, ""); // literal already exists.. but what follows the literal must be branched // Should never get here, but just in case queryBranch.Branch.Next.Add(literal.Next); } literal.Flags |= OpcodeFlags.InConditional; this.AddAlwaysBranch(queryBranch, literal.Next); }
internal override void Match(int valIndex, ref Value val, QueryBranchResultSet results) { QueryBranch branch = null; if (ValueDataType.Sequence == val.Type) { NodeSequence sequence = val.Sequence; for (int i = 0; i < sequence.Count; ++i) { branch = this[sequence.Items[i].NumberValue()]; if (null != branch) { results.Add(branch, valIndex); } } } else { branch = this[val.ToDouble()]; if (null != branch) { results.Add(branch, valIndex); } } }
internal override void Match(int valIndex, ref Value val, QueryBranchResultSet results) { QueryBranch branch = null; if (ValueDataType.Sequence == val.Type) { NodeSequence sequence = val.Sequence; for (int i = 0; i < sequence.Count; i++) { branch = this[sequence.Items[i].StringValue()]; if (branch != null) { results.Add(branch, valIndex); } } } else { branch = this[val.String]; if (branch != null) { results.Add(branch, valIndex); } } }
internal override void Add(Opcode opcode) { LiteralRelationOpcode opcode2 = this.ValidateOpcode(opcode); if (opcode2 == null) { base.Add(opcode); } else { QueryBranch literalBranch = this.branchIndex[opcode2.Literal]; if (literalBranch == null) { this.nextID++; literalBranch = new QueryBranch(opcode2, this.nextID); opcode2.Prev = this; this.branchIndex[opcode2.Literal] = literalBranch; } else { literalBranch.Branch.Next.Add(opcode2.Next); } opcode2.Flags |= OpcodeFlags.InConditional; this.AddAlwaysBranch(literalBranch, opcode2.Next); } }
internal override void Add(Opcode opcode) { LiteralRelationOpcode opcode2 = this.ValidateOpcode(opcode); if (opcode2 == null) { base.Add(opcode); } else { QueryBranch literalBranch = this.branchIndex[opcode2.Literal]; if (literalBranch == null) { this.nextID++; literalBranch = new QueryBranch(opcode2, this.nextID); opcode2.Prev = this; this.branchIndex[opcode2.Literal] = literalBranch; } else { literalBranch.Branch.Next.Add(opcode2.Next); } opcode2.Flags |= OpcodeFlags.InConditional; this.AddAlwaysBranch(literalBranch, opcode2.Next); } }
private void AddAlwaysBranch(QueryBranch literalBranch, Opcode next) { if (OpcodeID.Branch == next.ID) { BranchOpcode opcode = (BranchOpcode) next; OpcodeList branches = opcode.Branches; for (int i = 0; i < branches.Count; i++) { Opcode opcode2 = branches[i]; if (this.IsAlwaysBranch(opcode2)) { this.AlwaysBranches.AddInOrder(new QueryBranch(opcode2, literalBranch.ID)); } else { opcode2.Flags |= OpcodeFlags.NoContextCopy; } } } else if (this.IsAlwaysBranch(next)) { this.AlwaysBranches.AddInOrder(new QueryBranch(next, literalBranch.ID)); } else { next.Flags |= OpcodeFlags.NoContextCopy; } }
private void AddAlwaysBranch(QueryBranch literalBranch, Opcode next) { if (OpcodeID.Branch == next.ID) { BranchOpcode opcode = (BranchOpcode)next; OpcodeList branches = opcode.Branches; for (int i = 0; i < branches.Count; i++) { Opcode opcode2 = branches[i]; if (this.IsAlwaysBranch(opcode2)) { this.AlwaysBranches.AddInOrder(new QueryBranch(opcode2, literalBranch.ID)); } else { opcode2.Flags |= OpcodeFlags.NoContextCopy; } } } else if (this.IsAlwaysBranch(next)) { this.AlwaysBranches.AddInOrder(new QueryBranch(next, literalBranch.ID)); } else { next.Flags |= OpcodeFlags.NoContextCopy; } }
void AddAlwaysBranch(QueryBranch literalBranch, Opcode next) { if (OpcodeID.Branch == next.ID) { BranchOpcode opcode = (BranchOpcode)next; OpcodeList branches = opcode.Branches; for (int i = 0; i < branches.Count; ++i) { Opcode branch = branches[i]; if (this.IsAlwaysBranch(branch)) { this.AlwaysBranches.AddInOrder(new QueryBranch(branch, literalBranch.ID)); } else { branch.Flags |= OpcodeFlags.NoContextCopy; } } } else { Fx.Assert(!next.TestFlag(OpcodeFlags.Branch), ""); if (this.IsAlwaysBranch(next)) { this.AlwaysBranches.AddInOrder(new QueryBranch(next, literalBranch.ID)); } else { next.Flags |= OpcodeFlags.NoContextCopy; } } }
internal override Opcode Locate(Opcode opcode) { QueryBranch branch = this.GetBranch(opcode); if (branch != null) { return(branch.Branch); } return(null); }
// Whether or not the given literal matches, we must always take the branch rooted at 'next' // Add to the AlwaysBranches table if not already there.. internal void AddAlwaysBranch(LiteralRelationOpcode literal, Opcode next) { Fx.Assert(null != literal && null != next, ""); QueryBranch literalBranch = this.branchIndex[literal.Literal]; Fx.Assert(null != literalBranch, ""); this.AddAlwaysBranch(literalBranch, next); }
internal override Opcode Locate(Opcode opcode) { QueryBranch queryBranch = this.GetBranch(opcode); if (null != queryBranch) { return(queryBranch.Branch); } return(null); }
internal void InsertAt(int index, QueryBranch branch) { if (this.count == this.branches.Length) { this.Grow(); } if (index < this.count) { Array.Copy(this.branches, index, this.branches, index + 1, this.count - index); } this.branches[index] = branch; this.count++; }
internal void AddInOrder(QueryBranch branch) { int index = 0; while (index < this.count) { if (this.branches[index].ID >= branch.ID) { break; } index++; } this.InsertAt(index, branch); }
private void InvokeMultiMatch(ProcessingContext context) { int counterMarker = context.Processor.CounterMarker; BranchContext context2 = new BranchContext(context); int count = this.resultTable.Count; int num3 = 0; while (num3 < count) { ProcessingContext context3; QueryBranchResult result = this.resultTable[num3]; QueryBranch branch = result.Branch; Opcode next = branch.Branch.Next; if (next.TestFlag(OpcodeFlags.NoContextCopy)) { context3 = context; } else { context3 = context2.Create(); } this.InitResults(context3); context3.Values[context3.TopArg[result.ValIndex]].Boolean = true; while (++num3 < count) { result = this.resultTable[num3]; if (branch.ID != result.Branch.ID) { break; } context3.Values[context3.TopArg[result.ValIndex]].Boolean = true; } try { context3.EvalCodeBlock(next); } catch (XPathNavigatorException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception.Process(next)); } catch (NavigatorInvalidBodyAccessException exception2) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception2.Process(next)); } context.Processor.CounterMarker = counterMarker; } context2.Release(); }
internal void AddInOrder(QueryBranch branch) { // Insert in sorted order always int index; for (index = 0; index < this.count; ++index) { // if current node is >= key, we've found the spot if (this.branches[index].ID >= branch.ID) { break; } } this.InsertAt(index, branch); }
internal QueryBranch GetBranch(Opcode op) { if (op.TestFlag(OpcodeFlags.Literal)) { LiteralRelationOpcode opcode = this.ValidateOpcode(op); if (opcode != null) { QueryBranch branch = this.branchIndex[opcode.Literal]; if ((branch != null) && (branch.Branch.ID == op.ID)) { return(branch); } } } return(null); }
internal void Trim() { if (this.count < this.branches.Length) { QueryBranch[] destinationArray = new QueryBranch[this.count]; Array.Copy(this.branches, destinationArray, this.count); this.branches = destinationArray; } for (int i = 0; i < this.branches.Length; i++) { if ((this.branches[i] != null) && (this.branches[i].Branch != null)) { this.branches[i].Branch.Trim(); } } }
private void InvokeNonMatch(ProcessingContext context, QueryBranch branch) { context.PushFrame(); context.Push(false, this.resultCount); try { context.EvalCodeBlock(branch.Branch); } catch (XPathNavigatorException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception.Process(branch.Branch)); } catch (NavigatorInvalidBodyAccessException exception2) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception2.Process(branch.Branch)); } }
internal void Trim() { if (this.count < this.branches.Length) { QueryBranch[] branches = new QueryBranch[this.count]; Array.Copy(this.branches, branches, this.count); this.branches = branches; } for (int i = 0; i < this.branches.Length; ++i) { if (this.branches[i] != null && this.branches[i].Branch != null) { this.branches[i].Branch.Trim(); } } }
internal QueryBranch GetBranch(Opcode op) { if (op.TestFlag(OpcodeFlags.Literal)) { LiteralRelationOpcode relOp = this.ValidateOpcode(op); if (null != relOp) { QueryBranch branch = this.branchIndex[relOp.Literal]; if (null != branch && branch.Branch.ID == op.ID) { return(branch); } } } return(null); }
void Match(int valIndex, double point, QueryBranchResultSet results) { IntervalTreeTraverser traverser = new IntervalTreeTraverser(point, this.intervalTree.Root); while (traverser.MoveNext()) { IntervalCollection matches = traverser.Slot; for (int i = 0, count = matches.Count; i < count; ++i) { QueryBranch branch = matches[i].Branch; if (null != branch) { results.Add(branch, valIndex); } } } }
private void Match(int valIndex, double point, QueryBranchResultSet results) { IntervalTreeTraverser traverser = new IntervalTreeTraverser(point, this.intervalTree.Root); while (traverser.MoveNext()) { IntervalCollection slot = traverser.Slot; int num = 0; int count = slot.Count; while (num < count) { QueryBranch branch = slot[num].Branch; if (branch != null) { results.Add(branch, valIndex); } num++; } } }
internal override void RemoveChild(Opcode opcode) { LiteralRelationOpcode opcode2 = this.ValidateOpcode(opcode); QueryBranch branch = this.branchIndex[opcode2.Literal]; this.branchIndex.Remove(opcode2.Literal); Opcode opcode1 = branch.Branch; opcode1.Flags &= ~OpcodeFlags.NoContextCopy; if (this.alwaysBranches != null) { int index = this.alwaysBranches.IndexOfID(branch.ID); if (index >= 0) { this.alwaysBranches.RemoveAt(index); if (this.alwaysBranches.Count == 0) { this.alwaysBranches = null; } } } }
internal override void RemoveChild(Opcode opcode) { LiteralRelationOpcode literal = this.ValidateOpcode(opcode); Fx.Assert(null != literal, ""); QueryBranch branch = this.branchIndex[literal.Literal]; Fx.Assert(null != branch, ""); this.branchIndex.Remove(literal.Literal); branch.Branch.Flags &= (~OpcodeFlags.NoContextCopy); if (null != this.alwaysBranches) { int removeAt = this.alwaysBranches.IndexOfID(branch.ID); if (removeAt >= 0) { this.alwaysBranches.RemoveAt(removeAt); if (0 == this.alwaysBranches.Count) { this.alwaysBranches = null; } } } }
internal QueryBranchResult(QueryBranch branch, int valIndex) { this.branch = branch; this.valIndex = valIndex; }
void InvokeMultiMatch(ProcessingContext context) { int marker = context.Processor.CounterMarker; BranchContext branchContext = new BranchContext(context); // struct. quick. int resultTableCount = this.resultTable.Count; for (int i = 0; i < resultTableCount;) { QueryBranchResult result = this.resultTable[i]; QueryBranch branch = result.Branch; // Branches can arbitrarily alter context stacks, rendering them unuseable to other branches. // Therefore, before following a branch, we have to clone the context. Cloning is relatively efficient because // can avoid allocating memory in most cases. We cannot, unfortunately, avoid Array copies. // // Optimization: // We can avoid cloning altogether when we can predict that the branch does NOT tamper with the stack, // or does so in a predictable way. If we are sure that we can restore the stack easily after the branch // completes, we have no reason to copy the stack. ProcessingContext newContext; Opcode nextOpcode = branch.Branch.Next; if (nextOpcode.TestFlag(OpcodeFlags.NoContextCopy)) { newContext = context; } else { newContext = branchContext.Create(); } this.InitResults(newContext); // // Matches are sorted by their branch ID. // It is very possible that the a literal matches multiple times, especially when the value being // compared is a sequence. A literal may match multiple items in a single sequence // OR multiple items in multiple sequences. If there were 4 context sequences, the literal may have // matched one item each in 3 of them. The branchID for that literal will be present 3 times in the // resultTable. // Sorting the matches groups them by their branch Ids. We only want to take the branch ONCE, so now we // iterate over all the duplicate matches.. // result.ValIndex will give us the index of the value that was matched. Thus if the 3rd sequence // matched, ValIndex == 2 (0 based) newContext.Values[newContext.TopArg[result.ValIndex]].Boolean = true; while (++i < resultTableCount) { result = this.resultTable[i]; if (branch.ID == result.Branch.ID) { newContext.Values[newContext.TopArg[result.ValIndex]].Boolean = true; } else { break; } } try { newContext.EvalCodeBlock(nextOpcode); } catch (XPathNavigatorException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(nextOpcode)); } catch (NavigatorInvalidBodyAccessException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(nextOpcode)); } context.Processor.CounterMarker = marker; } branchContext.Release(); }
internal void AddAlwaysBranch(LiteralRelationOpcode literal, Opcode next) { QueryBranch literalBranch = this.branchIndex[literal.Literal]; this.AddAlwaysBranch(literalBranch, next); }
internal void Add(QueryBranch entry) { Fx.Assert(null != entry, ""); this.InsertAt(this.count, entry); }
void Grow() { QueryBranch[] branches = new QueryBranch[this.branches.Length + 1]; Array.Copy(this.branches, branches, this.branches.Length); this.branches = branches; }
internal void Set(QueryBranch branch, int valIndex) { this.branch = branch; this.valIndex = valIndex; }
private void InvokeNonMatch(ProcessingContext context, QueryBranch branch) { context.PushFrame(); context.Push(false, this.resultCount); try { context.EvalCodeBlock(branch.Branch); } catch (XPathNavigatorException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception.Process(branch.Branch)); } catch (NavigatorInvalidBodyAccessException exception2) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception2.Process(branch.Branch)); } }
internal void Add(QueryBranch branch, int valIndex) { this.results.Add(new QueryBranchResult(branch, valIndex)); }
private void Grow() { QueryBranch[] destinationArray = new QueryBranch[this.branches.Length + 1]; Array.Copy(this.branches, destinationArray, this.branches.Length); this.branches = destinationArray; }
internal QueryBranchResult(QueryBranch branch, int valIndex) { this.branch = branch; this.valIndex = valIndex; }