public int Next(int desiredCount, CancellationToken cancellationToken) { // If this is the first call, walk all rows once to find best rows if (!_isDictionaryBuilt) { _isDictionaryBuilt = true; BuildChooseDictionary(cancellationToken); _source.Reset(); } int outerCount; while ((outerCount = _source.Next(desiredCount, cancellationToken)) > 0) { // Ask for the indices of rows which were chosen in this page XArray chosenRows = _dictionary.GetChosenRows(_totalRowsRead, _totalRowsRead + outerCount, _totalRowsRead); // Track the total row count (so we know which rows to ask for chosens each time) _totalRowsRead += outerCount; // Tell the remapper to filter to chosen rows _chosenRowsFilter.SetMatches((int[])chosenRows.Array, chosenRows.Count); if (chosenRows.Count > 0) { CurrentRowCount = chosenRows.Count; return(CurrentRowCount); } } return(0); }
public int Next(int desiredCount, CancellationToken cancellationToken) { // If this is the first call, fully cache the JoinToSource and build a lookup Dictionary if (_joinDictionary == null) { BuildJoinDictionary(cancellationToken); } BitVector matchedRows = null; while (true) { // Get the next rows from the source int count = _source.Next(desiredCount, cancellationToken); if (count == 0) { CurrentRowCount = 0; return(0); } // Get values to join from XArray joinFromValues = _joinFromColumnGetter(); // Find which rows matched and to what right-side row indices matchedRows = _joinDictionary.TryGetValues(joinFromValues, out _currentRightSideSelector); if (_currentRightSideSelector.Count > 0) { break; } } // Filter left-side rows to the matches (inner join) _sourceJoinedRowsFilter.SetMatches(matchedRows); // Seek right-side rows to the matches for (int i = 0; i < _rightSideColumns.Length; ++i) { _rightSideColumns[i].Set(_currentRightSideSelector); } CurrentRowCount = _currentRightSideSelector.Count; return(_currentRightSideSelector.Count); }
public override int Next(int desiredCount, CancellationToken cancellationToken) { _currentMatchesReturned += _nextCountToReturn; // If we previously retrieved extra rows, return more of those if (_currentMatchesTotal > _currentMatchesReturned) { _nextCountToReturn = Math.Min(desiredCount, _currentMatchesTotal - _currentMatchesReturned); _mapper.NextMatchPage(_nextCountToReturn); return(_nextCountToReturn); } // Otherwise, retrieve more rows int countToRequest = CountToRequest(desiredCount); _currentMatchesReturned = 0; int outerCount; while ((outerCount = _source.Next(countToRequest, cancellationToken)) > 0) { // Track the total retrieved from the source _totalRowsRetrieved += outerCount; Allocator.AllocateToSize(ref _vector, outerCount); _vector.None(); // Match the query expression and count all matches _expression.Evaluate(_vector); _currentMatchesTotal = _vector.Count; _totalRowsMatched += _currentMatchesTotal; // If we got matches, return the first set requested, otherwise ask for more if (_currentMatchesTotal > 0) { _nextCountToReturn = Math.Min(desiredCount, _currentMatchesTotal - _currentMatchesReturned); _mapper.SetMatches(_vector, _nextCountToReturn); return(_nextCountToReturn); } // Reconsider how many rows to request if no matches countToRequest = CountToRequest(desiredCount); } // Tell the mapper there are no more matches Allocator.AllocateToSize(ref _vector, desiredCount); _vector.None(); _mapper.SetMatches(_vector, 0); return(0); // Where.Next implementation which doesn't request excess results and page through them. // Use instead to diagnose "wrong row count" problems which might be due to paging problems. //int outerCount; //while ((outerCount = _source.Next(desiredCount)) > 0) //{ // // Track the total retrieved from the source // _totalRowsRetrieved += outerCount; // Allocator.AllocateToSize(ref _vector, outerCount); // _vector.None(); // // Match the query expression and count all matches // _expression.Evaluate(_vector); // _currentMatchesTotal = _vector.Count; // _totalRowsMatched += _currentMatchesTotal; // _mapper.SetMatches(_vector); // if (_currentMatchesTotal > 0) return _currentMatchesTotal; //} //return 0; }