diff --git a/java/cost-accounting-benchmark/src/dist/cb/cb.postgresql.large50.online_rc.properties b/java/cost-accounting-benchmark/src/dist/cb/cb.postgresql.large50.online_rc.properties index 0740ff08..5d948f15 100755 --- a/java/cost-accounting-benchmark/src/dist/cb/cb.postgresql.large50.online_rc.properties +++ b/java/cost-accounting-benchmark/src/dist/cb/cb.postgresql.large50.online_rc.properties @@ -112,6 +112,7 @@ online.schedule.execute.per.minute.show-quantity=-1 online.schedule.execute.per.minute.show-cost=-1 periodic.schedule.interval.update-stock=0 periodic.schedule.update-stock.split.size=60 +periodic.schedule.update-stock.keep.size=4 ## online-command diff --git a/java/cost-accounting-benchmark/src/dist/cb/cb.postgresql.large50.properties b/java/cost-accounting-benchmark/src/dist/cb/cb.postgresql.large50.properties index fc419eda..e70bb39c 100755 --- a/java/cost-accounting-benchmark/src/dist/cb/cb.postgresql.large50.properties +++ b/java/cost-accounting-benchmark/src/dist/cb/cb.postgresql.large50.properties @@ -108,6 +108,7 @@ online.schedule.execute.per.minute.show-quantity=-1 online.schedule.execute.per.minute.show-cost=-1 periodic.schedule.interval.update-stock=0 periodic.schedule.update-stock.split.size=60 +periodic.schedule.update-stock.keep.size=4 ## online-command diff --git a/java/cost-accounting-benchmark/src/dist/cb/cb.tsurugi.large50.online_mix.properties b/java/cost-accounting-benchmark/src/dist/cb/cb.tsurugi.large50.online_mix.properties index 5f123b87..dc8a1396 100755 --- a/java/cost-accounting-benchmark/src/dist/cb/cb.tsurugi.large50.online_mix.properties +++ b/java/cost-accounting-benchmark/src/dist/cb/cb.tsurugi.large50.online_mix.properties @@ -114,6 +114,7 @@ online.schedule.execute.per.minute.show-quantity=-1 online.schedule.execute.per.minute.show-cost=-1 periodic.schedule.interval.update-stock=0 periodic.schedule.update-stock.split.size=60 +periodic.schedule.update-stock.keep.size=4 ## online-command diff --git a/java/cost-accounting-benchmark/src/dist/cb/cb.tsurugi.large50.online_var.properties b/java/cost-accounting-benchmark/src/dist/cb/cb.tsurugi.large50.online_var.properties index def83db2..cd32669d 100755 --- a/java/cost-accounting-benchmark/src/dist/cb/cb.tsurugi.large50.online_var.properties +++ b/java/cost-accounting-benchmark/src/dist/cb/cb.tsurugi.large50.online_var.properties @@ -114,6 +114,7 @@ online.schedule.execute.per.minute.show-quantity=-1 online.schedule.execute.per.minute.show-cost=-1 periodic.schedule.interval.update-stock=0 periodic.schedule.update-stock.split.size=60 +periodic.schedule.update-stock.keep.size=4 ## online-command diff --git a/java/cost-accounting-benchmark/src/dist/cb/cb.tsurugi.large50.properties b/java/cost-accounting-benchmark/src/dist/cb/cb.tsurugi.large50.properties index cac51760..21af786f 100755 --- a/java/cost-accounting-benchmark/src/dist/cb/cb.tsurugi.large50.properties +++ b/java/cost-accounting-benchmark/src/dist/cb/cb.tsurugi.large50.properties @@ -110,6 +110,7 @@ online.schedule.execute.per.minute.show-quantity=-1 online.schedule.execute.per.minute.show-cost=-1 periodic.schedule.interval.update-stock=0 periodic.schedule.update-stock.split.size=60 +periodic.schedule.update-stock.keep.size=4 ## online-command diff --git a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/dao/StockHistoryDao.java b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/dao/StockHistoryDao.java index 916fdbfb..278a3e23 100755 --- a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/dao/StockHistoryDao.java +++ b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/dao/StockHistoryDao.java @@ -3,11 +3,11 @@ import java.time.LocalDate; import java.time.LocalTime; import java.util.Collection; +import java.util.List; import java.util.function.Consumer; import com.tsurugidb.benchmark.costaccounting.db.entity.StockHistory; -import com.tsurugidb.benchmark.costaccounting.db.iceaxe.domain.BenchVariable; -import com.tsurugidb.iceaxe.sql.parameter.TgBindVariable; +import com.tsurugidb.benchmark.costaccounting.db.entity.StockHistoryDateTime; /** * 在庫履歴DAO @@ -16,11 +16,6 @@ public interface StockHistoryDao { public static final String TABLE_NAME = "stock_history"; - public static final String PS_COND_DATE = "s_date = ?"; - - public static final TgBindVariable vDate = BenchVariable.ofDate("date"); - public static final String TG_COND_DATE = "s_date = " + vDate.sqlName(); - /** *
      * truncate table stock_history
