/// <summary> /// Advances iteration. /// </summary> /// <returns>False if at end of iteration, true otherwise.</returns> public override bool MoveNext() { if (_leftSource == null) { _leftSource = (InternalRecordSource)_inputList[0]; _rightSource = (InternalRecordSource)_inputList[1]; // advance the right side from the start so that // a record is there waiting to be compared to _rightNotDone = _rightSource.MoveNext(); if (_rightNotDone) _currentRightRecord = _rightSource.CurrentRecord; } _leftNotDone = _leftSource.MoveNext(); if (!_leftNotDone) return false; _currentLeftRecord = _leftSource.CurrentRecord; // Don't need a match to create a joiner if (_joiner == null) { _joiner = new RecordJoiner(_leftSource, _rightSource, _tableColumnSeparator); } // advance the right side int diff = -1; bool firstTime = true; while (diff < 0) { // the first time we test we check against the currentRightSource // (i.e. don't go in this block) since we allow dups on the left side. if (!firstTime && _rightNotDone) { _rightSource.MoveNextHint = _currentLeftRecord.Key; _rightNotDone = _rightSource.MoveNext(); if (!_rightNotDone) _currentRightRecord = null; else _currentRightRecord = _rightSource.CurrentRecord; } if (_currentRightRecord != null) { diff = TMSNStoreUtils.Utf8BytesCompare(_currentLeftRecord.KeyBytes, _currentRightRecord.KeyBytes); } else diff = 1; // break out of loop firstTime = false; } CurrentRecord = _joiner.Join(_currentLeftRecord, _currentRightRecord, (diff == 0)); return true; }
/// <summary> /// Advances Iteration. /// </summary> /// <returns>False if at end of iteration, true otherwise.</returns> public override bool MoveNext() { if (_leftSource == null) { _leftSource = (InternalRecordSource)_inputList[0]; _rightSource = (InternalRecordSource)_inputList[1]; _rightNotDone = _rightSource.MoveNext(); if (!_rightNotDone) return false; //_currentRightRecord = _rightSource.CurrentRecord; } while (true) { // advance the left side first _leftNotDone = _leftSource.MoveNext(); if (!_leftNotDone) return false; // advance the right side int diff = -1; bool firstTime = true; while (diff < 0) { // the first time we test we check against the currentRightSource since // we allow dups on the left side. if (!firstTime && _rightNotDone) { _rightSource.MoveNextHint = _leftSource.CurrentRecord.Key; _rightNotDone = _rightSource.MoveNext(); if (!_rightNotDone) return false; } diff = TMSNStoreUtils.Utf8BytesCompare(_leftSource.CurrentRecord.KeyBytes, _rightSource.CurrentRecord.KeyBytes); firstTime = false; } // if there's a match, join the right to the left if (diff == 0) { if (_joiner == null) { _joiner = new RecordJoiner(_leftSource, _rightSource, _tableColumnSeparator); } CurrentRecord = _joiner.Join(_leftSource.CurrentRecord, _rightSource.CurrentRecord, true); return true; } } }
/// <summary> /// Advances iteration. /// </summary> /// <returns>False if at end of iteration, true otherwise.</returns> public override bool MoveNext() { if (_leftSource == null) { _leftSource = new BookmarkableSource(); _rightSource = new LookAheadWrapper(); _leftSource.AddInput(Inputs[0] as InternalRecordSource); _rightSource.AddInput(Inputs[1] as InternalRecordSource); } // start by advancing the left if (_advanceLeft && !_leftSource.MoveNext()) return false; int diff = -1; while (diff < 0) { bool notDone = true; if (_advanceRight) notDone = _rightSource.MoveNext(); if (!notDone) { // diff will not equal zero at this point so we'll join as non-match _advanceRight = true; // so we continue to find out we're done break; // so we goto join } if (_compareRequired) { diff = TMSNStoreUtils.Utf8BytesCompare(_leftSource.CurrentRecord.KeyBytes, _rightSource.CurrentRecord.KeyBytes); } else diff = 0; // so it looks like we matched #region MATCH_CODE if (diff == 0) { // see notes in InnerJoin. LeftOuterJoin is exactly the same in the match case. // LNE == T if (_leftSource.NextRecordEqualsCurrent) { _advanceLeft = true; _advanceRight = false; _compareRequired = false; // no need to compare // LNE == T, RNE == T if (_rightSource.NextRecordEqualsCurrent) { _leftSource.SetBookmark(); } } // LNE == F, RNE == T else if (_rightSource.NextRecordEqualsCurrent) { _advanceRight = true; _compareRequired = false; // no need to compare if (_leftSource.BookmarkExists) { _leftSource.GoToBookmark(); _advanceLeft = true; } else _advanceLeft = false; } // LNE == F, RNE == F else { _leftSource.ClearBookmark(); _advanceLeft = true; _advanceRight = true; _compareRequired = true; } break; // go to join code } #endregion else if (diff > 0) { // right side is ahead of left side _advanceRight = false; _leftSource.MoveNextHint = _rightSource.CurrentRecord.Key; } // diff < 0 (right side is behind left side) else { // leave advance left as it is (which is true). _advanceRight = true; _rightSource.MoveNextHint = _leftSource.CurrentRecord.Key; } } if (_joiner == null) { _joiner = new RecordJoiner(_leftSource, _rightSource, _tableColumnSeparator); } // joiner knows how to create record if match or if non-match CurrentRecord = _joiner.Join(_leftSource.CurrentRecord, _rightSource.CurrentRecord, (diff == 0)); return true; }
/// <summary> /// Advances Iteration. /// </summary> /// <returns>False if at end of iteration, true otherwise.</returns> public override bool MoveNext() { if (_leftSource == null) { _leftSource = new BookmarkableSource(); _rightSource = new LookAheadWrapper(); _leftSource.AddInput(Inputs[0] as InternalRecordSource); _rightSource.AddInput(Inputs[1] as InternalRecordSource); } int diff = 0; // if we skip compare then diff = 0 for equality // the top of this loop is always ready to compare the current records while (true) { if (_advanceLeft && !_leftSource.MoveNext()) return false; if (_advanceRight && !_rightSource.MoveNext()) return false; if (_compareRequired) { diff = TMSNStoreUtils.Utf8BytesCompare(_leftSource.CurrentRecord.KeyBytes, _rightSource.CurrentRecord.KeyBytes); } #region MATCH_CODE // if there's a match, join the right to the left if (diff == 0) { if (_joiner == null) { _joiner = new RecordJoiner(_leftSource, _rightSource, _tableColumnSeparator); } CurrentRecord = _joiner.Join(_leftSource.CurrentRecord, _rightSource.CurrentRecord, true); // LeftNextEqual RightNextEqual // A 1 B 2 // M 3 M 4 ==> F F // X 4 Y 1 // A 1 B 2 // M 3 M 41 ==> F T (advance right) // X 4 M 2 ==> F F // Z 1 Y 1 // A 1 B 2 // M 3 M 41 ==> T F (advance left) // M 4 N 2 ==> F F // Z 1 Y 1 // A 1 B 2 // M 3 M 41 ==> T T (set left bookmark, advance left) // M 4 M 2 ==> F T (goto left bookmark, advance left, advance right) // Z 1 Y 1 ==> T F (advance left) // ==> F F (advance left, advance right) // figure out what to advance // LNE RNE => AdvanceLeft AdvanceRight Note // F F T T if (bookmarkExists) ClearBookmark(); // F T X T if (bookmarkExists) {gotoBookmark, X=true} else X=false // T F T F // T T T F set left bookmark // LNE == T if (_leftSource.NextRecordEqualsCurrent) { _advanceLeft = true; _advanceRight = false; _compareRequired = false; // no need to compare // LNE == T, RNE == T if (_rightSource.NextRecordEqualsCurrent) { _leftSource.SetBookmark(); } } // LNE == F, RNE == T else if (_rightSource.NextRecordEqualsCurrent) { _advanceRight = true; _compareRequired = false; // no need to compare if (_leftSource.BookmarkExists) { _leftSource.GoToBookmark(); _advanceLeft = true; } else _advanceLeft = false; } // LNE == F, RNE == F else { _leftSource.ClearBookmark(); _advanceLeft = true; _advanceRight = true; _compareRequired = true; } return true; } #endregion else if (diff > 0) { _advanceLeft = true; _advanceRight = false; _leftSource.MoveNextHint = _rightSource.CurrentRecord.Key; } else { _advanceLeft = false; _advanceRight = true; _rightSource.MoveNextHint = _leftSource.CurrentRecord.Key; } } }