code: @Override
    public boolean nextKeyValue() throws IOException, InterruptedException {
      // Since the lzop codec reads everything in lzo blocks, we can't stop if pos == end.
      // Instead we wait for the next block to be read in, when pos will be > end.
      while (pos_ <= end_) {
        key_.set(pos_);
  
        int newSize = lineReader_.readLine(line_, maxLineLen);
        if (newSize == 0) {
          return false;
        }
        HadoopCompat.incrementCounter(linesReadCounter, 1);
        pos_ = getLzoFilePos();
        if (line_.getLength() == 0 || line_.charAt(0) == '\n') {
          HadoopCompat.incrementCounter(emptyLinesCounter, 1);
          continue;
        }
        if (line_.getLength() >= maxLineLen) {
          HadoopCompat.incrementCounter(truncatedLinesCounter, 1);
        }
  
        M protoValue = null;
  
        errorTracker.incRecords();
  
        try {
          protoValue = converter_.fromBytes(Base64Codec.decodeFast(line_.getBytes(), line_.getLength()));
        } catch(DecodeException t1) {
          HadoopCompat.incrementCounter(recordErrorsCounter, 1);
          errorTracker.incErrors(t1);
        }
  
        if (protoValue == null) {
          HadoopCompat.incrementCounter(recordsSkippedCounter, 1);
          continue;
        }
  
        HadoopCompat.incrementCounter(recordsReadCounter, 1);
        value_.set(protoValue);
        return true;
      }
  
      return false;
    }
docs: Read the next key, value pair.
  <p>
  A small fraction of bad records in input are tolerated.
  See  {@link LzoRecordReader} for more information on error handling.
  
  @return true if a key/value pair was read
  @throws IOException
  @throws InterruptedException