~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/log.py

Streamline _walkdirs_utf8 for utf8 file systems, reducing time to traverse a mozilla tree from 1s to .6 seconds. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2007 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Transport decorator that logs transport operations to .bzr.log."""
18
18
 
26
26
import types
27
27
 
28
28
from bzrlib.trace import mutter
29
 
from bzrlib.transport import decorator
30
 
 
31
 
 
32
 
class TransportLogDecorator(decorator.TransportDecorator):
 
29
from bzrlib.transport.decorator import (
 
30
    TransportDecorator,
 
31
    )
 
32
from bzrlib.transport.trace import (
 
33
    DecoratorServer,
 
34
    TransportTraceDecorator,
 
35
    )
 
36
 
 
37
 
 
38
 
 
39
 
 
40
class TransportLogDecorator(TransportDecorator):
33
41
    """Decorator for Transports that logs interesting operations to .bzr.log.
34
42
 
35
43
    In general we want to log things that usually take a network round trip
36
44
    and may be slow.
37
45
 
38
46
    Not all operations are logged yet.
39
 
 
40
 
    See also TransportTraceDecorator, that records a machine-readable log in 
41
 
    memory for eg testing.
42
47
    """
43
48
 
44
49
    def __init__(self, *args, **kw):
99
104
    def _show_result(self, before, methodname, result):
100
105
        result_len = None
101
106
        if isinstance(result, types.GeneratorType):
102
 
            # We now consume everything from the generator so that we can show
103
 
            # the results and the time it took to get them.  However, to keep
104
 
            # compatibility with callers that may specifically expect a result
105
 
            # (see <https://launchpad.net/bugs/340347>) we also return a new
106
 
            # generator, reset to the starting position.
 
107
            # eagerly pull in all the contents, so that we can measure how
 
108
            # long it takes to get them.  this does make the behaviour a bit
 
109
            # different, but we hope not noticably so
107
110
            result = list(result)
108
 
            return_result = iter(result)
109
 
        else:
110
 
            return_result = result
111
111
        if isinstance(result, (cStringIO.OutputType, StringIO.StringIO)):
112
112
            val = repr(result.getvalue())
113
113
            result_len = len(val)
122
122
        else:
123
123
            shown_result = self._shorten(self._strip_tuple_parens(result))
124
124
        mutter("  --> %s" % shown_result)
125
 
        # The log decorator no longer shows the elapsed time or transfer rate
126
 
        # because they're available in the log prefixes and the transport
127
 
        # activity display respectively.
128
 
        if False:
129
 
            elapsed = time.time() - before
130
 
            if result_len and elapsed > 0:
131
 
                # this is the rate of higher-level data, not the raw network
132
 
                # speed using base-10 units (see HACKING.txt).
133
 
                mutter("      %9.03fs %8dkB/s"
134
 
                       % (elapsed, result_len/elapsed/1000))
135
 
            else:
136
 
                mutter("      %9.03fs" % (elapsed))
137
 
        return return_result
 
125
        # XXX: the time may be wrong when e.g. a generator object is returned from
 
126
        # an http readv, if the object is returned before the bulk data
 
127
        # is read.
 
128
        elapsed = time.time() - before
 
129
        if result_len and elapsed > 0:
 
130
            # this is the rate of higher-level data, not the raw network speed
 
131
            mutter("      %9.03fs %8dkB/s" % (elapsed, result_len/elapsed/1024))
 
132
        else:
 
133
            mutter("      %9.03fs" % (elapsed))
 
134
        return result
138
135
 
139
136
    def _shorten(self, x):
140
137
        if len(x) > 70:
148
145
        return t
149
146
 
150
147
 
 
148
class LogDecoratorServer(DecoratorServer):
 
149
    """Server for testing."""
 
150
 
 
151
    def get_decorator_class(self):
 
152
        return TransportLogDecorator
 
153
 
 
154
 
151
155
def get_test_permutations():
152
156
    """Return the permutations to be used in testing."""
153
 
    from bzrlib.tests import test_server
154
 
    return [(TransportLogDecorator, test_server.LogDecoratorServer)]
 
157
    return [(TransportLogDecorator, LogDecoratorServer)]