Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up BSQ supply view load #3956

Merged
merged 2 commits into from
Feb 17, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@

import javafx.util.StringConverter;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
Expand All @@ -77,8 +78,10 @@
import java.util.Map;
import java.util.Set;
import java.util.Spliterators.AbstractSpliterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand All @@ -88,9 +91,6 @@
import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
import static bisq.desktop.util.FormBuilder.addTopLabelReadOnlyTextField;


import java.sql.Date;

@FxmlView
public class SupplyView extends ActivatableView<GridPane, Void> implements DaoStateListener {

Expand All @@ -110,7 +110,7 @@ public class SupplyView extends ActivatableView<GridPane, Void> implements DaoSt

private XYChart.Series<Number, Number> seriesBSQIssuedMonthly2;

private ListChangeListener changeListenerBSQBurntDaily;
private ListChangeListener<XYChart.Data<Number, Number>> changeListenerBSQBurntDaily;
private NumberAxis yAxisBSQBurntDaily;

private ToggleButton zoomToInliersSlide;
Expand Down Expand Up @@ -194,22 +194,19 @@ private void initializeSeries() {
var burntLabel = Res.get("dao.factsAndFigures.supply.burnt");

seriesBSQIssuedMonthly = new XYChart.Series<>();
var issuedMonthlyLabel = issuedLabel;
seriesBSQIssuedMonthly.setName(issuedMonthlyLabel);
seriesBSQIssuedMonthly.setName(issuedLabel);

// Because Series cannot be reused in multiple charts, we create a
// "second" Series and populate it at the same time as the original.
// Some other solutions: https://stackoverflow.com/questions/49770442
seriesBSQIssuedMonthly2 = new XYChart.Series<>();
seriesBSQIssuedMonthly2.setName(issuedMonthlyLabel);
seriesBSQIssuedMonthly2.setName(issuedLabel);

seriesBSQBurntMonthly = new XYChart.Series<>();
var burntMonthlyLabel = burntLabel;
seriesBSQBurntMonthly.setName(burntMonthlyLabel);
seriesBSQBurntMonthly.setName(burntLabel);

seriesBSQBurntDaily = new XYChart.Series<>();
var burntDailyLabel = burntLabel;
seriesBSQBurntDaily.setName(burntDailyLabel);
seriesBSQBurntDaily.setName(burntLabel);

seriesBSQBurntDailyMA = new XYChart.Series<>();
var burntMALabel = Res.get("dao.factsAndFigures.supply.burntMovingAverage");
Expand All @@ -223,21 +220,20 @@ private void createSupplyIncreasedVsDecreasedInformation() {

var chartPane = wrapInChartPane(chart);

addToTopMargin(chartPane, Layout.COMPACT_FIRST_ROW_DISTANCE);
addToTopMargin(chartPane);

root.getChildren().add(chartPane);
}

private void addToTopMargin(Node child, double amount) {
private void addToTopMargin(Node child) {
var margin = GridPane.getMargin(child);

var new_insets =
new Insets(
margin.getTop() + amount,
margin.getRight(),
margin.getBottom(),
margin.getLeft()
);
var new_insets = new Insets(
margin.getTop() + Layout.COMPACT_FIRST_ROW_DISTANCE,
margin.getRight(),
margin.getBottom(),
margin.getLeft()
);

GridPane.setMargin(child, new_insets);
}
Expand Down Expand Up @@ -318,7 +314,7 @@ private Node createBSQIssuedVsBurntChart(
configureChart(chart);
chart.setCreateSymbols(false);

chart.getData().addAll(seriesBSQIssuedMonthly, seriesBSQBurntMonthly);
chart.getData().addAll(List.of(seriesBSQIssuedMonthly, seriesBSQBurntMonthly));

chart.setLegendVisible(true);

Expand All @@ -344,7 +340,6 @@ private Node createBSQIssuedChart(XYChart.Series<Number, Number> series) {
return chart;
}

@SuppressWarnings("unchecked")
private Node createBSQBurntChart(
XYChart.Series<Number, Number> seriesBSQBurntDaily,
XYChart.Series<Number, Number> seriesBSQBurntDailyMA
Expand All @@ -371,7 +366,7 @@ private Node createBSQBurntChart(
configureChart(chart);
chart.setCreateSymbols(false);

chart.getData().addAll(seriesBSQBurntDaily, seriesBSQBurntDailyMA);
chart.getData().addAll(List.of(seriesBSQBurntDaily, seriesBSQBurntDailyMA));

chart.setLegendVisible(true);

Expand Down Expand Up @@ -501,11 +496,9 @@ private List<Tx> getSortedBurntTxs() {
Set<Tx> burntTxs = new HashSet<>(daoStateService.getBurntFeeTxs());
burntTxs.addAll(daoStateService.getInvalidTxs());

List<Tx> sortedBurntTxs = burntTxs.stream()
return burntTxs.stream()
.sorted(Comparator.comparing(Tx::getTime))
.collect(Collectors.toList());

return sortedBurntTxs;
}

private List<XYChart.Data<Number, Number>> updateBSQBurntDaily(List<Tx> sortedBurntTxs) {
Expand All @@ -515,18 +508,16 @@ private List<XYChart.Data<Number, Number>> updateBSQBurntDaily(List<Tx> sortedBu
sortedBurntTxs
.stream()
.collect(Collectors.groupingBy(
tx ->
new Date(tx.getTime())
.toLocalDate()
.with(ADJUSTERS.get(DAY))
tx -> Instant.ofEpochMilli(tx.getTime()).atZone(ZoneId.systemDefault())
.toLocalDate()
.with(ADJUSTERS.get(DAY))
));

List<XYChart.Data<Number, Number>> updatedBurntBsqDaily =
burntBsqByDay
.keySet()
.stream()
.map(date ->
{
.map(date -> {
ZonedDateTime zonedDateTime = date.atStartOfDay(ZoneId.systemDefault());
return new XYChart.Data<Number, Number>(
zonedDateTime.toInstant().getEpochSecond(),
Expand All @@ -550,18 +541,16 @@ private void updateBSQBurntMonthly(List<Tx> sortedBurntTxs) {
sortedBurntTxs
.stream()
.collect(Collectors.groupingBy(
tx ->
new Date(tx.getTime())
.toLocalDate()
.with(ADJUSTERS.get(MONTH))
tx -> Instant.ofEpochMilli(tx.getTime()).atZone(ZoneId.systemDefault())
.toLocalDate()
.with(ADJUSTERS.get(MONTH))
));

List<XYChart.Data<Number, Number>> updatedBurntBsqMonthly =
burntBsqByMonth
.keySet()
.stream()
.map(date ->
{
.map(date -> {
ZonedDateTime zonedDateTime = date.atStartOfDay(ZoneId.systemDefault());
return new XYChart.Data<Number, Number>(
zonedDateTime.toInstant().getEpochSecond(),
Expand Down Expand Up @@ -603,7 +592,7 @@ private void updateBSQBurntDailyMA(List<XYChart.Data<Number, Number>> updatedBur
maPeriod);

BiFunction<Number, Double, XYChart.Data<Number, Number>> xyToXyData =
XYChart.Data::new;
XYChart.Data<Number, Number>::new;

List<XYChart.Data<Number, Number>> burntBsqMA =
zip(burntBsqXValues, burntBsqMAYValues, xyToXyData)
Expand All @@ -614,15 +603,19 @@ private void updateBSQBurntDailyMA(List<XYChart.Data<Number, Number>> updatedBur
}

private void updateBSQIssuedMonthly() {
Function<Integer, LocalDate> blockTimeFn = memoize(height ->
Instant.ofEpochMilli(daoFacade.getBlockTime(height)).atZone(ZoneId.systemDefault())
.toLocalDate()
.with(ADJUSTERS.get(MONTH)));

Stream<Issuance> bsqByCompensation = daoStateService.getIssuanceSet(IssuanceType.COMPENSATION).stream()
.sorted(Comparator.comparing(Issuance::getChainHeight));

Stream<Issuance> bsqByReimbursement = daoStateService.getIssuanceSet(IssuanceType.REIMBURSEMENT).stream()
.sorted(Comparator.comparing(Issuance::getChainHeight));

Map<LocalDate, List<Issuance>> bsqAddedByVote = Stream.concat(bsqByCompensation, bsqByReimbursement)
.collect(Collectors.groupingBy(item -> new Date(daoFacade.getBlockTime(item.getChainHeight())).toLocalDate()
.with(ADJUSTERS.get(MONTH))));
.collect(Collectors.groupingBy(blockTimeFn.compose(Issuance::getChainHeight)));

List<XYChart.Data<Number, Number>> updatedAddedBSQ = bsqAddedByVote.keySet().stream()
.map(date -> {
Expand Down Expand Up @@ -686,7 +679,7 @@ private void triggerZoomToInliers() {

// When Guava version is bumped to at least 21.0,
// can be replaced with com.google.common.collect.Streams.zip
public static <L, R, T> Stream<T> zip(
private static <L, R, T> Stream<T> zip(
Stream<L> leftStream,
Stream<R> rightStream,
BiFunction<L, R, T> combiner
Expand All @@ -712,4 +705,9 @@ public boolean tryAdvance(Consumer<? super T> action) {
};
return StreamSupport.stream(spliterator, false);
}

private static <T, R> Function<T, R> memoize(Function<T, R> fn) {
Map<T, R> map = new ConcurrentHashMap<>();
return x -> map.computeIfAbsent(x, fn);
}
}