[meld] Avoid some repetitive prev/next diff calculations (closes bgo#669867)



commit 9fb9c111971cf97501e3b3f2a7f7f606935505f2
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Thu Feb 23 05:17:31 2012 +1000

    Avoid some repetitive prev/next diff calculations (closes bgo#669867)
    
    When correct prev/next diff sensitivity setting was added to directory
    and VC views in 1.5.2, the code just recalculated on every cursor
    movement, leading to some slowness in large treeviews. This commit
    adds some invalidation checks which should significantly improve
    performance in common situations.

 meld/dirdiff.py |   25 +++++++++++++++++--------
 meld/vcview.py  |   23 +++++++++++++++++------
 2 files changed, 34 insertions(+), 14 deletions(-)
---
diff --git a/meld/dirdiff.py b/meld/dirdiff.py
index 3ea9cbd..a650933 100644
--- a/meld/dirdiff.py
+++ b/meld/dirdiff.py
@@ -270,7 +270,7 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
             self.focus_in_events.append(handler_id)
             handler_id = treeview.connect("focus-out-event", self.on_treeview_focus_out_event)
             self.focus_out_events.append(handler_id)
-        self.prev_path, self.next_path = None, None
+        self.current_path, self.prev_path, self.next_path = None, None, None
         self.on_treeview_focus_out_event(None, None)
         self.treeview_focussed = None
 
@@ -714,13 +714,22 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
         if not cursor_path:
             self.emit("next-diff-changed", False, False)
         else:
-            # TODO: Only recalculate when needed;
-            # not self.prev_path < cursor_path < self.next_path is a start,
-            # but fails when we move off a changed row.
-            prev_path, next_path = self.model._find_next_prev_diff(cursor_path)
-            self.prev_path, self.next_path = prev_path, next_path
-            have_next_diffs = (prev_path is not None, next_path is not None)
-            self.emit("next-diff-changed", *have_next_diffs)
+            if self.current_path:
+                old_cursor = self.model.get_iter(self.current_path)
+                state = self.model.get_state(old_cursor, 0)
+                # We can skip recalculation if the new cursor is between the
+                # previous/next bounds, and we weren't on a changed row
+                skip = state in (tree.STATE_NORMAL, tree.STATE_EMPTY) and \
+                       self.prev_path < cursor_path < self.next_path
+            else:
+                skip = False
+
+            if not skip:
+                prev, next = self.model._find_next_prev_diff(cursor_path)
+                self.prev_path, self.next_path = prev, next
+                have_next_diffs = (prev is not None, next is not None)
+                self.emit("next-diff-changed", *have_next_diffs)
+        self.current_path = cursor_path
 
         paths = self._get_selected_paths(pane)
         if len(paths) > 0:
diff --git a/meld/vcview.py b/meld/vcview.py
index 8620640..e6b5242 100644
--- a/meld/vcview.py
+++ b/meld/vcview.py
@@ -162,7 +162,7 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
         self.treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
         self.treeview.set_headers_visible(1)
         self.treeview.set_search_equal_func(self.treeview_search_cb)
-        self.prev_path, self.next_path = None, None
+        self.current_path, self.prev_path, self.next_path = None, None, None
         column = gtk.TreeViewColumn( _("Name") )
         renicon = ui.emblemcellrenderer.EmblemCellRenderer()
         rentext = gtk.CellRendererText()
@@ -696,11 +696,22 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
         if not cursor_path:
             self.emit("next-diff-changed", False, False)
         else:
-            # TODO: Only recalculate when needed; see DirDiff
-            prev_path, next_path = self.model._find_next_prev_diff(cursor_path)
-            self.prev_path, self.next_path = prev_path, next_path
-            have_next_diffs = (prev_path is not None, next_path is not None)
-            self.emit("next-diff-changed", *have_next_diffs)
+            if self.current_path:
+                old_cursor = self.model.get_iter(self.current_path)
+                state = self.model.get_state(old_cursor, 0)
+                # We can skip recalculation if the new cursor is between the
+                # previous/next bounds, and we weren't on a changed row
+                skip = state in (tree.STATE_NORMAL, tree.STATE_EMPTY) and \
+                       self.prev_path < cursor_path < self.next_path
+            else:
+                skip = False
+
+            if not skip:
+                prev, next = self.model._find_next_prev_diff(cursor_path)
+                self.prev_path, self.next_path = prev, next
+                have_next_diffs = (prev is not None, next is not None)
+                self.emit("next-diff-changed", *have_next_diffs)
+        self.current_path = cursor_path
 
     def next_diff(self, direction):
         if direction == gtk.gdk.SCROLL_UP:



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]