@@ -45,11 +40,35 @@ public interface StockHistoryDao {
 
     int[] insertBatch(Collection entityList);
 
+    /**
+     * 
+     * select distinct s_date, s_time from stock_history
+     * order by s_date, s_time
+     * 
+ */ + List selectDistinctDateTime(); + + /** + *
+     * delete from stock_history
+     * where (s_date < :date) or (s_date = :date and s_time <= :time)
+     * 
+ */ + int deleteOldDateTime(LocalDate date, LocalTime time); + + /** + *
+     * delete from stock_history
+     * where ((s_date < :date) or (s_date = :date and s_time <= :time) and s_f_id = :factoryId
+     * 
+ */ + int deleteOldDateTime(LocalDate date, LocalTime time, int factoryId); + /** *
      * insert into stock_history
      * select ... from cost_master
-     * 
+ *
*/ void insertSelectFromCostMaster(LocalDate date, LocalTime time); @@ -57,7 +76,7 @@ public interface StockHistoryDao { *
      * insert into stock_history
      * select ... from cost_master where c_f_id = :factoryId
-     * 
+ * */ void insertSelectFromCostMaster(LocalDate date, LocalTime time, int factoryId); diff --git a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/entity/StockHistoryDateTime.java b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/entity/StockHistoryDateTime.java new file mode 100755 index 00000000..5b4e50be --- /dev/null +++ b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/entity/StockHistoryDateTime.java @@ -0,0 +1,62 @@ +package com.tsurugidb.benchmark.costaccounting.db.entity; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.Objects; + +/** + * key(s_date, s_time) for stock_history + */ +public class StockHistoryDateTime implements Comparable { + + /** s_date date(8) */ + private LocalDate sDate; + + /** s_time time(6) */ + private LocalTime sTime; + + public void setSDate(LocalDate value) { + this.sDate = value; + } + + public LocalDate getSDate() { + return this.sDate; + } + + public void setSTime(LocalTime value) { + this.sTime = value; + } + + public LocalTime getSTime() { + return this.sTime; + } + + @Override + public int compareTo(StockHistoryDateTime o) { + int c = sDate.compareTo(o.getSDate()); + if (c != 0) { + return c; + } + return sTime.compareTo(o.getSTime()); + } + + @Override + public int hashCode() { + return Objects.hash(sDate, sTime); + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof StockHistoryDateTime)) { + return false; + } + + var other = (StockHistoryDateTime) obj; + return Objects.equals(sDate, other.sDate) && Objects.equals(sTime, other.sTime); + } + + @Override + public String toString() { + return "(s_date=" + sDate + ", s_time=" + sTime + ")"; + } +} diff --git a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/iceaxe/dao/StockHistoryDaoIceaxe.java b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/iceaxe/dao/StockHistoryDaoIceaxe.java index af1038fb..7c6bbcd3 100755 --- a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/iceaxe/dao/StockHistoryDaoIceaxe.java +++ b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/iceaxe/dao/StockHistoryDaoIceaxe.java @@ -4,16 +4,28 @@ import java.time.LocalTime; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; import com.tsurugidb.benchmark.costaccounting.db.dao.StockHistoryDao; import com.tsurugidb.benchmark.costaccounting.db.entity.StockHistory; +import com.tsurugidb.benchmark.costaccounting.db.entity.StockHistoryDateTime; import com.tsurugidb.benchmark.costaccounting.db.iceaxe.CostBenchDbManagerIceaxe; import com.tsurugidb.benchmark.costaccounting.db.iceaxe.domain.BenchVariable; +import com.tsurugidb.benchmark.costaccounting.util.BenchConst; +import com.tsurugidb.iceaxe.sql.parameter.TgBindParameters; +import com.tsurugidb.iceaxe.sql.parameter.TgBindVariable; +import com.tsurugidb.iceaxe.sql.parameter.TgBindVariable.TgBindVariableInteger; +import com.tsurugidb.iceaxe.sql.parameter.TgParameterMapping; +import com.tsurugidb.iceaxe.sql.result.TgResultMapping; public class StockHistoryDaoIceaxe extends IceaxeDao implements StockHistoryDao { + public static final TgBindVariable vDate = BenchVariable.ofDate("date"); + public static final TgBindVariable vTime = BenchVariable.ofTime("time"); + public static final TgBindVariableInteger vFactory = BenchVariable.ofInt("fId"); + private static final List> COLUMN_LIST; static { List> list = new ArrayList<>(); @@ -51,6 +63,59 @@ public int[] insertBatch(Collection entityList) { return doInsert(entityList, false); } + @Override + public List selectDistinctDateTime() { + var ps = selectDistinctDateTimeCache.get(); + var list = executeAndGetList(ps); + if (BenchConst.WORKAROUND) { + Collections.sort(list); + } + return list; + } + + private final CacheQuery selectDistinctDateTimeCache = new CacheQuery<>() { + @Override + protected void initialize() { + this.sql = "select distinct s_date, s_time from " + TABLE_NAME // + + " order by s_date, s_time"; + this.resultMapping = TgResultMapping.of(StockHistoryDateTime::new) // + .addDate("s_date", StockHistoryDateTime::setSDate) // + .addTime("s_time", StockHistoryDateTime::setSTime); + } + }; + + @Override + public int deleteOldDateTime(LocalDate date, LocalTime time) { + var ps = deleteOldDateTimeCache.get(); + var parameter = TgBindParameters.of(vDate.bind(date), vTime.bind(time)); + return executeAndGetCount(ps, parameter); + } + + private final CachePreparedStatement deleteOldDateTimeCache = new CachePreparedStatement<>() { + @Override + protected void initialize() { + this.sql = "delete from " + TABLE_NAME // + + " where (s_date < " + vDate + ") or (s_date = " + vDate + " and s_time <= " + vTime + ")"; + this.parameterMapping = TgParameterMapping.of(vDate, vTime); + } + }; + + @Override + public int deleteOldDateTime(LocalDate date, LocalTime time, int factoryId) { + var ps = deleteOldDateTimeFactoryCache.get(); + var parameter = TgBindParameters.of(vDate.bind(date), vTime.bind(time), vFactory.bind(factoryId)); + return executeAndGetCount(ps, parameter); + } + + private final CachePreparedStatement deleteOldDateTimeFactoryCache = new CachePreparedStatement<>() { + @Override + protected void initialize() { + this.sql = "delete from " + TABLE_NAME // + + " where ((s_date < " + vDate + ") or (s_date = " + vDate + " and s_time <= " + vTime + ")) and s_f_id = " + vFactory; + this.parameterMapping = TgParameterMapping.of(vDate, vTime, vFactory); + } + }; + @Override public void insertSelectFromCostMaster(LocalDate date, LocalTime time) { throw new UnsupportedOperationException("not yet impl"); diff --git a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/jdbc/dao/StockHistoryDaoJdbc.java b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/jdbc/dao/StockHistoryDaoJdbc.java index 00b400d0..2695e605 100755 --- a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/jdbc/dao/StockHistoryDaoJdbc.java +++ b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/jdbc/dao/StockHistoryDaoJdbc.java @@ -13,6 +13,7 @@ import com.tsurugidb.benchmark.costaccounting.db.dao.CostMasterDao; import com.tsurugidb.benchmark.costaccounting.db.dao.StockHistoryDao; import com.tsurugidb.benchmark.costaccounting.db.entity.StockHistory; +import com.tsurugidb.benchmark.costaccounting.db.entity.StockHistoryDateTime; import com.tsurugidb.benchmark.costaccounting.db.jdbc.CostBenchDbManagerJdbc; public class StockHistoryDaoJdbc extends JdbcDao implements StockHistoryDao { @@ -54,6 +55,44 @@ public int[] insertBatch(Collection entityList) { return doInsert(entityList); } + @Override + public List selectDistinctDateTime() { + String sql = "select distinct s_date, s_time from " + TABLE_NAME // + + " order by s_date, s_time"; + return executeQueryList(sql, ps -> { + }, rs -> { + var entity = new StockHistoryDateTime(); + entity.setSDate(JdbcUtil.getDate(rs, "s_date")); + entity.setSTime(JdbcUtil.getTime(rs, "s_time")); + return entity; + }); + } + + @Override + public int deleteOldDateTime(LocalDate date, LocalTime time) { + String sql = "delete from " + TABLE_NAME // + + " where (s_date < ?) or (s_date = ? and s_time <= ?)"; + return executeUpdate(sql, ps -> { + int i = 1; + JdbcUtil.setDate(ps, i++, date); + JdbcUtil.setDate(ps, i++, date); + JdbcUtil.setTime(ps, i++, time); + }); + } + + @Override + public int deleteOldDateTime(LocalDate date, LocalTime time, int factoryId) { + String sql = "delete from " + TABLE_NAME // + + " where ((s_date < ?) or (s_date = ? and s_time <= ?)) and s_f_id = ?"; + return executeUpdate(sql, ps -> { + int i = 1; + JdbcUtil.setDate(ps, i++, date); + JdbcUtil.setDate(ps, i++, date); + JdbcUtil.setTime(ps, i++, time); + JdbcUtil.setInt(ps, i++, factoryId); + }); + } + private static final String INSERT_SELECT_FROM_COST_MASTER_SQL = "insert into " + TABLE_NAME // + "(" + COLUMN_LIST.stream().map(c -> c.getName()).collect(Collectors.joining(", ")) + ")" // + " select ?, ?, c_f_id, c_i_id, c_stock_unit, c_stock_quantity, c_stock_amount from " + CostMasterDao.TABLE_NAME; diff --git a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/tsubakuro/dao/StockHistoryDaoTsubakuro.java b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/tsubakuro/dao/StockHistoryDaoTsubakuro.java index efcac80f..d96de0d0 100755 --- a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/tsubakuro/dao/StockHistoryDaoTsubakuro.java +++ b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/db/tsubakuro/dao/StockHistoryDaoTsubakuro.java @@ -9,6 +9,7 @@ import com.tsurugidb.benchmark.costaccounting.db.dao.StockHistoryDao; import com.tsurugidb.benchmark.costaccounting.db.entity.StockHistory; +import com.tsurugidb.benchmark.costaccounting.db.entity.StockHistoryDateTime; import com.tsurugidb.benchmark.costaccounting.db.tsubakuro.CostBenchDbManagerTsubakuro; import com.tsurugidb.sql.proto.SqlCommon.AtomType; @@ -53,6 +54,21 @@ public int[] insertBatch(Collection entityList) { return doInsert(entityList, false); } + @Override + public List selectDistinctDateTime() { + throw new UnsupportedOperationException("not yet impl"); + } + + @Override + public int deleteOldDateTime(LocalDate date, LocalTime time) { + throw new UnsupportedOperationException("not yet impl"); + } + + @Override + public int deleteOldDateTime(LocalDate date, LocalTime time, int factoryId) { + throw new UnsupportedOperationException("not yet impl"); + } + @Override public void insertSelectFromCostMaster(LocalDate date, LocalTime time) { throw new UnsupportedOperationException("not yet impl"); diff --git a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/online/periodic/BenchPeriodicUpdateStockTask.java b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/online/periodic/BenchPeriodicUpdateStockTask.java index 637d1bff..6a297341 100755 --- a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/online/periodic/BenchPeriodicUpdateStockTask.java +++ b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/online/periodic/BenchPeriodicUpdateStockTask.java @@ -2,7 +2,7 @@ import java.io.IOException; import java.io.UncheckedIOException; -import java.time.LocalTime; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -21,6 +21,7 @@ import com.tsurugidb.benchmark.costaccounting.db.dao.StockHistoryDao; import com.tsurugidb.benchmark.costaccounting.db.entity.CostMaster; import com.tsurugidb.benchmark.costaccounting.db.entity.StockHistory; +import com.tsurugidb.benchmark.costaccounting.db.entity.StockHistoryDateTime; import com.tsurugidb.benchmark.costaccounting.init.InitialData; import com.tsurugidb.benchmark.costaccounting.online.OnlineConfig; import com.tsurugidb.benchmark.costaccounting.util.BenchConst; @@ -35,9 +36,11 @@ public class BenchPeriodicUpdateStockTask extends BenchPeriodicTask { public static final String TASK_NAME = "update-stock"; + private TgTmSetting settingPre; private TgTmSetting settingMain; private final int threadSize; private final ExecutorService service; + private final int keepSize; public BenchPeriodicUpdateStockTask(int taskId) { super(TASK_NAME, taskId); @@ -48,10 +51,22 @@ public BenchPeriodicUpdateStockTask(int taskId) { } else { this.service = Executors.newFixedThreadPool(threadSize); } + this.keepSize = BenchConst.periodicKeepSize(TASK_NAME); + LOG.info("keep.size={}", keepSize); + } + + BenchPeriodicUpdateStockTask(int threadSize, int keepSize) { // for test + super(TASK_NAME, 0); + this.threadSize = threadSize; + this.service = null; + this.keepSize = keepSize; } @Override public void initializeSetting() { + this.settingPre = TgTmSetting.ofAlways(TgTxOption.ofLTX() // RTXだと古いデータが読まれてしまうことがある + .addInclusiveReadArea(StockHistoryDao.TABLE_NAME).label(TASK_NAME + ".pre")); +// this.settingPre = TgTmSetting.ofAlways(TgTxOption.ofOCC().label(TASK_NAME + ".pre")); this.settingMain = config.getSetting(LOG, this, () -> { if (BenchConst.useReadArea()) { return TgTxOption.ofLTX(BenchConst.DEFAULT_TX_OPTION).addWritePreserve(StockHistoryDao.TABLE_NAME) // @@ -65,15 +80,52 @@ public void initializeSetting() { @Override protected boolean execute1() { - if (threadSize <= 1) { - return executeAll(); - } else { - return executeFactory(threadSize); + long start = System.currentTimeMillis(); + var deleteDateTime = getDeleteDateTime(); + LOG.info("deleteDateTime={} {}[ms]", deleteDateTime, System.currentTimeMillis() - start); + start = System.currentTimeMillis(); + try { + if (threadSize <= 1) { + return executeAll(deleteDateTime); + } else { + return executeFactory(threadSize, deleteDateTime); + } + } finally { + if (deleteDateTime == null) { + LOG.info("insert {}[ms]", System.currentTimeMillis() - start); + } else { + LOG.info("delete+insert {}[ms]", System.currentTimeMillis() - start); + } } } - private boolean executeAll() { + private StockHistoryDateTime getDeleteDateTime() { + if (this.keepSize <= 0) { + return null; + } + + var list = dbManager.execute(settingPre, () -> { + var dao = dbManager.getStockHistoryDao(); + return dao.selectDistinctDateTime(); + }); + return getDeleteDateTime(list); + } + + StockHistoryDateTime getDeleteDateTime(List list) { + int i = list.size() - this.keepSize; + if (i < 0) { + return null; + } + return list.get(i); + } + + private boolean executeAll(StockHistoryDateTime deleteDateTime) { return dbManager.execute(settingMain, () -> { + if (deleteDateTime != null) { + var dao = dbManager.getStockHistoryDao(); + dao.deleteOldDateTime(deleteDateTime.getSDate(), deleteDateTime.getSTime()); + } + executeAllInTransaction(); return true; @@ -81,30 +133,30 @@ private boolean executeAll() { } private void executeAllInTransaction() { - var time = LocalTime.now(); + var now = LocalDateTime.now(); if (BenchConst.WORKAROUND) { var costMasterDao = dbManager.getCostMasterDao(); try (var stream = costMasterDao.selectAll()) { - streamInsert(stream, time); + streamInsert(stream, now); } return; } var dao = dbManager.getStockHistoryDao(); - dao.insertSelectFromCostMaster(date, time); + dao.insertSelectFromCostMaster(now.toLocalDate(), now.toLocalTime()); } - private void streamInsert(Stream stream, LocalTime time) { + private void streamInsert(Stream stream, LocalDateTime now) { var dao = dbManager.getStockHistoryDao(); final int batchSize = 10000; var list = new ArrayList(batchSize); stream.forEach(cost -> { var entity = new StockHistory(); - entity.setSDate(date); + entity.setSDate(now.toLocalDate()); + entity.setSTime(now.toLocalTime()); entity.setSFId(cost.getCFId()); entity.setSIId(cost.getCIId()); - entity.setSTime(time); entity.setSStockUnit(cost.getCStockUnit()); entity.setSStockQuantity(cost.getCStockQuantity()); entity.setSStockAmount(cost.getCStockAmount()); @@ -119,12 +171,12 @@ private void streamInsert(Stream stream, LocalTime time) { } } - private boolean executeFactory(int threadSize) { - var time = LocalTime.now(); + private boolean executeFactory(int threadSize, StockHistoryDateTime deleteDateTime) { + var now = LocalDateTime.now(); List> taskList = new ArrayList<>(factoryList.size()); for (int factoryId : factoryList) { - var task = new FactoryTask(factoryId, time); + var task = new FactoryTask(factoryId, now, deleteDateTime); taskList.add(task); } @@ -172,17 +224,24 @@ private static IOException findIOException(Exception e) { private class FactoryTask implements Callable { private final int factoryId; - private final LocalTime time; + private final LocalDateTime now; + private final StockHistoryDateTime deleteDateTime; - public FactoryTask(int factoryId, LocalTime time) { + public FactoryTask(int factoryId, LocalDateTime now, StockHistoryDateTime deleteDateTime) { this.factoryId = factoryId; - this.time = time; + this.now = now; + this.deleteDateTime = deleteDateTime; } @Override public Void call() throws Exception { try { dbManager.execute(settingMain, () -> { + if (deleteDateTime != null) { + var dao = dbManager.getStockHistoryDao(); + dao.deleteOldDateTime(deleteDateTime.getSDate(), deleteDateTime.getSTime(), factoryId); + } + executeInTransaction(); }); } catch (Throwable e) { @@ -196,13 +255,13 @@ private void executeInTransaction() { if (BenchConst.WORKAROUND) { var costMasterDao = dbManager.getCostMasterDao(); try (var stream = costMasterDao.selectByFactory(factoryId)) { - streamInsert(stream, time); + streamInsert(stream, now); } return; } var dao = dbManager.getStockHistoryDao(); - dao.insertSelectFromCostMaster(date, time, factoryId); + dao.insertSelectFromCostMaster(now.toLocalDate(), now.toLocalTime(), factoryId); } } diff --git a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/util/BenchConst.java b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/util/BenchConst.java index a1f17cf8..ec598f76 100755 --- a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/util/BenchConst.java +++ b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/util/BenchConst.java @@ -390,6 +390,10 @@ public static int periodicSplitSize(String taskName) { return getPropertyInt("periodic.schedule." + taskName + ".split.size", 1); } + public static int periodicKeepSize(String taskName) { + return getPropertyInt("periodic.schedule." + taskName + ".keep.size", -1); + } + // online-command public static String onlineCommandLabel() { diff --git a/java/cost-accounting-benchmark/src/test/java/com/tsurugidb/benchmark/costaccounting/db/entity/StockHistoryDateTimeTest.java b/java/cost-accounting-benchmark/src/test/java/com/tsurugidb/benchmark/costaccounting/db/entity/StockHistoryDateTimeTest.java new file mode 100755 index 00000000..b8a983d7 --- /dev/null +++ b/java/cost-accounting-benchmark/src/test/java/com/tsurugidb/benchmark/costaccounting/db/entity/StockHistoryDateTimeTest.java @@ -0,0 +1,36 @@ +package com.tsurugidb.benchmark.costaccounting.db.entity; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.Test; + +class StockHistoryDateTimeTest { + + @Test + void testCompareTo() { + var entity17_00 = create(2024, 1, 17, 0); + var entity17_12 = create(2024, 1, 17, 12); + var entity17_23 = create(2024, 1, 17, 23); + var entity16_00 = create(2024, 1, 16, 0); + var entity16_12 = create(2024, 1, 16, 12); + var entity16_23 = create(2024, 1, 16, 23); + var list = new ArrayList<>(List.of(entity17_00, entity17_23, entity16_23, entity16_12, entity16_00, entity17_12)); + Collections.sort(list); + + var expected = List.of(entity16_00, entity16_12, entity16_23, entity17_00, entity17_12, entity17_23); + assertEquals(expected, list); + } + + static StockHistoryDateTime create(int y, int m, int d, int h) { + var entity = new StockHistoryDateTime(); + entity.setSDate(LocalDate.of(y, m, d)); + entity.setSTime(LocalTime.of(h, 0)); + return entity; + } +} diff --git a/java/cost-accounting-benchmark/src/test/java/com/tsurugidb/benchmark/costaccounting/online/periodic/BenchPeriodicUpdateStockTaskTest.java b/java/cost-accounting-benchmark/src/test/java/com/tsurugidb/benchmark/costaccounting/online/periodic/BenchPeriodicUpdateStockTaskTest.java new file mode 100755 index 00000000..4ea70a49 --- /dev/null +++ b/java/cost-accounting-benchmark/src/test/java/com/tsurugidb/benchmark/costaccounting/online/periodic/BenchPeriodicUpdateStockTaskTest.java @@ -0,0 +1,65 @@ +package com.tsurugidb.benchmark.costaccounting.online.periodic; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import com.tsurugidb.benchmark.costaccounting.db.entity.StockHistoryDateTime; + +class BenchPeriodicUpdateStockTaskTest { + + @Test + void testGetDeleteDateTime() { + try (var task = new BenchPeriodicUpdateStockTask(1, 1)) { + for (int listSize = 0; listSize <= 4; listSize++) { + var list = createList(listSize); + + var actual = task.getDeleteDateTime(list); + + if (listSize == 0) { + assertNull(actual); + } else { + assertEquals(create(2024, 1, 17), actual); + } + } + } + + int keepSize = 3; + try (var task = new BenchPeriodicUpdateStockTask(1, keepSize)) { + for (int listSize = 0; listSize <= 10; listSize++) { + var list = createList(listSize); + + var actual = task.getDeleteDateTime(list); + + if (listSize < keepSize) { + assertNull(actual); + } else { + var sub = list.subList(0, listSize - keepSize + 1); + var last = sub.get(sub.size() - 1); + assertEquals(last, actual); + } + } + } + } + + private static List createList(int size) { + var list = new ArrayList(); + for (int i = 0; i < size; i++) { + list.add(create(2024, 1, 17 - size + i + 1)); + } + return list; + } + + private static StockHistoryDateTime create(int y, int m, int d) { + var entity = new StockHistoryDateTime(); + entity.setSDate(LocalDate.of(y, m, d)); + entity.setSTime(LocalTime.of(0, 0)); + return entity; + } +}