documentListStreamFromChunks method

Stream<List<Snapshot>> documentListStreamFromChunks(
  1. Stream<List<Snapshot>> stream,
  2. {DocumentScoring documentScoring,
  3. Sorter existingSorter}
)

Converts chunks into an incrementally improving result stream.

Optional parameter documentScoringAlgorithm can be used to replace the default document scoring algorithm.

Optional parameter existingSorter can be used to tell the existing order of items. By avoiding sorting, the implementation can achieve much better performance.

Implementation

Stream<List<Snapshot>> documentListStreamFromChunks(
  Stream<List<Snapshot>> stream, {
  DocumentScoring documentScoring,
  Sorter existingSorter,
}) {
  // Handle trivial case
  if (take == 0) {
    return Stream<List<Snapshot>>.value(const <Snapshot>[]);
  }

  //
  // Is any of the following true?
  //   * No order is specified
  //   * The order is the same as the existing order in the stream.
  //
  final sorter = this.sorter;
  if (sorter == null ||
      (existingSorter != null &&
          sorter.simplify() == existingSorter.simplify())) {
    //
    // Great! We don't need to load snapshots into the memory!
    //
    return _incrementalStreamFromSortedChunks(
      stream,
      documentScoring: documentScoring,
    );
  }
  documentScoring ??= const DocumentScoring();
  final documentScoringState = documentScoring.newState(filter);

  final list = <Snapshot>[];
  return stream.map((chunk) {
    //
    // Filter
    //
    if (filter == null) {
      list.addAll(chunk);
    } else {
      final matchingItems = chunk.where((snapshot) {
        final score = documentScoringState.evaluateSnapshot(snapshot);
        return score > 0.0;
      });
      list.addAll(matchingItems);
    }

    //
    // Sort
    //
    if (sorter != null) {
      list.sort((a, b) {
        final result = sorter.compare(a.data, b.data);
        return result;
      });
    }

    //
    // Skip
    //
    Iterable<Snapshot> iterable = list;
    if (skip != 0) {
      iterable = iterable.skip(skip);
    }

    //
    // Take
    //
    if (take != null) {
      iterable = iterable.take(take);
    }

    return List<Snapshot>.unmodifiable(iterable);
  });
}