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

gui: Optimize OverviewPage::updateTransactions() #1794

Merged
merged 3 commits into from
Jul 22, 2020
Merged
Show file tree
Hide file tree
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
49 changes: 41 additions & 8 deletions src/qt/overviewpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,16 +161,46 @@ void OverviewPage::showEvent(QShowEvent *event)
updateTransactions();
}

int OverviewPage::getNumTransactionsForView()
{
// Compute the maximum number of transactions the transaction list widget
// can hold without overflowing.
const size_t itemHeight = DECORATION_SIZE + ui->listTransactions->spacing();
const size_t contentsHeight = ui->listTransactions->height();
const int numItems = contentsHeight / itemHeight;

return numItems;
}


void OverviewPage::updateTransactions()
{
if(filter)
if (filter)
{
// Show the maximum number of transactions the transaction list widget
// can hold without overflowing.
const size_t itemHeight = DECORATION_SIZE + ui->listTransactions->spacing();
const size_t contentsHeight = ui->listTransactions->height();
const size_t numItems = contentsHeight / itemHeight;
filter->setLimit(numItems);
int numItems = getNumTransactionsForView();

// This is a "stairstep" approach, using x3 to x6 factors to size the setLimit.
// Based on testing with a wallet with a large number of transactions (40k+)
// Using a factor of three is a good balance between the setRowHidden loop
// and the very high expense of the getLimit call, which invalidates the filter
jamescowens marked this conversation as resolved.
Show resolved Hide resolved
// and sort, and implicitly redoes the sort, which can take seconds for a large
// wallet.

// Most main window resizes will be done without an actual call to setLimit.
if (filter->getLimit() < numItems)
{
filter->setLimit(numItems * 3);
}
else if (filter->getLimit() > numItems * 6)
{
filter->setLimit(numItems * 3);
}

for (int i = 0; i <= filter->getLimit(); ++i)
{
ui->listTransactions->setRowHidden(i, i >= numItems);
}

ui->listTransactions->update();
}
}
Expand Down Expand Up @@ -240,8 +270,8 @@ void OverviewPage::setWalletModel(WalletModel *model)
filter->setDynamicSortFilter(true);
filter->setSortRole(Qt::EditRole);
filter->setShowInactive(false);
filter->setLimit(getNumTransactionsForView());
filter->sort(TransactionTableModel::Status, Qt::DescendingOrder);

ui->listTransactions->setModel(filter.get());
ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);

Expand All @@ -250,6 +280,9 @@ void OverviewPage::setWalletModel(WalletModel *model)
connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64)));

connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));

connect(model, SIGNAL(transactionUpdated()), this, SLOT(updateTransactions()));

UpdateBoincUtilization();
}

Expand Down
3 changes: 2 additions & 1 deletion src/qt/overviewpage.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public slots:
void showEvent(QShowEvent *event);

private:
void updateTransactions();
int getNumTransactionsForView();

Ui::OverviewPage *ui;
ResearcherModel *researcherModel;
Expand All @@ -62,6 +62,7 @@ public slots:

private slots:
void updateDisplayUnit();
void updateTransactions();
void updateResearcherStatus();
void updateMagnitude();
void updatePendingAccrual();
Expand Down
5 changes: 5 additions & 0 deletions src/qt/transactionfilterproxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ void TransactionFilterProxy::setLimit(int limit)
invalidate();
}

int TransactionFilterProxy::getLimit()
{
return this->limitRows;
}

void TransactionFilterProxy::setShowInactive(bool showInactive)
{
this->showInactive = showInactive;
Expand Down
3 changes: 3 additions & 0 deletions src/qt/transactionfilterproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class TransactionFilterProxy : public QSortFilterProxyModel
/** Set maximum number of rows returned, -1 if unlimited. */
void setLimit(int limit);

/** Get maximum number of rows returned, -1 if unlimited. */
int getLimit();

/** Set whether to show conflicted transactions. */
void setShowInactive(bool showInactive);

Expand Down
3 changes: 2 additions & 1 deletion src/qt/transactiontablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ class TransactionTablePriv
status = CT_DELETED; /* In model, but want to hide, treat as deleted */
}

LogPrint(BCLog::LogFlags::VERBOSE, " inWallet=%i inModel=%i Index=%i-%i showTransaction=%i derivedStatus=%i", inWallet, inModel, lowerIndex, upperIndex, showTransaction, status);
LogPrint(BCLog::LogFlags::VERBOSE, " inWallet=%i inModel=%i Index=%i-%i showTransaction=%i derivedStatus=%i",
inWallet, inModel, lowerIndex, upperIndex, showTransaction, status);


switch(status)
Expand Down
12 changes: 10 additions & 2 deletions src/qt/walletmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,24 @@ void WalletModel::checkBalanceChanged()

void WalletModel::updateTransaction(const QString &hash, int status)
{
if(transactionTableModel)
if (transactionTableModel)
{
transactionTableModel->updateTransaction(hash, status);

// Note this is subtly different than the below. If a resync is being done on a wallet
// that already has transactions, the numTransactionsChanged will not be emitted after the
// wallet is loaded because the size() does not change. See the comments in the header file.
emit transactionUpdated();
}

// Balance and number of transactions might have changed
checkBalanceChanged();

int newNumTransactions = getNumTransactions();
if(cachedNumTransactions != newNumTransactions)
if (cachedNumTransactions != newNumTransactions)
{
cachedNumTransactions = newNumTransactions;

emit numTransactionsChanged(newNumTransactions);
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/qt/walletmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ public slots:
void pollBalanceChanged();

signals:
// Transaction updated. This is necessary because on a resync from zero with an existing wallet.
// the numTransactionsChanged signal will not be emitted, and therefore the overpage transaction list
// needs this signal instead.
void transactionUpdated();

// Signal that balance in wallet changed
void balanceChanged(qint64 balance, qint64 stake, qint64 unconfirmedBalance, qint64 immatureBalance);

Expand Down