Commit graph

17730 commits

Author SHA1 Message Date
Steven Barclay
6e330e4a14
Speed up SortedList creation in TradesChartsView.fillList
Reduce a hotspot sorting the trade statistics table, triggered by the
'sortedList.bind(comparatorProperty)' call upon completion of the
'fillList' future. Profiling shows that repeated invocation of the cell
value factory over the entries of the sorted column is a bottleneck, so
speed this up by caching the returned cell value (given by calling
'new ReadOnlyObjectWrapper<>(listItem)') as an instance field of
TradeStatistics3ListItem.

As a further significant optimisation, stream the trade statistics in
reverse chronological order, when collecting into a list wrapped by
SortedList, as this matches the default display order, reducing the
number of comparisons done by SortedList's internal mergesort to O(n).
2023-05-10 19:41:24 +01:00
Steven Barclay
a489697a54
Speed up candle data creation in getUpdateChartResult
Optimise (further) the ChartCalculations methods 'getItemsPerInterval' &
'getCandleData' by replacing HashSets in the former with sorted sets,
which avoids relatively expensive calls to 'TradeStatistics3.hashCode'
and needless subsequent re-sorting by date in 'getCandleData'. (Forming
the trade statistics into an ImmutableSortedSet, OTOH, is cheap since
they are already encountered in chronological order.)

Further optimise the latter by using a primitive array sort of the trade
prices to calculate their median, instead of needlessly boxing them and
using 'Collections.sort'.
2023-05-10 19:41:23 +01:00
Steven Barclay
0f52b65daa
Further speedups to getUsdAveragePriceMapsPerTickUnit
Avoid calculating average prices for ticks that won't ever be part of a
visible chart candle, as only the last 90 ticks can fit on the chart. To
this end, stream the trade statistics in reverse chronological order
(which requires passing them as a NavigableSet), so that once more than
MAX_TICKS ticks have been encountered for a given tick unit, the
relevant map (and all lower granularity maps) can stop being filled up.

Also add a 'PriceAccumulator' static class to save time and memory when
filling up the intermediate maps, by avoiding the addition of each trade
statistics object to (multiple) temporary lists prior to average price
calculation.
2023-05-10 19:41:23 +01:00
Steven Barclay
372f92d7aa
Add cache to speed up ChartCalculations.roundToTick
Now that the trade statistics are encountered in chronological order,
speed up 'roundToTick(LocalDateTime, TickUnit)' by caching the last
calculated LocalDateTime -> Date mapping from the tick start (with one
cache entry per tick unit), as multiple successive trades will tend to
have the same tick start.

