content: /*
   * Copyright (C) 2016-2023 ActionTech.
   * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
   */
  
  package com.actiontech.dble.performance;
  
  import java.sql.Connection;
  import java.sql.SQLException;
  import java.sql.Statement;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.concurrent.atomic.AtomicLong;
  
  public class UserTableInsertJob implements Runnable {
      private long finsihed;
      private final long batchSize;
      private final AtomicLong finshiedCount;
      private final AtomicLong failedCount;
  
      private final SimpleConPool conPool;
      private final long totalRecords;
      private LinkedList<StringItem> sqlTemplateItems;
      private final boolean autocommit;
  
      public UserTableInsertJob(SimpleConPool conPool, long totalRecords,
                                long batchSize, AtomicLong finshiedCount, AtomicLong failedCount,
                                LinkedList<StringItem> sqlTemplateItems, boolean autoCommit) {
          super();
          this.conPool = conPool;
          this.totalRecords = totalRecords;
          this.batchSize = batchSize;
          this.finshiedCount = finshiedCount;
          this.failedCount = failedCount;
          this.sqlTemplateItems = sqlTemplateItems;
          this.autocommit = autoCommit;
      }
  
      private long insert(Connection con, List<String> list) throws SQLException {
          Statement stms = con.createStatement();
          for (String sql : list) {
              stms.addBatch(sql);
          }
          stms.executeBatch();
          if (this.autocommit == false) {
              con.commit();
          }
          // stms.clearBatch();
          stms.close();
          return list.size();
      }
  
      private List<String> getNextBatch() {
          if (finsihed >= totalRecords) {
              return Collections.emptyList();
          }
          int curBatchSize = (int) ((finsihed + batchSize) < totalRecords ? batchSize
                  : (totalRecords - finsihed));
          ArrayList<String> list = new ArrayList<String>(curBatchSize);
          for (long i = 0; i < curBatchSize; i++) {
              list.add(RandomDataValueUtil.evalRandValueString(sqlTemplateItems));
          }
          // System.out.println("finsihed :" + finsihed + "-" + end);
          finsihed += list.size();
          return list;
      }
  
      @Override
      public void run() {
          Connection con = null;
          try {
  
              List<String> batch = getNextBatch();
              while (!batch.isEmpty()) {
                  try {
                      if (con == null || con.isClosed()) {
                          con = conPool.getConnection();
                          if (con.getAutoCommit() != autocommit) {
                              con.setAutoCommit(autocommit);
                          }
                      }
  
                      insert(con, batch);
                      finshiedCount.addAndGet(batch.size());
                  } catch (Exception e) {
                      System.out.println("caught err in  thread :"
                              + Thread.currentThread().getId() + " " + e);
                      try {
                          con.rollback();
                      } catch (SQLException e1) {
                          System.out.println("caught err in thread :"
                                  + Thread.currentThread().getId()
                                  + " rollback err " + e1);
                      }
                      failedCount.addAndGet(batch.size());
                  }
                  batch = getNextBatch();
              }
          } finally {
              if (con != null) {
                  this.conPool.returnCon(con);
              }
          }
  
      }
  }