tqt history: speed up ensure_fields_available (faster startup) - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit cc0db418797b469abe684beb1a8208c51c3e5e25 DIR parent e35f2c5beded584fa2845af9f3a6f18211a75a23 HTML Author: SomberNight <somber.night@protonmail.com> Date: Tue, 4 Dec 2018 22:24:32 +0100 qt history: speed up ensure_fields_available (faster startup) Diffstat: M electrum/gui/qt/history_list.py | 8 +++----- M electrum/util.py | 54 ++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 6 deletions(-) --- DIR diff --git a/electrum/gui/qt/history_list.py b/electrum/gui/qt/history_list.py t@@ -31,7 +31,7 @@ from collections import OrderedDict from electrum.address_synchronizer import TX_HEIGHT_LOCAL from electrum.i18n import _ -from electrum.util import block_explorer_URL, profiler, print_error, TxMinedStatus, Fiat +from electrum.util import block_explorer_URL, profiler, print_error, TxMinedStatus, OrderedDictWithIndex from .util import * t@@ -92,7 +92,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop): self.setModel(self.proxy) self.txid_to_items = {} - self.transactions = OrderedDict() + self.transactions = OrderedDictWithIndex() self.summary = {} self.blue_brush = QBrush(QColor("#1E1EFF")) self.red_brush = QBrush(QColor("#BC1E1E")) t@@ -311,7 +311,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop): def ensure_fields_available(self, items, idx, txid): while len(items) < idx + 1: - row = list(self.transactions.keys()).index(txid) + row = self.transactions.get_pos_of_key(txid) qidx = self.std_model.index(row, len(items)) assert qidx.isValid(), (self.std_model.columnCount(), idx) item = self.std_model.itemFromIndex(qidx) t@@ -334,7 +334,6 @@ class HistoryList(MyTreeView, AcceptFileDragDrop): txid = row['txid'] if txid not in self.transactions: self.transactions[txid] = row - self.transactions.move_to_end(txid, last=True) self.insert_tx(row) return else: t@@ -344,7 +343,6 @@ class HistoryList(MyTreeView, AcceptFileDragDrop): seen.add(txid) if txid not in self.transactions: self.transactions[txid] = row - self.transactions.move_to_end(txid, last=True) self.insert_tx(row) continue old = self.transactions[txid] DIR diff --git a/electrum/util.py b/electrum/util.py t@@ -22,7 +22,7 @@ # SOFTWARE. import binascii import os, sys, re, json -from collections import defaultdict +from collections import defaultdict, OrderedDict from typing import NamedTuple, Union, TYPE_CHECKING, Tuple, Optional, Callable from datetime import datetime import decimal t@@ -993,3 +993,55 @@ def create_and_start_event_loop() -> Tuple[asyncio.AbstractEventLoop, name='EventLoop') loop_thread.start() return loop, stopping_fut, loop_thread + + +class OrderedDictWithIndex(OrderedDict): + """An OrderedDict that keeps track of the positions of keys. + + Note: very inefficient to modify contents, except to add new items. + """ + + _key_to_pos = {} + + def _recalc_key_to_pos(self): + self._key_to_pos = {key: pos for (pos, key) in enumerate(self.keys())} + + def get_pos_of_key(self, key): + return self._key_to_pos[key] + + def popitem(self, *args, **kwargs): + ret = super().popitem(*args, **kwargs) + self._recalc_key_to_pos() + return ret + + def move_to_end(self, *args, **kwargs): + ret = super().move_to_end(*args, **kwargs) + self._recalc_key_to_pos() + return ret + + def clear(self): + ret = super().clear() + self._recalc_key_to_pos() + return ret + + def pop(self, *args, **kwargs): + ret = super().pop(*args, **kwargs) + self._recalc_key_to_pos() + return ret + + def update(self, *args, **kwargs): + ret = super().update(*args, **kwargs) + self._recalc_key_to_pos() + return ret + + def __delitem__(self, *args, **kwargs): + ret = super().__delitem__(*args, **kwargs) + self._recalc_key_to_pos() + return ret + + def __setitem__(self, key, *args, **kwargs): + is_new_key = key not in self + ret = super().__setitem__(key, *args, **kwargs) + if is_new_key: + self._key_to_pos[key] = len(self) - 1 + return ret