[meld] Cache merged diffs by disallowing arbitrary text sequences
- From: Kai Willadsen <kaiw src gnome org>
- To: svn-commits-list gnome org
- Subject: [meld] Cache merged diffs by disallowing arbitrary text sequences
- Date: Tue, 14 Jul 2009 07:22:54 +0000 (UTC)
commit f04a838c547c43b16e074c9c2f36736c6d14e1c2
Author: Kai Willadsen <kai willadsen gmail com>
Date: Sun Jun 7 16:16:55 2009 +1000
Cache merged diffs by disallowing arbitrary text sequences
In theory, the Differ interface allowed changes to be requested based on
arbitrary text sequences. However, in practice, Differ's change accessors
were only ever called using raw buffer text. Caching the merged diffs
allows us to do significantly less work.
diffutil.py | 25 +++++++++++++++----------
filediff.py | 18 +++++++++---------
2 files changed, 24 insertions(+), 19 deletions(-)
---
diff --git a/diffutil.py b/diffutil.py
index a941927..019b778 100644
--- a/diffutil.py
+++ b/diffutil.py
@@ -74,6 +74,10 @@ class Differ(object):
self.num_sequences = 0
self.seqlength = [0, 0, 0]
self.diffs = [[], []]
+ self._merge_cache = []
+
+ def _update_merge_cache(self, texts):
+ self._merge_cache = [c for c in self._merge_diffs(self.diffs[0], self.diffs[1], texts)]
def change_sequence(self, sequence, startidx, sizechange, texts):
assert sequence in (0, 1, 2)
@@ -82,6 +86,7 @@ class Differ(object):
if sequence == 2 or (sequence == 1 and self.num_sequences == 3):
self._change_sequence(1, sequence, startidx, sizechange, texts)
self.seqlength[sequence] += sizechange
+ self._update_merge_cache(texts)
def _locate_chunk(self, whichdiffs, sequence, line):
"""Find the index of the chunk which contains line."""
@@ -128,34 +133,33 @@ class Differ(object):
for c in self.diffs[which][hiidx:] ]
self.diffs[which][loidx:hiidx] = newdiffs
- def all_changes(self, texts):
- for c in self._merge_diffs(self.diffs[0], self.diffs[1], texts):
- yield c
+ def all_changes(self):
+ return iter(self._merge_cache)
- def pair_changes(self, fromindex, toindex, texts):
+ def pair_changes(self, fromindex, toindex):
"""Give all changes between file1 and either file0 or file2.
"""
if fromindex == 1:
seq = toindex/2
- for c in self.all_changes( texts ):
+ for c in self._merge_cache:
if c[seq]:
yield c[seq]
else:
seq = fromindex/2
- for c in self.all_changes( texts ):
+ for c in self._merge_cache:
if c[seq]:
yield reverse_chunk(c[seq])
- def single_changes(self, textindex, texts):
+ def single_changes(self, textindex):
"""Give changes for single file only. do not return 'equal' hunks.
"""
if textindex in (0,2):
seq = textindex/2
- for cs in self.all_changes( texts ):
+ for cs in self._merge_cache:
if cs[seq]:
yield reverse_chunk(cs[seq]) + (1,)
else:
- for cs in self.all_changes( texts ):
+ for cs in self._merge_cache:
if cs[0]:
yield cs[0] + (0,)
elif cs[1]:
@@ -241,7 +245,7 @@ class Differ(object):
for c in self._auto_merge(using, texts):
yield c
- def set_sequences_iter(self, *sequences):
+ def set_sequences_iter(self, sequences, texts):
assert 0 <= len(sequences) <= 3
self.diffs = [[], []]
self.num_sequences = len(sequences)
@@ -253,5 +257,6 @@ class Differ(object):
while work.next() == None:
yield None
self.diffs[i] = matcher.get_difference_opcodes()
+ self._update_merge_cache(texts)
yield 1
diff --git a/filediff.py b/filediff.py
index f825525..5e9441b 100644
--- a/filediff.py
+++ b/filediff.py
@@ -591,7 +591,7 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
yield _("[%s] Computing differences") % self.label_text
panetext = [self._filter_text(p) for p in panetext]
lines = map(lambda x: x.split("\n"), panetext)
- step = self.linediffer.set_sequences_iter(*lines)
+ step = self.linediffer.set_sequences_iter(lines, self._get_texts())
while step.next() == None:
yield 1
@@ -628,7 +628,7 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
for tagname in taglist:
tag = table.lookup(tagname)
b.remove_tag(tag, b.get_start_iter(), b.get_end_iter() )
- for chunk in self.linediffer.all_changes(self._get_texts()):
+ for chunk in self.linediffer.all_changes():
for i,c in enumerate(chunk):
if c and c[0] == "replace":
bufs = self.textbuffer[1], self.textbuffer[i*2]
@@ -696,7 +696,7 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
context.rectangle(0, ypos0, width, ypos1 - ypos0)
context.fill()
- for change in self.linediffer.single_changes(pane, self._get_texts()):
+ for change in self.linediffer.single_changes(pane):
change, skip = self._consume_blank_lines(change, pane, change[5])
if skip:
continue
@@ -938,7 +938,7 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
for (i,adj) in others:
mbegin,mend, obegin,oend = 0, self._get_line_count(master), 0, self._get_line_count(i)
# look for the chunk containing 'line'
- for c in self.linediffer.pair_changes(master, i, self._get_texts()):
+ for c in self.linediffer.pair_changes(master, i):
c = c[1:]
if c[0] >= line:
mend = c[0]
@@ -1000,7 +1000,7 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
"insert":solid_green,
"replace":solid_blue,
"delete":solid_green}
- for c in self.linediffer.single_changes(textindex, self._get_texts()):
+ for c in self.linediffer.single_changes(textindex):
assert c[0] != "equal"
c, skip = self._consume_blank_lines(c, textindex, c[5])
if skip:
@@ -1066,7 +1066,7 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
curline = -1
c = None
if direction == gdk.SCROLL_DOWN:
- for c in self.linediffer.single_changes(1, self._get_texts()):
+ for c in self.linediffer.single_changes(1):
assert c[0] != "equal"
c, skip = self._consume_blank_lines(c, 1, c[5])
if skip:
@@ -1074,7 +1074,7 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
if c[1] > curline:
break
else: #direction == gdk.SCROLL_UP
- for chunk in self.linediffer.single_changes(1, self._get_texts()):
+ for chunk in self.linediffer.single_changes(1):
chunk, skip = self._consume_blank_lines(chunk, 1, chunk[5])
if skip:
continue
@@ -1161,7 +1161,7 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
context.paint()
context.identity_matrix()
- for c in self.linediffer.pair_changes(which, which+1, self._get_texts()):
+ for c in self.linediffer.pair_changes(which, which + 1):
c, skip = self._consume_blank_lines(c, which, which + 1)
if skip:
continue
@@ -1243,7 +1243,7 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
dst = which + 1 - side
adj = self.scrolledwindow[src].get_vadjustment()
- for c in self.linediffer.pair_changes(src, dst, self._get_texts()):
+ for c in self.linediffer.pair_changes(src, dst):
c, skip = self._consume_blank_lines(c, src, dst)
if skip:
continue
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]