~bzr-pqm/bzr/bzr.dev

1327 by Martin Pool
- draft patch to cache weave inclusions
1
=== modified file 'bzrlib/weave.py'
2
--- bzrlib/weave.py
3
+++ bzrlib/weave.py
4
@@ -83,6 +83,10 @@
5
 
6
 # TODO: Perhaps the API should work only in names to hide the integer
7
 # indexes from the user?
8
+
9
+# TODO: Is there any potential performance win by having an add()
10
+# variant that is passed a pre-cooked version of the single basis
11
+# version?
12
 
13
 
14
 
15
@@ -191,8 +195,8 @@
16
         Set by read_weave.
17
     """
18
 
19
-    __slots__ = ['_weave', '_parents', '_sha1s', '_names', '_name_map',
20
-                 '_weave_name']
21
+    ##__slots__ = ['_weave', '_parents', '_sha1s', '_names', '_name_map',
22
+    ##             '_weave_name', '_inclusion_cache']
23
     
24
     def __init__(self, weave_name=None):
25
         self._weave = []
26
@@ -201,7 +205,7 @@
27
         self._names = []
28
         self._name_map = {}
29
         self._weave_name = weave_name
30
-
31
+        self._inclusion_cache = {}
32
 
33
     def __eq__(self, other):
34
         if not isinstance(other, Weave):
35
@@ -300,7 +304,6 @@
36
                 self._weave.append(('{', new_version))
37
                 self._weave.extend(text)
38
                 self._weave.append(('}', None))
39
-        
40
             return new_version
41
 
42
         if len(parents) == 1:
43
@@ -308,10 +311,9 @@
44
             if sha1 == self._sha1s[pv]:
45
                 # special case: same as the single parent
46
                 return new_version
47
-            
48
 
49
         ancestors = self.inclusions(parents)
50
-
51
+        self._inclusion_cache[(new_version,)] = ancestors | set([new_version])
52
         l = self._weave
53
 
54
         # basis a list of (origin, lineno, line)
55
@@ -379,17 +381,19 @@
56
 
57
     def inclusions(self, versions):
58
         """Return set of all ancestors of given version(s)."""
59
+        tv = tuple(sorted(versions))
60
+        cached_val = self._inclusion_cache.get(tv)
61
+        if cached_val is not None:
62
+            return cached_val
63
         i = set(versions)
64
-        v = max(versions)
65
-        try:
66
-            while v >= 0:
67
-                if v in i:
68
-                    # include all its parents
69
-                    i.update(self._parents[v])
70
-                v -= 1
71
-            return i
72
-        except IndexError:
73
-            raise ValueError("version %d not present in weave" % v)
74
+        for v in xrange(max(versions), 0, -1):
75
+            if v in i:
76
+                # include all its parents
77
+                i.update(self._parents[v])
78
+        self._inclusion_cache[tv] = i
79
+        return i
80
+        ## except IndexError:
81
+        ##     raise ValueError("version %d not present in weave" % v)
82
 
83
 
84
     def parents(self, version):
85