private void readBlockFromSpillToMemory(VectorSpillBlock block) throws HiveException {
    VectorRowBytesContainer rowBytesContainer = block.getSpillRowBytesContainer();
    try {
      rowBytesContainer.prepareForReading();

      int batchIndex = 0;
      bufferedBatches.get(batchIndex).reset();

      /*
       * On rowBytesContainer level, we have a row-wise structure. As we want to get the rows back
       * into batches, we need to distribute them simply by filling the batches sequentially, but
       * taking care of the original number of rows in the batches (startRowIndex).
       */
      while (rowBytesContainer.readNext()) {
        if (batchIndex < block.startRowIndex.length - 1
            && bufferedBatches.get(batchIndex).size == block.startRowIndex[batchIndex + 1]
                - block.startRowIndex[batchIndex]) {
          batchIndex += 1;
          bufferedBatches.get(batchIndex).reset();
        }
        BufferedVectorizedRowBatch bufferedBatch = bufferedBatches.get(batchIndex);
        block.readSingleRowFromBytesContainer(bufferedBatch);
        bufferedBatch.size += 1;
        bufferedBatch.isLastGroupBatch = block.isLastGroupBatch[batchIndex];
        bufferedBatch.isInputExpressionEvaluated = block.isInputExpressionEvaluated[batchIndex];
      }
      currentBufferedBatchCount = block.spillBatchCount;
      partitionMetrics.batchesReadFromSpill += currentBufferedBatchCount;
    } catch (IOException e) {
      throw new HiveException(e);
    }
  }
Jumps to a given block by index. This method doesn't take care of spilling the current contents
from memory (even if it would be needed), so it should be used in cases where the caller
already made sure the the current contents of bufferedBatches have been spilled, so this is a
private method intentionally.

@param toBlock
@throws HiveException
ql/src/java/org/apache/hadoop/hive/ql/exec/vector/ptf/VectorPTFGroupBatches.java