fix row cache issues

I think this may have accidentally been changed in the refactoring.
If we discard self._rows, it will result in the entire table flashing
"..." until the new data is available. Instead, we leave the cached
rows alone, and just update the cutoff point, so we can serve stale
content (avoiding any visible redraw) until the new data is available.

I've updated search() to reset the rows there, so we free up memory
on a new search.
This commit is contained in:
Damien Elmes 2021-04-05 14:42:04 +10:00
parent a18bb2af12
commit 758550ea17

View File

@ -182,7 +182,7 @@ class Table:
def op_executed(self, changes: OpChanges, meta: OpMeta, focused: bool) -> None: def op_executed(self, changes: OpChanges, meta: OpMeta, focused: bool) -> None:
if changes.browser_table: if changes.browser_table:
self._model.empty_cache() self._model.mark_cache_stale()
if focused: if focused:
self.redraw_cells() self.redraw_cells()
@ -858,9 +858,9 @@ class DataModel(QAbstractTableModel):
self._state: ItemState = state self._state: ItemState = state
self._items: Sequence[ItemId] = [] self._items: Sequence[ItemId] = []
self._rows: Dict[int, CellRow] = {} self._rows: Dict[int, CellRow] = {}
self._last_refresh = 0.0
# serve stale content to avoid hitting the DB? # serve stale content to avoid hitting the DB?
self._block_updates = False self._block_updates = False
self._stale_cutoff = 0.0
# Row Object Interface # Row Object Interface
###################################################################### ######################################################################
@ -873,7 +873,7 @@ class DataModel(QAbstractTableModel):
def get_row(self, index: QModelIndex) -> CellRow: def get_row(self, index: QModelIndex) -> CellRow:
item = self.get_item(index) item = self.get_item(index)
if row := self._rows.get(item): if row := self._rows.get(item):
if not self._block_updates and row.is_stale(self._last_refresh): if not self._block_updates and row.is_stale(self._stale_cutoff):
# need to refresh # need to refresh
self._rows[item] = self._fetch_row_from_backend(item) self._rows[item] = self._fetch_row_from_backend(item)
return self._rows[item] return self._rows[item]
@ -901,8 +901,8 @@ class DataModel(QAbstractTableModel):
# Reset # Reset
def empty_cache(self) -> None: def mark_cache_stale(self) -> None:
self._rows = {} self._stale_cutoff = time.time()
def reset(self) -> None: def reset(self) -> None:
self.begin_reset() self.begin_reset()
@ -910,7 +910,7 @@ class DataModel(QAbstractTableModel):
def begin_reset(self) -> None: def begin_reset(self) -> None:
self.beginResetModel() self.beginResetModel()
self.empty_cache() self.mark_cache_stale()
def end_reset(self) -> None: def end_reset(self) -> None:
self.endResetModel() self.endResetModel()
@ -930,7 +930,6 @@ class DataModel(QAbstractTableModel):
return return
top_left = self.index(0, 0) top_left = self.index(0, 0)
bottom_right = self.index(self.len_rows() - 1, self.len_columns() - 1) bottom_right = self.index(self.len_rows() - 1, self.len_columns() - 1)
self._last_refresh = time.time()
self.dataChanged.emit(top_left, bottom_right) # type: ignore self.dataChanged.emit(top_left, bottom_right) # type: ignore
# Item Interface # Item Interface
@ -1014,6 +1013,7 @@ class DataModel(QAbstractTableModel):
context.ids = self._state.find_items(context.search, context.order) context.ids = self._state.find_items(context.search, context.order)
gui_hooks.browser_did_search(context) gui_hooks.browser_did_search(context)
self._items = context.ids self._items = context.ids
self._rows = {}
finally: finally:
self.end_reset() self.end_reset()