diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/action/RequirementAndObligationCreationCompoundAction.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/action/RequirementAndObligationCreationCompoundAction.java new file mode 100644 index 000000000..2610c0926 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/action/RequirementAndObligationCreationCompoundAction.java @@ -0,0 +1,96 @@ +package ru.spcex.clearing.session.state.action; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.statemachine.StateContext; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.execution.ExecutionCommon; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.spcex.clearing.session.stage.TaskType; +import ru.spcex.clearing.session.state.DataEnum; +import ru.spcex.clearing.session.state.SsnEvent; +import static ru.spcex.clearing.util.ComparatorUtil.*; +import ru.spcex.platform.classes.base.interfaces.ExecutionType; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.collection.Pair; + +@Service +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class RequirementAndObligationCreationCompoundAction extends RequirementAndObligationCreationAction { + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Autowired + public RequirementAndObligationCreationCompoundAction(ImdgProvider imdgProvider) { + super(imdgProvider); + } + + @SuppressWarnings("unchecked") + @Override + public void actualExecute(StateContext ctx) { + Long sessionId = ctx.getExtendedState().get(DataEnum.sessionId, Long.class); + List tmpList = new ArrayList<>(Arrays.asList(new ExecutionCommon[2])); + List executionFond = ctx.getExtendedState().get(DataEnum.dealsPreparedFond, List.class); + List executionCurrency = ctx.getExtendedState().get(DataEnum.dealsPreparedDeposit, List.class); + List executionDeposit = ctx.getExtendedState().get(DataEnum.dealsPreparedCurrency, List.class); + Map newRgss = storageMap(executionFond, executionCurrency, executionDeposit); + Stream.of(executionFond, executionCurrency, executionDeposit).forEach(c -> c.sort(tradeTimeComparator.thenComparing(execIdComparator).thenComparing(execMarketComparator))); + + int efs = executionFond.size(); + int eds = executionDeposit.size(); + int ecs = executionCurrency.size(); + + int[] ief = {0}, ied = {0}, iec = {0}; + while (ief[0] < efs || ied[0] < eds || iec[0] < ecs) { + Pair pair = getMinTimeExecutions( + safeMatch(executionFond, ief), + safeMatch(executionDeposit, ied), + safeMatch(executionCurrency, iec) + ); + if (pair == null) continue; + if (pair.getFirst().type().equals(ExecutionType.ExecutionFond)) ief[0] += 2; + if (pair.getFirst().type().equals(ExecutionType.ExecutionDeposit)) ied[0] += 2; + if (pair.getFirst().type().equals(ExecutionType.ExecutionCurrency)) iec[0] += 2; + pair.map(f -> tmpList.set(0, f), s -> tmpList.set(1, s)); + createRegisters(tmpList, sessionId, newRgss); + } + log.info("batch insert {} registries into map", newRgss.size()); + registryImdg.putAll(newRgss); + } + + protected Map storageMap(List executionFond, List executionCurrency, List executionDeposit) { + int depSize = executionDeposit.size() * 4; + int othersSize = Math.max(executionFond.size() * 2, executionCurrency.size() * 2); + int capacity = calcMapCapacity(Math.max(depSize, othersSize)); + return new HashMap<>(capacity, 1f); + } + + private Pair safeMatch(List l, int[] i) { + Pair pair = matchExecutions(l, i[0]); + if (pair == null) { + i[0]++; + return null; + } +// i[0] += 2; + return pair; + } + + private Pair getMinTimeExecutions( + Pair fond, + Pair deposit, + Pair currency) { + + return Stream.of(fond, deposit, currency) + .filter(Objects::nonNull) + .min((p1, p2) -> tradeTimeComparator.compare(p1.getFirst(), p2.getFirst())).orElse(null); + } +}