Make 'FormattingUtils.formatDateTime(Date, boolean)' two or three times
faster by caching the 'java.text.DateFormat' objects used to format the
given date & time in either the local or UTC time zone. Since these
formatters are not thread safe (though they may be reused), use a
ThreadLocal to store them (as a tuple, along with the current locale to
make sure it hasn't changed since the last invocation).
This is a minor hotspot for the Transactions view load, since the date
strings in TransactionsListItem are formatted eagerly (via DisplayUtils)
for the purpose of filtering the items by substring match. (Other list
views seem to format dates lazily, though it's possible that there will
be speedups elsewhere in the UI.)
Multiple threads read and write to the accounting blocks list causing
data races. Luckily, the LinkedList threw a ConcurrentModificationException
to limit damage. Now, a ReadWriteLock protects the LinkedList against
data races. Multiple threads can read the list at the same time but only
one thread can write to it. Other writing threads wait until it's their
turn.
Fixes#6545
Add a third cache to WalletService, cleared upon wallet change events,
which maps txIds to txs. This allows the speedup of repeated calls to
'WalletService.getConfidenceForTxId', by avoiding the need to copy and
scan the entire set of wallet txs to find the one with matching id,
for each method invocation.
This is mainly to provide a further speedup to the closed-trades-view
load, by making it much faster to filter the list of BSQ swap trades by
tx confirmation status in 'ClosedTradesDataModel.applyList' and
'ClosedTradesManager.getNumPastTrades'.
Reduce a bottleneck in the closed-trades-view load & table scrolling,
caused by a call to 'ClosedTradesManager.getNumPastTrades' for each
list item displayed. This repeatedly scans the entire collection of
closed trades and BSQ swap trades, in order to count all those which
share a given peer node address. (Scanning the BSQ swap trades is
particularly slow due to their filtering by tx confirmation status.)
To this end, cache the counts of trades by peer node address with a
nullable Multiset field in ClosedTradesManager & BsqSwapTradeManager,
so that the trades are scanned at most once when the view loads. Add
listeners to clear the respective cache when the trade list changes or
the BSQ wallet txs change.
The DaoStateStorageService submits tasks to a daemon thread executor
service. The JVM continues to execute threads until all non-daemon
threads have terminated. So the JVM will kill the DaoStateStorageService
during write requests leading to data corruption.
This change uses a non-daemon thread executor service at waits during
shutdown until all data is written to disk.