This avoids a relatively expensive '.atZone(..).toInstant()' call, which
was slowing down 'ChartCalculations.getUsdAveragePriceMapsPerTickUnit',
as it uses 'roundToTick' in a tight loop (#trades * #tick-units calls).

Also unqualify 'TradesChartsViewModel.TickUnit' references for brevity.
2023-05-10 19:41:22 +01:00
Steven Barclay
914d75682c
Cache enum.values() in ChartCalculations & TradeStatistics3
Cache enum arrays 'TickUnit.values()' & 'PaymentMethodWrapper.values()'
as the JVM makes defensive copies of them every time they are returned,
and they are both being used in tight loops. In particular, profiling
suggests this will make 'TradeStatistics3.isValid' about twice as fast.
2023-05-10 19:41:22 +01:00
Steven Barclay
835593f2c9
Fix broken test in TradesChartsViewModelTest that passed accidentally
The test was erroneously passing a candle tick start time (as a long) to
'ChartCalculations.getCandleData', which expects a tick index from 0 to
MAX_TICKS + 1 (91) inclusive. Since this is out of range, the method
skipped an 'itemsPerInterval' map lookup which would have thrown an NPE
prior to the last commit. Fix the test by making 'itemsPerInterval'
nonempty and passing 0 as the tick index. Also check the now correctly
populated 'date' field in the returned candle data.

Additionally, tidy up the class a little and avoid an unnecessary temp
directory creation.
2023-05-10 19:41:22 +01:00
Steven Barclay
47776b3836
Speed up ChartCalculations.getItemsPerInterval & return as List
Avoid scanning all the ticks backwards from 90 to 1 repeatedly, to find
the one with the correct date interval for each item in the
'tradeStatisticsByCurrency' list. Instead, for each item, remember the
last found tick index and move forwards if necessary, then scan
backwards from that point to find the correct tick. As the trade
statistics are now in chronological order, this is much faster (though
it will still work correctly regardless of the order of the list items).

Also, hold 'itemsPerInterval' as a 'List<Pair<..>>' instead of a
'Map<Long, Pair<..>>', since the keys are just tick indices from 0 to 91
inclusive, so it is cleaner and more efficient to use an array than a
hash table.
2023-05-10 19:41:21 +01:00
Steven Barclay
5846095b6b
Minor cleanup of ChartCalculations & TradesChartsView
1) Change statement lambdas to expression lambdas;
2) Replace 'Map.putIfAbsent' then 'Map.get' with 'Map.computeIfAbsent';
3) Add missing @VisibleForTesting annotation or make private.
2023-05-10 19:41:21 +01:00
Steven Barclay
0ba2e491ca
Fix quadratic time bug in AveragePriceUtil.getUSDAverage
Now that the trade statistics are retrieved as a sorted set, it can be
assumed that the USD & BSQ trade lists passed to 'getUSDAverage' are
already sorted. Use this to avoid repeatedly scanning the USD trade list
for the first trade dated after each given BSQ trade, by moving two
cursors in a single pass across the respective lists simultaneously.
2023-05-10 19:41:20 +01:00
Steven Barclay
b417e36a28
Make TradeStatistics3 comparable & hold in a TreeSet
Make TradeStatistics3 implement the previously added ComparableExt
interface and make TradeStatisticsManager hold them as a TreeSet instead
of a HashSet, to support fast retrieval of statistics in any given date
range. (Even though red-black trees are generally slower than hash
tables, this should not matter here since the set is only being iterated
over and infrequently appended, and does not benefit from O(1) lookups/
additions/removals.)

Add a 'TradeStatisticsManager.getNavigableTradeStatisticsSet' accessor,
which returns the backing TreeSet of the current ObservableSet field, so
that callers can access its NavigableSet interface where needed (as
there is no ObservableSortedSet or similar in JavaFX). Use this to
optimise 'AveragePriceUtil.getAveragePriceTuple',
'DisputeAgentSelection.getLeastUsedDisputeAgent' and
'MutableOfferDataModel.getSuggestedSecurityDeposit', to obtain a narrow
date range of trade statistics without streaming over the entire set.

Additionally optimise & simplify the price collation in
'TradeStatisticsManager.onAllServicesInitialised', by exploiting the
fact that the statistics are now sorted in order of date (which is the
presently defined natural order).
2023-05-10 19:41:20 +01:00
Steven Barclay
1f8538f6c1
Add utilities for SortedSet ranging with mapped keys & predicates
Provide a 'RangeUtils' class for computing subsets of a navigable set
with natural element order, with each bound defined by a mathematical
filter (that is, a predicate specifying whether an element is 'big' -
true, or 'small' - false), instead of a specific element. This allows
the subset of all elements which map into a given range to be computed,
provided the mapping function is (strictly or non-strictly) increasing.
Provide a fluent interface for this in RangeUtils (with unit tests).

To support this, provide a Comparable sub-interface, 'ComparableExt', of
elements which may be compared with marks/delimiters instead of just
elements of the same type, to work round the limitation that sorted (&
navigable) Sets/Maps in Java do not support general binary searching
with a filter (predicate) on the keys instead of just a specific key.

This will make it possible to efficiently take subsets of objects within
a given date range, say, without having to scan the entire set, provided
it is sorted (w.r.t. a suitable natural order).
2023-05-10 19:41:19 +01:00
Steven Barclay
e231c64cc2
Use primitive arrays & streams to optimise InlierUtil
Use a DoubleStream when streaming over 'List<Double>' method arguments
in InlierUtil, as well as a primitive array sort in 'InlierUtil.trim'
(followed by taking a sublist view), instead of calling 'Stream.sorted'.

