public override void Open() { _build.Open(); _probe.Open(); BuildHashtable(); _entry = null; _entryEnumerator = null; _currentPhase = Phase.ProduceMatch; _probeMatched = true; }
private void AddToHashtable(object keyValue, object[] values) { HashMatchEntry entry; _hashTable.TryGetValue(keyValue, out entry); if (entry == null) { entry = new HashMatchEntry(); } else { var newEntry = new HashMatchEntry { Next = entry }; entry = newEntry; } entry.RowValues = values; _hashTable[keyValue] = entry; }
public override bool Read() { switch (_currentPhase) { case Phase.ProduceMatch: { var matchFound = false; _rowBuffer.SetProbe(_probe.RowBuffer); while (!matchFound) { if (_entry != null) { _entry = _entry.Next; } if (_entry == null) { // All rows having the same key value are exhausted. if (!_probeMatched && (_logicalOperator == BoundHashMatchOperator.FullOuter || _logicalOperator == BoundHashMatchOperator.RightOuter)) { _probeMatched = true; _rowBuffer.SetBuild(null); return(true); } // Read next row from probe input. if (!_probe.Read()) { // The probe input is exhausted. If we have a full outer or left outer // join we are not finished. We have to return all rows from the build // input that have not been matched with the probe input. if (_logicalOperator == BoundHashMatchOperator.FullOuter || _logicalOperator == BoundHashMatchOperator.LeftOuter) { _currentPhase = Phase.ReturnUnmatchedRowsFromBuildInput; _entry = null; goto case Phase.ReturnUnmatchedRowsFromBuildInput; } return(false); } // Get probe value _probeMatched = false; var probeValue = _probe.RowBuffer[_probeIndex]; // Seek first occurence of probe value if (probeValue != null) { _hashTable.TryGetValue(probeValue, out _entry); } } if (_entry != null) { _rowBuffer.SetBuild(_entry); if (_remainder()) { _entry.Matched = true; matchFound = true; _probeMatched = true; } } } return(true); } case Phase.ReturnUnmatchedRowsFromBuildInput: { var unmatchedFound = false; _rowBuffer.SetProbe(null); while (!unmatchedFound) { if (_entry != null) { _entry = _entry.Next; } if (_entry == null) { if (_entryEnumerator == null) { _entryEnumerator = _hashTable.Values.GetEnumerator(); } // All rows having the same key value are exhausted. // Read next key from build input. if (!_entryEnumerator.MoveNext()) { // We have read all keys. So we are finished. return(false); } _entry = _entryEnumerator.Current; } unmatchedFound = !_entry.Matched; } _rowBuffer.SetBuild(_entry); return(true); } default: throw ExceptionBuilder.UnexpectedValue(_currentPhase); } }
public void SetBuild(HashMatchEntry entry) { _buildEntry.Entry = entry; _build.ActiveRowBuffer = entry == null ? (RowBuffer)_buildNull : _buildEntry; }