mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 18:03:12 +01:00
Run getUsdAveragePriceMapsPerTickUnit and getTradeStatisticsForCurrency
in parallel and once both are done we call asyncUpdateChartData (not yet refactored). Clear all data at deactivate This cause a bit of costs when we activate again but as we delegate now all work to threads it should be OK. It decreases the memory usage if we do not keep those data in the fields. The View classes are cached in the view loader so all data in fields stays in memory once it was activated once and not manually cleared in deactivate. Move getTradeStatisticsForCurrency to ChartCalculations Rename buildUsdPricesPerTickUnit to getUsdAveragePriceMapsPerTickUnit Rename selectedTradeStatistics to tradeStatisticsByCurrency Make itemsPerInterval final Remove modelReady Add deactivateCalled flag
This commit is contained in:
parent
65706e7c14
commit
7ad5993aad
@ -34,11 +34,12 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ChartCalculations {
|
public class ChartCalculations {
|
||||||
static final ZoneId ZONE_ID = ZoneId.systemDefault();
|
static final ZoneId ZONE_ID = ZoneId.systemDefault();
|
||||||
|
|
||||||
static CompletableFuture<Map<TradesChartsViewModel.TickUnit, Map<Long, Long>>> buildUsdPricesPerTickUnit(Set<TradeStatistics3> tradeStatisticsSet) {
|
static CompletableFuture<Map<TradesChartsViewModel.TickUnit, Map<Long, Long>>> getUsdAveragePriceMapsPerTickUnit(Set<TradeStatistics3> tradeStatisticsSet) {
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
Map<TradesChartsViewModel.TickUnit, Map<Long, Long>> usdAveragePriceMapsPerTickUnit = new HashMap<>();
|
Map<TradesChartsViewModel.TickUnit, Map<Long, Long>> usdAveragePriceMapsPerTickUnit = new HashMap<>();
|
||||||
Map<TradesChartsViewModel.TickUnit, Map<Long, List<TradeStatistics3>>> dateMapsPerTickUnit = new HashMap<>();
|
Map<TradesChartsViewModel.TickUnit, Map<Long, List<TradeStatistics3>>> dateMapsPerTickUnit = new HashMap<>();
|
||||||
@ -66,6 +67,15 @@ public class ChartCalculations {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CompletableFuture<List<TradeStatistics3>> getTradeStatisticsForCurrency(Set<TradeStatistics3> tradeStatisticsSet,
|
||||||
|
String currencyCode,
|
||||||
|
boolean showAllTradeCurrencies) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
return tradeStatisticsSet.stream()
|
||||||
|
.filter(e -> showAllTradeCurrencies || e.getCurrency().equals(currencyCode))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static long getAveragePrice(List<TradeStatistics3> tradeStatisticsList) {
|
static long getAveragePrice(List<TradeStatistics3> tradeStatisticsList) {
|
||||||
long accumulatedAmount = 0;
|
long accumulatedAmount = 0;
|
||||||
|
@ -39,6 +39,7 @@ import bisq.core.trade.statistics.TradeStatisticsManager;
|
|||||||
import bisq.core.user.Preferences;
|
import bisq.core.user.Preferences;
|
||||||
|
|
||||||
import bisq.common.UserThread;
|
import bisq.common.UserThread;
|
||||||
|
import bisq.common.util.CompletableFutureUtils;
|
||||||
import bisq.common.util.MathUtils;
|
import bisq.common.util.MathUtils;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
@ -70,6 +71,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -103,18 +105,18 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
|||||||
final BooleanProperty showAllTradeCurrenciesProperty = new SimpleBooleanProperty(false);
|
final BooleanProperty showAllTradeCurrenciesProperty = new SimpleBooleanProperty(false);
|
||||||
private final CurrencyList currencyListItems;
|
private final CurrencyList currencyListItems;
|
||||||
private final CurrencyListItem showAllCurrencyListItem = new CurrencyListItem(new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, ""), -1);
|
private final CurrencyListItem showAllCurrencyListItem = new CurrencyListItem(new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, ""), -1);
|
||||||
final ObservableList<TradeStatistics3> selectedTradeStatistics = FXCollections.observableArrayList();
|
final ObservableList<TradeStatistics3> tradeStatisticsByCurrency = FXCollections.observableArrayList();
|
||||||
final ObservableList<XYChart.Data<Number, Number>> priceItems = FXCollections.observableArrayList();
|
final ObservableList<XYChart.Data<Number, Number>> priceItems = FXCollections.observableArrayList();
|
||||||
final ObservableList<XYChart.Data<Number, Number>> volumeItems = FXCollections.observableArrayList();
|
final ObservableList<XYChart.Data<Number, Number>> volumeItems = FXCollections.observableArrayList();
|
||||||
final ObservableList<XYChart.Data<Number, Number>> volumeInUsdItems = FXCollections.observableArrayList();
|
final ObservableList<XYChart.Data<Number, Number>> volumeInUsdItems = FXCollections.observableArrayList();
|
||||||
private Map<Long, Pair<Date, Set<TradeStatistics3>>> itemsPerInterval;
|
private final Map<Long, Pair<Date, Set<TradeStatistics3>>> itemsPerInterval = new HashMap<>();
|
||||||
|
|
||||||
TickUnit tickUnit;
|
TickUnit tickUnit;
|
||||||
final int maxTicks = 90;
|
final int maxTicks = 90;
|
||||||
private int selectedTabIndex;
|
private int selectedTabIndex;
|
||||||
final Map<TickUnit, Map<Long, Long>> usdAveragePriceMapsPerTickUnit = new HashMap<>();
|
final Map<TickUnit, Map<Long, Long>> usdAveragePriceMapsPerTickUnit = new HashMap<>();
|
||||||
private boolean fillTradeCurrenciesOnActivateCalled;
|
private boolean fillTradeCurrenciesOnActivateCalled;
|
||||||
final BooleanProperty modelReady = new SimpleBooleanProperty(false);
|
private volatile boolean deactivateCalled;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -149,6 +151,10 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void activate() {
|
protected void activate() {
|
||||||
|
deactivateCalled = false;
|
||||||
|
long ts = System.currentTimeMillis();
|
||||||
|
|
||||||
|
|
||||||
tradeStatisticsManager.getObservableTradeStatisticsSet().addListener(setChangeListener);
|
tradeStatisticsManager.getObservableTradeStatisticsSet().addListener(setChangeListener);
|
||||||
if (!fillTradeCurrenciesOnActivateCalled) {
|
if (!fillTradeCurrenciesOnActivateCalled) {
|
||||||
fillTradeCurrencies();
|
fillTradeCurrencies();
|
||||||
@ -157,32 +163,92 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
|||||||
syncPriceFeedCurrency();
|
syncPriceFeedCurrency();
|
||||||
setMarketPriceFeedCurrency();
|
setMarketPriceFeedCurrency();
|
||||||
|
|
||||||
ChartCalculations.buildUsdPricesPerTickUnit(tradeStatisticsManager.getObservableTradeStatisticsSet())
|
long ts1 = System.currentTimeMillis();
|
||||||
.whenComplete((usdAveragePriceMapsPerTickUnit, throwable) -> {
|
|
||||||
|
List<CompletableFuture<Boolean>> allFutures = new ArrayList<>();
|
||||||
|
CompletableFuture<Boolean> task1Done = new CompletableFuture<>();
|
||||||
|
allFutures.add(task1Done);
|
||||||
|
CompletableFuture<Boolean> task2Done = new CompletableFuture<>();
|
||||||
|
allFutures.add(task2Done);
|
||||||
|
CompletableFutureUtils.allOf(allFutures)
|
||||||
|
.whenComplete((res, throwable) -> {
|
||||||
|
if (deactivateCalled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
log.error(throwable.toString());
|
log.error(throwable.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//Once getUsdAveragePriceMapsPerTickUnit and getUsdAveragePriceMapsPerTickUnit are both completed we
|
||||||
|
// call updateChartData2
|
||||||
|
UserThread.execute(this::asyncUpdateChartData);
|
||||||
|
});
|
||||||
|
|
||||||
|
// We start getUsdAveragePriceMapsPerTickUnit and getUsdAveragePriceMapsPerTickUnit in parallel threads for
|
||||||
|
// better performance
|
||||||
|
ChartCalculations.getUsdAveragePriceMapsPerTickUnit(tradeStatisticsManager.getObservableTradeStatisticsSet())
|
||||||
|
.whenComplete((usdAveragePriceMapsPerTickUnit, throwable) -> {
|
||||||
|
if (deactivateCalled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (throwable != null) {
|
||||||
|
log.error(throwable.toString());
|
||||||
|
task1Done.completeExceptionally(throwable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
UserThread.execute(() -> {
|
UserThread.execute(() -> {
|
||||||
this.usdAveragePriceMapsPerTickUnit.clear();
|
this.usdAveragePriceMapsPerTickUnit.clear();
|
||||||
this.usdAveragePriceMapsPerTickUnit.putAll(usdAveragePriceMapsPerTickUnit);
|
this.usdAveragePriceMapsPerTickUnit.putAll(usdAveragePriceMapsPerTickUnit);
|
||||||
|
log.error("getUsdAveragePriceMapsPerTickUnit took {}", System.currentTimeMillis() - ts1);
|
||||||
List<TradeStatistics3> list = getTradeStatisticsForCurrency(tradeStatisticsManager.getObservableTradeStatisticsSet(),
|
task1Done.complete(true);
|
||||||
getCurrencyCode(),
|
|
||||||
showAllTradeCurrenciesProperty.get());
|
|
||||||
selectedTradeStatistics.setAll(list);
|
|
||||||
|
|
||||||
updateChartData();
|
|
||||||
modelReady.set(true);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
long ts2 = System.currentTimeMillis();
|
||||||
|
ChartCalculations.getTradeStatisticsForCurrency(tradeStatisticsManager.getObservableTradeStatisticsSet(),
|
||||||
|
getCurrencyCode(),
|
||||||
|
showAllTradeCurrenciesProperty.get())
|
||||||
|
.whenComplete((list, throwable) -> {
|
||||||
|
if (deactivateCalled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (throwable != null) {
|
||||||
|
log.error(throwable.toString());
|
||||||
|
task2Done.completeExceptionally(throwable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserThread.execute(() -> {
|
||||||
|
tradeStatisticsByCurrency.setAll(list);
|
||||||
|
log.error("getTradeStatisticsForCurrency took {}", System.currentTimeMillis() - ts2);
|
||||||
|
task2Done.complete(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
log.error("activate took {}", System.currentTimeMillis() - ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void asyncUpdateChartData() {
|
||||||
|
long ts = System.currentTimeMillis();
|
||||||
|
updateChartData();
|
||||||
|
log.error("updateChartData took {}", System.currentTimeMillis() - ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void deactivate() {
|
protected void deactivate() {
|
||||||
|
deactivateCalled = true;
|
||||||
tradeStatisticsManager.getObservableTradeStatisticsSet().removeListener(setChangeListener);
|
tradeStatisticsManager.getObservableTradeStatisticsSet().removeListener(setChangeListener);
|
||||||
usdAveragePriceMapsPerTickUnit.clear();
|
|
||||||
|
// We want to avoid to trigger listeners in the view so we delay a bit. Deactivate on model is called before
|
||||||
|
// deactivate on view.
|
||||||
|
UserThread.execute(() -> {
|
||||||
|
usdAveragePriceMapsPerTickUnit.clear();
|
||||||
|
tradeStatisticsByCurrency.clear();
|
||||||
|
priceItems.clear();
|
||||||
|
volumeItems.clear();
|
||||||
|
volumeInUsdItems.clear();
|
||||||
|
itemsPerInterval.clear();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -271,7 +337,7 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
|||||||
|
|
||||||
private void updateChartData() {
|
private void updateChartData() {
|
||||||
// Generate date range and create sets for all ticks
|
// Generate date range and create sets for all ticks
|
||||||
itemsPerInterval = new HashMap<>();
|
itemsPerInterval.clear();
|
||||||
Date time = new Date();
|
Date time = new Date();
|
||||||
for (long i = maxTicks + 1; i >= 0; --i) {
|
for (long i = maxTicks + 1; i >= 0; --i) {
|
||||||
Pair<Date, Set<TradeStatistics3>> pair = new Pair<>((Date) time.clone(), new HashSet<>());
|
Pair<Date, Set<TradeStatistics3>> pair = new Pair<>((Date) time.clone(), new HashSet<>());
|
||||||
@ -282,7 +348,7 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get all entries for the defined time interval
|
// Get all entries for the defined time interval
|
||||||
selectedTradeStatistics.forEach(tradeStatistics -> {
|
tradeStatisticsByCurrency.forEach(tradeStatistics -> {
|
||||||
for (long i = maxTicks; i > 0; --i) {
|
for (long i = maxTicks; i > 0; --i) {
|
||||||
Pair<Date, Set<TradeStatistics3>> pair = itemsPerInterval.get(i);
|
Pair<Date, Set<TradeStatistics3>> pair = itemsPerInterval.get(i);
|
||||||
if (tradeStatistics.getDate().after(pair.getKey())) {
|
if (tradeStatistics.getDate().after(pair.getKey())) {
|
||||||
@ -322,16 +388,8 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
|||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<TradeStatistics3> getTradeStatisticsForCurrency(Set<TradeStatistics3> tradeStatisticsSet,
|
|
||||||
String currencyCode,
|
|
||||||
boolean showAllTradeCurrencies) {
|
|
||||||
return tradeStatisticsSet.stream()
|
|
||||||
.filter(e -> showAllTradeCurrencies || e.getCurrency().equals(currencyCode))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateSelectedTradeStatistics(String currencyCode) {
|
private void updateSelectedTradeStatistics(String currencyCode) {
|
||||||
selectedTradeStatistics.setAll(tradeStatisticsManager.getObservableTradeStatisticsSet().stream()
|
tradeStatisticsByCurrency.setAll(tradeStatisticsManager.getObservableTradeStatisticsSet().stream()
|
||||||
.filter(e -> showAllTradeCurrenciesProperty.get() || e.getCurrency().equals(currencyCode))
|
.filter(e -> showAllTradeCurrenciesProperty.get() || e.getCurrency().equals(currencyCode))
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user