To this end, use Guava 'Doubles.asList' to pass lists of Doubles to/from
the InlierUtil methods without incurring any boxing or unboxing costs,
since their spliterators can be simply downcast to Spliterator.OfDouble
(opportunistically), instead of needing to use 'mapToDouble' to unbox.

This was a minor hotspot when called from AveragePriceUtil (used by the
burning man and BSQ dashboard views).
2023-05-10 19:41:19 +01:00
Steven Barclay
069b20ae5f
Use correct bounds in AveragePriceUtil.removeOutliers
Use nonstrict bounds when filtering outliers from the provided trade
statistics list, since otherwise it will always remove the outermost two
inliers from the list. This is because the dependent call to
'InlierUtil.findInlierRange' returns the min & max inlier values.
2023-05-10 19:41:19 +01:00
Steven Barclay
277b170e3c
Further speedups of TradeStatistics3.isValid
Use a Map to speed up 'PaymentMethod.getPaymentMethod', called from
'isValid', instead of scanning the payment method list every invocation.
Make the list immutable to ensure the map never goes stale, which is OK
since no code modified it outside PaymentMethod's static initialisation.

Also speed up the global accessor 'TradeLimits.getMaxTradeLimit', by
caching the DAO param value in a volatile field, cleared upon each new
block arrival.

Furthermore, speed up 'TradeLimits.getFirstMonthRiskBasedTradeLimit' by
simplifying the rounding logic to avoid a pass through the (rather slow)
BigDecimal type.
2023-05-10 19:41:18 +01:00
Steven Barclay
4bc1d299e5
Avoid exception to speed up TradeStatistics3.isValid
Short circuit the exception control flow used in the method
'TradeStatistics3.getPaymentMethodId', which occurs whenever the payment
method code is stored directly in the 'paymentMethod' field instead of
first being converted into a numeric string. This occurs if the method
is unrecognised as it is not in listed into 'PaymentMethodWrapper' enum.

This fixes an unnecessary slowdown of 'TradeStatistics3.isValid', which
calls the above, when scanning the list of BSQ trade statistics in
AveragePriceUtil and elsewhere, due to the fact that the 'BSQ_SWAP'
payment method has been missed out of the above enum.

