All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.gesellix.couchdb.PagedViewIterator Maven / Gradle / Ivy

The newest version!
package de.gesellix.couchdb;

import de.gesellix.couchdb.model.NonReducedViewQueryResponse;
import de.gesellix.couchdb.model.RowReference;
import de.gesellix.couchdb.model.ViewQueryResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.BiFunction;

public class PagedViewIterator>
    implements Iterator> {

  private static final Logger log = LoggerFactory.getLogger(PagedViewIterator.class);

  private final int pageSize;
  private final BiFunction, Integer, ViewQueryResponse> pageProvider;

  RowReference nextPage;

  ViewQueryResponse lastResult;

  public PagedViewIterator(int pageSize, BiFunction, Integer, ViewQueryResponse> pageProvider) {
    this.pageSize = pageSize;
    this.pageProvider = pageProvider;
    this.nextPage = null;
    this.lastResult = null;
  }

  @Override
  public boolean hasNext() {
    if (lastResult == null) {
      // we didn't even try, yet
      return true;
    }
    return nextPage != null;
  }

  @Override
  public ViewQueryResponse next() {
    if (!hasNext()) {
      throw new NoSuchElementException("no more pages available");
    }
    ViewQueryResponse fetched = fetch();
    return fetched;
  }

  private ViewQueryResponse fetch() {
    lastResult = pageProvider.apply(nextPage, pageSize + 1);
    if (lastResult == null || lastResult.getRows() == null) {
      throw new IllegalStateException("failed to fetch more rows. nextPage(" + RowReference.toString(nextPage) + ")");
    }
    if (lastResult instanceof NonReducedViewQueryResponse) {
      NonReducedViewQueryResponse nonReducedLastResult = (NonReducedViewQueryResponse) lastResult;
      log.info("got result, totalRows({}), offset({}), rows({}), nextPage({})",
          nonReducedLastResult.getTotalRows(), nonReducedLastResult.getOffset(), lastResult.getRows().size(), RowReference.toString(nextPage));
    } else {
      log.info("got result, rows({}), nextPage({})",
          lastResult.getRows().size(), RowReference.toString(nextPage));
    }

    if (lastResult.getRows().size() <= pageSize) {
      // finished
      updateNextPage(null);
    } else {
      // safe for the next iteration
      Row trailingRow = lastResult.getRows().remove(lastResult.getRows().size() - 1);
      updateNextPage(trailingRow);
    }
    return lastResult;
  }

  private void updateNextPage(RowReference nextPage) {
    if (Objects.equals(this.nextPage, nextPage)) {
      if (lastResult instanceof NonReducedViewQueryResponse) {
        NonReducedViewQueryResponse nonReducedLastResult = (NonReducedViewQueryResponse) lastResult;
        int offset = nonReducedLastResult.getOffset() == null ? -1 : nonReducedLastResult.getOffset();
        log.info("nextPage hasn't changed: previous({}) == next({}), lastResult.offset({})",
            RowReference.toString(this.nextPage),
            RowReference.toString(nextPage),
            offset);
      } else {
        log.info("nextPage hasn't changed: previous({}) == next({})",
            RowReference.toString(this.nextPage),
            RowReference.toString(nextPage));
      }
      // throw exception?
      nextPage = null;
    }
    this.nextPage = nextPage;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy