From dc960b0cda2c0e611c2147015fb8a09885f031db Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Sat, 19 Dec 2015 13:34:35 -0800 Subject: [PATCH] Cache counts of project changes So that the project list page is more responsive, cache counts of open and unreviewed changes for projects. Change-Id: I270f4009d6c7cca9d9868a181db94f779662b643 --- gertty/app.py | 18 ++++++++++++++++++ gertty/sync.py | 2 ++ gertty/view/change.py | 2 ++ gertty/view/change_list.py | 1 + gertty/view/project_list.py | 19 +++++++++++-------- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/gertty/app.py b/gertty/app.py index d40abc3..0ce0367 100644 --- a/gertty/app.py +++ b/gertty/app.py @@ -185,6 +185,22 @@ class BackgroundBrowser(webbrowser.GenericBrowser): except OSError: return False +class ProjectCache(object): + def __init__(self): + self.projects = {} + + def get(self, project): + if project.key not in self.projects: + self.projects[project.key] = dict( + unreviewed_changes = len(project.unreviewed_changes), + open_changes = len(project.open_changes), + ) + return self.projects[project.key] + + def clear(self, project): + if project.key in self.projects: + del self.projects[project.key] + class App(object): simple_change_search = re.compile('^(\d+|I[a-fA-F0-9]{40})$') @@ -216,6 +232,7 @@ class App(object): self.log = logging.getLogger('gertty.App') self.log.debug("Starting") + self.project_cache = ProjectCache() self.ring = mywid.KillRing() self.input_buffer = [] webbrowser.register('xdg-open', None, BackgroundBrowser("xdg-open")) @@ -668,6 +685,7 @@ class App(object): message_key = draft_message.key if upload: change.reviewed = True + self.project_cache.clear(change.project) if submit: change.status = 'SUBMITTED' change.pending_status = True diff --git a/gertty/sync.py b/gertty/sync.py index caf1b7e..78075ab 100644 --- a/gertty/sync.py +++ b/gertty/sync.py @@ -571,6 +571,7 @@ class SyncChangeTask(Task): result = ChangeAddedEvent(change) else: result = ChangeUpdatedEvent(change) + app.project_cache.clear(change.project) self.results.append(result) change.owner = account if change.status != remote_change['status']: @@ -829,6 +830,7 @@ class SyncChangeTask(Task): if change.reviewed: change.reviewed = False result.review_flag_changed = True + app.project_cache.clear(change.project) for url, refs in fetches.items(): self.log.debug("Fetching from %s with refs %s", url, refs) try: diff --git a/gertty/view/change.py b/gertty/view/change.py index c39e1af..a95284b 100644 --- a/gertty/view/change.py +++ b/gertty/view/change.py @@ -772,11 +772,13 @@ class ChangeView(urwid.WidgetWrap): with self.app.db.getSession() as session: change = session.getChange(self.change_key) change.reviewed = not change.reviewed + self.app.project_cache.clear(change.project) def toggleHidden(self): with self.app.db.getSession() as session: change = session.getChange(self.change_key) change.hidden = not change.hidden + self.app.project_cache.clear(change.project) def toggleStarred(self): with self.app.db.getSession() as session: diff --git a/gertty/view/change_list.py b/gertty/view/change_list.py index 3ba5865..55fc8f7 100644 --- a/gertty/view/change_list.py +++ b/gertty/view/change_list.py @@ -390,6 +390,7 @@ class ChangeListView(urwid.WidgetWrap): with self.app.db.getSession() as session: change = session.getChange(change_key) change.reviewed = not change.reviewed + self.app.project_cache.clear(change.project) ret = change.reviewed reviewed_str = 'reviewed' if change.reviewed else 'unreviewed' self.log.debug("Set change %s to %s", change_key, reviewed_str) diff --git a/gertty/view/project_list.py b/gertty/view/project_list.py index 6444fc2..e577b84 100644 --- a/gertty/view/project_list.py +++ b/gertty/view/project_list.py @@ -41,9 +41,10 @@ class ProjectRow(urwid.Button): name = ' '+name self.name.set_text(name) - def __init__(self, project, topic, callback=None): + def __init__(self, app, project, topic, callback=None): super(ProjectRow, self).__init__('', on_press=callback, user_data=(project.key, project.name)) + self.app = app self.mark = False self._style = None self.project_key = project.key @@ -67,8 +68,9 @@ class ProjectRow(urwid.Button): self.update(project) def update(self, project): + cache = self.app.project_cache.get(project) if project.subscribed: - if len(project.unreviewed_changes) > 0: + if cache['unreviewed_changes'] > 0: style = 'unreviewed-project' else: style = 'subscribed-project' @@ -78,8 +80,8 @@ class ProjectRow(urwid.Button): if self.mark: style = 'marked-project' self.row_style.set_attr_map({None: style}) - self.unreviewed_changes.set_text('%i ' % len(project.unreviewed_changes)) - self.open_changes.set_text('%i ' % len(project.open_changes)) + self.unreviewed_changes.set_text('%i ' % cache['unreviewed_changes']) + self.open_changes.set_text('%i ' % cache['open_changes']) def toggleMark(self): self.mark = not self.mark @@ -247,7 +249,7 @@ class ProjectListView(urwid.WidgetWrap): break self._deleteRow(current_row) if not row: - row = ProjectRow(project, topic, self.onSelect) + row = ProjectRow(self.app, project, topic, self.onSelect) self.listbox.body.insert(i, row) self.project_rows[key] = row else: @@ -293,12 +295,13 @@ class ProjectListView(urwid.WidgetWrap): topic_open = 0 for project in topic.projects: #self.log.debug(" project: %s" % project.name) - topic_unreviewed += len(project.unreviewed_changes) - topic_open += len(project.open_changes) + cache = self.app.project_cache.get(project) + topic_unreviewed += cache['unreviewed_changes'] + topic_open += cache['open_changes'] if self.subscribed: if not project.subscribed: continue - if self.unreviewed and not project.unreviewed_changes: + if self.unreviewed and not cache['unreviewed_changes']: continue if topic.key in self.open_topics: i = self._projectRow(i, project, topic)