~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/__init__.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-03-09 06:39:13 UTC
  • mfrom: (1596.2.6 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20060309063913-6d8ce700706d0802
Merge knit performance stage 1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
"""
21
21
 
22
22
import errno
 
23
from collections import deque
23
24
from copy import deepcopy
24
25
from stat import *
25
26
import sys
244
245
        """
245
246
        raise NotImplementedError
246
247
 
 
248
    def readv(self, relpath, offsets):
 
249
        """Get parts of the file at the given relative path.
 
250
 
 
251
        :offsets: A list of (offset, size) tuples.
 
252
        :return: A list or generator of (offset, data) tuples
 
253
        """
 
254
        def do_combined_read(combined_offsets):
 
255
            total_size = 0
 
256
            for offset, size in combined_offsets:
 
257
                total_size += size
 
258
            mutter('readv coalesced %d reads.', len(combined_offsets))
 
259
            offset = combined_offsets[0][0]
 
260
            fp.seek(offset)
 
261
            data = fp.read(total_size)
 
262
            pos = 0
 
263
            for offset, size in combined_offsets:
 
264
                yield offset, data[pos:pos + size]
 
265
                pos += size
 
266
 
 
267
        if not len(offsets):
 
268
            return
 
269
        fp = self.get(relpath)
 
270
        pending_offsets = deque(offsets)
 
271
        combined_offsets = []
 
272
        while len(pending_offsets):
 
273
            offset, size = pending_offsets.popleft()
 
274
            if not combined_offsets:
 
275
                combined_offsets = [[offset, size]]
 
276
            else:
 
277
                if (len (combined_offsets) < 50 and
 
278
                    combined_offsets[-1][0] + combined_offsets[-1][1] == offset):
 
279
                    # combatible offset:
 
280
                    combined_offsets.append([offset, size])
 
281
                else:
 
282
                    # incompatible, or over the threshold issue a read and yield
 
283
                    pending_offsets.appendleft((offset, size))
 
284
                    for result in do_combined_read(combined_offsets):
 
285
                        yield result
 
286
                    combined_offsets = []
 
287
        # whatever is left is a single coalesced request
 
288
        if len(combined_offsets):
 
289
            for result in do_combined_read(combined_offsets):
 
290
                yield result
 
291
 
247
292
    def get_multi(self, relpaths, pb=None):
248
293
        """Get a list of file-like objects, one for each entry in relpaths.
249
294
 
630
675
                # from running this test
631
676
                pass
632
677
        return result
 
678
 
 
679
 
 
680
class TransportLogger(object):
 
681
    """Adapt a transport to get clear logging data on api calls.
 
682
    
 
683
    Feel free to extend to log whatever calls are of interest.
 
684
    """
 
685
 
 
686
    def __init__(self, adapted):
 
687
        self._adapted = adapted
 
688
        self._calls = []
 
689
 
 
690
    def get(self, name):
 
691
        self._calls.append((name,))
 
692
        return self._adapted.get(name)
 
693
 
 
694
    def __getattr__(self, name):
 
695
        """Thunk all undefined access through to self._adapted."""
 
696
        # raise AttributeError, name 
 
697
        return getattr(self._adapted, name)
 
698
 
 
699
    def readv(self, name, offsets):
 
700
        self._calls.append((name, offsets))
 
701
        return self._adapted.readv(name, offsets)
633
702
        
634
703
 
635
704
# None is the default transport, for things with no url scheme