/// <summary> /// Insert the specified sequence into the list of sequences to be merged. /// Insert it in reverse document order with respect to the current nodes in other sequences. /// </summary> private void InsertSequence(IEnumerator <XPathNavigator> sequence) { for (int i = _sequencesToMerge.Count - 1; i >= 0; i--) { int cmp = _runtime.ComparePosition(sequence.Current, _sequencesToMerge[i].Current); if (cmp == -1) { // Insert after current item _sequencesToMerge.Insert(i + 1, sequence); return; } else if (cmp == 0) { // Found duplicate, so skip the duplicate if (!sequence.MoveNext()) { // No more nodes, so don't insert anything return; } // Next node must be after current node in document order, so don't need to reset loop } } // Insert at beginning of list _sequencesToMerge.Insert(0, sequence); }
/// <summary> /// Position this iterator to the next node in the union. /// </summary> public SetIteratorResult MoveNext(XPathNavigator nestedNavigator) { switch (_state) { case IteratorState.InitLeft: // Fetched node from left iterator, now get initial node from right iterator _navLeft = nestedNavigator; _state = IteratorState.NeedRight; return(SetIteratorResult.InitRightIterator); case IteratorState.NeedLeft: _navLeft = nestedNavigator; break; case IteratorState.NeedRight: _navRight = nestedNavigator; break; case IteratorState.NeedLeftAndRight: // After fetching left node, still need right node _navLeft = nestedNavigator; _state = IteratorState.NeedRight; return(SetIteratorResult.NeedRightNode); case IteratorState.HaveCurrent: // Just returned left node as current, so fetch new left node Debug.Assert(nestedNavigator == null, "null is passed to MoveNext after IteratorState.HaveCurrent has been returned."); _state = IteratorState.NeedLeft; return(SetIteratorResult.NeedLeftNode); } if (_navLeft == null) { // If navLeft is null, then difference operation is complete return(SetIteratorResult.NoMoreNodes); } else if (_navRight != null) { int order = _runtime.ComparePosition(_navLeft, _navRight); // If navLeft is positioned to same node as navRight, if (order == 0) { // Skip navLeft and navRight _state = IteratorState.NeedLeftAndRight; return(SetIteratorResult.NeedLeftNode); } // If navLeft is after navRight in document order, then skip navRight if (order > 0) { _state = IteratorState.NeedRight; return(SetIteratorResult.NeedRightNode); } } // Return navLeft _state = IteratorState.HaveCurrent; return(SetIteratorResult.HaveCurrentNode); }
/// <summary> /// Position this iterator to the next node in the union. /// </summary> public SetIteratorResult MoveNext(XPathNavigator nestedNavigator) { int order; switch (_state) { case IteratorState.InitLeft: // Fetched node from left iterator, now get initial node from right iterator _navLeft = nestedNavigator; _state = IteratorState.NeedRight; return(SetIteratorResult.InitRightIterator); case IteratorState.NeedLeft: _navLeft = nestedNavigator; break; case IteratorState.NeedRight: _navRight = nestedNavigator; break; case IteratorState.NeedLeftAndRight: // After fetching left node, still need right node _navLeft = nestedNavigator; _state = IteratorState.NeedRight; return(SetIteratorResult.NeedRightNode); case IteratorState.HaveCurrent: // Just returned left node as current, so fetch new left and right nodes Debug.Assert(nestedNavigator == null, "null is passed to MoveNext after IteratorState.HaveCurrent has been returned."); _state = IteratorState.NeedLeftAndRight; return(SetIteratorResult.NeedLeftNode); } if (_navLeft == null || _navRight == null) { // No more nodes from either left or right iterator (or both), so iteration is complete return(SetIteratorResult.NoMoreNodes); } // Intersect left and right sets order = _runtime.ComparePosition(_navLeft, _navRight); if (order < 0) { // If navLeft is positioned to a node that is before navRight, skip left node _state = IteratorState.NeedLeft; return(SetIteratorResult.NeedLeftNode); } else if (order > 0) { // If navLeft is positioned to a node that is after navRight, so skip right node _state = IteratorState.NeedRight; return(SetIteratorResult.NeedRightNode); } // Otherwise, navLeft is positioned to the same node as navRight, so found one item in the intersection _state = IteratorState.HaveCurrent; return(SetIteratorResult.HaveCurrentNode); }
/// <summary> /// Position this iterator to the next node in the union. /// </summary> public SetIteratorResult MoveNext(XPathNavigator nestedNavigator) { switch (_state) { case IteratorState.InitLeft: // Fetched node from left iterator, now get initial node from right iterator _navOther = nestedNavigator; _state = IteratorState.NeedRight; return(SetIteratorResult.InitRightIterator); case IteratorState.NeedLeft: _navCurr = nestedNavigator; _state = IteratorState.LeftIsCurrent; break; case IteratorState.NeedRight: _navCurr = nestedNavigator; _state = IteratorState.RightIsCurrent; break; case IteratorState.LeftIsCurrent: // Just returned left node as current, so get new left _state = IteratorState.NeedLeft; return(SetIteratorResult.NeedLeftNode); case IteratorState.RightIsCurrent: // Just returned right node as current, so get new right _state = IteratorState.NeedRight; return(SetIteratorResult.NeedRightNode); } // Merge left and right nodes if (_navCurr == null) { // If both navCurr and navOther are null, then iteration is complete if (_navOther == null) { return(SetIteratorResult.NoMoreNodes); } Swap(); } else if (_navOther != null) { int order = _runtime.ComparePosition(_navOther, _navCurr); // If navCurr is positioned to same node as navOther, if (order == 0) { // Skip navCurr, since it is a duplicate if (_state == IteratorState.LeftIsCurrent) { _state = IteratorState.NeedLeft; return(SetIteratorResult.NeedLeftNode); } _state = IteratorState.NeedRight; return(SetIteratorResult.NeedRightNode); } // If navOther is before navCurr in document order, then swap navCurr with navOther if (order < 0) { Swap(); } } // Return navCurr return(SetIteratorResult.HaveCurrentNode); }