@Override
  public ROW first() throws HiveException {
    if (size == 0) {
      return null;
    }

    try {
      firstCalled = true;
      // when we reach here, we must have some data already (because size >0).
      // We need to see if there are any data flushed into file system. If not,
      // we can
      // directly read from the current write block. Otherwise, we need to read
      // from the beginning of the underlying file.
      this.itrCursor = 0;
      closeWriter();
      closeReader();

      if (tblDesc == null) {
        this.itrCursor++;
        return dummyRow;
      }

      this.currentReadBlock = this.firstReadBlockPointer;
      if (this.numFlushedBlocks == 0) {
        this.readBlockSize = this.addCursor;
        this.currentReadBlock = this.currentWriteBlock;
      } else {
        JobConf localJc = getLocalFSJobConfClone(jc);
        if (inputSplits == null) {
          if (this.inputFormat == null) {
            inputFormat = ReflectionUtil.newInstance(
                tblDesc.getInputFileFormatClass(), localJc);
          }

          localJc.set(FileInputFormat.INPUT_DIR,
              org.apache.hadoop.util.StringUtils.escapeString(parentDir.getAbsolutePath()));
          inputSplits = inputFormat.getSplits(localJc, 1);
          actualSplitNum = inputSplits.length;
        }
        currentSplitPointer = 0;
        rr = inputFormat.getRecordReader(inputSplits[currentSplitPointer],
          localJc, reporter);
        currentSplitPointer++;

        nextBlock(0);
      }
      // we are guaranteed that we can get data here (since 'size' is not zero)
      ROW ret = currentReadBlock[itrCursor++];
      removeKeys(ret);
      return ret;
    } catch (Exception e) {
      throw new HiveException(e);
    }

  }
Simple persistent container for rows.

This container interface only accepts adding or appending new rows and iterating through the rows
in the order of their insertions.

The iterator interface is a lightweight first()/next() API rather than the Java Iterator
interface. This way we do not need to create an Iterator object every time we want to start a new
iteration. Below is simple example of how to convert a typical Java's Iterator code to the LW
iterator interface.

Iterator itr = rowContainer.iterator(); while (itr.hasNext()) { v = itr.next(); // do anything
with v }

can be rewritten to:

for ( v = rowContainer.first(); v != null; v = rowContainer.next()) { // do anything with v }

Once the first is called, it will not be able to write again. So there can not be any writes
after read. It can be read multiple times, but it does not support multiple reader interleaving
reading.
ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/RowContainer.java