Пример #1
0
        /// <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;
        }
Пример #2
0
        /// <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;
                }
            }
        }