~abentley/bzrtools/bzrtools.dev

565 by Aaron Bentley
Add new bug
1
Hello Aaron. Here's yet another bug report we received at Debian's BTS. :)
2
3
Thanks.
4
5
----- Forwarded message from Loïc Minier <lool@dooz.org> -----
6
7
From: Loïc Minier <lool@dooz.org>
8
To: Debian Bug Tracking System <submit@bugs.debian.org>
9
Date: Mon, 30 Jul 2007 12:27:11 +0200
10
Subject: Bug#435240: multi-pull is slow because it doesn't reuse connections
11
12
Package: bzrtools
13
Version: 0.18.0-1
14
Severity: wishlist
15
Tags: patch
16
17
        Hi,
18
19
 multi-pull is relatively slow because it opens a connection for each
20
 branch (especially ssh connections are slow).  I'm attaching a patch to
21
 reuse the connection for all branches with the same URL base.  I hope
22
 it's not so ugly that you poke yourself an eye out.
23
24
 The old behavior isn't available anymore with the patch, but perhaps
25
 this is a problem for some transports?  I have no idea.
26
27
   Bye,
28
29
-- System Information:
30
Debian Release: lenny/sid
31
  APT prefers unstable
32
  APT policy: (500, 'unstable'), (1, 'experimental')
33
Architecture: i386 (i686)
34
35
Kernel: Linux 2.6.22-1-686 (SMP w/2 CPU cores)
36
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
37
Shell: /bin/sh linked to /bin/dash
38
39
Versions of packages bzrtools depends on:
40
ii  bzr                           0.18-1     Bazaar, the next-generation distri
41
ii  patch                         2.5.9-4    Apply a diff file to an original
42
ii  python                        2.4.4-6    An interactive high-level object-o
43
ii  python-central                0.5.14     register and build utility for Pyt
44
45
Versions of packages bzrtools recommends:
46
ii  graphviz                      2.12-3     rich set of graph drawing tools
47
ii  rsync                         2.6.9-3    fast remote file copy program (lik
48
49
-- no debconf information
50
51
-- 
52
Loïc Minier
53
54
--- bzrtools-0.18.0/debian/changelog
55
+++ bzrtools-0.18.0/debian/changelog
56
@@ -1,3 +1,11 @@
57
+bzrtools (0.18.0-1.1) UNRELEASED; urgency=low
58
+
59
+  * Non-maintainer upload.
60
+  * Group branches by URL base and reuse one transport per URL base to avoid
61
+    reopening a connection for each pull in multi-pull.
62
+
63
+ -- Loic Minier <lool@dooz.org>  Mon, 30 Jul 2007 12:06:43 +0200
64
+
65
 bzrtools (0.18.0-1) unstable; urgency=low
66
 
67
   [ Arnaud Fontaine ]
68
--- bzrtools-0.18.0.orig/__init__.py
69
+++ bzrtools-0.18.0/__init__.py
70
@@ -503,27 +503,72 @@
71
         if not t.listable():
72
             print "Can't list this type of location."
73
             return 3
74
-        for branch, wt in iter_branch_tree(t):
75
-            if wt is None:
76
-                pullable = branch
77
-            else:
78
-                pullable = wt
79
-            parent = branch.get_parent()
80
-            if parent is None:
81
-                continue
82
-            if wt is not None:
83
-                base = wt.basedir
84
-            else:
85
-                base = branch.base
86
-            if base.startswith(t.base):
87
-                relpath = base[len(t.base):].rstrip('/')
88
-            else:
89
-                relpath = base
90
-            print "Pulling %s from %s" % (relpath, parent)
91
-            try:
92
-                pullable.pull(Branch.open(parent))
93
-            except Exception, e:
94
-                print e
95
+        print "Grouping branches by URL"
96
+        by_urlbase = pullable_infos_by_urlbase(t)
97
+        for urlbase in by_urlbase:
98
+            print "Processing branches for %s/" % urlbase
99
+            urlbase_transport = get_transport(urlbase)
100
+            for pi in by_urlbase[urlbase]:
101
+                pullable = pi.get_pullable()
102
+                relpath = get_relpath(t.base, pi.get_base())
103
+                parent = pi.get_parent()
104
+                from bzrtools import bzrdir_from_transport
105
+                pull_transport = urlbase_transport.clone(get_relpath(urlbase, parent))
106
+                bzrdir = bzrdir_from_transport(pull_transport)
107
+                pull_branch = bzrdir.open_branch()
108
+                print "Pulling %s from %s" % (relpath, parent)
109
+                try:
110
+                    pullable.pull(pull_branch)
111
+                except Exception, e:
112
+                    print e
113
+
114
+
115
+def get_relpath(base, path):
116
+    if path.startswith(base):
117
+        return path[len(base):].rstrip('/')
118
+    else:
119
+        return path
120
+
121
+
122
+class PullableInfo:
123
+    def __init__(self, branch, wt):
124
+        self.branch = branch
125
+        self.wt = wt
126
+
127
+    def get_pullable(self):
128
+        if self.wt is None:
129
+            return self.branch
130
+        return self.wt
131
+
132
+    def get_parent(self):
133
+        return self.branch.get_parent()
134
+
135
+    def get_base(self):
136
+        if self.wt is not None:
137
+            return self.wt.basedir
138
+        return self.branch.base
139
+
140
+    def get_urlbase(self):
141
+        import re
142
+        # always matches at least the empty string
143
+        urlbase_pattern = re.compile("^(([^:]*://)?([^/]*))")
144
+        return urlbase_pattern.match(self.get_parent()).groups()[0]
145
+
146
+
147
+def pullable_infos_by_urlbase(t):
148
+    pullables_by_urlbase = {}
149
+    from bzrtools import iter_branch_tree
150
+    for branch, wt in iter_branch_tree(t):
151
+        parent = branch.get_parent()
152
+        if parent is None:
153
+            continue
154
+        pullable_info = PullableInfo(branch, wt)
155
+        urlbase = pullable_info.get_urlbase()
156
+        try:
157
+            pullables_by_urlbase[urlbase] += (pullable_info, )
158
+        except KeyError:
159
+            pullables_by_urlbase[urlbase] = (pullable_info, )
160
+    return pullables_by_urlbase
161
 
162
 
163
 class cmd_branch_mark(bzrlib.commands.Command):