Rev 2691: Merge pack api improvements to allow readv. in http://people.ubuntu.com/~robertc/baz2.0/repository

Robert Collins robertc at robertcollins.net
Thu Aug 2 05:18:33 BST 2007


At http://people.ubuntu.com/~robertc/baz2.0/repository

------------------------------------------------------------
revno: 2691
revision-id: robertc at robertcollins.net-20070802041827-sllv9yvivttnw3az
parent: robertc at robertcollins.net-20070801080022-o9eosczwispn9l53
parent: robertc at robertcollins.net-20070802031746-mpnoaxym829719w6
committer: Robert Collins <robertc at robertcollins.net>
branch nick: repository
timestamp: Thu 2007-08-02 14:18:27 +1000
message:
  Merge pack api improvements to allow readv.
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/help_topics.py          help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
  bzrlib/lsprof.py               lsprof.py-20051208071030-833790916798ceed
  bzrlib/pack.py                 container.py-20070607160755-tr8zc26q18rn0jnb-1
  bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
  bzrlib/tests/test_pack.py      test_container.py-20070607160755-tr8zc26q18rn0jnb-2
  bzrlib/transport/local.py      local_transport.py-20050711165921-9b1f142bfe480c24
  bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
  doc/developers/profiling.txt   profiling.txt-20070531045713-j15mxufywgzwdeu8-1
    ------------------------------------------------------------
    revno: 2592.1.25.2.7.1.28.1.6.1.5
    revision-id: robertc at robertcollins.net-20070802031746-mpnoaxym829719w6
    parent: robertc at robertcollins.net-20070802021817-n8a86kevyvk2f9jo
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack
    timestamp: Thu 2007-08-02 13:17:46 +1000
    message:
      * ``bzrlib.pack.make_readv_reader`` allows readv based access to pack
        files that are stored on a transport. (Robert Collins)
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/pack.py                 container.py-20070607160755-tr8zc26q18rn0jnb-1
      bzrlib/tests/test_pack.py      test_container.py-20070607160755-tr8zc26q18rn0jnb-2
      bzrlib/transport/local.py      local_transport.py-20050711165921-9b1f142bfe480c24
    ------------------------------------------------------------
    revno: 2592.1.25.2.7.1.28.1.6.1.4
    revision-id: robertc at robertcollins.net-20070802021817-n8a86kevyvk2f9jo
    parent: pqm at pqm.ubuntu.com-20070730235409-pfqxlkh2dcs95u70
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack
    timestamp: Thu 2007-08-02 12:18:17 +1000
    message:
      * ``bzrlib.pack.ContainerWriter`` now returns an offset, length tuple to
        callers when inserting data, allowing generation of readv style access
        during pack creation, without needing a separate pass across the output
        pack to gather such details. (Robert Collins)
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/pack.py                 container.py-20070607160755-tr8zc26q18rn0jnb-1
      bzrlib/tests/test_pack.py      test_container.py-20070607160755-tr8zc26q18rn0jnb-2
    ------------------------------------------------------------
    revno: 2592.1.25.2.7.1.28.1.6.1.3
    revision-id: pqm at pqm.ubuntu.com-20070730235409-pfqxlkh2dcs95u70
    parent: pqm at pqm.ubuntu.com-20070730181918-3i2gb12zxmvjwh3r
    parent: robertc at robertcollins.net-20070730050210-2acxfrs1glrjexix
    committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
    branch nick: +trunk
    timestamp: Tue 2007-07-31 00:54:09 +0100
    message:
      (robertc) Fix mismatch between KnitGraphIndex and KnitIndex in get_options. (Robert Collins).
    modified:
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
    ------------------------------------------------------------
    revno: 2592.1.25.2.7.1.28.1.6.1.2
    revision-id: pqm at pqm.ubuntu.com-20070730181918-3i2gb12zxmvjwh3r
    parent: pqm at pqm.ubuntu.com-20070730051419-0jdj7g8fm4iuoz7h
    parent: john at arbash-meinel.com-20070730170648-9agmhx8qdv0tna1g
    committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
    branch nick: +trunk
    timestamp: Mon 2007-07-30 19:19:18 +0100
    message:
      (John Arbash Meinel) remove a spurious get_master_branch() call, to avoid 1 extra remote connection
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
        ------------------------------------------------------------
        revno: 2592.1.25.2.7.1.28.1.3.1.4
        revision-id: john at arbash-meinel.com-20070730170648-9agmhx8qdv0tna1g
        parent: john at arbash-meinel.com-20070730170502-t13pxmv7kygd6qpm
        committer: John Arbash Meinel <john at arbash-meinel.com>
        branch nick: remove_extra_connect
        timestamp: Mon 2007-07-30 12:06:48 -0500
        message:
          NEWS entry for update, partial fix for bug #128076
        modified:
          NEWS                           NEWS-20050323055033-4e00b5db738777ff
        ------------------------------------------------------------
        revno: 2592.1.25.2.7.1.28.1.3.1.3
        revision-id: john at arbash-meinel.com-20070730170502-t13pxmv7kygd6qpm
        parent: john at arbash-meinel.com-20070730143604-aigt4pksc8hop053
        parent: pqm at pqm.ubuntu.com-20070730051419-0jdj7g8fm4iuoz7h
        committer: John Arbash Meinel <john at arbash-meinel.com>
        branch nick: remove_extra_connect
        timestamp: Mon 2007-07-30 12:05:02 -0500
        message:
          [merge] bzr.dev 2659
        modified:
          NEWS                           NEWS-20050323055033-4e00b5db738777ff
          bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
          bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
          bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
          bzrlib/help_topics.py          help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
          bzrlib/index.py                index.py-20070712131115-lolkarso50vjr64s-1
          bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
          bzrlib/lsprof.py               lsprof.py-20051208071030-833790916798ceed
          bzrlib/tests/test_graph.py     test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
          bzrlib/tests/test_index.py     test_index.py-20070712131115-lolkarso50vjr64s-2
          bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
          doc/developers/HACKING         HACKING-20050805200004-2a5dc975d870f78c
          doc/developers/profiling.txt   profiling.txt-20070531045713-j15mxufywgzwdeu8-1
        ------------------------------------------------------------
        revno: 2592.1.25.2.7.1.28.1.3.1.2
        revision-id: john at arbash-meinel.com-20070730143604-aigt4pksc8hop053
        parent: john at arbash-meinel.com-20070727194103-xj3g89nsqnxsiwpq
        committer: John Arbash Meinel <john at arbash-meinel.com>
        branch nick: remove_extra_connect
        timestamp: Mon 2007-07-30 09:36:04 -0500
        message:
          Remove the extra traceback.
        modified:
          bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
        ------------------------------------------------------------
        revno: 2592.1.25.2.7.1.28.1.3.1.1
        revision-id: john at arbash-meinel.com-20070727194103-xj3g89nsqnxsiwpq
        parent: pqm at pqm.ubuntu.com-20070727061532-14ly852y2g2dbcb8
        committer: John Arbash Meinel <john at arbash-meinel.com>
        branch nick: remove_extra_connect
        timestamp: Fri 2007-07-27 14:41:03 -0500
        message:
          Add some more hpss logging.
          Also, remove a spurious call to 'get_master_branch()' as part of 'bzr update'
        modified:
          bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
          bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
          bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
    ------------------------------------------------------------
    revno: 2592.1.25.2.7.1.28.1.6.1.1
    revision-id: pqm at pqm.ubuntu.com-20070730051419-0jdj7g8fm4iuoz7h
    parent: pqm at pqm.ubuntu.com-20070728030946-tfjmxwe9y2eq1gzo
    parent: ian.clatworthy at internode.on.net-20070730032503-4w8lmn0s42nxpxna
    committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
    branch nick: +trunk
    timestamp: Mon 2007-07-30 06:14:19 +0100
    message:
      (Ian Clatworthy) Dump profiling data for KCacheGrind if the filename starts with callgrind.out
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/help_topics.py          help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/lsprof.py               lsprof.py-20051208071030-833790916798ceed
      doc/developers/profiling.txt   profiling.txt-20070531045713-j15mxufywgzwdeu8-1
    ------------------------------------------------------------
    revno: 2592.1.25.2.7.1.28.1.6.2.1
    revision-id: ian.clatworthy at internode.on.net-20070730032503-4w8lmn0s42nxpxna
    parent: pqm at pqm.ubuntu.com-20070728030946-tfjmxwe9y2eq1gzo
    parent: ian.clatworthy at internode.on.net-20070730015544-7g5r7kbv1nejica3
    committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
    branch nick: ianc-integration
    timestamp: Mon 2007-07-30 13:25:03 +1000
    message:
      (Ian Clatworthy) Dump profiling data for KCacheGrind if the filename starts with callgrind.out
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/help_topics.py          help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/lsprof.py               lsprof.py-20051208071030-833790916798ceed
      doc/developers/profiling.txt   profiling.txt-20070531045713-j15mxufywgzwdeu8-1
    ------------------------------------------------------------
    revno: 2592.1.25.2.7.1.28.1.2.2.2
    revision-id: ian.clatworthy at internode.on.net-20070730015544-7g5r7kbv1nejica3
    parent: ian.clatworthy at internode.on.net-20070727055727-yxxco3di19yykrev
    committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
    branch nick: bzr.callgrind-out
    timestamp: Mon 2007-07-30 11:55:44 +1000
    message:
      Put all format detection stuff in one spot as requested by John Arbash Meinel
    modified:
      bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
      bzrlib/lsprof.py               lsprof.py-20051208071030-833790916798ceed
    ------------------------------------------------------------
    revno: 2592.1.25.2.7.1.28.1.2.2.1
    revision-id: ian.clatworthy at internode.on.net-20070727055727-yxxco3di19yykrev
    parent: pqm at pqm.ubuntu.com-20070726223348-t2howycr63c04q7r
    committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
    branch nick: bzr.callgrind-out
    timestamp: Fri 2007-07-27 15:57:27 +1000
    message:
      Dump profiling data for KCacheGrind if the filename starts with callgrind.out
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
      bzrlib/help_topics.py          help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      doc/developers/profiling.txt   profiling.txt-20070531045713-j15mxufywgzwdeu8-1
