URI: 
       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