Also add a (presently disabled) unit test to prevent any future payment
methods from being missed out of the enum. (Should fix the missing BSQ
swaps issue in a separate PR to make sure that the seed nodes recognise
the new payment method code before anyone else.)
2023-05-10 19:40:19 +01:00
Alva Swanson
787da04539
Fix broken ProtectedStorageEntryTest
Relates to #6619
2023-05-10 18:00:01 +10:00
Alva Swanson
5f655f6d48
Fix broken P2PDataStoragePersistableNetworkPayloadTest
Relates to #6619
2023-05-10 17:48:21 +10:00
HenrikJannsen
60fad3ab6c
Fix incorrect filtering of offers with shared maker fee
Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
2023-05-10 11:42:00 +07:00
Alva Swanson
734650d43e
core: Fix broken PriceTest.testParse test
Relates to #6619
2023-05-09 21:23:18 +10:00
Alva Swanson
b5402d840b
Add bisq2 Gradle Tor Plugin 2023-05-09 18:09:35 +10:00
Alva Swanson
4bd8d421be
Add bisq2 gradle-tasks module 2023-05-09 17:58:17 +10:00
Alejandro García
2e892bf90a
Merge pull request #6688 from alvasw/move_mockito_definition_to_bisq_java_conventions
Move mockito dependency definition to bisq.java-conventions
2023-05-08 18:19:19 +00:00
Alejandro García
cc9a49ef2b
Merge pull request #6687 from alvasw/move_hamcrest_definition_to_bisq_java_conventions
Move hamcrest dependency definition to bisq.java-conventions
2023-05-08 18:18:33 +00:00
Alejandro García
6f851b944c
Merge pull request #6686 from alvasw/move_junit_definition_to_bisq_java_conventions
Move JUnit dependency definition to bisq.java-conventions
2023-05-08 18:17:49 +00:00
Alejandro García
fcec096ba5
Merge pull request #6685 from alvasw/run_ci_on_all_branches
GitHub Actions: Run on all branches
2023-05-08 18:17:00 +00:00
Alejandro García
ce4c1190b7
Merge pull request #6684 from alvasw/ci_enable_build_scans
CI: Enable build scans
2023-05-08 18:16:16 +00:00
Alejandro García
e7a29b1a20
Merge pull request #6683 from alvasw/common_reformat_math_utils_test
Common: Reformat MathUtilsTest
2023-05-08 18:15:47 +00:00
Alejandro García
642f7a60cb
Merge pull request #6682 from alvasw/remove_empty_verify_task_test_class
Remove empty VerifyTaskTest class
2023-05-08 18:15:10 +00:00
Alva Swanson
28a4787853
Move mockito dependency definition to bisq.java-conventions 2023-05-08 17:51:05 +10:00
Alva Swanson
7c1eb65775
Move hamcrest dependency definition to bisq.java-conventions 2023-05-08 17:51:05 +10:00
Alva Swanson
6e0e5028a3
Move JUnit dependency definition to bisq.java-conventions 2023-05-08 17:51:05 +10:00
Alva Swanson
e5e09db3f1
GitHub Actions: Publish Gradle build scan 2023-05-08 17:49:41 +10:00
Alva Swanson
8bbd941b82
GitHub Actions: Run on all branches 2023-05-08 17:40:35 +10:00
Alva Swanson
59521731c9
Accept Gradle terms if buildScan property set by developer 2023-05-08 17:37:36 +10:00
Alva Swanson
02107ad9f0
Common: Reformat MathUtilsTest 2023-05-08 17:19:35 +10:00
Alva Swanson
2e63d2f0ca
Remove empty VerifyTaskTest class 2023-05-08 16:35:36 +10:00
Alejandro García
b90776989b
Merge pull request #6619 from napoly/upgrade_junit4_to_junit5_jupiter
Replacing JUnit4 with JUnit5 Jupiter
2023-05-07 16:57:57 +00:00
napoly
fc42044949
Remove edit button for BSQ offers 2023-05-06 20:06:58 +02:00
HenrikJannsen
2651a88d5e
Do not reset addressEntries if its from cloned offers at cleanUpAddressEntries
Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
2023-05-05 19:42:08 +07:00
HenrikJannsen
13bcfb3121
Use new offerId and fresh data at clone offer
Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
2023-05-05 19:41:24 +07:00
HenrikJannsen
d42895637f
Publish cloned offer if activated
Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
2023-05-05 14:19:31 +07:00
HenrikJannsen
21672a1bd0
Add clone offer tab
Change flow of cloning an offer:
We open the clone offer tab similar like the duplicate/edit offer tab. When clicking the clone button we create and publish the cloned offer. if the clone would not have changed the payment method/currency we show a popup and deactivate the offer.
At editOffer we check if the offer is using a shared maker fee and if so we check if the edit triggered same payment method/currency. If so we show a popup and deactivate the offer.

Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
2023-05-05 13:34:03 +07:00
HenrikJannsen
4ae89e748c
Use link icon for cloned offers
Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
2023-05-05 11:11:58 +07:00
HenrikJannsen
384173c894
Rename translation string
Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
2023-05-05 10:01:57 +07:00
HenrikJannsen
a621973eed
Add translation string
Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
2023-05-05 09:41:05 +07:00
HenrikJannsen
8b91ed7a00
Only reset if there are no other shared maker fee offers
Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
2023-05-05 09:33:35 +07:00
napoly
e19ffe2308
Upgrade JUnit4 to JUnit5 Jupiter 2023-05-04 20:04:49 +02:00
HenrikJannsen
6036da352b
Add cloneItemColumn
Hide trigger price column if none is in list

Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
2023-05-04 20:25:11 +07:00
HenrikJannsen
3403b1662c
User maker fee as column name (instead of group)
Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
2023-05-04 20:10:38 +07:00
HenrikJannsen
992854c9b9
Various refactorings and changes
Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
2023-05-04 18:31:20 +07:00