=== modified file 'NEWS'
--- a/NEWS	2007-07-30 05:04:59 +0000
+++ b/NEWS	2007-08-02 04:18:27 +0000
@@ -95,6 +95,15 @@
       ``other`` is large. This improves ``VF.get_graph([version_id])`` for
       a 12.5k graph from 2.9s down to 200ms. (John Arbash Meinel)
 
+    * The ``--lsprof-file`` option now generates output for KCacheGrind if
+      the file starts with ``callgrind.out``. This matches the default file
+      filtering done by KCacheGrind's Open Dialog. (Ian Clatworthy)
+
+    * Fix ``bzr update`` to avoid an unnecessary
+      ``branch.get_master_branch`` call, which avoids 1 extra connection
+      to the remote server. (Partial fix for #128076, John Arbash Meinel)
+      
+
   LIBRARY API BREAKS:
 
     * Deprecated dictionary ``bzrlib.option.SHORT_OPTIONS`` removed.
@@ -168,6 +177,14 @@
     * Graph now has an is_ancestor method, various bits use it.
       (Aaron Bentley)
 
+    * ``bzrlib.pack.ContainerWriter`` now returns an offset, length tuple to
+      callers when inserting data, allowing generation of readv style access
+      during pack creation, without needing a separate pass across the output
+      pack to gather such details. (Robert Collins)
+
+    * ``bzrlib.pack.make_readv_reader`` allows readv based access to pack
+      files that are stored on a transport. (Robert Collins)
+
     * New methods on Repository - ``start_write_group``,
       ``commit_write_group``, ``abort_write_group`` and ``is_in_write_group`` -
       which provide a clean hook point for transactional Repositories - ones

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2007-07-26 19:51:56 +0000
+++ b/bzrlib/builtins.py	2007-07-30 17:05:02 +0000
@@ -1029,7 +1029,6 @@
             if last_rev == _mod_revision.ensure_null(
                 tree.branch.last_revision()):
                 # may be up to date, check master too.
-                master = tree.branch.get_master_branch()
                 if master is None or last_rev == _mod_revision.ensure_null(
                     master.last_revision()):
                     revno = tree.branch.revision_id_to_revno(last_rev)

=== modified file 'bzrlib/help_topics.py'
--- a/bzrlib/help_topics.py	2007-07-12 12:07:13 +0000
+++ b/bzrlib/help_topics.py	2007-07-27 05:57:27 +0000
@@ -194,9 +194,10 @@
 --lsprof       Profile execution using the lsprof profiler
 --lsprof-file  Profile execution using the lsprof profiler, and write the
                results to a specified file.  If the filename ends with ".txt",
-               text format will be used.  If the filename ends with
-               ".callgrind", output will be formatted for use with KCacheGrind.
-               Otherwise, the output will be a pickle.
+               text format will be used.  If the filename either starts with
+               "callgrind.out" or end with ".callgrind", the output will be
+               formatted for use with KCacheGrind. Otherwise, the output
+               will be a pickle.
 
 See doc/developers/profiling.txt for more information on profiling.
 

=== modified file 'bzrlib/lsprof.py'
--- a/bzrlib/lsprof.py	2007-06-06 10:45:08 +0000
+++ b/bzrlib/lsprof.py	2007-07-30 01:55:44 +0000
@@ -113,13 +113,17 @@
         :param format: 'txt' for a text representation;
             'callgrind' for calltree format;
             otherwise a pickled Python object. A format of None indicates
-            that the format to use is to be found from the extension of
-            filename.
+            that the format to use is to be found from the filename. If
+            the name starts with callgrind.out, callgrind format is used
+            otherwise the format is given by the filename extension.
         """
         if format is None:
-            ext = os.path.splitext(filename)[1]
-            if len(ext) > 1:
-                format = ext[1:]
+            if filename.startswith('callgrind.out'):
+                format = "callgrind"
+            else:
+                ext = os.path.splitext(filename)[1]
+                if len(ext) > 1:
+                    format = ext[1:]
         outfile = open(filename, 'wb')
         try:
             if format == "callgrind":

=== modified file 'bzrlib/pack.py'
--- a/bzrlib/pack.py	2007-07-03 04:12:19 +0000
+++ b/bzrlib/pack.py	2007-08-02 03:17:46 +0000
@@ -19,6 +19,7 @@
 "Containers" and "records" are described in doc/developers/container-format.txt.
 """
 
+from cStringIO import StringIO
 import re
 
 from bzrlib import errors
@@ -66,18 +67,34 @@
         :param write_func: a callable that will be called when this
             ContainerWriter needs to write some bytes.
         """
-        self.write_func = write_func
+        self._write_func = write_func
+        self.current_offset = 0
 
     def begin(self):
         """Begin writing a container."""
         self.write_func(FORMAT_ONE + "\n")
 
+    def write_func(self, bytes):
+        self._write_func(bytes)
+        self.current_offset += len(bytes)
+
     def end(self):
         """Finish writing a container."""
         self.write_func("E")
 
     def add_bytes_record(self, bytes, names):
-        """Add a Bytes record with the given names."""
+        """Add a Bytes record with the given names.
+        
+        :param bytes: The bytes to insert.
+        :param names: The names to give the inserted bytes.
+        :return: An offset, length tuple. The offset is the offset
+            of the record within the container, and the length is the
+            length of data that will need to be read to reconstitute the
+            record. These offset and length can only be used with the pack
+            interface - they might be offset by headers or other such details
+            and thus are only suitable for use by a ContainerReader.
+        """
+        current_offset = self.current_offset
         # Kind marker
         self.write_func("B")
         # Length
@@ -92,6 +109,54 @@
         self.write_func("\n")
         # Finally, the contents.
         self.write_func(bytes)
+        # return a memo of where we wrote data to allow random access.
+        return current_offset, self.current_offset - current_offset
+
+
+class ReadVFile(object):
+    """Adapt a readv result iterator to a file like protocol."""
+
+    def __init__(self, readv_result):
+        self.readv_result = readv_result
+        # the most recent readv result block
+        self._string = None
+
+    def _next(self):
+        if (self._string is None or
+            self._string.tell() == self._string_length):
+            length, data = self.readv_result.next()
+            self._string_length = len(data)
+            self._string = StringIO(data)
+
+    def read(self, length):
+        self._next()
+        result = self._string.read(length)
+        if len(result) < length:
+            raise errors.BzrError('request for too much data from a readv hunk.')
+        return result
+
+    def readline(self):
+        """Note that readline will not cross readv segments."""
+        self._next()
+        result = self._string.readline()
+        if self._string.tell() == self._string_length and result[-1] != '\n':
+            raise errors.BzrError('short readline in the readvfile hunk.')
+        return result
+
+
+def make_readv_reader(transport, filename, requested_records):
+    """Create a ContainerReader that will read selected records only.
+
+    :param transport: The transport the pack file is located on.
+    :param filename: The filename of the pack file.
+    :param requested_records: The record offset, length tuples as returned
+        by add_bytes_record for the desired records.
+    """
+    readv_blocks = [(0, len(FORMAT_ONE)+1)]
+    readv_blocks.extend(requested_records)
+    result = ContainerReader(ReadVFile(
+        transport.readv(filename, readv_blocks)))
+    return result
 
 
 class BaseReader(object):

=== modified file 'bzrlib/smart/protocol.py'
--- a/bzrlib/smart/protocol.py	2007-07-09 05:56:41 +0000
+++ b/bzrlib/smart/protocol.py	2007-07-27 19:41:03 +0000
@@ -302,7 +302,7 @@
 
     def call(self, *args):
         if 'hpss' in debug.debug_flags:
-            mutter('hpss call: %r', args)
+            mutter('hpss call:   %r', args)
         self._write_args(args)
         self._request.finished_writing()
 

=== modified file 'bzrlib/tests/test_pack.py'
--- a/bzrlib/tests/test_pack.py	2007-07-03 04:05:08 +0000
+++ b/bzrlib/tests/test_pack.py	2007-08-02 03:17:46 +0000
@@ -54,7 +54,8 @@
         output = StringIO()
         writer = pack.ContainerWriter(output.write)
         writer.begin()
-        writer.add_bytes_record('abc', names=[])
+        offset, length = writer.add_bytes_record('abc', names=[])
+        self.assertEqual((42, 7), (offset, length))
         self.assertEqual('Bazaar pack format 1 (introduced in 0.18)\nB3\n\nabc',
                          output.getvalue())
 
@@ -63,7 +64,8 @@
         output = StringIO()
         writer = pack.ContainerWriter(output.write)
         writer.begin()
-        writer.add_bytes_record('abc', names=['name1'])
+        offset, length = writer.add_bytes_record('abc', names=['name1'])
+        self.assertEqual((42, 13), (offset, length))
         self.assertEqual(
             'Bazaar pack format 1 (introduced in 0.18)\n'
             'B3\nname1\n\nabc',
@@ -74,12 +76,26 @@
         output = StringIO()
         writer = pack.ContainerWriter(output.write)
         writer.begin()
-        writer.add_bytes_record('abc', names=['name1', 'name2'])
+        offset, length = writer.add_bytes_record('abc', names=['name1', 'name2'])
+        self.assertEqual((42, 19), (offset, length))
         self.assertEqual(
             'Bazaar pack format 1 (introduced in 0.18)\n'
             'B3\nname1\nname2\n\nabc',
             output.getvalue())
 
+    def test_add_second_bytes_record_gets_higher_offset(self):
+        output = StringIO()
+        writer = pack.ContainerWriter(output.write)
+        writer.begin()
+        writer.add_bytes_record('abc', names=[])
+        offset, length = writer.add_bytes_record('abc', names=[])
+        self.assertEqual((49, 7), (offset, length))
+        self.assertEqual(
+            'Bazaar pack format 1 (introduced in 0.18)\n'
+            'B3\n\nabc'
+            'B3\n\nabc',
+            output.getvalue())
+
     def test_add_bytes_record_invalid_name(self):
         """Adding a Bytes record with a name with whitespace in it raises
         InvalidRecordError.
@@ -375,3 +391,63 @@
         self.assertEqual('', get_bytes(99))
 
 
+class TestReadvReader(tests.TestCaseWithTransport):
+
+    def test_read_skipping_records(self):
+        pack_data = StringIO()
+        writer = pack.ContainerWriter(pack_data.write)
+        writer.begin()
+        memos = []
+        memos.append(writer.add_bytes_record('abc', names=[]))
+        memos.append(writer.add_bytes_record('def', names=['name1']))
+        memos.append(writer.add_bytes_record('ghi', names=['name2']))
+        memos.append(writer.add_bytes_record('jkl', names=[]))
+        writer.end()
+        transport = self.get_transport()
+        pack_data.seek(0)
+        transport.put_file('mypack', pack_data)
+        requested_records = [memos[0], memos[2]]
+        reader = pack.make_readv_reader(transport, 'mypack', requested_records)
+        result = []
+        for names, reader_func in reader.iter_records():
+            result.append((names, reader_func(None)))
+        self.assertEqual([([], 'abc'), (['name2'], 'ghi')], result)
+
+
+class TestReadvFile(tests.TestCaseWithTransport):
+
+    def test_read_bytes(self):
+        # this tests byte reading - solo, all in a hunk at once
+        transport = self.get_transport()
+        transport.put_bytes('sample', '0123456789')
+        f = pack.ReadVFile(transport.readv('sample', [(0,1), (1,2), (4,1), (6,2)]))
+        results = []
+        results.append(f.read(1))
+        results.append(f.read(2))
+        results.append(f.read(1))
+        results.append(f.read(1))
+        results.append(f.read(1))
+        self.assertEqual(['0', '12', '4', '6', '7'], results)
+
+    def test_readline(self):
+        # this tests readline as the ContainerReader needs it - 
+        # just within a record, never across.
+        transport = self.get_transport()
+        transport.put_bytes('sample', '0\n2\n4\n')
+        f = pack.ReadVFile(transport.readv('sample', [(0,2), (2,4)]))
+        results = []
+        results.append(f.readline())
+        results.append(f.readline())
+        results.append(f.readline())
+        self.assertEqual(['0\n', '2\n', '4\n'], results)
+
+    def test_readline_and_read(self):
+        # this tests read, then readline, then read again 
+        transport = self.get_transport()
+        transport.put_bytes('sample', '0\n2\n4\n')
+        f = pack.ReadVFile(transport.readv('sample', [(0,6)]))
+        results = []
+        results.append(f.read(1))
+        results.append(f.readline())
+        results.append(f.read(4))
+        self.assertEqual(['0', '\n', '2\n4\n'], results)

=== modified file 'bzrlib/transport/local.py'
--- a/bzrlib/transport/local.py	2007-07-20 03:20:20 +0000
+++ b/bzrlib/transport/local.py	2007-08-02 03:17:46 +0000
@@ -127,7 +127,7 @@
             abspath = u'.'
 
         return urlutils.file_relpath(
-            urlutils.strip_trailing_slash(self.base), 
+            urlutils.strip_trailing_slash(self.base),
             urlutils.strip_trailing_slash(abspath))
 
     def has(self, relpath):

=== modified file 'bzrlib/transport/remote.py'
--- a/bzrlib/transport/remote.py	2007-07-20 18:59:29 +0000
+++ b/bzrlib/transport/remote.py	2007-07-30 14:36:04 +0000
@@ -27,7 +27,9 @@
 import urlparse
 
 from bzrlib import (
+    debug,
     errors,
+    trace,
     transport,
     urlutils,
     )
@@ -105,8 +107,11 @@
             credentials = None
             if medium is None:
                 medium, credentials = self._build_medium()
-            self._shared_connection= transport._SharedConnection(medium,
-                                                                 credentials)
+                if 'hpss' in debug.debug_flags:
+                    trace.mutter('hpss: Built a new medium: %s',
+                                 medium.__class__.__name__)
+            self._shared_connection = transport._SharedConnection(medium,
+                                                                  credentials)
 
         if _client is None:
             self._client = client._SmartClient(self.get_shared_medium())

=== modified file 'doc/developers/profiling.txt'
--- a/doc/developers/profiling.txt	2007-06-27 09:39:45 +0000
+++ b/doc/developers/profiling.txt	2007-07-27 05:57:27 +0000
@@ -1,35 +1,42 @@
 Profiling
 =========
 
+Using profilers
+---------------
+
 Bazaar has some built-in support for collecting and saving profiling
-information. In the simpliest case, the --lsprof option can be used as
+information. In the simpliest case, the ``--lsprof`` option can be used as
 shown below::
 
   bzr --lsprof ...
 
 This will dump the profiling information to stdout before exiting.
-Alternatively, the --lsprof-file option can be used to specify a filename
+Alternatively, the ``--lsprof-file`` option can be used to specify a filename
 to save the profiling data into to. By default, profiling data saved to a
 file is a pickled Python object making it possible to reload the data and
 do with it what you will. For convenience though:
 
-* if the filename ends in ".txt", it will be dumped in a text format.
-
-* if the filename ends in ".callgrind", it will be converted to a format
-  loadable by the KCacheGrind visualization tool.
-
-Here is an example of how to use the --lsprof-file option in combination
-with KCacheGrind to visualize what the "status" command is doing::
-
-  bzr --lsprof-file status001.callgrind status
-  kcachegrind status001.callgrind &
-
-.. Note:: bzr also has a --profile option that uses the hotshot profiler
+* if the filename ends in ``.txt``, it will be dumped in a text format.
+
+* if the filename either starts with ``callgrind.out`` or ends with
+  ``.callgrind``, it will be converted to a format loadable by the
+  KCacheGrind visualization tool.
+
+Note that KCacheGrind's Open Dialog has a default filter than only shows
+files starting with ``callgrind.out`` so the longer filename is usually
+preferable. Here is an example of how to use the ``--lsprof-file`` option
+in combination with KCacheGrind to visualize what the ``status`` command
+is doing::
+
+  bzr --lsprof-file callgrind.out.st001 status
+  kcachegrind callgrind.out.st001 &
+
+.. Note:: bzr also has a ``--profile`` option that uses the hotshot profiler
    instead of the lsprof profiler. The hotshot profiler can be useful
    though the lsprof one is generally recommended. See
    http://docs.python.org/lib/node795.html.
 
-Note that to use --lsprof you must install the lsprof module, which you
+Note that to use ``--lsprof`` you must install the lsprof module, which you
 can get with::
 
   svn co http://codespeak.net/svn/user/arigo/hack/misc/lsprof
@@ -42,7 +49,7 @@
 identifying unnecessary lock traffic.  This is activated by the ``-Dlock``
 global option.
 
-This writes messages into ~/.bzr.log.
+This writes messages into ``~/.bzr.log``.
 At present this only logs actions relating to the on-disk lockdir.  It 
 doesn't describe actions on in-memory lock counters, or OS locks (which
 are used for dirstate.)



More information about the bazaar-commits mailing list