public boolean doNext(K key, V value) throws IOException {
    if (this.isSorted) {
      if (this.getIOContext().shouldEndBinarySearch() ||
          (!this.getIOContext().useSorted() && this.wasUsingSortedSearch)) {
        beginLinearSearch();
        this.wasUsingSortedSearch = false;
        this.getIOContext().setEndBinarySearch(false);
      }

      if (this.getIOContext().useSorted()) {
        if (this.genericUDFClassName == null &&
            this.getIOContext().getGenericUDFClassName() != null) {
          setGenericUDFClassName(this.getIOContext().getGenericUDFClassName());
        }

        if (this.getIOContext().isBinarySearching()) {
          // Proceed with a binary search
          if (this.getIOContext().getComparison() != null) {
            switch (this.getIOContext().getComparison()) {
              case GREATER:
              case EQUAL:
                // Indexes have only one entry per value, could go linear from here, if we want to
                // use this for any sorted table, we'll need to continue the search
                rangeEnd = previousPosition;
                break;
              case LESS:
                rangeStart = previousPosition;
                break;
              default:
                break;
            }
          }

          long position = (rangeStart + rangeEnd) / 2;
          sync(position);

          long newPosition = getSyncedPosition();
          // If the newPosition is the same as the previousPosition, we've reached the end of the
          // binary search, if the new position at least as big as the size of the split, any
          // matching rows must be in the final block, so we can end the binary search.
          if (newPosition == previousPosition || newPosition >= splitEnd) {
            this.getIOContext().setBinarySearching(false);
            sync(rangeStart);
          }

          previousPosition = newPosition;
        }  else if (foundAllTargets()) {
          // Found all possible rows which will not be filtered
          return false;
        }
      }
    }

    try {

      /**
       * When start reading new file, check header, footer rows.
       * If file contains header, skip header lines before reading the records.
       * If file contains footer, used a FooterBuffer to remove footer lines
       * at the end of the table file.
       **/
      if (this.ioCxtRef.getCurrentBlockStart() == 0) {

        // Check if the table file has header to skip.
        footerBuffer = null;
        Path filePath = this.ioCxtRef.getInputPath();
        PartitionDesc part = null;
        try {
          if (pathToPartitionInfo == null) {
            pathToPartitionInfo = Utilities
              .getMapWork(jobConf).getPathToPartitionInfo();
          }
          part = HiveFileFormatUtils
              .getFromPathRecursively(pathToPartitionInfo,
                  filePath, IOPrepareCache.get().getPartitionDescMap());
        } catch (AssertionError ae) {
          LOG.info("Cannot get partition description from " + this.ioCxtRef.getInputPath()
              + "because " + ae.getMessage());
          part = null;
        } catch (Exception e) {
          LOG.info("Cannot get partition description from " + this.ioCxtRef.getInputPath()
              + "because " + e.getMessage());
          part = null;
        }
        TableDesc table = (part == null) ? null : part.getTableDesc();
        // In TextFormat, skipping is already taken care of as part of SkippingTextInputFormat.
        // This code will be also called from LLAP when pipeline is non-vectorized and cannot create wrapper.
        if (table != null && !TextInputFormat.class.isAssignableFrom(part.getInputFileFormatClass())) {
          headerCount = Utilities.getHeaderCount(table);
          footerCount = Utilities.getFooterCount(table, jobConf);
        }

        // If input contains header, skip header.
        if (!Utilities.skipHeader(recordReader, headerCount, key, value)) {
          return false;
        }
        if (footerCount > 0) {
          footerBuffer = new FooterBuffer();
          if (!footerBuffer.initializeBuffer(jobConf, recordReader, footerCount, key, value)) {
            return false;
          }
        }
      }
      if (footerBuffer == null) {

        // Table files don't have footer rows.
        return recordReader.next(key,  value);
      } else {
        return footerBuffer.updateBuffer(jobConf, recordReader, key, value);
      }
    } catch (Exception e) {
      return HiveIOExceptionHandlerUtil.handleRecordReaderNextException(e, jobConf);
    }
  }
Close this {@link InputSplit} to future operations.

@throws IOException
ql/src/java/org/apache/hadoop/hive/ql/io/HiveContextAwareRecordReader.java