public RowMergingIterator merge(List<Iterator<Row>> iterators) {
   for (Iterator<Row> rowIterator : iterators) {
     if (rowIterator.hasNext()) {
       queue.add(peekingIterator(rowIterator));
     }
   }
   leastExhausted = false;
   return this;
 }
 @Override
 public Row peek() {
   if (!hasPeeked) {
     peekedElement = new RowN(iterator.next().materialize());
     hasPeeked = true;
   }
   return peekedElement;
 }
    public RowMergingIterator(
        Iterable<? extends Iterator<? extends Row>> iterators,
        final Comparator<? super Row> itemComparator) {
      Comparator<PeekingRowIterator> heapComparator =
          new Comparator<PeekingRowIterator>() {
            @Override
            public int compare(PeekingRowIterator o1, PeekingRowIterator o2) {
              return itemComparator.compare(o1.peek(), o2.peek());
            }
          };
      queue = new PriorityQueue<>(2, heapComparator);

      for (Iterator<? extends Row> iterator : iterators) {
        if (iterator.hasNext()) {
          queue.add(peekingIterator(iterator));
        }
      }
    }
 @Override
 public Row next() {
   if (!hasPeeked) {
     return iterator.next();
   }
   Row result = peekedElement;
   hasPeeked = false;
   peekedElement = null;
   return result;
 }
 @Override
 public void remove() {
   checkState(!hasPeeked, "Can't remove after you've peeked at next");
   iterator.remove();
 }
 @Override
 public boolean hasNext() {
   return hasPeeked || iterator.hasNext();
 }