protected List<RunAndMaxFrameSizePair> testSortRecords(
      int pageSize,
      int frameLimit,
      int numRuns,
      int minRecordSize,
      int maxRecordSize,
      HashMap<Integer, String> specialData)
      throws HyracksDataException {
    IHyracksTaskContext ctx = testUtils.create(pageSize);

    HashMap<Integer, String> keyValuePair = new HashMap<>();
    List<IFrame> frameList = new ArrayList<>();
    prepareData(
        ctx,
        frameList,
        pageSize * frameLimit * numRuns,
        minRecordSize,
        maxRecordSize,
        specialData,
        keyValuePair);
    AbstractSortRunGenerator runGenerator =
        getSortRunGenerator(ctx, frameLimit, keyValuePair.size());
    runGenerator.open();
    for (IFrame frame : frameList) {
      runGenerator.nextFrame(frame.getBuffer());
    }
    runGenerator.close();
    matchResult(ctx, runGenerator.getRuns(), keyValuePair);
    return runGenerator.getRuns();
  }
 @Override
 public ByteBuffer next() {
   IFrame frame = null;
   try {
     frame = new VSizeFrame(ctx);
     Arrays.fill(frame.getBuffer().array(), (byte) 0);
     bis.read(frame.getBuffer().array(), 0, frame.getFrameSize());
     readFrameCount++;
     if (LOGGER.isLoggable(Level.INFO)) {
       LOGGER.info("Read spill frome " + readFrameCount);
     }
   } catch (IOException e) {
     e.printStackTrace();
   }
   return frame.getBuffer();
 }
  static void assertReadSorted(
      List<RunAndMaxFrameSizePair> runs,
      IFrameTupleAccessor fta,
      IFrame frame,
      Map<Integer, String> keyValuePair)
      throws HyracksDataException {

    assertTrue(runs.size() > 0);
    for (RunAndMaxFrameSizePair run : runs) {
      run.run.open();
      int preKey = Integer.MIN_VALUE;
      while (run.run.nextFrame(frame)) {
        fta.reset(frame.getBuffer());
        preKey = assertFTADataIsSorted(fta, keyValuePair, preKey);
      }
      run.run.close();
    }
    assertTrue(keyValuePair.isEmpty());
  }