@Override public RecordReader<ImmutableBytesWritable, ResultWritable> getRecordReader(InputSplit split,
      JobConf jobConf, final Reporter reporter) throws IOException {

    HBaseSplit hbaseSplit = (HBaseSplit) split;
    TableSplit tableSplit = hbaseSplit.getTableSplit();

    final org.apache.hadoop.mapreduce.RecordReader<ImmutableBytesWritable, Result> recordReader;

    Job job = new Job(jobConf);
    TaskAttemptContext tac = ShimLoader.getHadoopShims().newTaskAttemptContext(job.getConfiguration(), reporter);

    final Configuration hbaseConf = HBaseConfiguration.create(jobConf);
    final Scan scan = HiveHBaseInputFormatUtil.getScan(jobConf);

    LOG.debug("HBase configurations: {}", hbaseConf);
    LOG.info("Using global scan configuration (ignore per-split scan configs): {}", scan);

    final Connection conn;

    synchronized (HBASE_TABLE_MONITOR) {
      conn = ConnectionFactory.createConnection(hbaseConf);
      initializeTable(conn, tableSplit.getTable());
      setScan(scan);
      recordReader = createRecordReader(tableSplit, tac);
      try {
        recordReader.initialize(tableSplit, tac);
      } catch (InterruptedException e) {
        closeTable(); // Free up the HTable connections
        conn.close();
        throw new IOException("Failed to initialize RecordReader", e);
      }
    }

    return new RecordReader<ImmutableBytesWritable, ResultWritable>() {

      @Override public void close() throws IOException {
        synchronized (HBASE_TABLE_MONITOR) {
          recordReader.close();
          closeTable();
          conn.close();
        }
      }

      @Override public ImmutableBytesWritable createKey() {
        return new ImmutableBytesWritable();
      }

      @Override public ResultWritable createValue() {
        return new ResultWritable(new Result());
      }

      @Override public long getPos() throws IOException {
        return 0;
      }

      @Override public float getProgress() throws IOException {
        float progress = 0.0F;

        try {
          progress = recordReader.getProgress();
        } catch (InterruptedException e) {
          throw new IOException(e);
        }

        return progress;
      }

      @Override public boolean next(ImmutableBytesWritable rowKey, ResultWritable value) throws IOException {

        boolean next = false;

        try {
          next = recordReader.nextKeyValue();

          if (next) {
            rowKey.set(recordReader.getCurrentValue().getRow());
            value.setResult(recordReader.getCurrentValue());
          }
        } catch (InterruptedException e) {
          throw new IOException(e);
        }

        return next;
      }
    };
  }
HiveHBaseTableInputFormat implements InputFormat for HBase storage handler
tables, decorating an underlying HBase TableInputFormat with extra Hive logic
such as column pruning and filter pushdown.
hbase-handler/src/java/org/apache/hadoop/hive/hbase/HiveHBaseTableInputFormat.java