private static void writeData(Table t1, Table t2, int start, int end) throws Exception {
    Database db = t1.getDatabase();
    ((DatabaseImpl) db).getPageChannel().startWrite();
    try {
      for (int i = start; i < end; ++i) {
        t1.addRow(null, "rowdata-" + i + TestUtil.createString(100));
        t2.addRow(null, "rowdata-" + i + TestUtil.createString(100));
      }
    } finally {
      ((DatabaseImpl) db).getPageChannel().finishWrite();
    }

    Cursor c1 = t1.newCursor().setIndex(t1.getPrimaryKeyIndex()).toCursor();
    Cursor c2 = t2.newCursor().setIndex(t2.getPrimaryKeyIndex()).toCursor();

    Iterator<? extends Row> i1 = c1.iterator();
    Iterator<? extends Row> i2 = c2.newIterable().reverse().iterator();

    int t1rows = 0;
    int t2rows = 0;
    ((DatabaseImpl) db).getPageChannel().startWrite();
    try {
      while (i1.hasNext() || i2.hasNext()) {
        if (i1.hasNext()) {
          checkRow(i1.next());
          i1.remove();
          ++t1rows;
        }
        if (i2.hasNext()) {
          checkRow(i2.next());
          i2.remove();
          ++t2rows;
        }
      }
    } finally {
      ((DatabaseImpl) db).getPageChannel().finishWrite();
    }

    assertEquals(100, t1rows);
    assertEquals(100, t2rows);
  }
  @Override
  public void generateAccess(
      String accessFilename,
      int rowCount,
      List<FieldDefinition> fieldDefinitionList,
      int tableCount) {

    long startTime = new Date().getTime();

    outputWriterHolder.writeValueInLine("Access data generation started");
    Database db = null;

    try {
      db = DatabaseBuilder.create(Database.FileFormat.V2010, new File(accessFilename));
      // New table
      int columnCount = fieldDefinitionList.size();

      // Create Hash Map of Field Definitions
      Map<Integer, Input2TableInfo> input2TableInfoMap = new LinkedHashMap<>(columnCount);
      Map<Table, List<Object[]>> tableToGeneratedData = new HashMap<>();

      for (int i = 0; i < columnCount; i++) {
        Input2TableInfo input2TableInfo = new Input2TableInfo();
        FieldDefinition fieldDefinition = fieldDefinitionList.get(i);
        input2TableInfo.setFieldText(fieldDefinition.getFieldName());
        input2TableInfo.setFieldDefinition(fieldDefinition);
        input2TableInfo.initGenerator();
        input2TableInfoMap.put(i, input2TableInfo);
      }

      if (tableCount > 1) {
        List<Table> tableListForGeneration = new ArrayList<>();
        for (int i = 0; i < tableCount; i++) {
          TableBuilder tableBuilder = new TableBuilder("dataTable_" + i);
          for (Integer key : input2TableInfoMap.keySet()) {
            Input2TableInfo input2TableInfo = input2TableInfoMap.get(key);
            tableBuilder.addColumn(
                new ColumnBuilder(input2TableInfo.getFieldText())
                    .setSQLType(getType(input2TableInfo.getFieldDefinition().getType())));
          }
          tableListForGeneration.add(tableBuilder.toTable(db));
        }

        CountDownLatch startSignal = new CountDownLatch(1);
        CountDownLatch doneSignal;

        doneSignal = new CountDownLatch(tableCount);

        ParameterVault parameterVault = new DefaultParameterVault(0, rowCount);
        TableProcessor tableProcessor1 =
            new TableProcessor(
                parameterVault,
                startSignal,
                doneSignal,
                tableListForGeneration.get(0),
                columnCount,
                input2TableInfoMap,
                outputWriterHolder,
                tableToGeneratedData);
        new Thread(tableProcessor1, "Processor-" + tableCount).start();

        for (int i = 1; i < tableCount; i++) {
          ParameterVault parameterVaultRest = new DefaultParameterVault(i, rowCount);
          TableProcessor tableProcessor =
              new TableProcessor(
                  parameterVaultRest,
                  startSignal,
                  doneSignal,
                  tableListForGeneration.get(i),
                  columnCount,
                  input2TableInfoMap,
                  outputWriterHolder,
                  tableToGeneratedData);
          new Thread(tableProcessor, "Processor-" + i).start();
        }

        startSignal.countDown();
        doneSignal.await();
      } else {
        TableBuilder tableBuilder = new TableBuilder("dataTable_0");
        for (Integer key : input2TableInfoMap.keySet()) {
          Input2TableInfo input2TableInfo = input2TableInfoMap.get(key);
          tableBuilder.addColumn(
              new ColumnBuilder(input2TableInfo.getFieldText())
                  .setSQLType(getType(input2TableInfo.getFieldDefinition().getType())));
        }
        ParameterVault parameterVault = new DefaultParameterVault(0, rowCount);
        new TableProcessor(outputWriterHolder)
            .generateTableData(
                parameterVault,
                tableBuilder.toTable(db),
                columnCount,
                input2TableInfoMap,
                tableToGeneratedData);
      }

      outputWriterHolder.writeValueInLine("Access data generation finished.");
      long generationTime = new Date().getTime();
      outputWriterHolder.writeValueInLine(
          "Time used " + ((generationTime - startTime) / 1000) + " sec");
      outputWriterHolder.writeValueInLine("Writing to file.");

      for (Map.Entry<Table, List<Object[]>> tableListEntry : tableToGeneratedData.entrySet()) {
        Table table = tableListEntry.getKey();
        List<Object[]> rowListForTable = tableListEntry.getValue();
        for (Object[] row : rowListForTable) {
          table.addRow(row);
        }
      }

      long writeTime = new Date().getTime();
      outputWriterHolder.writeValueInLine(
          "Time used " + ((writeTime - generationTime) / 1000) + " sec");
      outputWriterHolder.writeValueInLine(
          "Total time used " + ((writeTime - startTime) / 1000) + " sec");
      outputWriterHolder.writeValueInLine("Done");
    } catch (Exception e) {
      LOGGER.error(e.getMessage(), e);
    } finally {
      try {
        if (db != null) {
          db.close();
        }
      } catch (IOException e) {
        LOGGER.error(e.getMessage(), e);
      }
    }
  }